summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-06-14 20:45:43 +0000
committernobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-06-14 20:45:43 +0000
commit2a56f334b4bdaa8ea1d39d6863ae3c6b3bf4b6a0 (patch)
tree32ea02eab6bc436a29fe2fa67c4d72500bcefacd
parent8818e88452839abbf8f468f7ee2e7f638904d96f (diff)
downloadATCD-2a56f334b4bdaa8ea1d39d6863ae3c6b3bf4b6a0.tar.gz
This commit was manufactured by cvs2svn to create branch
'jha_ipv6_newbranch'.
-rw-r--r--ace/Obchunk.cpp30
-rw-r--r--ace/Obchunk.h72
-rw-r--r--ace/Obchunk.i9
-rw-r--r--ace/Obstack_T.cpp165
-rw-r--r--ace/Obstack_T.h114
-rw-r--r--ace/Obstack_T.i33
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;
+}