From 94656b0b3c2dc646344c46bfdb558f0b2a83639d Mon Sep 17 00:00:00 2001
From: Tinny Ng <tng@apache.org>
Date: Mon, 22 Jul 2002 23:23:15 +0000
Subject: [PATCH] DOM L3: MemBufFormatTarget stores fDataBuf as XMLByte
 directly, consistent design as MemBufInputSource

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@174047 13f79535-47bb-0310-9956-ffa450edef68
---
 src/xercesc/framework/MemBufFormatTarget.cpp | 72 ++++++++++++++++----
 src/xercesc/framework/MemBufFormatTarget.hpp | 55 ++++++++++++---
 2 files changed, 105 insertions(+), 22 deletions(-)

diff --git a/src/xercesc/framework/MemBufFormatTarget.cpp b/src/xercesc/framework/MemBufFormatTarget.cpp
index f3214187f..697e1197c 100644
--- a/src/xercesc/framework/MemBufFormatTarget.cpp
+++ b/src/xercesc/framework/MemBufFormatTarget.cpp
@@ -57,6 +57,9 @@
 /*
  * $Id$
  * $Log$
+ * Revision 1.3  2002/07/22 23:23:15  tng
+ * DOM L3: MemBufFormatTarget stores fDataBuf as XMLByte directly, consistent design as MemBufInputSource
+ *
  * Revision 1.2  2002/06/05 15:47:13  peiyongz
  * data member changed, reset() added.
  *
@@ -67,42 +70,83 @@
 
 #include <xercesc/framework/MemBufFormatTarget.hpp>
 #include <xercesc/util/XMLString.hpp>
+#include <string.h>
 
-MemBufFormatTarget::MemBufFormatTarget()
+MemBufFormatTarget::MemBufFormatTarget(int capacity)
+    : fDataBuf(0)
+    , fIndex(0)
+    , fCapacity(capacity)
 {
+    // Buffer is one larger than capacity, to allow for zero term
+    fDataBuf = new XMLByte[fCapacity+4];
+
+    // Keep it null terminated
+    fDataBuf[0] = XMLByte(0);
 }
 
 MemBufFormatTarget::~MemBufFormatTarget()
 {
+    delete [] fDataBuf;
 }
 
 void MemBufFormatTarget::writeChars(const XMLByte* const toWrite
                                   , const unsigned int   count
                                   , XMLFormatter * const formatter)
 {
-	//
-	// The toWrite may not be null terminated,
-	// so we need to do some extra work here
-	//
-	XMLByte  lastChar = toWrite[count];   // preserve the last char
-	XMLByte* tmpBuf   = (XMLByte *)toWrite;
+    //
+    // The toWrite may not be null terminated,
+    // so we need to do some extra work here
+    //
+    XMLByte  lastChar = toWrite[count];   // preserve the last char
+    XMLByte* tmpBuf   = (XMLByte *)toWrite;
     tmpBuf[count] = 0;
 
-	XMLCh*   transBuf = XMLString::transcode((char *) tmpBuf);
-	fDataBuf.append(transBuf, XMLString::stringLen(transBuf));
-	delete[] transBuf;
+    if (count) {
+        insureCapacity(count);
+        memcpy(&fDataBuf[fIndex], toWrite, count * sizeof(XMLByte));
+        fIndex += count;
+    }
 
-	tmpBuf[count] = lastChar;             // restore the last char
+    tmpBuf[count] = lastChar;             // restore the last char
 }
 
-XMLCh* MemBufFormatTarget::getString() const
+const XMLByte* MemBufFormatTarget::getRawBuffer() const
 {
-	return XMLString::replicate(fDataBuf.getRawBuffer());
+    fDataBuf[fIndex] = 0;
+    fDataBuf[fIndex + 1] = 0;
+    fDataBuf[fIndex + 2] = 0;
+    fDataBuf[fIndex + 3] = 0;
+    return fDataBuf;
 }
 
 void MemBufFormatTarget::reset()
 {
-    fDataBuf.reset();
+    fIndex = 0;
+    fDataBuf[0] = 0;
+    fDataBuf[fIndex + 1] = 0;
+    fDataBuf[fIndex + 2] = 0;
+    fDataBuf[fIndex + 3] = 0;
 }
 
+// ---------------------------------------------------------------------------
+//  MemBufFormatTarget: Private helper methods
+// ---------------------------------------------------------------------------
+void MemBufFormatTarget::insureCapacity(const unsigned int extraNeeded)
+{
+    // If we can handle it, do nothing yet
+    if (fIndex + extraNeeded < fCapacity)
+        return;
+
+    // Oops, not enough room. Calc new capacity and allocate new buffer
+    const unsigned int newCap = (unsigned int)((fIndex + extraNeeded) * 1.25);
+    XMLByte* newBuf = new XMLByte[newCap+4];
+
+    // Copy over the old stuff
+    memcpy(newBuf, fDataBuf, fCapacity * sizeof(XMLByte) + 4);
+
+    // Clean up old buffer and store new stuff
+    delete [] fDataBuf;
+    fDataBuf = newBuf;
+    fCapacity = newCap;
+}
 
diff --git a/src/xercesc/framework/MemBufFormatTarget.hpp b/src/xercesc/framework/MemBufFormatTarget.hpp
index 715407f6f..b77bbd999 100644
--- a/src/xercesc/framework/MemBufFormatTarget.hpp
+++ b/src/xercesc/framework/MemBufFormatTarget.hpp
@@ -57,6 +57,9 @@
 /*
  * $Id$
  * $Log$
+ * Revision 1.3  2002/07/22 23:23:15  tng
+ * DOM L3: MemBufFormatTarget stores fDataBuf as XMLByte directly, consistent design as MemBufInputSource
+ *
  * Revision 1.2  2002/06/05 15:47:13  peiyongz
  * data member changed, reset() added.
  *
@@ -69,14 +72,13 @@
 #define MemBufFormatTarget_HEADER_GUARD_
 
 #include <xercesc/framework/XMLFormatter.hpp>
-#include <xercesc/framework/XMLBuffer.hpp>
 
 class XMLPARSER_EXPORT MemBufFormatTarget : public XMLFormatTarget {
 public:
 
     /** @name constructors and destructor */
     //@{
-    MemBufFormatTarget() ;
+    MemBufFormatTarget(int capacity = 1023) ;
     ~MemBufFormatTarget();
     //@}
 
@@ -90,16 +92,30 @@ public:
     // -----------------------------------------------------------------------
     //  Getter
     // -----------------------------------------------------------------------
-    /** @name getString */
+    /** @name getRawBuffer */
+    //@{
+    /**
+     * Returned the internal raw buffer.
+     *
+     * The MemBufFormatTarget object owns the buffer which will be deleted when
+     * MemBufFormatTarget is destructed; or will be reset when the reset() function
+     * is called.  User should make a copy of the returned buffer if intend to keep
+     * it independent on the state of the MemBufFormatTarget.
+     */
+    //@}
+    const XMLByte* getRawBuffer() const;
+
+    /** @name getLen */
     //@{
     /**
-     * Returned the internal string buffer.
+     * Returned the length of the raw buffer.
      *
-     * Caller owns the returned string and is accountable
-     * for the memory release
      */
-    XMLCh* getString() const;
     //@}
+    unsigned int getLen() const
+    {
+        return fIndex;
+    }
 
     /** @name reset */
     //@{
@@ -117,7 +133,30 @@ private:
     MemBufFormatTarget(const MemBufFormatTarget&);
     MemBufFormatTarget& operator=(const MemBufFormatTarget&);
 
-    XMLBuffer     fDataBuf;
+    // -----------------------------------------------------------------------
+    //  Private helpers
+    // -----------------------------------------------------------------------
+    void insureCapacity(const unsigned int extraNeeded);
+
+    // -----------------------------------------------------------------------
+    //  Private data members
+    //
+    //  fDataBuf
+    //      The pointer to the buffer data. Its grown as needed. Its always
+    //      one larger than fCapacity, to leave room for the null terminator.
+    //
+    //  fIndex
+    //      The current index into the buffer, as characters are appended
+    //      to it. If its zero, then the buffer is empty.
+    //
+    //  fCapacity
+    //      The current capacity of the buffer. Its actually always one
+    //      larger, to leave room for the null terminator.
+    //
+    // -----------------------------------------------------------------------
+    XMLByte*        fDataBuf;
+    unsigned int    fIndex;
+    unsigned int    fCapacity;
 
 };
 
-- 
GitLab