|
||||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |