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_LIB_TEXT ("size_ = %d\n"), this->size_));
00030 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("head_ = %x\n"), this->head_));
00031 ACE_DEBUG ((LM_DEBUG, ACE_LIB_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 {
00129 ACE_TRACE ("ACE_Obstack_T<CHAR>::ACE_Obstack");
00130
00131 if (this->allocator_strategy_ == 0)
00132 ACE_ALLOCATOR (this->allocator_strategy_,
00133 ACE_Allocator::instance ());
00134
00135 this->head_ = this->new_chunk ();
00136 this->curr_ = this->head_;
00137 }
00138
00139 template <class CHAR>
00140 ACE_Obstack_T<CHAR>::~ACE_Obstack_T (void)
00141 {
00142 ACE_TRACE ("ACE_Obstack_T<CHAR>::~ACE_Obstack_T");
00143
00144 ACE_Obchunk *temp = this->head_;
00145
00146 while (temp != 0)
00147 {
00148 ACE_Obchunk *next = temp->next_;
00149 temp->next_ = 0;
00150 this->allocator_strategy_->free (temp);
00151 temp = next;
00152 }
00153 }
00154
00155 template <class CHAR> CHAR *
00156 ACE_Obstack_T<CHAR>::copy (const CHAR *s,
00157 size_t len)
00158 {
00159 ACE_TRACE ("ACE_Obstack_T<CHAR>::copy");
00160
00161 if (this->request (len) != 0)
00162 return 0;
00163
00164 size_t tsize = len * sizeof (CHAR);
00165 ACE_OS::memcpy (this->curr_->cur_, s, tsize);
00166 this->curr_->cur_ += tsize ;
00167 return this->freeze ();
00168 }
00169
00170 template <class CHAR> void
00171 ACE_Obstack_T<CHAR>::unwind (void* obj)
00172 {
00173 if (obj >= this->curr_->contents_ && obj < this->curr_->end_)
00174 this->curr_->block_ = this->curr_->cur_ = reinterpret_cast<char*> (obj);
00175 else
00176 this->unwind_i (obj);
00177 }
00178
00179 template <class CHAR> void
00180 ACE_Obstack_T<CHAR>::unwind_i (void* obj)
00181 {
00182 ACE_Obchunk* curr;
00183
00184 curr = this->head_;
00185 while (curr != 0 && (curr->contents_ > obj || curr->end_ < obj))
00186 curr = curr->next_;
00187 if (curr)
00188 {
00189 this->curr_ = curr;
00190 this->curr_->block_ = this->curr_->cur_ = reinterpret_cast<char*> (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 ACE_END_VERSIONED_NAMESPACE_DECL
00207
00208 #endif