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