diff options
author | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2001-06-14 20:45:43 +0000 |
---|---|---|
committer | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2001-06-14 20:45:43 +0000 |
commit | 2a56f334b4bdaa8ea1d39d6863ae3c6b3bf4b6a0 (patch) | |
tree | 32ea02eab6bc436a29fe2fa67c4d72500bcefacd | |
parent | 8818e88452839abbf8f468f7ee2e7f638904d96f (diff) | |
download | ATCD-2a56f334b4bdaa8ea1d39d6863ae3c6b3bf4b6a0.tar.gz |
This commit was manufactured by cvs2svn to create branch
'jha_ipv6_newbranch'.
-rw-r--r-- | ace/Obchunk.cpp | 30 | ||||
-rw-r--r-- | ace/Obchunk.h | 72 | ||||
-rw-r--r-- | ace/Obchunk.i | 9 | ||||
-rw-r--r-- | ace/Obstack_T.cpp | 165 | ||||
-rw-r--r-- | ace/Obstack_T.h | 114 | ||||
-rw-r--r-- | ace/Obstack_T.i | 33 |
6 files changed, 423 insertions, 0 deletions
diff --git a/ace/Obchunk.cpp b/ace/Obchunk.cpp new file mode 100644 index 00000000000..5143a07a20c --- /dev/null +++ b/ace/Obchunk.cpp @@ -0,0 +1,30 @@ +// $Id$ + +#include "ace/Obchunk.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Obchunk.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Obchunk, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_Obchunk) + +void +ACE_Obchunk::dump (void) const +{ + ACE_TRACE ("ACE_Obchunk::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("end_ = %x\n"), this->end_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("cur_ = %x\n"), this->cur_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Obchunk::ACE_Obchunk (size_t size) + : end_ (contents_ + size), + block_ (contents_), + cur_ (contents_), + next_ (0) +{ +} diff --git a/ace/Obchunk.h b/ace/Obchunk.h new file mode 100644 index 00000000000..9259b97a7a0 --- /dev/null +++ b/ace/Obchunk.h @@ -0,0 +1,72 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file Obchunk.h + * + * $Id$ + * + * @author Doug Schmidt + */ +//============================================================================= + + +#ifndef ACE_OBCHUNK_H +#define ACE_OBCHUNK_H +#include "ace/pre.h" + +#include "ace/Malloc.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class ACE_Obchunk + * + * @brief Defines the state that represents a "chunk" of memory. + * Evenything in this class is public because it is designed + * as an internal structure of Obstack_T and users are + * not supposed to use this class directly. + * @sa ACE_Obstack_T + */ +class ACE_Export ACE_Obchunk +{ +public: + /// Constructor. + ACE_Obchunk (size_t size); + + /// Dtor. + ~ACE_Obchunk (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Pointer to the end of the chunk. + char *end_; + + /// Pointer to the head of the current building block. + char *block_; + + /// Pointer to the current location in the chunk. + char *cur_; + + /// Next chunk in the chain. + ACE_Obchunk *next_; + + /** + * Pointer to the beginning contents of this chunk. This field is + * actually overlayed by the memory allocated by + * <ACE_Obstack::new_chunk>. Therefore, it *must* come last. + */ + char contents_[4]; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Obchunk.i" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" +#endif /* ACE_OBCHUNK_H */ diff --git a/ace/Obchunk.i b/ace/Obchunk.i new file mode 100644 index 00000000000..510c511d4f9 --- /dev/null +++ b/ace/Obchunk.i @@ -0,0 +1,9 @@ +/* -*- C++ -*- */ +// $Id$ + +// Obchunk.i + +ACE_INLINE +ACE_Obchunk::~ACE_Obchunk (void) +{ +} diff --git a/ace/Obstack_T.cpp b/ace/Obstack_T.cpp new file mode 100644 index 00000000000..5bb13b7e44d --- /dev/null +++ b/ace/Obstack_T.cpp @@ -0,0 +1,165 @@ +// $Id$ + +#include "ace/Obstack_T.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Obstack_T.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Obstack_T, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_Obstack_T) + +template <class CHAR> void +ACE_Obstack_T<CHAR>::dump (void) const +{ + ACE_TRACE ("ACE_Obstack_T<CHAR>::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("size_ = %d\n"), this->size_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("head_ = %x\n"), this->head_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("curr_ = %x\n"), this->curr_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template <class CHAR> int +ACE_Obstack_T<CHAR>::request (size_t len) +{ + ACE_TRACE ("ACE_Obstack_T<CHAR>::request"); + + // normalize the length. + len *= sizeof (CHAR); + + // We will always have enough room for null terminating char + // unless sizeof (char) > 4. + // There's no way we can handle more than this->size_ of strings. + if (this->size_ < len) + return -1; + + // Check whether we need to grow our chunk... + if (this->curr_->cur_ + len >= this->curr_->end_) + { + ACE_Obchunk *temp = this->curr_; + if (this->curr_->next_ == 0) + { + // We must allocate new memory. + this->curr_->next_ = this->new_chunk (); + this->curr_ = this->curr_->next_; + } + else + { + // We can reuse previously allocated memory. + this->curr_ = this->curr_->next_; + this->curr_->block_ = this->curr_->cur_ = this->curr_->contents_; + } + + // if there are something in there already. + if (temp->cur_ != temp->block_) + { + // @@ Require pointer arithmatic? + size_t datasize = temp->cur_ - temp->block_; + + // Check the total length of data again. + if (this->size_ < len + datasize) + return -1; + + ACE_OS::memcpy (this->curr_->block_, + temp->block_, + datasize); + this->curr_->cur_ = this->curr_->block_ + datasize; + } + } + + return 0; +} + +template <class CHAR> CHAR * +ACE_Obstack_T<CHAR>::grow (CHAR c) +{ + ACE_TRACE ("ACE_Obstack_T<CHAR>::grow"); + + if (this->request (1) == 0) + { + CHAR *retv = ACE_reinterpret_cast (CHAR *, + this->curr_->cur_); + this->curr_->cur_ += sizeof (CHAR); + *retv = c; + return retv; + } + else + return 0; +} + +template <class CHAR> ACE_Obchunk * +ACE_Obstack_T<CHAR>::new_chunk (void) +{ + ACE_TRACE ("ACE_Obstack_T<CHAR>::new_chunk"); + + char *temp; + + ACE_ALLOCATOR_RETURN + (temp, + ACE_static_cast (char *, + this->allocator_strategy_->malloc + (sizeof (class ACE_Obchunk) + + this->size_)), + 0); + + return new (temp) ACE_Obchunk (this->size_); +} + +template <class CHAR> +ACE_Obstack_T<CHAR>::ACE_Obstack_T (size_t size, + ACE_Allocator *allocator_strategy) + : allocator_strategy_ (allocator_strategy), + size_ (size) +{ + ACE_TRACE ("ACE_Obstack_T<CHAR>::ACE_Obstack"); + + if (this->allocator_strategy_ == 0) + ACE_ALLOCATOR (this->allocator_strategy_, + ACE_Allocator::instance ()); + + this->head_ = this->new_chunk (); + this->curr_ = this->head_; +} + +template <class CHAR> +ACE_Obstack_T<CHAR>::~ACE_Obstack_T (void) +{ + ACE_TRACE ("ACE_Obstack_T<CHAR>::~ACE_Obstack_T"); + + ACE_Obchunk *temp = this->head_; + + while (temp != 0) + { + ACE_Obchunk *next = temp->next_; + temp->next_ = 0; + this->allocator_strategy_->free ((void *) temp); + temp = next; + } +} + +template <class CHAR> CHAR * +ACE_Obstack_T<CHAR>::copy (const CHAR *s, + size_t len) +{ + ACE_TRACE ("ACE_Obstack_T<CHAR>::copy"); + + if (this->request (len) != 0) + return 0; + + size_t tsize = len * sizeof (CHAR); + ACE_OS::memcpy (this->curr_->cur_, s, tsize); + this->curr_->cur_ += tsize ; + return this->freeze (); +} + +template <class CHAR> void +ACE_Obstack_T<CHAR>::release (void) +{ + ACE_TRACE ("ACE_Obstack_T<CHAR>::release"); + + this->curr_ = this->head_; + this->curr_->block_ = this->curr_->cur_ = this->curr_->contents_; +} diff --git a/ace/Obstack_T.h b/ace/Obstack_T.h new file mode 100644 index 00000000000..0cf272b3dd0 --- /dev/null +++ b/ace/Obstack_T.h @@ -0,0 +1,114 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file Obstack_T.h + * + * $Id$ + * + * @author Doug Schmidt, Nanbor Wang + */ +//============================================================================= + + +#ifndef ACE_OBSTACK_T_H +#define ACE_OBSTACK_T_H +#include "ace/pre.h" + +#include "ace/Obchunk.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +/** + * @class ACE_Obstack + * + * @brief Define a simple "mark and release" memory allocation utility. + * + * The implementation is similar to the GNU obstack utility, + * which is used extensively in the GCC compiler. + */ +template <class CHAR> +class ACE_Obstack_T +{ +public: + // = Initialization and termination methods. + ACE_Obstack_T (size_t size = (4096 * sizeof (CHAR)) - sizeof (ACE_Obchunk), + ACE_Allocator *allocator_strategy = 0); + ~ACE_Obstack_T (void); + + /// Request Obstack to prepare a block at least @a len long for building + /// a new string. Return -1 if fail, 0 if success. + int request (size_t len); + + /// Inserting a new CHAR \a c into the current building + /// block without freezing (null terminating) the block. + /// This function will create new chunk by checking the + /// boundary of current Obchunk. Return + /// the location \a c gets inserted to, or 0 if error. + CHAR *grow (CHAR c); + + /// Inserting a new CHAR \a c into the current building + /// block without freezing (null terminating) the block and without + /// checking for out-of-bound error. + void grow_fast (CHAR c); + + /// Freeze the current building block by null terminating it. + /// Return the starting address of the current building block, 0 + /// if error occurs. + CHAR *freeze (void); + + /// Copy the data into the current Obchunk and freeze the current + /// block. Return the starting address of the current building + /// block, 0 if error occurs. @a len specify the string length, + /// not the actually data size. + CHAR *copy (const CHAR *data, + size_t len); + + /// Return the maximum @a length or @a size of a string that can be put into + /// this Obstack. @a size = @a length * sizeof (CHAR). + size_t length (void) const; + size_t size (void) const; + + /// "Release" the entire stack of Obchunks, putting it back on the + /// free list. + void release (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + class ACE_Obchunk *new_chunk (void); + + /// Pointer to the allocator used by this Obstack. + ACE_Allocator *allocator_strategy_; + + /// Current size of the Obstack; + size_t size_; + + // Don't change the order of the following two fields. + /// Head of the Obchunk chain. + class ACE_Obchunk *head_; + + /// Pointer to the current Obchunk. + class ACE_Obchunk *curr_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Obstack_T.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Obstack_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Obstack_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include "ace/post.h" +#endif /* ACE_OBSTACK_T_H */ diff --git a/ace/Obstack_T.i b/ace/Obstack_T.i new file mode 100644 index 00000000000..f6ff337ba6e --- /dev/null +++ b/ace/Obstack_T.i @@ -0,0 +1,33 @@ +// $Id$ + +template <class CHAR> ACE_INLINE size_t +ACE_Obstack_T<CHAR>::length () const +{ + return this->size_ / sizeof (CHAR); +} + +template <class CHAR> ACE_INLINE size_t +ACE_Obstack_T<CHAR>::size () const +{ + return this->size_; +} + +template <class CHAR> ACE_INLINE void +ACE_Obstack_T<CHAR>::grow_fast (CHAR c) +{ + * (ACE_reinterpret_cast (CHAR *, + this->curr_->cur_)) = c; + this->curr_->cur_ += sizeof (CHAR); +} + +template <class CHAR> ACE_INLINE CHAR * +ACE_Obstack_T<CHAR>::freeze (void) +{ + CHAR *retv = ACE_reinterpret_cast (CHAR *, this->curr_->block_); + * (ACE_reinterpret_cast (CHAR *, + this->curr_->cur_)) = 0; + + this->curr_->cur_ += sizeof (CHAR); + this->curr_->block_ = this->curr_->cur_; + return retv; +} |