1 // $Id: Obstack_T.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #ifndef ACE_OBSTACK_T_CPP
4 #define ACE_OBSTACK_T_CPP
6 #include "ace/Obstack_T.h"
7 #include "ace/Malloc_Base.h"
8 #include "ace/OS_NS_string.h"
10 #if !defined (ACE_LACKS_PRAGMA_ONCE)
12 #endif /* ACE_LACKS_PRAGMA_ONCE */
14 #if !defined (__ACE_INLINE__)
15 #include "ace/Obstack_T.inl"
16 #endif /* __ACE_INLINE__ */
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 ACE_ALLOC_HOOK_DEFINE(ACE_Obstack_T
)
22 template <class CHAR
> void
23 ACE_Obstack_T
<CHAR
>::dump (void) const
25 #if defined (ACE_HAS_DUMP)
26 ACE_TRACE ("ACE_Obstack_T<CHAR>::dump");
28 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
29 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("size_ = %d\n"), this->size_
));
30 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("head_ = %x\n"), this->head_
));
31 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("curr_ = %x\n"), this->curr_
));
32 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
33 #endif /* ACE_HAS_DUMP */
36 template <class CHAR
> int
37 ACE_Obstack_T
<CHAR
>::request (size_t len
)
39 ACE_TRACE ("ACE_Obstack_T<CHAR>::request");
41 // normalize the length.
44 // Check to see if there's room for the requested length, including
45 // any part of an existing string, if any.
46 size_t resulting_len
= (this->curr_
->cur_
- this->curr_
->block_
) + len
;
48 // Increase the length of the underlying chunks if the request made is
49 // for bigger sized chunks.
50 if (this->size_
< resulting_len
)
51 this->size_
= this->size_
<< 1;
53 // We now know the request will fit; see if it can fit in the current
54 // chunk or will need a new one.
55 if (this->curr_
->cur_
+ len
>= this->curr_
->end_
)
57 // Need a new chunk. Save the current one so the current string can be
58 // copied to the new chunk.
59 ACE_Obchunk
*temp
= this->curr_
;
60 if (this->curr_
->next_
== 0)
62 // We must allocate new memory.
63 ACE_Obchunk
* tmp
= this->new_chunk();
66 this->curr_
->next_
= tmp
;
67 this->curr_
= this->curr_
->next_
;
71 // We can reuse previously allocated memory.
72 this->curr_
= this->curr_
->next_
;
73 this->curr_
->block_
= this->curr_
->cur_
= this->curr_
->contents_
;
76 // Copy any initial characters to the new chunk.
77 if (temp
->cur_
!= temp
->block_
)
79 size_t datasize
= temp
->cur_
- temp
->block_
;
80 ACE_OS::memcpy (this->curr_
->block_
,
83 this->curr_
->cur_
= this->curr_
->block_
+ datasize
;
84 // Reset the old chunk.
85 temp
->cur_
= temp
->block_
;
92 template <class CHAR
> CHAR
*
93 ACE_Obstack_T
<CHAR
>::grow (CHAR c
)
95 ACE_TRACE ("ACE_Obstack_T<CHAR>::grow");
97 if (this->request (1) == 0)
99 CHAR
*retv
= reinterpret_cast<CHAR
*> (this->curr_
->cur_
);
100 this->curr_
->cur_
+= sizeof (CHAR
);
108 template <class CHAR
> ACE_Obchunk
*
109 ACE_Obstack_T
<CHAR
>::new_chunk (void)
111 ACE_TRACE ("ACE_Obstack_T<CHAR>::new_chunk");
113 ACE_Obchunk
*temp
= 0;
115 ACE_NEW_MALLOC_RETURN (temp
,
116 static_cast<ACE_Obchunk
*> (this->allocator_strategy_
->malloc
117 (sizeof (class ACE_Obchunk
) + this->size_
)),
118 ACE_Obchunk (this->size_
),
123 template <class CHAR
>
124 ACE_Obstack_T
<CHAR
>::ACE_Obstack_T (size_t size
,
125 ACE_Allocator
*allocator_strategy
)
126 : allocator_strategy_ (allocator_strategy
),
131 ACE_TRACE ("ACE_Obstack_T<CHAR>::ACE_Obstack");
133 if (this->allocator_strategy_
== 0)
134 ACE_ALLOCATOR (this->allocator_strategy_
,
135 ACE_Allocator::instance ());
137 this->head_
= this->new_chunk ();
138 this->curr_
= this->head_
;
141 template <class CHAR
>
142 ACE_Obstack_T
<CHAR
>::~ACE_Obstack_T (void)
144 ACE_TRACE ("ACE_Obstack_T<CHAR>::~ACE_Obstack_T");
146 ACE_Obchunk
*temp
= this->head_
;
150 ACE_Obchunk
*next
= temp
->next_
;
152 this->allocator_strategy_
->free (temp
);
157 template <class CHAR
> CHAR
*
158 ACE_Obstack_T
<CHAR
>::copy (const CHAR
*s
,
161 ACE_TRACE ("ACE_Obstack_T<CHAR>::copy");
163 if (this->request (len
) != 0)
166 size_t tsize
= len
* sizeof (CHAR
);
167 ACE_OS::memcpy (this->curr_
->cur_
, s
, tsize
);
168 this->curr_
->cur_
+= tsize
;
169 return this->freeze ();
172 template <class CHAR
> void
173 ACE_Obstack_T
<CHAR
>::unwind (void* obj
)
175 if (obj
>= this->curr_
->contents_
&& obj
< this->curr_
->end_
)
176 this->curr_
->block_
= this->curr_
->cur_
= reinterpret_cast<char*> (obj
);
178 this->unwind_i (obj
);
181 template <class CHAR
> void
182 ACE_Obstack_T
<CHAR
>::unwind_i (void* obj
)
184 ACE_Obchunk
* curr
= this->head_
;
185 while (curr
!= 0 && (curr
->contents_
> obj
|| curr
->end_
< obj
))
190 this->curr_
->block_
= this->curr_
->cur_
= reinterpret_cast<char*> (obj
);
193 ACE_ERROR ((LM_ERROR
,
194 ACE_TEXT ("Deletion of non-existent object.\n%a")));
197 template <class CHAR
> void
198 ACE_Obstack_T
<CHAR
>::release (void)
200 ACE_TRACE ("ACE_Obstack_T<CHAR>::release");
202 this->curr_
= this->head_
;
203 this->curr_
->block_
= this->curr_
->cur_
= this->curr_
->contents_
;
206 template <class CHAR
> void
207 ACE_Obstack_T
<CHAR
>::grow_fast (CHAR c
)
209 * (reinterpret_cast<CHAR
*> (this->curr_
->cur_
)) = c
;
210 this->curr_
->cur_
+= sizeof (CHAR
);
213 template <class CHAR
> CHAR
*
214 ACE_Obstack_T
<CHAR
>::freeze (void)
216 CHAR
*retv
= reinterpret_cast<CHAR
*> (this->curr_
->block_
);
217 * (reinterpret_cast<CHAR
*> (this->curr_
->cur_
)) = 0;
219 this->curr_
->cur_
+= sizeof (CHAR
);
220 this->curr_
->block_
= this->curr_
->cur_
;
224 ACE_END_VERSIONED_NAMESPACE_DECL
226 #endif /* ACE_OBSTACK_T_CPP */