xserializeengine.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,145 行 · 第 1/2 页

CPP
1,145
字号
/* * Copyright 2003-2004 The Apache Software Foundation. *  * Licensed 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: XSerializeEngine.cpp,v 1.19 2004/09/08 13:56:14 peiyongz Exp $ * $Log: XSerializeEngine.cpp,v $ * Revision 1.19  2004/09/08 13:56:14  peiyongz * Apache License Version 2.0 * * Revision 1.18  2004/07/21 14:54:39  peiyongz * using the supplied memory manager , patch from David Bertoni * * Revision 1.17  2004/03/05 22:21:45  peiyongz * readBytes()/writeBytes between BinOutputStream/BinInputStream and * XSerializeEngine will always be the full size of the buffer to maintain the exact * position for aligned data. * * Revision 1.16  2004/03/01 23:19:03  peiyongz * Grant XSerializeEngine access to GrammarPool * * Revision 1.15  2004/02/20 20:57:39  peiyongz * Bug#27046: path from David Bertoni * * Revision 1.14  2004/01/29 11:46:30  cargilld * Code cleanup changes to get rid of various compiler diagnostic messages. * * Revision 1.13  2004/01/15 23:42:32  peiyongz * proper allignment for built-in datatype read/write * * Revision 1.12  2004/01/13 16:34:20  cargilld * Misc memory management changes. * * Revision 1.11  2004/01/12 16:27:41  neilg * remove use of static buffers * * Revision 1.10  2003/12/17 00:18:34  cargilld * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data. * * Revision 1.9  2003/11/25 20:37:40  jberry * Cleanup build errors/warnings from CodeWarrior * * Revision 1.8  2003/10/20 17:37:05  amassari * Removed compiler warning * * Revision 1.7  2003/10/17 21:09:03  peiyongz * renaming methods * * Revision 1.6  2003/10/07 19:38:31  peiyongz * API for Template_Class Object Serialization/Deserialization * * Revision 1.5  2003/09/25 22:22:00  peiyongz * Introduction of readString/writeString * * Revision 1.4  2003/09/25 15:21:12  peiyongz * Loose the assert condition so that Serializable class need NOT to check the * actual string length before read/write. * * Revision 1.3  2003/09/23 18:11:29  peiyongz * Using HashPtr * * Revision 1.1  2003/09/18 18:31:24  peiyongz * OSU: Object Serialization Utilities * * */// ---------------------------------------------------------------------------//  Includes// ---------------------------------------------------------------------------#include <xercesc/internal/XSerializeEngine.hpp>#include <xercesc/internal/XSerializable.hpp>#include <xercesc/internal/XProtoType.hpp>#include <xercesc/util/HashPtr.hpp>#include <xercesc/framework/XMLGrammarPool.hpp>#include <xercesc/framework/BinOutputStream.hpp>#include <xercesc/util/BinInputStream.hpp>XERCES_CPP_NAMESPACE_BEGINconst bool XSerializeEngine::toWriteBufferLen = true;const bool XSerializeEngine::toReadBufferLen  = true;static const int noDataFollowed = -1;static const XSerializeEngine::XSerializedObjectId_t fgNullObjectTag  = 0;           // indicating null ptrsstatic const XSerializeEngine::XSerializedObjectId_t fgNewClassTag    = 0xFFFFFFFF;  // indicating new classstatic const XSerializeEngine::XSerializedObjectId_t fgTemplateObjTag = 0xFFFFFFFE;  // indicating template objectstatic const XSerializeEngine::XSerializedObjectId_t fgClassMask      = 0x80000000;  // indicates class tagstatic const XSerializeEngine::XSerializedObjectId_t fgMaxObjectCount = 0x3FFFFFFD;  #define TEST_THROW_ARG1(condition, data, err_msg) \if (condition) \{ \    XMLCh value1[17]; \    XMLString::binToText(data, value1, 16, 10, getMemoryManager()); \    ThrowXMLwithMemMgr1(XSerializationException \            , err_msg  \            , value1 \            , getMemoryManager()); \}#define TEST_THROW_ARG2(condition, data1, data2, err_msg) \if (condition) \{ \    XMLCh value1[17]; \    XMLCh value2[17]; \    XMLString::binToText(data1, value1, 16, 10, getMemoryManager()); \    XMLString::binToText(data2, value2, 16, 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                                 , unsigned long           bufSize):fStoreLoad(mode_Load),fGrammarPool(gramPool),fInputStream(inStream),fOutputStream(0),fBufSize(bufSize),fBufStart( (XMLByte*) gramPool->getMemoryManager()->allocate(bufSize)),fBufEnd(0),fBufCur(fBufStart),fBufLoadMax(fBufStart),fStorePool(0),fLoadPool( new (gramPool->getMemoryManager()) ValueVectorOf<void*>(29, gramPool->getMemoryManager(), false)),fObjectCount(0){    /***      *  initialize buffer from the inStream     ***/    fillBuffer();}XSerializeEngine::XSerializeEngine(BinOutputStream*        outStream                                 , XMLGrammarPool* const   gramPool                                 , unsigned long           bufSize):fStoreLoad(mode_Store),fGrammarPool(gramPool),fInputStream(0),fOutputStream(outStream),fBufSize(bufSize),fBufStart((XMLByte*) gramPool->getMemoryManager()->allocate(bufSize)),fBufEnd(fBufStart+bufSize),fBufCur(fBufStart),fBufLoadMax(0),fStorePool( new (gramPool->getMemoryManager()) RefHashTableOf<XSerializedObjectId>(29, true, new (gramPool->getMemoryManager()) HashPtr(), gramPool->getMemoryManager()) ),fLoadPool(0),fObjectCount(0){    //initialize store pool    fStorePool->put(0, new (gramPool->getMemoryManager()) XSerializedObjectId(fgNullObjectTag));}// ---------------------------------------------------------------------------// Deprecated Constructor // ---------------------------------------------------------------------------XSerializeEngine::XSerializeEngine(BinInputStream*         inStream                                 , MemoryManager* const    manager                                 , unsigned long           bufSize):fStoreLoad(mode_Load),fGrammarPool(0),fInputStream(inStream),fOutputStream(0),fBufSize(bufSize),fBufStart( (XMLByte*) manager->allocate(bufSize)),fBufEnd(0),fBufCur(fBufStart),fBufLoadMax(fBufStart),fStorePool(0),fLoadPool( new (manager) ValueVectorOf<void*>(29, manager, false)),fObjectCount(0){    /***      *  initialize buffer from the inStream     ***/    fillBuffer();}XSerializeEngine::XSerializeEngine(BinOutputStream*        outStream                                 , MemoryManager* const    manager                                 , unsigned long           bufSize):fStoreLoad(mode_Store),fGrammarPool(0),fInputStream(0),fOutputStream(outStream),fBufSize(bufSize),fBufStart((XMLByte*) manager->allocate(bufSize)),fBufEnd(fBufStart+bufSize),fBufCur(fBufStart),fBufLoadMax(0),fStorePool( new (manager) RefHashTableOf<XSerializedObjectId>(29, true, new (manager) HashPtr(), manager) ),fLoadPool(0),fObjectCount(0){    //initialize store pool    fStorePool->put(0, new (manager) 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                           ,       int          writeLen){    write((XMLByte*)toWrite, (sizeof(XMLCh)/sizeof(XMLByte)) * writeLen);}void XSerializeEngine::write(const XMLByte* const toWrite                           ,       int            writeLen){    ensureStoring();    ensurePointer((void*)toWrite);    ensureBufferLen(writeLen);    ensureStoreBuffer();    if (writeLen == 0)        return;    /***     *  If the available space is sufficient, write it up     ***/    int bufAvail = fBufEnd - fBufCur;    if (writeLen <= bufAvail)    {        memcpy(fBufCur, toWrite, writeLen);        fBufCur += writeLen;        return;    }    const XMLByte*  tempWrite   = (const XMLByte*) toWrite;    unsigned int    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 int          bufferLen                                 , bool               toWriteBufLen){    if (toWrite)     {        if (toWriteBufLen)            *this<<bufferLen;        int strLen = XMLString::stringLen(toWrite);        *this<<strLen;        write(toWrite, strLen);    }    else    {        *this<<noDataFollowed;    }}void XSerializeEngine::writeString(const XMLByte* const toWrite                                 , const int            bufferLen                                 , bool                 toWriteBufLen){    if (toWrite)     {        if (toWriteBufLen)            *this<<bufferLen;        int strLen = XMLString::stringLen((char*)toWrite);        *this<<strLen;        write(toWrite, strLen);    }    else    {        *this<<noDataFollowed;    }}// ---------------------------------------------------------------------------//  Loading// ---------------------------------------------------------------------------XSerializable* XSerializeEngine::read(XProtoType* const protoType){    ensureLoading();    ensurePointer(protoType);	XSerializedObjectId_t    objectTag;	XSerializable*           objRet;    if (! read(protoType, &objectTag))	{        /***         * We hava a reference to an existing object in         * load pool, get it.         */        objRet = lookupLoadPool(objectTag);	}	else	{		// create the object from the prototype		objRet = protoType->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();        TEST_THROW_ARG2(((classIndex == 0 ) || (classIndex > loadPoolSize))                  , classIndex                  , loadPoolSize                  , XMLExcepts::XSer_Inv_ClassIndex                  )        ensurePointer(lookupLoadPool(classIndex));   }	return true;}void XSerializeEngine::read(XMLCh* const toRead                          , int          readLen){    read((XMLByte*)toRead, (sizeof(XMLCh)/sizeof(XMLByte))*readLen);}void XSerializeEngine::read(XMLByte* const toRead                          , int            readLen){    ensureLoading();    ensureBufferLen(readLen);    ensurePointer(toRead);    ensureLoadBuffer();    if (readLen == 0)        return;    /***     *  If unread is sufficient, read it up     ***/    int 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;    unsigned int 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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?