/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id$ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include #include #include #include #include #include XERCES_CPP_NAMESPACE_BEGIN const bool XSerializeEngine::toWriteBufferLen = true; const bool XSerializeEngine::toReadBufferLen = true; static const unsigned long noDataFollowed = (unsigned long)-1; static const XSerializeEngine::XSerializedObjectId_t fgNullObjectTag = 0; // indicating null ptrs static const XSerializeEngine::XSerializedObjectId_t fgNewClassTag = 0xFFFFFFFF; // indicating new class static const XSerializeEngine::XSerializedObjectId_t fgTemplateObjTag = 0xFFFFFFFE; // indicating template object static const XSerializeEngine::XSerializedObjectId_t fgClassMask = 0x80000000; // indicates class tag static const XSerializeEngine::XSerializedObjectId_t fgMaxObjectCount = 0x3FFFFFFD; #define TEST_THROW_ARG1(condition, data, err_msg) \ if (condition) \ { \ XMLCh value1[64]; \ XMLString::sizeToText(data, value1, 65, 10, getMemoryManager()); \ ThrowXMLwithMemMgr1(XSerializationException \ , err_msg \ , value1 \ , getMemoryManager()); \ } #define TEST_THROW_ARG2(condition, data1, data2, err_msg) \ if (condition) \ { \ XMLCh value1[64]; \ XMLCh value2[64]; \ XMLString::sizeToText(data1, value1, 65, 10, getMemoryManager()); \ XMLString::sizeToText(data2, value2, 65, 10, getMemoryManager()); \ ThrowXMLwithMemMgr2(XSerializationException \ , err_msg \ , value1 \ , value2 \ , getMemoryManager()); \ } // --------------------------------------------------------------------------- // Constructor and Destructor // --------------------------------------------------------------------------- XSerializeEngine::~XSerializeEngine() { if (isStoring()) { flush(); delete fStorePool; } else { delete fLoadPool; } getMemoryManager()->deallocate(fBufStart); } XSerializeEngine::XSerializeEngine(BinInputStream* inStream , XMLGrammarPool* const gramPool , XMLSize_t bufSize) :fStoreLoad(mode_Load) ,fStorerLevel(0) ,fGrammarPool(gramPool) ,fInputStream(inStream) ,fOutputStream(0) ,fBufCount(0) ,fBufSize(bufSize) ,fBufStart( (XMLByte*) gramPool->getMemoryManager()->allocate(bufSize)) ,fBufEnd(0) ,fBufCur(fBufStart) ,fBufLoadMax(fBufStart) ,fStorePool(0) ,fLoadPool( new (gramPool->getMemoryManager()) ValueVectorOf(29, gramPool->getMemoryManager(), false)) ,fObjectCount(0) { /*** * initialize buffer from the inStream ***/ fillBuffer(); } XSerializeEngine::XSerializeEngine(BinOutputStream* outStream , XMLGrammarPool* const gramPool , XMLSize_t bufSize) :fStoreLoad(mode_Store) ,fStorerLevel(0) ,fGrammarPool(gramPool) ,fInputStream(0) ,fOutputStream(outStream) ,fBufCount(0) ,fBufSize(bufSize) ,fBufStart((XMLByte*) gramPool->getMemoryManager()->allocate(bufSize)) ,fBufEnd(fBufStart+bufSize) ,fBufCur(fBufStart) ,fBufLoadMax(0) ,fStorePool( new (gramPool->getMemoryManager()) RefHashTableOf(29, true, gramPool->getMemoryManager()) ) ,fLoadPool(0) ,fObjectCount(0) { resetBuffer(); //initialize store pool fStorePool->put(0, new (gramPool->getMemoryManager()) XSerializedObjectId(fgNullObjectTag)); } void XSerializeEngine::flush() { if (isStoring()) flushBuffer(); } // --------------------------------------------------------------------------- // Storing // --------------------------------------------------------------------------- void XSerializeEngine::write(XSerializable* const objectToWrite) { ensureStoring(); //don't ensurePointer here !!! XSerializedObjectId_t objIndex = 0; if (!objectToWrite) // null pointer { *this << fgNullObjectTag; } else if (0 != (objIndex = lookupStorePool((void*) objectToWrite))) { // writing an object reference tag *this << objIndex; } else { // write protoType first XProtoType* protoType = objectToWrite->getProtoType(); write(protoType); // put the object into StorePool addStorePool((void*)objectToWrite); // ask the object to serialize itself objectToWrite->serialize(*this); } } void XSerializeEngine::write(XProtoType* const protoType) { ensureStoring(); ensurePointer(protoType); XSerializedObjectId_t objIndex = lookupStorePool((void*)protoType); if (objIndex) { //protoType seen in the store pool *this << (fgClassMask | objIndex); } else { // store protoType *this << fgNewClassTag; protoType->store(*this); addStorePool((void*)protoType); } } /*** * ***/ void XSerializeEngine::write(const XMLCh* const toWrite , XMLSize_t writeLen) { write((XMLByte*)toWrite, (sizeof(XMLCh)/sizeof(XMLByte)) * writeLen); } void XSerializeEngine::write(const XMLByte* const toWrite , XMLSize_t writeLen) { ensureStoring(); ensurePointer((void*)toWrite); ensureStoreBuffer(); if (writeLen == 0) return; /*** * If the available space is sufficient, write it up ***/ XMLSize_t bufAvail = fBufEnd - fBufCur; if (writeLen <= bufAvail) { memcpy(fBufCur, toWrite, writeLen); fBufCur += writeLen; return; } const XMLByte* tempWrite = (const XMLByte*) toWrite; XMLSize_t writeRemain = writeLen; // fill up the avaiable space and flush memcpy(fBufCur, tempWrite, bufAvail); tempWrite += bufAvail; writeRemain -= bufAvail; flushBuffer(); // write chunks of fBufSize while (writeRemain >= fBufSize) { memcpy(fBufCur, tempWrite, fBufSize); tempWrite += fBufSize; writeRemain -= fBufSize; flushBuffer(); } // write the remaining if any if (writeRemain) { memcpy(fBufCur, tempWrite, writeRemain); fBufCur += writeRemain; } } /*** * * Storage scheme (normal): * * < * 1st integer: bufferLen (optional) * 2nd integer: dataLen * bytes following: * > * * Storage scheme (special): * < * only integer: noDataFollowed * > */ void XSerializeEngine::writeString(const XMLCh* const toWrite , const XMLSize_t bufferLen , bool toWriteBufLen) { if (toWrite) { if (toWriteBufLen) *this<<(unsigned long)bufferLen; XMLSize_t strLen = XMLString::stringLen(toWrite); *this<<(unsigned long)strLen; write(toWrite, strLen); } else { *this<fCreateObject(getMemoryManager()); Assert((objRet != 0), XMLExcepts::XSer_CreateObject_Fail); // put it into load pool addLoadPool(objRet); // de-serialize it objRet->serialize(*this); } return objRet; } bool XSerializeEngine::read(XProtoType* const protoType , XSerializedObjectId_t* objectTagRet) { ensureLoading(); ensurePointer(protoType); XSerializedObjectId_t obTag; *this >> obTag; // object reference tag found if (!(obTag & fgClassMask)) { *objectTagRet = obTag; return false; } if (obTag == fgNewClassTag) { // what follows fgNewClassTag is the prototype object info // for the object anticipated, go and verify the info XProtoType::load(*this, protoType->fClassName, getMemoryManager()); addLoadPool((void*)protoType); } else { // what follows class tag is an XSerializable object XSerializedObjectId_t classIndex = (obTag & ~fgClassMask); XSerializedObjectId_t loadPoolSize = (XSerializedObjectId_t)fLoadPool->size(); if ((classIndex == 0 ) || (classIndex > loadPoolSize)) { XMLCh value1[64]; XMLCh value2[64]; XMLString::binToText(classIndex, value1, 65, 10, getMemoryManager()); XMLString::binToText(loadPoolSize, value2, 65, 10, getMemoryManager()); ThrowXMLwithMemMgr2(XSerializationException , XMLExcepts::XSer_Inv_ClassIndex , value1 , value2 , getMemoryManager()); } ensurePointer(lookupLoadPool(classIndex)); } return true; } void XSerializeEngine::read(XMLCh* const toRead , XMLSize_t readLen) { read((XMLByte*)toRead, (sizeof(XMLCh)/sizeof(XMLByte))*readLen); } void XSerializeEngine::read(XMLByte* const toRead , XMLSize_t readLen) { ensureLoading(); ensurePointer(toRead); ensureLoadBuffer(); if (readLen == 0) return; /*** * If unread is sufficient, read it up ***/ XMLSize_t dataAvail = fBufLoadMax - fBufCur; if (readLen <= dataAvail) { memcpy(toRead, fBufCur, readLen); fBufCur += readLen; return; } /*** * * fillBuffer will discard anything left in the buffer * before it asks the inputStream to fill in the buffer, * so we need to readup everything in the buffer before * calling fillBuffer * ***/ XMLByte* tempRead = (XMLByte*) toRead; XMLSize_t readRemain = readLen; // read the unread memcpy(tempRead, fBufCur, dataAvail); tempRead += dataAvail; readRemain -= dataAvail; // read chunks of fBufSize while (readRemain >= fBufSize) { fillBuffer(); memcpy(tempRead, fBufCur, fBufSize); tempRead += fBufSize; readRemain -= fBufSize; } // read the remaining if any if (readRemain) { fillBuffer(); memcpy(tempRead, fBufCur, readRemain); fBufCur += readRemain; } } /*** * * Storage scheme (normal): * * < * 1st integer: bufferLen (optional) * 2nd integer: dataLen * bytes following: * > * * Storage scheme (special): * < * only integer: noDataFollowed * > */ void XSerializeEngine::readString(XMLCh*& toRead , XMLSize_t& bufferLen , XMLSize_t& dataLen , bool toReadBufLen) { /*** * Check if any data written ***/ unsigned long tmp; *this>>tmp; bufferLen=tmp; if (bufferLen == noDataFollowed) { toRead = 0; bufferLen = 0; dataLen = 0; return; } if (toReadBufLen) { *this>>tmp; dataLen=tmp; } else { dataLen = bufferLen++; } toRead = (XMLCh*) getMemoryManager()->allocate(bufferLen * sizeof(XMLCh)); read(toRead, dataLen); toRead[dataLen] = 0; } void XSerializeEngine::readString(XMLByte*& toRead , XMLSize_t& bufferLen , XMLSize_t& dataLen , bool toReadBufLen) { /*** * Check if any data written ***/ unsigned long tmp; *this>>tmp; bufferLen=tmp; if (bufferLen == noDataFollowed) { toRead = 0; bufferLen = 0; dataLen = 0; return; } if (toReadBufLen) { *this>>tmp; dataLen=tmp; } else { dataLen = bufferLen++; } toRead = (XMLByte*) getMemoryManager()->allocate(bufferLen * sizeof(XMLByte)); read(toRead, dataLen); toRead[dataLen] = 0; } // --------------------------------------------------------------------------- // Insertion & Extraction // --------------------------------------------------------------------------- XSerializeEngine& XSerializeEngine::operator<<(XMLCh xch) { checkAndFlushBuffer(calBytesNeeded(sizeof(XMLCh))); alignBufCur(sizeof(XMLCh)); *(XMLCh*)fBufCur = xch; fBufCur += sizeof(XMLCh); return *this; } XSerializeEngine& XSerializeEngine::operator>>(XMLCh& xch) { checkAndFillBuffer(calBytesNeeded(sizeof(XMLCh))); alignBufCur(sizeof(XMLCh)); xch = *(XMLCh*)fBufCur; fBufCur += sizeof(XMLCh); return *this; } XSerializeEngine& XSerializeEngine::operator<<(XMLByte by) { checkAndFlushBuffer(sizeof(XMLByte)); *(XMLByte*)fBufCur = by; fBufCur += sizeof(XMLByte); return *this; } XSerializeEngine& XSerializeEngine::operator>>(XMLByte& by) { checkAndFillBuffer(sizeof(XMLByte)); by = *(XMLByte*)fBufCur; fBufCur += sizeof(XMLByte); return *this; } XSerializeEngine& XSerializeEngine::operator<<(bool b) { checkAndFlushBuffer(sizeof(bool)); *(bool*)fBufCur = b; fBufCur += sizeof(bool); return *this; } XSerializeEngine& XSerializeEngine::operator>>(bool& b) { checkAndFillBuffer(sizeof(bool)); b = *(bool*)fBufCur; fBufCur += sizeof(bool); return *this; } void XSerializeEngine::writeSize (XMLSize_t t) { checkAndFlushBuffer(sizeof(t)); memcpy(fBufCur, &t, sizeof(t)); fBufCur += sizeof(t); } void XSerializeEngine::writeInt64 (XMLInt64 t) { checkAndFlushBuffer(sizeof(t)); memcpy(fBufCur, &t, sizeof(t)); fBufCur += sizeof(t); } void XSerializeEngine::writeUInt64 (XMLUInt64 t) { checkAndFlushBuffer(sizeof(t)); memcpy(fBufCur, &t, sizeof(t)); fBufCur += sizeof(t); } void XSerializeEngine::readSize (XMLSize_t& t) { checkAndFillBuffer(sizeof(t)); memcpy(&t, fBufCur, sizeof(t)); fBufCur += sizeof(t); } void XSerializeEngine::readInt64 (XMLInt64& t) { checkAndFillBuffer(sizeof(t)); memcpy(&t, fBufCur, sizeof(t)); fBufCur += sizeof(t); } void XSerializeEngine::readUInt64 (XMLUInt64& t) { checkAndFillBuffer(sizeof(t)); memcpy(&t, fBufCur, sizeof(t)); fBufCur += sizeof(t); } XSerializeEngine& XSerializeEngine::operator<<(char ch) { return XSerializeEngine::operator<<((XMLByte)ch); } XSerializeEngine& XSerializeEngine::operator>>(char& ch) { return XSerializeEngine::operator>>((XMLByte&)ch); } XSerializeEngine& XSerializeEngine::operator<<(short sh) { checkAndFlushBuffer(calBytesNeeded(sizeof(short))); alignBufCur(sizeof(short)); *(short*)fBufCur = sh; fBufCur += sizeof(short); return *this; } XSerializeEngine& XSerializeEngine::operator>>(short& sh) { checkAndFillBuffer(calBytesNeeded(sizeof(short))); alignBufCur(sizeof(short)); sh = *(short*)fBufCur; fBufCur += sizeof(short); return *this; } XSerializeEngine& XSerializeEngine::operator<<(int i) { checkAndFlushBuffer(calBytesNeeded(sizeof(int))); alignBufCur(sizeof(int)); *(int*)fBufCur = i; fBufCur += sizeof(int); return *this; } XSerializeEngine& XSerializeEngine::operator>>(int& i) { checkAndFillBuffer(calBytesNeeded(sizeof(int))); alignBufCur(sizeof(int)); i = *(int*)fBufCur; fBufCur += sizeof(int); return *this; } XSerializeEngine& XSerializeEngine::operator<<(unsigned int ui) { checkAndFlushBuffer(calBytesNeeded(sizeof(unsigned int))); alignBufCur(sizeof(unsigned int)); *(unsigned int*)fBufCur = ui; fBufCur += sizeof(unsigned int); return *this; } XSerializeEngine& XSerializeEngine::operator>>(unsigned int& ui) { checkAndFillBuffer(calBytesNeeded(sizeof(unsigned int))); alignBufCur(sizeof(unsigned int)); ui = *(unsigned int*)fBufCur; fBufCur += sizeof(unsigned int); return *this; } XSerializeEngine& XSerializeEngine::operator<<(long l) { checkAndFlushBuffer(calBytesNeeded(sizeof(long))); alignBufCur(sizeof(long)); *(long*)fBufCur = l; fBufCur += sizeof(long); return *this; } XSerializeEngine& XSerializeEngine::operator>>(long& l) { checkAndFillBuffer(calBytesNeeded(sizeof(long))); alignBufCur(sizeof(long)); l = *(long*)fBufCur; fBufCur += sizeof(long); return *this; } XSerializeEngine& XSerializeEngine::operator<<(unsigned long ul) { checkAndFlushBuffer(calBytesNeeded(sizeof(unsigned long))); alignBufCur(sizeof(unsigned long)); *(unsigned long*)fBufCur = ul; fBufCur += sizeof(unsigned long); return *this; } XSerializeEngine& XSerializeEngine::operator>>(unsigned long& ul) { checkAndFillBuffer(calBytesNeeded(sizeof(unsigned long))); alignBufCur(sizeof(unsigned long)); ul = *(unsigned long*)fBufCur; fBufCur += sizeof(unsigned long); return *this; } XSerializeEngine& XSerializeEngine::operator<<(float f) { checkAndFlushBuffer(calBytesNeeded(sizeof(float))); alignBufCur(sizeof(float)); *(float*)fBufCur = *(float*)&f; fBufCur += sizeof(float); return *this; } XSerializeEngine& XSerializeEngine::operator>>(float& f) { checkAndFillBuffer(calBytesNeeded(sizeof(float))); alignBufCur(sizeof(float)); *(float*)&f = *(float*)fBufCur; fBufCur += sizeof(float); return *this; } XSerializeEngine& XSerializeEngine::operator<<(double d) { checkAndFlushBuffer(calBytesNeeded(sizeof(double))); alignBufCur(sizeof(double)); *(double*)fBufCur = *(double*)&d; fBufCur += sizeof(double); return *this; } XSerializeEngine& XSerializeEngine::operator>>(double& d) { checkAndFillBuffer(calBytesNeeded(sizeof(double))); alignBufCur(sizeof(double)); *(double*)&d = *(double*)fBufCur; fBufCur += sizeof(double); return *this; } // --------------------------------------------------------------------------- // StorePool/LoadPool Opertions // --------------------------------------------------------------------------- XSerializeEngine::XSerializedObjectId_t XSerializeEngine::lookupStorePool(void* const objToLookup) const { //0 indicating object is not in the StorePool XSerializedObjectId* data = fStorePool->get(objToLookup); return (XSerializeEngine::XSerializedObjectId_t) (data ? data->getValue() : 0); } void XSerializeEngine::addStorePool(void* const objToAdd) { pumpCount(); fStorePool->put(objToAdd, new (fGrammarPool->getMemoryManager()) XSerializedObjectId(fObjectCount)); } XSerializable* XSerializeEngine::lookupLoadPool(XSerializedObjectId_t objectTag) const { /*** * an object tag read from the binary refering to * an object beyond the upper most boundary of the load pool ***/ if (objectTag > fLoadPool->size()) { XMLCh value1[64]; XMLCh value2[64]; XMLString::binToText(objectTag, value1, 65, 10, getMemoryManager()); XMLString::sizeToText(fLoadPool->size(), value2, 65, 10, getMemoryManager()); ThrowXMLwithMemMgr2(XSerializationException , XMLExcepts::XSer_LoadPool_UppBnd_Exceed , value1 , value2 , getMemoryManager()); } if (objectTag == 0) return 0; /*** * A non-null object tag starts from 1 while fLoadPool starts from 0 ***/ return (XSerializable*) fLoadPool->elementAt(objectTag - 1); } void XSerializeEngine::addLoadPool(void* const objToAdd) { TEST_THROW_ARG2( (fLoadPool->size() != fObjectCount) , fObjectCount , fLoadPool->size() , XMLExcepts::XSer_LoadPool_NoTally_ObjCnt ) pumpCount(); fLoadPool->addElement(objToAdd); } void XSerializeEngine::pumpCount() { if (fObjectCount >= fgMaxObjectCount) { XMLCh value1[64]; XMLCh value2[64]; XMLString::sizeToText(fObjectCount, value1, 65, 10, getMemoryManager()); XMLString::binToText(fgMaxObjectCount, value2, 65, 10, getMemoryManager()); ThrowXMLwithMemMgr2(XSerializationException , XMLExcepts::XSer_ObjCount_UppBnd_Exceed , value1 , value2 , getMemoryManager()); } fObjectCount++; } // --------------------------------------------------------------------------- // Buffer Opertions // --------------------------------------------------------------------------- /*** * * Though client may need only miniBytesNeeded, we always request * a full size reading from our inputStream. * * Whatever possibly left in the buffer is abandoned, such as in * the case of CheckAndFillBuffer() * ***/ void XSerializeEngine::fillBuffer() { ensureLoading(); ensureLoadBuffer(); resetBuffer(); XMLSize_t bytesRead = fInputStream->readBytes(fBufStart, fBufSize); /*** * InputStream MUST fill in the exact amount of bytes as requested * to do: combine the checking and create a new exception code later ***/ TEST_THROW_ARG2( (bytesRead < fBufSize) , bytesRead , fBufSize , XMLExcepts::XSer_InStream_Read_LT_Req ) TEST_THROW_ARG2( (bytesRead > fBufSize) , bytesRead , fBufSize , XMLExcepts::XSer_InStream_Read_OverFlow ) fBufLoadMax = fBufStart + fBufSize; fBufCur = fBufStart; ensureLoadBuffer(); fBufCount++; } /*** * * Flush out whatever left in the buffer, from * fBufStart to fBufEnd. * ***/ void XSerializeEngine::flushBuffer() { ensureStoring(); ensureStoreBuffer(); fOutputStream->writeBytes(fBufStart, fBufSize); fBufCur = fBufStart; resetBuffer(); ensureStoreBuffer(); fBufCount++; } inline void XSerializeEngine::checkAndFlushBuffer(XMLSize_t bytesNeedToWrite) { TEST_THROW_ARG1( (bytesNeedToWrite <= 0) , bytesNeedToWrite , XMLExcepts::XSer_Inv_checkFlushBuffer_Size ) // fBufStart ... fBufCur ...fBufEnd if ((fBufCur + bytesNeedToWrite) > fBufEnd) flushBuffer(); } inline void XSerializeEngine::checkAndFillBuffer(XMLSize_t bytesNeedToRead) { TEST_THROW_ARG1( (bytesNeedToRead <= 0) , bytesNeedToRead , XMLExcepts::XSer_Inv_checkFillBuffer_Size ) // fBufStart ... fBufCur ...fBufLoadMax if ((fBufCur + bytesNeedToRead) > fBufLoadMax) { fillBuffer(); } } inline void XSerializeEngine::ensureStoreBuffer() const { XMLSize_t a = (XMLSize_t) (fBufCur - fBufStart); XMLSize_t b = (XMLSize_t) (fBufEnd - fBufCur); TEST_THROW_ARG2 ( !((fBufStart <= fBufCur) && (fBufCur <= fBufEnd)) , a , b , XMLExcepts::XSer_StoreBuffer_Violation ) } inline void XSerializeEngine::ensureLoadBuffer() const { XMLSize_t a = (XMLSize_t) (fBufCur - fBufStart); XMLSize_t b = (XMLSize_t) (fBufLoadMax - fBufCur); TEST_THROW_ARG2 ( !((fBufStart <= fBufCur) && (fBufCur <= fBufLoadMax)) , a , b , XMLExcepts::XSer_LoadBuffer_Violation ) } inline void XSerializeEngine::ensurePointer(void* const ptr) const { TEST_THROW_ARG1( (ptr == 0) , 0 , XMLExcepts::XSer_Inv_Null_Pointer ) } inline void XSerializeEngine::resetBuffer() { memset(fBufStart, 0, fBufSize * sizeof(XMLByte)); } // --------------------------------------------------------------------------- // Template object // --------------------------------------------------------------------------- /*** * * Search the store pool to see if the address has been seen before or not. * * If yes, write the corresponding object Tag to the internal buffer * and return true. * * Otherwise, add the address to the store pool and return false * to notifiy the client application code to store the template object. * ***/ bool XSerializeEngine::needToStoreObject(void* const templateObjectToWrite) { ensureStoring(); //don't ensurePointer here !!! XSerializedObjectId_t objIndex = 0; if (!templateObjectToWrite) { *this << fgNullObjectTag; // null pointer return false; } else if (0 != (objIndex = lookupStorePool(templateObjectToWrite))) { *this << objIndex; // write an object reference tag return false; } else { *this << fgTemplateObjTag; // write fgTemplateObjTag to denote that actual // template object follows addStorePool(templateObjectToWrite); // put the address into StorePool return true; } } bool XSerializeEngine::needToLoadObject(void** templateObjectToRead) { ensureLoading(); XSerializedObjectId_t obTag; *this >> obTag; if (obTag == fgTemplateObjTag) { /*** * what follows fgTemplateObjTag is the actual template object * We need the client application to create a template object * and register it through registerObject(), and deserialize * template object ***/ return true; } else { /*** * We hava a reference to an existing template object, get it. */ *templateObjectToRead = lookupLoadPool(obTag); return false; } } void XSerializeEngine::registerObject(void* const templateObjectToRegister) { ensureLoading(); addLoadPool(templateObjectToRegister); } XMLGrammarPool* XSerializeEngine::getGrammarPool() const { return fGrammarPool; } XMLStringPool* XSerializeEngine::getStringPool() const { return fGrammarPool->getURIStringPool(); } MemoryManager* XSerializeEngine::getMemoryManager() const { //todo: changed to return fGrammarPool->getMemoryManager() return fGrammarPool ? fGrammarPool->getMemoryManager() : XMLPlatformUtils::fgMemoryManager; } // // Based on the current position (fBufCur), calculated the needed size // to read/write // inline XMLSize_t XSerializeEngine::alignAdjust(XMLSize_t size) const { XMLSize_t remainder = (XMLSize_t) fBufCur % size; return (remainder == 0) ? 0 : (size - remainder); } // Adjust the fBufCur inline void XSerializeEngine::alignBufCur(XMLSize_t size) { fBufCur+=alignAdjust(size); assert(((XMLSize_t) fBufCur % size)==0); } inline XMLSize_t XSerializeEngine::calBytesNeeded(XMLSize_t size) const { return (alignAdjust(size) + size); } void XSerializeEngine::trace(char* /*funcName*/) const { return; /* if (isStoring()) printf("\n funcName=<%s>, storing, count=<%lu>, postion=<%lu>\n", funcName, fBufCount, getBufCurAccumulated()); else printf("\n funcName=<%s>, loading, count=<%lu>, postion=<%lu>\n", funcName, fBufCount, getBufCurAccumulated()); */ } XERCES_CPP_NAMESPACE_END