source: icXML/icXML-devel/src/xercesc/internal/XSerializeEngine.cpp @ 2722

Last change on this file since 2722 was 2722, checked in by cameron, 7 years ago

Original Xerces files with import mods for icxercesc

File size: 28.5 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: XSerializeEngine.cpp 834826 2009-11-11 10:03:53Z borisk $
20 */
21
22
23// ---------------------------------------------------------------------------
24//  Includes
25// ---------------------------------------------------------------------------
26#include <xercesc/internal/XSerializeEngine.hpp>
27#include <xercesc/internal/XSerializable.hpp>
28#include <xercesc/internal/XProtoType.hpp>
29
30#include <icxercesc/framework/XMLGrammarPool.hpp>
31#include <xercesc/framework/BinOutputStream.hpp>
32#include <xercesc/util/BinInputStream.hpp>
33
34#include <stdio.h>
35#include <assert.h>
36
37XERCES_CPP_NAMESPACE_BEGIN
38
39const bool XSerializeEngine::toWriteBufferLen = true;
40const bool XSerializeEngine::toReadBufferLen  = true;
41
42static const unsigned long noDataFollowed = (unsigned long)-1;
43
44static const XSerializeEngine::XSerializedObjectId_t fgNullObjectTag  = 0;           // indicating null ptrs
45static const XSerializeEngine::XSerializedObjectId_t fgNewClassTag    = 0xFFFFFFFF;  // indicating new class
46static const XSerializeEngine::XSerializedObjectId_t fgTemplateObjTag = 0xFFFFFFFE;  // indicating template object
47static const XSerializeEngine::XSerializedObjectId_t fgClassMask      = 0x80000000;  // indicates class tag
48static const XSerializeEngine::XSerializedObjectId_t fgMaxObjectCount = 0x3FFFFFFD;
49
50#define TEST_THROW_ARG1(condition, data, err_msg) \
51if (condition) \
52{ \
53    XMLCh value1[64]; \
54    XMLString::sizeToText(data, value1, 65, 10, getMemoryManager()); \
55    ThrowXMLwithMemMgr1(XSerializationException \
56            , err_msg  \
57            , value1 \
58            , getMemoryManager()); \
59}
60
61#define TEST_THROW_ARG2(condition, data1, data2, err_msg) \
62if (condition) \
63{ \
64    XMLCh value1[64]; \
65    XMLCh value2[64]; \
66    XMLString::sizeToText(data1, value1, 65, 10, getMemoryManager()); \
67    XMLString::sizeToText(data2, value2, 65, 10, getMemoryManager()); \
68    ThrowXMLwithMemMgr2(XSerializationException \
69            , err_msg  \
70            , value1   \
71            , value2 \
72            , getMemoryManager()); \
73}
74
75// ---------------------------------------------------------------------------
76//  Constructor and Destructor
77// ---------------------------------------------------------------------------
78XSerializeEngine::~XSerializeEngine()
79{
80    if (isStoring())
81    {
82        flush();
83        delete fStorePool;
84    }
85    else
86    {
87        delete fLoadPool;
88    }
89
90    getMemoryManager()->deallocate(fBufStart);
91
92}
93
94XSerializeEngine::XSerializeEngine(BinInputStream*         inStream
95                                 , XMLGrammarPool* const   gramPool
96                                 , XMLSize_t               bufSize)
97:fStoreLoad(mode_Load)
98,fStorerLevel(0)
99,fGrammarPool(gramPool)
100,fInputStream(inStream)
101,fOutputStream(0)
102,fBufCount(0)
103,fBufSize(bufSize)
104,fBufStart( (XMLByte*) gramPool->getMemoryManager()->allocate(bufSize))
105,fBufEnd(0)
106,fBufCur(fBufStart)
107,fBufLoadMax(fBufStart)
108,fStorePool(0)
109,fLoadPool( new (gramPool->getMemoryManager()) ValueVectorOf<void*>(29, gramPool->getMemoryManager(), false))
110,fObjectCount(0)
111{
112    /***
113     *  initialize buffer from the inStream
114     ***/
115    fillBuffer();
116
117}
118
119XSerializeEngine::XSerializeEngine(BinOutputStream*        outStream
120                                 , XMLGrammarPool* const   gramPool
121                                 , XMLSize_t               bufSize)
122:fStoreLoad(mode_Store)
123,fStorerLevel(0)
124,fGrammarPool(gramPool)
125,fInputStream(0)
126,fOutputStream(outStream)
127,fBufCount(0)
128,fBufSize(bufSize)
129,fBufStart((XMLByte*) gramPool->getMemoryManager()->allocate(bufSize))
130,fBufEnd(fBufStart+bufSize)
131,fBufCur(fBufStart)
132,fBufLoadMax(0)
133,fStorePool( new (gramPool->getMemoryManager()) RefHashTableOf<XSerializedObjectId, PtrHasher>(29, true, gramPool->getMemoryManager()) )
134,fLoadPool(0)
135,fObjectCount(0)
136{
137    resetBuffer();
138
139    //initialize store pool
140    fStorePool->put(0, new (gramPool->getMemoryManager()) XSerializedObjectId(fgNullObjectTag));
141
142}
143
144void XSerializeEngine::flush()
145{
146    if (isStoring())
147        flushBuffer();
148
149}
150
151// ---------------------------------------------------------------------------
152//  Storing
153// ---------------------------------------------------------------------------
154void XSerializeEngine::write(XSerializable* const objectToWrite)
155{
156    ensureStoring();
157    //don't ensurePointer here !!!
158
159    XSerializedObjectId_t   objIndex = 0;
160
161        if (!objectToWrite)  // null pointer
162        {
163                *this << fgNullObjectTag;
164        }
165    else if (0 != (objIndex = lookupStorePool((void*) objectToWrite)))
166        {
167        // writing an object reference tag
168        *this << objIndex;
169        }
170        else
171        {
172                // write protoType first
173                XProtoType* protoType = objectToWrite->getProtoType();
174                write(protoType);
175
176                // put the object into StorePool
177        addStorePool((void*)objectToWrite);
178
179        // ask the object to serialize itself
180                objectToWrite->serialize(*this);
181        }
182
183}
184
185void XSerializeEngine::write(XProtoType* const protoType)
186{
187    ensureStoring();
188    ensurePointer(protoType);
189
190        XSerializedObjectId_t objIndex = lookupStorePool((void*)protoType);
191
192    if (objIndex)
193    {
194        //protoType seen in the store pool
195        *this << (fgClassMask | objIndex);
196        }
197        else
198        {
199                // store protoType
200                *this << fgNewClassTag;
201                protoType->store(*this);
202        addStorePool((void*)protoType);
203        }
204
205}
206
207/***
208 *
209***/
210void XSerializeEngine::write(const XMLCh* const toWrite
211                           ,       XMLSize_t    writeLen)
212{
213    write((XMLByte*)toWrite, (sizeof(XMLCh)/sizeof(XMLByte)) * writeLen);
214}
215
216
217void XSerializeEngine::write(const XMLByte* const toWrite
218                           ,       XMLSize_t      writeLen)
219{
220    ensureStoring();
221    ensurePointer((void*)toWrite);
222    ensureStoreBuffer();
223
224    if (writeLen == 0)
225        return;
226
227    /***
228     *  If the available space is sufficient, write it up
229     ***/
230    XMLSize_t bufAvail = fBufEnd - fBufCur;
231
232    if (writeLen <= bufAvail)
233    {
234        memcpy(fBufCur, toWrite, writeLen);
235        fBufCur += writeLen;
236        return;
237    }
238
239    const XMLByte*  tempWrite   = (const XMLByte*) toWrite;
240    XMLSize_t       writeRemain = writeLen;
241
242    // fill up the avaiable space and flush
243    memcpy(fBufCur, tempWrite, bufAvail);
244    tempWrite   += bufAvail;
245    writeRemain -= bufAvail;
246    flushBuffer();
247
248    // write chunks of fBufSize
249    while (writeRemain >= fBufSize)
250    {
251        memcpy(fBufCur, tempWrite, fBufSize);
252        tempWrite   += fBufSize;
253        writeRemain -= fBufSize;
254        flushBuffer();
255    }
256
257    // write the remaining if any
258    if (writeRemain)
259    {
260        memcpy(fBufCur, tempWrite, writeRemain);
261        fBufCur += writeRemain;
262    }
263
264}
265
266/***
267 *
268 *     Storage scheme (normal):
269 *
270 *     <
271 *     1st integer:    bufferLen (optional)
272 *     2nd integer:    dataLen
273 *     bytes following:
274 *     >
275 *
276 *     Storage scheme (special):
277 *     <
278 *     only integer:   noDataFollowed
279 *     >
280 */
281
282void XSerializeEngine::writeString(const XMLCh* const toWrite
283                                 , const XMLSize_t    bufferLen
284                                 , bool               toWriteBufLen)
285{
286    if (toWrite)
287    {
288        if (toWriteBufLen)
289            *this<<(unsigned long)bufferLen;
290
291        XMLSize_t strLen = XMLString::stringLen(toWrite);
292        *this<<(unsigned long)strLen;
293
294        write(toWrite, strLen);
295    }
296    else
297    {
298        *this<<noDataFollowed;
299    }
300
301}
302
303void XSerializeEngine::writeString(const XMLByte* const toWrite
304                                 , const XMLSize_t      bufferLen
305                                 , bool                 toWriteBufLen)
306{
307
308    if (toWrite)
309    {
310        if (toWriteBufLen)
311            *this<<(unsigned long)bufferLen;
312
313        XMLSize_t strLen = XMLString::stringLen((char*)toWrite);
314        *this<<(unsigned long)strLen;
315        write(toWrite, strLen);
316    }
317    else
318    {
319        *this<<noDataFollowed;
320    }
321
322}
323
324// ---------------------------------------------------------------------------
325//  Loading
326// ---------------------------------------------------------------------------
327XSerializable* XSerializeEngine::read(XProtoType* const protoType)
328{
329    ensureLoading();
330    ensurePointer(protoType);
331
332        XSerializedObjectId_t    objectTag;
333        XSerializable*           objRet;
334
335    if (! read(protoType, &objectTag))
336        {
337        /***
338         * We hava a reference to an existing object in
339         * load pool, get it.
340         */
341        objRet = lookupLoadPool(objectTag);
342        }
343        else
344        {
345                // create the object from the prototype
346                objRet = protoType->fCreateObject(getMemoryManager());
347        Assert((objRet != 0), XMLExcepts::XSer_CreateObject_Fail);
348
349        // put it into load pool
350        addLoadPool(objRet);
351
352        // de-serialize it
353                objRet->serialize(*this);
354
355        }
356
357        return objRet;
358}
359
360bool XSerializeEngine::read(XProtoType*            const    protoType
361                          , XSerializedObjectId_t*          objectTagRet)
362{
363    ensureLoading();
364    ensurePointer(protoType);
365
366        XSerializedObjectId_t obTag;
367
368    *this >> obTag;
369
370    // object reference tag found
371    if (!(obTag & fgClassMask))
372        {
373                *objectTagRet = obTag;
374                return false;
375        }
376
377        if (obTag == fgNewClassTag)
378        {
379        // what follows fgNewClassTag is the prototype object info
380        // for the object anticipated, go and verify the info
381        XProtoType::load(*this, protoType->fClassName, getMemoryManager());
382
383        addLoadPool((void*)protoType);
384        }
385        else
386        {
387        // what follows class tag is an XSerializable object
388        XSerializedObjectId_t classIndex = (obTag & ~fgClassMask);
389        XSerializedObjectId_t loadPoolSize = (XSerializedObjectId_t)fLoadPool->size();
390
391        if ((classIndex == 0 ) || (classIndex > loadPoolSize))
392        {
393          XMLCh value1[64];
394          XMLCh value2[64];
395          XMLString::binToText(classIndex, value1, 65, 10, getMemoryManager());
396          XMLString::binToText(loadPoolSize, value2, 65, 10, getMemoryManager());
397          ThrowXMLwithMemMgr2(XSerializationException
398                              , XMLExcepts::XSer_Inv_ClassIndex
399                              , value1
400                              , value2
401                              , getMemoryManager());
402        }
403
404        ensurePointer(lookupLoadPool(classIndex));
405   }
406
407        return true;
408}
409
410void XSerializeEngine::read(XMLCh* const toRead
411                          , XMLSize_t    readLen)
412{
413    read((XMLByte*)toRead, (sizeof(XMLCh)/sizeof(XMLByte))*readLen);
414}
415
416void XSerializeEngine::read(XMLByte* const toRead
417                          , XMLSize_t      readLen)
418{
419    ensureLoading();
420    ensurePointer(toRead);
421    ensureLoadBuffer();
422
423    if (readLen == 0)
424        return;
425
426    /***
427     *  If unread is sufficient, read it up
428     ***/
429    XMLSize_t dataAvail = fBufLoadMax - fBufCur;
430
431    if (readLen <= dataAvail)
432    {
433        memcpy(toRead, fBufCur, readLen);
434        fBufCur += readLen;
435        return;
436    }
437
438    /***
439     *
440     * fillBuffer will discard anything left in the buffer
441     * before it asks the inputStream to fill in the buffer,
442     * so we need to readup everything in the buffer before
443     * calling fillBuffer
444     *
445     ***/
446    XMLByte*     tempRead   = (XMLByte*) toRead;
447    XMLSize_t    readRemain = readLen;
448
449    // read the unread
450    memcpy(tempRead, fBufCur, dataAvail);
451    tempRead   += dataAvail;
452    readRemain -= dataAvail;
453
454    // read chunks of fBufSize
455    while (readRemain >= fBufSize)
456    {
457        fillBuffer();
458        memcpy(tempRead, fBufCur, fBufSize);
459        tempRead   += fBufSize;
460        readRemain -= fBufSize;
461    }
462
463    // read the remaining if any
464    if (readRemain)
465    {
466        fillBuffer();
467        memcpy(tempRead, fBufCur, readRemain);
468        fBufCur += readRemain;
469    }
470
471}
472
473/***
474 *
475 *     Storage scheme (normal):
476 *
477 *     <
478 *     1st integer:    bufferLen (optional)
479 *     2nd integer:    dataLen
480 *     bytes following:
481 *     >
482 *
483 *     Storage scheme (special):
484 *     <
485 *     only integer:   noDataFollowed
486 *     >
487 */
488void XSerializeEngine::readString(XMLCh*&       toRead
489                                , XMLSize_t&    bufferLen
490                                , XMLSize_t&    dataLen
491                                , bool          toReadBufLen)
492{
493    /***
494     * Check if any data written
495     ***/
496    unsigned long tmp;
497    *this>>tmp;
498    bufferLen=tmp;
499
500    if (bufferLen == noDataFollowed)
501    {
502        toRead = 0;
503        bufferLen = 0;
504        dataLen = 0;
505        return;
506    }
507
508    if (toReadBufLen)
509    {
510        *this>>tmp;
511        dataLen=tmp;
512    }
513    else
514    {
515        dataLen = bufferLen++;
516    }
517
518    toRead = (XMLCh*) getMemoryManager()->allocate(bufferLen * sizeof(XMLCh));
519    read(toRead, dataLen);
520    toRead[dataLen] = 0;
521}
522
523void XSerializeEngine::readString(XMLByte*&     toRead
524                                , XMLSize_t&    bufferLen
525                                , XMLSize_t&    dataLen
526                                , bool          toReadBufLen)
527{
528    /***
529     * Check if any data written
530     ***/
531    unsigned long tmp;
532    *this>>tmp;
533    bufferLen=tmp;
534    if (bufferLen == noDataFollowed)
535    {
536        toRead = 0;
537        bufferLen = 0;
538        dataLen = 0;
539        return;
540    }
541
542    if (toReadBufLen)
543    {
544        *this>>tmp;
545        dataLen=tmp;
546    }
547    else
548    {
549        dataLen = bufferLen++;
550    }
551
552    toRead = (XMLByte*) getMemoryManager()->allocate(bufferLen * sizeof(XMLByte));
553    read(toRead, dataLen);
554    toRead[dataLen] = 0;
555
556}
557
558// ---------------------------------------------------------------------------
559//  Insertion & Extraction
560// ---------------------------------------------------------------------------
561
562XSerializeEngine& XSerializeEngine::operator<<(XMLCh xch)
563{
564    checkAndFlushBuffer(calBytesNeeded(sizeof(XMLCh)));
565
566    alignBufCur(sizeof(XMLCh));
567    *(XMLCh*)fBufCur = xch;
568    fBufCur += sizeof(XMLCh);
569    return *this;
570}
571
572XSerializeEngine& XSerializeEngine::operator>>(XMLCh& xch)
573{
574    checkAndFillBuffer(calBytesNeeded(sizeof(XMLCh)));
575
576    alignBufCur(sizeof(XMLCh));
577    xch = *(XMLCh*)fBufCur;
578    fBufCur += sizeof(XMLCh);
579    return *this;
580}
581
582XSerializeEngine& XSerializeEngine::operator<<(XMLByte by)
583{
584    checkAndFlushBuffer(sizeof(XMLByte));
585
586    *(XMLByte*)fBufCur = by;
587    fBufCur += sizeof(XMLByte);
588    return *this;
589}
590
591XSerializeEngine& XSerializeEngine::operator>>(XMLByte& by)
592{
593    checkAndFillBuffer(sizeof(XMLByte));
594
595    by = *(XMLByte*)fBufCur;
596    fBufCur += sizeof(XMLByte);
597    return *this;
598}
599
600XSerializeEngine& XSerializeEngine::operator<<(bool b)
601{
602    checkAndFlushBuffer(sizeof(bool));
603
604    *(bool*)fBufCur = b;
605    fBufCur += sizeof(bool);
606    return *this;
607}
608
609XSerializeEngine& XSerializeEngine::operator>>(bool& b)
610{
611    checkAndFillBuffer(sizeof(bool));
612
613    b = *(bool*)fBufCur;
614    fBufCur += sizeof(bool);
615    return *this;
616}
617
618void XSerializeEngine::writeSize (XMLSize_t t)
619{
620  checkAndFlushBuffer(sizeof(t));
621
622  memcpy(fBufCur, &t, sizeof(t));
623  fBufCur += sizeof(t);
624}
625
626void XSerializeEngine::writeInt64 (XMLInt64 t)
627{
628  checkAndFlushBuffer(sizeof(t));
629
630  memcpy(fBufCur, &t, sizeof(t));
631  fBufCur += sizeof(t);
632}
633
634void XSerializeEngine::writeUInt64 (XMLUInt64 t)
635{
636  checkAndFlushBuffer(sizeof(t));
637
638  memcpy(fBufCur, &t, sizeof(t));
639  fBufCur += sizeof(t);
640}
641
642void XSerializeEngine::readSize (XMLSize_t& t)
643{
644  checkAndFillBuffer(sizeof(t));
645
646  memcpy(&t, fBufCur, sizeof(t));
647  fBufCur += sizeof(t);
648}
649
650void XSerializeEngine::readInt64 (XMLInt64& t)
651{
652  checkAndFillBuffer(sizeof(t));
653
654  memcpy(&t, fBufCur, sizeof(t));
655  fBufCur += sizeof(t);
656}
657
658void XSerializeEngine::readUInt64 (XMLUInt64& t)
659{
660  checkAndFillBuffer(sizeof(t));
661
662  memcpy(&t, fBufCur, sizeof(t));
663  fBufCur += sizeof(t);
664}
665
666XSerializeEngine& XSerializeEngine::operator<<(char ch)
667{
668    return XSerializeEngine::operator<<((XMLByte)ch);
669}
670
671XSerializeEngine& XSerializeEngine::operator>>(char& ch)
672{
673    return XSerializeEngine::operator>>((XMLByte&)ch);
674}
675
676XSerializeEngine& XSerializeEngine::operator<<(short sh)
677{
678    checkAndFlushBuffer(calBytesNeeded(sizeof(short)));
679
680    alignBufCur(sizeof(short));
681    *(short*)fBufCur = sh;
682    fBufCur += sizeof(short);
683    return *this;
684}
685
686XSerializeEngine& XSerializeEngine::operator>>(short& sh)
687{
688    checkAndFillBuffer(calBytesNeeded(sizeof(short)));
689
690    alignBufCur(sizeof(short));
691    sh = *(short*)fBufCur;
692    fBufCur += sizeof(short);
693    return *this;
694}
695
696XSerializeEngine& XSerializeEngine::operator<<(int i)
697{
698    checkAndFlushBuffer(calBytesNeeded(sizeof(int)));
699
700    alignBufCur(sizeof(int));
701    *(int*)fBufCur = i;
702    fBufCur += sizeof(int);
703    return *this;
704}
705
706XSerializeEngine& XSerializeEngine::operator>>(int& i)
707{
708    checkAndFillBuffer(calBytesNeeded(sizeof(int)));
709
710    alignBufCur(sizeof(int));
711    i = *(int*)fBufCur;
712    fBufCur += sizeof(int);
713    return *this;
714}
715
716XSerializeEngine& XSerializeEngine::operator<<(unsigned int ui)
717{
718
719    checkAndFlushBuffer(calBytesNeeded(sizeof(unsigned int)));
720
721    alignBufCur(sizeof(unsigned int));
722    *(unsigned int*)fBufCur = ui;
723    fBufCur += sizeof(unsigned int);
724    return *this;
725}
726
727XSerializeEngine& XSerializeEngine::operator>>(unsigned int& ui)
728{
729
730    checkAndFillBuffer(calBytesNeeded(sizeof(unsigned int)));
731
732    alignBufCur(sizeof(unsigned int));
733    ui = *(unsigned int*)fBufCur;
734    fBufCur += sizeof(unsigned int);
735    return *this;
736}
737
738XSerializeEngine& XSerializeEngine::operator<<(long l)
739{
740    checkAndFlushBuffer(calBytesNeeded(sizeof(long)));
741
742    alignBufCur(sizeof(long));
743    *(long*)fBufCur = l;
744    fBufCur += sizeof(long);
745    return *this;
746}
747
748XSerializeEngine& XSerializeEngine::operator>>(long& l)
749{
750    checkAndFillBuffer(calBytesNeeded(sizeof(long)));
751
752    alignBufCur(sizeof(long));
753    l = *(long*)fBufCur;
754    fBufCur += sizeof(long);
755    return *this;
756}
757
758XSerializeEngine& XSerializeEngine::operator<<(unsigned long ul)
759{
760    checkAndFlushBuffer(calBytesNeeded(sizeof(unsigned long)));
761
762    alignBufCur(sizeof(unsigned long));
763    *(unsigned long*)fBufCur = ul;
764    fBufCur += sizeof(unsigned long);
765    return *this;
766}
767
768XSerializeEngine& XSerializeEngine::operator>>(unsigned long& ul)
769{
770    checkAndFillBuffer(calBytesNeeded(sizeof(unsigned long)));
771
772    alignBufCur(sizeof(unsigned long));
773    ul = *(unsigned long*)fBufCur;
774    fBufCur += sizeof(unsigned long);
775    return *this;
776}
777
778XSerializeEngine& XSerializeEngine::operator<<(float f)
779{
780    checkAndFlushBuffer(calBytesNeeded(sizeof(float)));
781
782    alignBufCur(sizeof(float));
783    *(float*)fBufCur = *(float*)&f;
784    fBufCur += sizeof(float);
785    return *this;
786}
787
788XSerializeEngine& XSerializeEngine::operator>>(float& f)
789{
790    checkAndFillBuffer(calBytesNeeded(sizeof(float)));
791
792    alignBufCur(sizeof(float));
793    *(float*)&f = *(float*)fBufCur;
794    fBufCur += sizeof(float);
795    return *this;
796}
797
798XSerializeEngine& XSerializeEngine::operator<<(double d)
799{
800    checkAndFlushBuffer(calBytesNeeded(sizeof(double)));
801
802    alignBufCur(sizeof(double));
803    *(double*)fBufCur = *(double*)&d;
804    fBufCur += sizeof(double);
805    return *this;
806}
807
808XSerializeEngine& XSerializeEngine::operator>>(double& d)
809{
810    checkAndFillBuffer(calBytesNeeded(sizeof(double)));
811
812    alignBufCur(sizeof(double));
813    *(double*)&d = *(double*)fBufCur;
814    fBufCur += sizeof(double);
815    return *this;
816}
817
818// ---------------------------------------------------------------------------
819//  StorePool/LoadPool Opertions
820// ---------------------------------------------------------------------------
821XSerializeEngine::XSerializedObjectId_t
822XSerializeEngine::lookupStorePool(void* const objToLookup) const
823{
824    //0 indicating object is not in the StorePool
825    XSerializedObjectId* data = fStorePool->get(objToLookup);
826    return (XSerializeEngine::XSerializedObjectId_t) (data ? data->getValue() : 0);
827
828}
829
830void XSerializeEngine::addStorePool(void* const objToAdd)
831{
832    pumpCount();
833    fStorePool->put(objToAdd, new (fGrammarPool->getMemoryManager()) XSerializedObjectId(fObjectCount));
834}
835
836XSerializable* XSerializeEngine::lookupLoadPool(XSerializedObjectId_t objectTag) const
837{
838
839    /***
840      *  an object tag read from the binary refering to
841      *  an object beyond the upper most boundary of the load pool
842      ***/
843
844    if (objectTag > fLoadPool->size())
845    {
846      XMLCh value1[64];
847      XMLCh value2[64];
848      XMLString::binToText(objectTag, value1, 65, 10, getMemoryManager());
849      XMLString::sizeToText(fLoadPool->size(), value2, 65, 10, getMemoryManager());
850      ThrowXMLwithMemMgr2(XSerializationException
851                          , XMLExcepts::XSer_LoadPool_UppBnd_Exceed
852                          , value1
853                          , value2
854                          , getMemoryManager());
855    }
856
857    if (objectTag == 0)
858        return 0;
859
860    /***
861     *   A non-null object tag starts from 1 while fLoadPool starts from 0
862     ***/
863    return (XSerializable*) fLoadPool->elementAt(objectTag - 1);
864}
865
866void XSerializeEngine::addLoadPool(void* const objToAdd)
867{
868
869    TEST_THROW_ARG2( (fLoadPool->size() != fObjectCount)
870               , fObjectCount
871               , fLoadPool->size()
872               , XMLExcepts::XSer_LoadPool_NoTally_ObjCnt
873               )
874
875    pumpCount();
876    fLoadPool->addElement(objToAdd);
877
878}
879
880void XSerializeEngine::pumpCount()
881{
882    if (fObjectCount >= fgMaxObjectCount)
883    {
884      XMLCh value1[64];
885      XMLCh value2[64];
886      XMLString::sizeToText(fObjectCount, value1, 65, 10, getMemoryManager());
887      XMLString::binToText(fgMaxObjectCount, value2, 65, 10, getMemoryManager());
888      ThrowXMLwithMemMgr2(XSerializationException
889                          , XMLExcepts::XSer_ObjCount_UppBnd_Exceed
890                          , value1
891                          , value2
892                          , getMemoryManager());
893    }
894
895    fObjectCount++;
896
897}
898
899// ---------------------------------------------------------------------------
900//  Buffer Opertions
901// ---------------------------------------------------------------------------
902/***
903 *
904 *  Though client may need only miniBytesNeeded, we always request
905 *  a full size reading from our inputStream.
906 *
907 *  Whatever possibly left in the buffer is abandoned, such as in
908 *  the case of CheckAndFillBuffer()
909 *
910 ***/
911void XSerializeEngine::fillBuffer()
912{
913    ensureLoading();
914    ensureLoadBuffer();
915
916    resetBuffer();
917
918    XMLSize_t bytesRead = fInputStream->readBytes(fBufStart, fBufSize);
919
920    /***
921     * InputStream MUST fill in the exact amount of bytes as requested
922     * to do: combine the checking and create a new exception code later
923    ***/
924    TEST_THROW_ARG2( (bytesRead < fBufSize)
925               , bytesRead
926               , fBufSize
927               , XMLExcepts::XSer_InStream_Read_LT_Req
928               )
929
930    TEST_THROW_ARG2( (bytesRead > fBufSize)
931               , bytesRead
932               , fBufSize
933               , XMLExcepts::XSer_InStream_Read_OverFlow
934               )
935
936    fBufLoadMax = fBufStart + fBufSize;
937    fBufCur     = fBufStart;
938
939    ensureLoadBuffer();
940
941    fBufCount++;
942}
943
944/***
945 *
946 *  Flush out whatever left in the buffer, from
947 *  fBufStart to fBufEnd.
948 *
949 ***/
950void XSerializeEngine::flushBuffer()
951{
952    ensureStoring();
953    ensureStoreBuffer();
954
955    fOutputStream->writeBytes(fBufStart, fBufSize);
956    fBufCur = fBufStart;
957
958    resetBuffer();
959    ensureStoreBuffer();
960
961    fBufCount++;
962}
963
964inline void XSerializeEngine::checkAndFlushBuffer(XMLSize_t bytesNeedToWrite)
965{
966    TEST_THROW_ARG1( (bytesNeedToWrite <= 0)
967                   , bytesNeedToWrite
968                   , XMLExcepts::XSer_Inv_checkFlushBuffer_Size
969                   )
970
971    // fBufStart ... fBufCur ...fBufEnd
972    if ((fBufCur + bytesNeedToWrite) > fBufEnd)
973        flushBuffer();
974}
975
976inline void XSerializeEngine::checkAndFillBuffer(XMLSize_t bytesNeedToRead)
977{
978
979    TEST_THROW_ARG1( (bytesNeedToRead <= 0)
980                   , bytesNeedToRead
981                   , XMLExcepts::XSer_Inv_checkFillBuffer_Size
982                   )
983
984    // fBufStart ... fBufCur ...fBufLoadMax
985    if ((fBufCur + bytesNeedToRead) > fBufLoadMax)
986    {
987        fillBuffer();
988    }
989
990}
991
992inline void XSerializeEngine::ensureStoreBuffer() const
993{
994    XMLSize_t a = (XMLSize_t) (fBufCur - fBufStart);
995    XMLSize_t b = (XMLSize_t) (fBufEnd - fBufCur);
996
997    TEST_THROW_ARG2 ( !((fBufStart <= fBufCur) && (fBufCur <= fBufEnd))
998                    , a
999                    , b
1000                    , XMLExcepts::XSer_StoreBuffer_Violation
1001                    )
1002
1003}
1004
1005inline void XSerializeEngine::ensureLoadBuffer() const
1006{
1007    XMLSize_t a = (XMLSize_t) (fBufCur - fBufStart);
1008    XMLSize_t b = (XMLSize_t) (fBufLoadMax - fBufCur);
1009
1010    TEST_THROW_ARG2 ( !((fBufStart <= fBufCur) && (fBufCur <= fBufLoadMax))
1011                    , a
1012                    , b
1013                    , XMLExcepts::XSer_LoadBuffer_Violation
1014                    )
1015
1016}
1017
1018inline void XSerializeEngine::ensurePointer(void* const ptr) const
1019{
1020
1021    TEST_THROW_ARG1( (ptr == 0)
1022                   , 0
1023                   , XMLExcepts::XSer_Inv_Null_Pointer
1024                   )
1025
1026}
1027
1028inline void XSerializeEngine::resetBuffer()
1029{
1030    memset(fBufStart, 0, fBufSize * sizeof(XMLByte));
1031}
1032
1033// ---------------------------------------------------------------------------
1034//  Template object
1035// ---------------------------------------------------------------------------
1036/***
1037 *
1038 *  Search the store pool to see if the address has been seen before or not.
1039 *
1040 *  If yes, write the corresponding object Tag to the internal buffer
1041 *  and return true.
1042 *
1043 *  Otherwise, add the address to the store pool and return false
1044 *  to notifiy the client application code to store the template object.
1045 *
1046 ***/
1047bool XSerializeEngine::needToStoreObject(void* const  templateObjectToWrite)
1048{
1049    ensureStoring(); //don't ensurePointer here !!!
1050
1051    XSerializedObjectId_t   objIndex = 0;
1052
1053        if (!templateObjectToWrite)
1054        {
1055                *this << fgNullObjectTag; // null pointer
1056        return false;
1057        }
1058    else if (0 != (objIndex = lookupStorePool(templateObjectToWrite)))
1059        {
1060        *this << objIndex;         // write an object reference tag
1061        return false;
1062        }
1063        else
1064        {
1065        *this << fgTemplateObjTag;            // write fgTemplateObjTag to denote that actual
1066                                              // template object follows
1067        addStorePool(templateObjectToWrite); // put the address into StorePool
1068        return true;
1069        }
1070
1071}
1072
1073bool XSerializeEngine::needToLoadObject(void**  templateObjectToRead)
1074{
1075    ensureLoading();
1076
1077        XSerializedObjectId_t obTag;
1078
1079    *this >> obTag;
1080
1081        if (obTag == fgTemplateObjTag)
1082        {
1083        /***
1084         * what follows fgTemplateObjTag is the actual template object
1085         * We need the client application to create a template object
1086         * and register it through registerObject(), and deserialize
1087         * template object
1088         ***/
1089        return true;
1090        }
1091        else
1092        {
1093        /***
1094         * We hava a reference to an existing template object, get it.
1095         */
1096        *templateObjectToRead = lookupLoadPool(obTag);
1097        return false;
1098   }
1099
1100}
1101
1102void XSerializeEngine::registerObject(void*  const templateObjectToRegister)
1103{
1104    ensureLoading();
1105    addLoadPool(templateObjectToRegister);
1106}
1107
1108XMLGrammarPool* XSerializeEngine::getGrammarPool() const
1109{
1110    return fGrammarPool;
1111}
1112
1113XMLStringPool* XSerializeEngine::getStringPool() const
1114{
1115    return fGrammarPool->getURIStringPool();
1116}
1117
1118MemoryManager* XSerializeEngine::getMemoryManager() const
1119{
1120    //todo: changed to return fGrammarPool->getMemoryManager()
1121    return fGrammarPool ? fGrammarPool->getMemoryManager() : XMLPlatformUtils::fgMemoryManager;
1122}
1123
1124//
1125// Based on the current position (fBufCur), calculated the needed size
1126// to read/write
1127//
1128inline XMLSize_t XSerializeEngine::alignAdjust(XMLSize_t size) const
1129{
1130    XMLSize_t remainder = (XMLSize_t) fBufCur % size;
1131    return (remainder == 0) ? 0 : (size - remainder);
1132}
1133
1134// Adjust the fBufCur
1135inline void XSerializeEngine::alignBufCur(XMLSize_t size)
1136{
1137    fBufCur+=alignAdjust(size);
1138    assert(((XMLSize_t) fBufCur % size)==0);
1139}
1140
1141inline XMLSize_t XSerializeEngine::calBytesNeeded(XMLSize_t size) const
1142{
1143    return (alignAdjust(size) + size);
1144}
1145
1146void XSerializeEngine::trace(char* /*funcName*/) const
1147{
1148    return;
1149
1150/*
1151   if (isStoring())
1152        printf("\n funcName=<%s>, storing, count=<%lu>, postion=<%lu>\n", funcName, fBufCount, getBufCurAccumulated());
1153    else
1154        printf("\n funcName=<%s>, loading, count=<%lu>, postion=<%lu>\n", funcName, fBufCount, getBufCurAccumulated());
1155*/
1156}
1157
1158XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.