Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Obstack_T.cpp

Go to the documentation of this file.
00001 // $Id: Obstack_T.cpp,v 1.1.1.2 2003/02/21 18:36:32 chad Exp $
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 /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #if !defined (__ACE_INLINE__)
00013 #include "ace/Obstack_T.i"
00014 #endif /* __ACE_INLINE__ */
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   // normalize the length.
00038   len *= sizeof (CHAR);
00039 
00040   // Check to see if there's room for the requested length, including
00041   // any part of an existing string, if any.
00042   size_t resulting_len = (this->curr_->cur_ - this->curr_->block_) + len;
00043 
00044   // Increase the length of the underlying chunks if the request made is
00045   // for bigger sized chunks.
00046   if (this->size_ < resulting_len)
00047     this->size_ = this->size_ << 1;
00048 
00049   // We now know the request will fit; see if it can fit in the current
00050   // chunk or will need a new one.
00051   if (this->curr_->cur_ + len >= this->curr_->end_)
00052     {
00053       // Need a new chunk. Save the current one so the current string can be
00054       // copied to the new chunk.
00055       ACE_Obchunk *temp = this->curr_;
00056       if (this->curr_->next_ == 0)
00057         {
00058           // We must allocate new memory.
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           // We can reuse previously allocated memory.
00068           this->curr_ = this->curr_->next_;
00069           this->curr_->block_ = this->curr_->cur_ = this->curr_->contents_;
00070         }
00071 
00072       // Copy any initial characters to the new chunk.
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           // Reset the old chunk.
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 /* ACE_OBSTACK_T_C */

Generated on Mon Jun 16 11:20:30 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002