1 #ifndef ACE_OBSTACK_T_CPP
2 #define ACE_OBSTACK_T_CPP
4 #include "ace/Obstack_T.h"
5 #include "ace/Malloc_Base.h"
6 #include "ace/OS_NS_string.h"
8 #if !defined (ACE_LACKS_PRAGMA_ONCE)
10 #endif /* ACE_LACKS_PRAGMA_ONCE */
12 #if !defined (__ACE_INLINE__)
13 #include "ace/Obstack_T.inl"
14 #endif /* __ACE_INLINE__ */
16 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
18 ACE_ALLOC_HOOK_DEFINE_Tc(ACE_Obstack_T
)
20 template <class ACE_CHAR_T
> void
21 ACE_Obstack_T
<ACE_CHAR_T
>::dump () const
23 #if defined (ACE_HAS_DUMP)
24 ACE_TRACE ("ACE_Obstack_T<ACE_CHAR_T>::dump");
26 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
27 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("size_ = %d\n"), this->size_
));
28 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("head_ = %x\n"), this->head_
));
29 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("curr_ = %x\n"), this->curr_
));
30 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
31 #endif /* ACE_HAS_DUMP */
34 template <class ACE_CHAR_T
> int
35 ACE_Obstack_T
<ACE_CHAR_T
>::request (size_t len
)
37 ACE_TRACE ("ACE_Obstack_T<ACE_CHAR_T>::request");
39 // normalize the length.
40 len
*= sizeof (ACE_CHAR_T
);
42 // Check to see if there's room for the requested length, including
43 // any part of an existing string, if any.
44 size_t resulting_len
= (this->curr_
->cur_
- this->curr_
->block_
) + len
;
46 // Increase the length of the underlying chunks if the request made is
47 // for bigger sized chunks.
48 if (this->size_
< resulting_len
)
49 this->size_
= this->size_
<< 1;
51 // We now know the request will fit; see if it can fit in the current
52 // chunk or will need a new one.
53 if (this->curr_
->cur_
+ len
>= this->curr_
->end_
)
55 // Need a new chunk. Save the current one so the current string
56 // can be copied to the new chunk.
57 ACE_Obchunk
*temp
= this->curr_
;
58 if (this->curr_
->next_
== 0)
60 // We must allocate new memory.
61 ACE_Obchunk
* tmp
= this->new_chunk();
64 this->curr_
->next_
= tmp
;
65 this->curr_
= this->curr_
->next_
;
69 // We can reuse previously allocated memory.
70 this->curr_
= this->curr_
->next_
;
71 this->curr_
->block_
= this->curr_
->cur_
= this->curr_
->contents_
;
74 // Copy any initial characters to the new chunk.
75 if (temp
->cur_
!= temp
->block_
)
77 size_t datasize
= temp
->cur_
- temp
->block_
;
78 ACE_OS::memcpy (this->curr_
->block_
,
81 this->curr_
->cur_
= this->curr_
->block_
+ datasize
;
82 // Reset the old chunk.
83 temp
->cur_
= temp
->block_
;
90 template <class ACE_CHAR_T
> ACE_CHAR_T
*
91 ACE_Obstack_T
<ACE_CHAR_T
>::grow (ACE_CHAR_T c
)
93 ACE_TRACE ("ACE_Obstack_T<ACE_CHAR_T>::grow");
95 if (this->request (1) == 0)
97 ACE_CHAR_T
*retv
= reinterpret_cast<ACE_CHAR_T
*> (this->curr_
->cur_
);
98 this->curr_
->cur_
+= sizeof (ACE_CHAR_T
);
106 template <class ACE_CHAR_T
> ACE_Obchunk
*
107 ACE_Obstack_T
<ACE_CHAR_T
>::new_chunk ()
109 ACE_TRACE ("ACE_Obstack_T<ACE_CHAR_T>::new_chunk");
111 ACE_Obchunk
*temp
= 0;
113 ACE_NEW_MALLOC_RETURN (temp
,
114 static_cast<ACE_Obchunk
*> (this->allocator_strategy_
->malloc
115 (sizeof (class ACE_Obchunk
) + this->size_
)),
116 ACE_Obchunk (this->size_
),
121 template <class ACE_CHAR_T
>
122 ACE_Obstack_T
<ACE_CHAR_T
>::ACE_Obstack_T (size_t size
,
123 ACE_Allocator
*allocator_strategy
)
124 : allocator_strategy_ (allocator_strategy
),
129 ACE_TRACE ("ACE_Obstack_T<ACE_CHAR_T>::ACE_Obstack");
131 if (this->allocator_strategy_
== 0)
132 ACE_ALLOCATOR (this->allocator_strategy_
,
133 ACE_Allocator::instance ());
135 this->head_
= this->new_chunk ();
136 this->curr_
= this->head_
;
139 template <class ACE_CHAR_T
>
140 ACE_Obstack_T
<ACE_CHAR_T
>::~ACE_Obstack_T ()
142 ACE_TRACE ("ACE_Obstack_T<ACE_CHAR_T>::~ACE_Obstack_T");
144 ACE_Obchunk
*temp
= this->head_
;
148 ACE_Obchunk
*next
= temp
->next_
;
150 this->allocator_strategy_
->free (temp
);
155 template <class ACE_CHAR_T
> ACE_CHAR_T
*
156 ACE_Obstack_T
<ACE_CHAR_T
>::copy (const ACE_CHAR_T
*s
,
159 ACE_TRACE ("ACE_Obstack_T<ACE_CHAR_T>::copy");
161 if (this->request (len
) != 0)
164 size_t tsize
= len
* sizeof (ACE_CHAR_T
);
165 ACE_OS::memcpy (this->curr_
->cur_
, s
, tsize
);
166 this->curr_
->cur_
+= tsize
;
167 return this->freeze ();
170 template <class ACE_CHAR_T
> void
171 ACE_Obstack_T
<ACE_CHAR_T
>::unwind (void* obj
)
173 if (obj
>= this->curr_
->contents_
&& obj
< this->curr_
->end_
)
174 this->curr_
->block_
= this->curr_
->cur_
= reinterpret_cast<char*> (obj
);
176 this->unwind_i (obj
);
179 template <class ACE_CHAR_T
> void
180 ACE_Obstack_T
<ACE_CHAR_T
>::unwind_i (void* obj
)
182 ACE_Obchunk
* curr
= this->head_
;
183 while (curr
!= 0 && (curr
->contents_
> obj
|| curr
->end_
< obj
))
188 this->curr_
->block_
= this->curr_
->cur_
= reinterpret_cast<char*> (obj
);
191 ACELIB_ERROR ((LM_ERROR
,
192 ACE_TEXT ("Deletion of non-existent object.\n%a")));
195 template <class ACE_CHAR_T
> void
196 ACE_Obstack_T
<ACE_CHAR_T
>::release ()
198 ACE_TRACE ("ACE_Obstack_T<ACE_CHAR_T>::release");
200 this->curr_
= this->head_
;
201 this->curr_
->block_
= this->curr_
->cur_
= this->curr_
->contents_
;
204 template <class ACE_CHAR_T
> void
205 ACE_Obstack_T
<ACE_CHAR_T
>::grow_fast (ACE_CHAR_T c
)
207 * (reinterpret_cast<ACE_CHAR_T
*> (this->curr_
->cur_
)) = c
;
208 this->curr_
->cur_
+= sizeof (ACE_CHAR_T
);
211 template <class ACE_CHAR_T
> ACE_CHAR_T
*
212 ACE_Obstack_T
<ACE_CHAR_T
>::freeze ()
214 ACE_CHAR_T
*retv
= reinterpret_cast<ACE_CHAR_T
*> (this->curr_
->block_
);
215 * (reinterpret_cast<ACE_CHAR_T
*> (this->curr_
->cur_
)) = 0;
217 this->curr_
->cur_
+= sizeof (ACE_CHAR_T
);
218 this->curr_
->block_
= this->curr_
->cur_
;
222 ACE_END_VERSIONED_NAMESPACE_DECL
224 #endif /* ACE_OBSTACK_T_CPP */