source: NonGTP/Xerces/xerces-c_2_8_0/include/xercesc/framework/XMLBuffer.hpp @ 2674

Revision 2674, 9.0 KB checked in by mattausch, 16 years ago (diff)
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: XMLBuffer.hpp 568078 2007-08-21 11:43:25Z amassari $
20 */
21
22
23#if !defined(XMLBUFFER_HPP)
24#define XMLBUFFER_HPP
25
26#include <xercesc/util/XMemory.hpp>
27#include <xercesc/util/PlatformUtils.hpp>
28#include <xercesc/framework/MemoryManager.hpp>
29#include <string.h>
30
31XERCES_CPP_NAMESPACE_BEGIN
32
33class XMLBufferFullHandler;
34
35/**
36 *  XMLBuffer is a lightweight, expandable Unicode text buffer. Since XML is
37 *  inherently theoretically unbounded in terms of the sizes of things, we
38 *  very often need to have expandable buffers. The primary concern here is
39 *  that appends of characters and other buffers or strings be very fast, so
40 *  it always maintains the current buffer size.
41 *
42 *  The buffer is not null terminated until some asks to see the raw buffer
43 *  contents. This also avoids overhead during append operations.
44 */
45class XMLPARSER_EXPORT XMLBuffer : public XMemory
46{
47public :
48    // -----------------------------------------------------------------------
49    //  Constructors and Destructor
50    // -----------------------------------------------------------------------
51
52    /** @name Constructor */
53    //@{
54    XMLBuffer(const unsigned int capacity = 1023
55              , MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager) :
56       
57        fIndex(0)
58        , fCapacity(capacity)
59        , fFullSize(0)
60        , fUsed(false)
61        , fMemoryManager(manager)
62        , fFullHandler(0)       
63        , fBuffer(0)
64    {
65        // Buffer is one larger than capacity, to allow for zero term
66        fBuffer = (XMLCh*) manager->allocate((capacity+1) * sizeof(XMLCh)); //new XMLCh[fCapacity+1];
67
68        // Keep it null terminated
69        fBuffer[0] = XMLCh(0);
70    }
71    //@}
72
73    /** @name Destructor */
74    //@{
75    ~XMLBuffer()
76    {
77        fMemoryManager->deallocate(fBuffer); //delete [] fBuffer;
78    }
79    //@}
80
81    // -----------------------------------------------------------------------
82    //  Buffer Full Handler Management
83    // -----------------------------------------------------------------------
84    void setFullHandler(XMLBufferFullHandler* handler, const unsigned int fullSize)
85    {
86        if (handler && fullSize) {           
87            fFullHandler = handler;
88            fFullSize = fullSize;
89
90            // Need to consider the case that the fullsize is less than the current capacity.
91            // For example, say fullSize = 100 and fCapacity is 1023 (the default).
92            // If the fIndex is less than the fullSize, then no problem.  We can just carry
93            // on by resetting fCapacity to fullsize and proceed business as usual.           
94            // If the fIndex is already bigger than the fullSize then we call insureCapacity
95            // to see if it can handle emptying the current buffer (it will throw an
96            // exception if it can't).
97            if (fullSize < fCapacity) {
98                fCapacity = fullSize;
99                if (fIndex >= fullSize) {
100                    insureCapacity(0);
101                }               
102            }
103        }
104        else {
105            // reset fFullHandler to zero because setFullHandler had bad input
106            fFullHandler = 0;           
107        }
108    }
109
110    // -----------------------------------------------------------------------
111    //  Buffer Management
112    // -----------------------------------------------------------------------
113    void append(const XMLCh toAppend)
114    {
115        // Put in char and bump the index
116        if (fIndex == fCapacity)
117            insureCapacity(1);
118        fBuffer[fIndex++] = toAppend;
119    }
120
121    void append (const XMLCh* const chars, const unsigned int count)
122    {       
123        if (count) {
124            if (fIndex + count >= fCapacity) {
125                insureCapacity(count);
126            }           
127            memcpy(&fBuffer[fIndex], chars, count * sizeof(XMLCh));
128            fIndex += count;
129        }
130        else {
131            append(chars);
132        }
133    }
134
135    void append (const XMLCh* const chars)
136    {
137        if (chars != 0 && *chars != 0) {
138            // get length of chars
139            unsigned int count = 0;
140            for (; *(chars+count); count++ );
141
142            if (fIndex + count >= fCapacity) {
143                insureCapacity(count);
144            } 
145            memcpy(&fBuffer[fIndex], chars, count * sizeof(XMLCh));
146            fIndex += count;
147        }
148    }
149
150    void set (const XMLCh* const chars, const unsigned int count)
151    {
152        fIndex = 0;
153        append(chars, count);
154    }
155
156    void set (const XMLCh* const chars)
157    {
158        fIndex = 0;
159        append(chars);
160    }
161
162    const XMLCh* getRawBuffer() const
163    {
164        fBuffer[fIndex] = 0;
165        return fBuffer;
166    }
167
168    XMLCh* getRawBuffer()
169    {
170        fBuffer[fIndex] = 0;
171        return fBuffer;
172    }
173
174    void reset()
175    {
176        fIndex = 0;
177        fBuffer[0] = 0;
178    }
179
180    // -----------------------------------------------------------------------
181    //  Getters
182    // -----------------------------------------------------------------------
183    bool getInUse() const
184    {
185        return fUsed;
186    }
187
188    unsigned int getLen() const
189    {
190        return fIndex;
191    }
192
193    bool isEmpty() const
194    {
195        return (fIndex == 0);
196    }
197
198    // -----------------------------------------------------------------------
199    //  Setters
200    // -----------------------------------------------------------------------
201    void setInUse(const bool newValue)
202    {
203        fUsed = newValue;
204    }
205
206private :
207    // -----------------------------------------------------------------------
208    //  Unimplemented constructors and operators
209    // -----------------------------------------------------------------------
210    XMLBuffer(const XMLBuffer&);
211    XMLBuffer& operator=(const XMLBuffer&);
212
213    // -----------------------------------------------------------------------
214    //  Declare our friends
215    // -----------------------------------------------------------------------
216    friend class XMLBufBid;
217
218    // -----------------------------------------------------------------------
219    //  Private helpers
220    // -----------------------------------------------------------------------
221    void insureCapacity(const unsigned int extraNeeded);
222
223
224    // -----------------------------------------------------------------------
225    //  Private data members
226    //
227    //  fBuffer
228    //      The pointer to the buffer data. Its grown as needed. Its always
229    //      one larger than fCapacity, to leave room for the null terminator.
230    //
231    //  fIndex
232    //      The current index into the buffer, as characters are appended
233    //      to it. If its zero, then the buffer is empty.
234    //
235    //  fCapacity
236    //      The current capacity of the buffer. Its actually always one
237    //      larger, to leave room for the null terminator.
238    //
239    //  fUsed
240    //      Indicates whether this buffer is in use or not.
241    //
242    //  fFullHandler, fFullSize
243    //      If fFullHandler is non-null, the buffer has a maximum size
244    //      indicated by fFullSize. If writing to the buffer would exceed the
245    //      buffer's maximum size, fFullHandler's bufferFull callback is
246    //      invoked, to empty the buffer.
247    // -----------------------------------------------------------------------   
248    unsigned int                fIndex;
249    unsigned int                fCapacity;
250    unsigned int                fFullSize;
251    bool                        fUsed;
252    MemoryManager* const        fMemoryManager;
253    XMLBufferFullHandler*       fFullHandler;   
254    XMLCh*                      fBuffer;
255};
256
257/**
258 *  XMLBufferFullHandler is a callback interface for clients of
259 *  XMLBuffers that impose a size restriction (e.g. XMLScanner).
260 *  Note that this is intended solely as a mix-in for internal
261 *  use, and therefore does not derive from XMemory (to avoid
262 *  the ambiguous base class problem).
263 */
264class XMLPARSER_EXPORT XMLBufferFullHandler
265{
266public :
267
268    virtual ~XMLBufferFullHandler() {}
269
270    /**
271     * Callback method, intended to allow clients of an XMLBuffer which has
272     * become full to empty it appropriately.
273     * @return true if the handler was able to empty the buffer (either
274     * partially or completely), otherwise false to indicate an error.
275     */
276    virtual bool bufferFull(XMLBuffer&) = 0;
277
278};
279
280XERCES_CPP_NAMESPACE_END
281
282#endif
Note: See TracBrowser for help on using the repository browser.