Obstack_T.cpp

Go to the documentation of this file.
00001 // Obstack_T.cpp,v 4.13 2005/11/22 09:23:55 ossama Exp
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 /* ACE_LACKS_PRAGMA_ONCE */
00013 
00014 #if !defined (__ACE_INLINE__)
00015 #include "ace/Obstack_T.inl"
00016 #endif /* __ACE_INLINE__ */
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 /* ACE_HAS_DUMP */
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   // normalize the length.
00042   len *= sizeof (CHAR);
00043 
00044   // Check to see if there's room for the requested length, including
00045   // any part of an existing string, if any.
00046   size_t resulting_len = (this->curr_->cur_ - this->curr_->block_) + len;
00047 
00048   // Increase the length of the underlying chunks if the request made is
00049   // for bigger sized chunks.
00050   if (this->size_ < resulting_len)
00051     this->size_ = this->size_ << 1;
00052 
00053   // We now know the request will fit; see if it can fit in the current
00054   // chunk or will need a new one.
00055   if (this->curr_->cur_ + len >= this->curr_->end_)
00056     {
00057       // Need a new chunk. Save the current one so the current string can be
00058       // copied to the new chunk.
00059       ACE_Obchunk *temp = this->curr_;
00060       if (this->curr_->next_ == 0)
00061         {
00062           // We must allocate new memory.
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           // We can reuse previously allocated memory.
00072           this->curr_ = this->curr_->next_;
00073           this->curr_->block_ = this->curr_->cur_ = this->curr_->contents_;
00074         }
00075 
00076       // Copy any initial characters to the new chunk.
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           // Reset the old chunk.
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 /* ACE_OBSTACK_T_CPP */

Generated on Thu Nov 9 09:41:57 2006 for ACE by doxygen 1.3.6