00001
00002
00003 #ifndef ACE_OBSTACK_T_CPP
00004 #define ACE_OBSTACK_T_CPP
00005
00006 #include "ace/Obstack_T.h"
00007 #include "ace/Malloc_Base.h"
00008 #include "ace/OS_NS_string.h"
00009
00010 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00011 # pragma once
00012 #endif
00013
00014 #if !defined (__ACE_INLINE__)
00015 #include "ace/Obstack_T.inl"
00016 #endif
00017
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019
00020 ACE_ALLOC_HOOK_DEFINE(ACE_Obstack_T)
00021
00022 template <class CHAR> void
00023 ACE_Obstack_T<CHAR>::dump (void) const
00024 {
00025 #if defined (ACE_HAS_DUMP)
00026 ACE_TRACE ("ACE_Obstack_T<CHAR>::dump");
00027
00028 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00029 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("size_ = %d\n"), this->size_));
00030 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("head_ = %x\n"), this->head_));
00031 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("curr_ = %x\n"), this->curr_));
00032 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00033 #endif
00034 }
00035
00036 template <class CHAR> int
00037 ACE_Obstack_T<CHAR>::request (size_t len)
00038 {
00039 ACE_TRACE ("ACE_Obstack_T<CHAR>::request");
00040
00041
00042 len *= sizeof (CHAR);
00043
00044
00045
00046 size_t resulting_len = (this->curr_->cur_ - this->curr_->block_) + len;
00047
00048
00049
00050 if (this->size_ < resulting_len)
00051 this->size_ = this->size_ << 1;
00052
00053
00054
00055 if (this->curr_->cur_ + len >= this->curr_->end_)
00056 {
00057
00058
00059 ACE_Obchunk *temp = this->curr_;
00060 if (this->curr_->next_ == 0)
00061 {
00062
00063 ACE_Obchunk* tmp = this->new_chunk();
00064 if (!tmp)
00065 return -1;
00066 this->curr_->next_ = tmp;
00067 this->curr_ = this->curr_->next_;
00068 }
00069 else
00070 {
00071
00072 this->curr_ = this->curr_->next_;
00073 this->curr_->block_ = this->curr_->cur_ = this->curr_->contents_;
00074 }
00075
00076
00077 if (temp->cur_ != temp->block_)
00078 {
00079 size_t datasize = temp->cur_ - temp->block_;
00080 ACE_OS::memcpy (this->curr_->block_,
00081 temp->block_,
00082 datasize);
00083 this->curr_->cur_ = this->curr_->block_ + datasize;
00084
00085 temp->cur_ = temp->block_;
00086 }
00087 }
00088
00089 return 0;
00090 }
00091
00092 template <class CHAR> CHAR *
00093 ACE_Obstack_T<CHAR>::grow (CHAR c)
00094 {
00095 ACE_TRACE ("ACE_Obstack_T<CHAR>::grow");
00096
00097 if (this->request (1) == 0)
00098 {
00099 CHAR *retv = reinterpret_cast<CHAR *> (this->curr_->cur_);
00100 this->curr_->cur_ += sizeof (CHAR);
00101 *retv = c;
00102 return retv;
00103 }
00104 else
00105 return 0;
00106 }
00107
00108 template <class CHAR> ACE_Obchunk *
00109 ACE_Obstack_T<CHAR>::new_chunk (void)
00110 {
00111 ACE_TRACE ("ACE_Obstack_T<CHAR>::new_chunk");
00112
00113 ACE_Obchunk *temp;
00114
00115 ACE_NEW_MALLOC_RETURN (temp,
00116 static_cast<ACE_Obchunk *> (this->allocator_strategy_->malloc
00117 (sizeof (class ACE_Obchunk) + this->size_)),
00118 ACE_Obchunk (this->size_),
00119 0);
00120 return temp;
00121 }
00122
00123 template <class CHAR>
00124 ACE_Obstack_T<CHAR>::ACE_Obstack_T (size_t size,
00125 ACE_Allocator *allocator_strategy)
00126 : allocator_strategy_ (allocator_strategy),
00127 size_ (size),
00128 head_ (0),
00129 curr_ (0)
00130 {
00131 ACE_TRACE ("ACE_Obstack_T<CHAR>::ACE_Obstack");
00132
00133 if (this->allocator_strategy_ == 0)
00134 ACE_ALLOCATOR (this->allocator_strategy_,
00135 ACE_Allocator::instance ());
00136
00137 this->head_ = this->new_chunk ();
00138 this->curr_ = this->head_;
00139 }
00140
00141 template <class CHAR>
00142 ACE_Obstack_T<CHAR>::~ACE_Obstack_T (void)
00143 {
00144 ACE_TRACE ("ACE_Obstack_T<CHAR>::~ACE_Obstack_T");
00145
00146 ACE_Obchunk *temp = this->head_;
00147
00148 while (temp != 0)
00149 {
00150 ACE_Obchunk *next = temp->next_;
00151 temp->next_ = 0;
00152 this->allocator_strategy_->free (temp);
00153 temp = next;
00154 }
00155 }
00156
00157 template <class CHAR> CHAR *
00158 ACE_Obstack_T<CHAR>::copy (const CHAR *s,
00159 size_t len)
00160 {
00161 ACE_TRACE ("ACE_Obstack_T<CHAR>::copy");
00162
00163 if (this->request (len) != 0)
00164 return 0;
00165
00166 size_t tsize = len * sizeof (CHAR);
00167 ACE_OS::memcpy (this->curr_->cur_, s, tsize);
00168 this->curr_->cur_ += tsize ;
00169 return this->freeze ();
00170 }
00171
00172 template <class CHAR> void
00173 ACE_Obstack_T<CHAR>::unwind (void* obj)
00174 {
00175 if (obj >= this->curr_->contents_ && obj < this->curr_->end_)
00176 this->curr_->block_ = this->curr_->cur_ = reinterpret_cast<char*> (obj);
00177 else
00178 this->unwind_i (obj);
00179 }
00180
00181 template <class CHAR> void
00182 ACE_Obstack_T<CHAR>::unwind_i (void* obj)
00183 {
00184 ACE_Obchunk* curr;
00185
00186 curr = this->head_;
00187 while (curr != 0 && (curr->contents_ > obj || curr->end_ < obj))
00188 curr = curr->next_;
00189 if (curr)
00190 {
00191 this->curr_ = curr;
00192 this->curr_->block_ = this->curr_->cur_ = reinterpret_cast<char*> (obj);
00193 }
00194 else if (obj != 0)
00195 ACE_ERROR ((LM_ERROR,
00196 ACE_TEXT ("Deletion of non-existent object.\n%a")));
00197 }
00198
00199 template <class CHAR> void
00200 ACE_Obstack_T<CHAR>::release (void)
00201 {
00202 ACE_TRACE ("ACE_Obstack_T<CHAR>::release");
00203
00204 this->curr_ = this->head_;
00205 this->curr_->block_ = this->curr_->cur_ = this->curr_->contents_;
00206 }
00207
00208 template <class CHAR> void
00209 ACE_Obstack_T<CHAR>::grow_fast (CHAR c)
00210 {
00211 * (reinterpret_cast<CHAR *> (this->curr_->cur_)) = c;
00212 this->curr_->cur_ += sizeof (CHAR);
00213 }
00214
00215 template <class CHAR> CHAR *
00216 ACE_Obstack_T<CHAR>::freeze (void)
00217 {
00218 CHAR *retv = reinterpret_cast<CHAR *> (this->curr_->block_);
00219 * (reinterpret_cast<CHAR *> (this->curr_->cur_)) = 0;
00220
00221 this->curr_->cur_ += sizeof (CHAR);
00222 this->curr_->block_ = this->curr_->cur_;
00223 return retv;
00224 }
00225
00226 ACE_END_VERSIONED_NAMESPACE_DECL
00227
00228 #endif