source: icXML/icXML-devel/src/icxercesc/framework/XMLBuffer.hpp @ 2721

Last change on this file since 2721 was 2721, checked in by cameron, 6 years ago

Fix imports in icXML modified Xerces files

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