Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:14:53

0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one or more
0003  * contributor license agreements.  See the NOTICE file distributed with
0004  * this work for additional information regarding copyright ownership.
0005  * The ASF licenses this file to You under the Apache License, Version 2.0
0006  * (the "License"); you may not use this file except in compliance with
0007  * the License.  You may obtain a copy of the License at
0008  *
0009  *      http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  */
0017 
0018 /*
0019  * $Id$
0020  */
0021 
0022 #if !defined(XERCESC_INCLUDE_GUARD_XMLBUFFER_HPP)
0023 #define XERCESC_INCLUDE_GUARD_XMLBUFFER_HPP
0024 
0025 #include <xercesc/util/XMemory.hpp>
0026 #include <xercesc/util/PlatformUtils.hpp>
0027 #include <xercesc/framework/MemoryManager.hpp>
0028 #include <string.h>
0029 
0030 XERCES_CPP_NAMESPACE_BEGIN
0031 
0032 class XMLBufferFullHandler;
0033 
0034 /**
0035  *  XMLBuffer is a lightweight, expandable Unicode text buffer. Since XML is
0036  *  inherently theoretically unbounded in terms of the sizes of things, we
0037  *  very often need to have expandable buffers. The primary concern here is
0038  *  that appends of characters and other buffers or strings be very fast, so
0039  *  it always maintains the current buffer size.
0040  *
0041  *  The buffer is not null terminated until some asks to see the raw buffer
0042  *  contents. This also avoids overhead during append operations.
0043  */
0044 class XMLPARSER_EXPORT XMLBuffer : public XMemory
0045 {
0046 public :
0047     // -----------------------------------------------------------------------
0048     //  Constructors and Destructor
0049     // -----------------------------------------------------------------------
0050 
0051     /** @name Constructor */
0052     //@{
0053     XMLBuffer(const XMLSize_t capacity = 1023
0054               , MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager) :
0055 
0056         fIndex(0)
0057         , fCapacity(capacity)
0058         , fFullSize(0)
0059         , fUsed(false)
0060         , fMemoryManager(manager)
0061         , fFullHandler(0)
0062         , fBuffer(0)
0063     {
0064         // Buffer is one larger than capacity, to allow for zero term
0065         fBuffer = (XMLCh*) manager->allocate((capacity+1) * sizeof(XMLCh)); //new XMLCh[fCapacity+1];
0066 
0067         // Keep it null terminated
0068         fBuffer[0] = XMLCh(0);
0069     }
0070     //@}
0071 
0072     /** @name Destructor */
0073     //@{
0074     ~XMLBuffer()
0075     {
0076         fMemoryManager->deallocate(fBuffer); //delete [] fBuffer;
0077     }
0078     //@}
0079 
0080     // -----------------------------------------------------------------------
0081     //  Buffer Full Handler Management
0082     // -----------------------------------------------------------------------
0083     void setFullHandler(XMLBufferFullHandler* handler, const XMLSize_t fullSize)
0084     {
0085         if (handler && fullSize) {
0086             fFullHandler = handler;
0087             fFullSize = fullSize;
0088 
0089             // Need to consider the case that the fullsize is less than the current capacity.
0090             // For example, say fullSize = 100 and fCapacity is 1023 (the default).
0091             // If the fIndex is less than the fullSize, then no problem.  We can just carry
0092             // on by resetting fCapacity to fullsize and proceed business as usual.
0093             // If the fIndex is already bigger than the fullSize then we call ensureCapacity
0094             // to see if it can handle emptying the current buffer (it will throw an
0095             // exception if it can't).
0096             if (fullSize < fCapacity) {
0097                 fCapacity = fullSize;
0098                 if (fIndex >= fullSize) {
0099                     ensureCapacity(0);
0100                 }
0101             }
0102         }
0103         else {
0104             // reset fFullHandler to zero because setFullHandler had bad input
0105             fFullHandler = 0;
0106         }
0107     }
0108 
0109     // -----------------------------------------------------------------------
0110     //  Buffer Management
0111     // -----------------------------------------------------------------------
0112     void append(const XMLCh toAppend)
0113     {
0114         // Put in char and bump the index
0115         if (fIndex == fCapacity)
0116             ensureCapacity(1);
0117         fBuffer[fIndex++] = toAppend;
0118     }
0119 
0120     void append (const XMLCh* const chars, const XMLSize_t count)
0121     {
0122         if (count) {
0123             if (fIndex + count >= fCapacity) {
0124                 ensureCapacity(count);
0125             }
0126             memcpy(&fBuffer[fIndex], chars, count * sizeof(XMLCh));
0127             fIndex += count;
0128         }
0129         else {
0130             append(chars);
0131         }
0132     }
0133 
0134     void append (const XMLCh* const chars)
0135     {
0136         if (chars != 0 && *chars != 0) {
0137             // get length of chars
0138             XMLSize_t count = 0;
0139             for (; *(chars+count); count++ ) /*noop*/;
0140 
0141             if (fIndex + count >= fCapacity) {
0142                 ensureCapacity(count);
0143             }
0144             memcpy(&fBuffer[fIndex], chars, count * sizeof(XMLCh));
0145             fIndex += count;
0146         }
0147     }
0148 
0149     void set (const XMLCh* const chars, const XMLSize_t count)
0150     {
0151         fIndex = 0;
0152         append(chars, count);
0153     }
0154 
0155     void set (const XMLCh* const chars)
0156     {
0157         fIndex = 0;
0158         if (chars != 0 && *chars != 0)
0159             append(chars);
0160     }
0161 
0162     const XMLCh* getRawBuffer() const
0163     {
0164         fBuffer[fIndex] = 0;
0165         return fBuffer;
0166     }
0167 
0168     XMLCh* getRawBuffer()
0169     {
0170         fBuffer[fIndex] = 0;
0171         return fBuffer;
0172     }
0173 
0174     void reset()
0175     {
0176         fIndex = 0;
0177     }
0178 
0179     // -----------------------------------------------------------------------
0180     //  Getters
0181     // -----------------------------------------------------------------------
0182     bool getInUse() const
0183     {
0184         return fUsed;
0185     }
0186 
0187     XMLSize_t getLen() const
0188     {
0189         return fIndex;
0190     }
0191 
0192     bool isEmpty() const
0193     {
0194         return (fIndex == 0);
0195     }
0196 
0197     // -----------------------------------------------------------------------
0198     //  Setters
0199     // -----------------------------------------------------------------------
0200     void setInUse(const bool newValue)
0201     {
0202         fUsed = newValue;
0203     }
0204 
0205 private :
0206     // -----------------------------------------------------------------------
0207     //  Unimplemented constructors and operators
0208     // -----------------------------------------------------------------------
0209     XMLBuffer(const XMLBuffer&);
0210     XMLBuffer& operator=(const XMLBuffer&);
0211 
0212     // -----------------------------------------------------------------------
0213     //  Declare our friends
0214     // -----------------------------------------------------------------------
0215     friend class XMLBufBid;
0216 
0217     // -----------------------------------------------------------------------
0218     //  Private helpers
0219     // -----------------------------------------------------------------------
0220     void ensureCapacity(const XMLSize_t extraNeeded);
0221 
0222 
0223     // -----------------------------------------------------------------------
0224     //  Private data members
0225     //
0226     //  fBuffer
0227     //      The pointer to the buffer data. Its grown as needed. Its always
0228     //      one larger than fCapacity, to leave room for the null terminator.
0229     //
0230     //  fIndex
0231     //      The current index into the buffer, as characters are appended
0232     //      to it. If its zero, then the buffer is empty.
0233     //
0234     //  fCapacity
0235     //      The current capacity of the buffer. Its actually always one
0236     //      larger, to leave room for the null terminator.
0237     //
0238     //  fUsed
0239     //      Indicates whether this buffer is in use or not.
0240     //
0241     //  fFullHandler, fFullSize
0242     //      If fFullHandler is non-null, the buffer has a maximum size
0243     //      indicated by fFullSize. If writing to the buffer would exceed the
0244     //      buffer's maximum size, fFullHandler's bufferFull callback is
0245     //      invoked, to empty the buffer.
0246     // -----------------------------------------------------------------------
0247     XMLSize_t                   fIndex;
0248     XMLSize_t                   fCapacity;
0249     XMLSize_t                   fFullSize;
0250     bool                        fUsed;
0251     MemoryManager* const        fMemoryManager;
0252     XMLBufferFullHandler*       fFullHandler;
0253     XMLCh*                      fBuffer;
0254 };
0255 
0256 /**
0257  *  XMLBufferFullHandler is a callback interface for clients of
0258  *  XMLBuffers that impose a size restriction (e.g. XMLScanner).
0259  *  Note that this is intended solely as a mix-in for internal
0260  *  use, and therefore does not derive from XMemory (to avoid
0261  *  the ambiguous base class problem).
0262  */
0263 class XMLPARSER_EXPORT XMLBufferFullHandler
0264 {
0265 public :
0266 
0267     virtual ~XMLBufferFullHandler() {}
0268 
0269     /**
0270      * Callback method, intended to allow clients of an XMLBuffer which has
0271      * become full to empty it appropriately.
0272      * @return true if the handler was able to empty the buffer (either
0273      * partially or completely), otherwise false to indicate an error.
0274      */
0275     virtual bool bufferFull(XMLBuffer&) = 0;
0276 
0277 };
0278 
0279 XERCES_CPP_NAMESPACE_END
0280 
0281 #endif