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$
20  */
21 
22 #if !defined(XERCESC_INCLUDE_GUARD_XSERIALIZE_ENGINE_HPP)
23 #define XERCESC_INCLUDE_GUARD_XSERIALIZE_ENGINE_HPP
24 
25 #include <xercesc/util/RefHashTableOf.hpp>
26 #include <xercesc/util/ValueVectorOf.hpp>
27 #include <xercesc/util/XMLExceptMsgs.hpp>
28 
29 #include <xercesc/internal/XSerializationException.hpp>
30 
31 XERCES_CPP_NAMESPACE_BEGIN
32 
33 class XSerializable;
34 class XProtoType;
35 class MemoryManager;
36 class XSerializedObjectId;
37 class BinOutputStream;
38 class BinInputStream;
39 class XMLGrammarPool;
40 class XMLGrammarPoolImpl;
41 class XMLStringPool;
42 
43 class XMLUTIL_EXPORT XSerializeEngine
44 {
45 public:
46 
47     enum { mode_Store
48          , mode_Load
49     };
50 
51 
52     static const bool toReadBufferLen;
53 
54     typedef unsigned int   XSerializedObjectId_t;
55 
56     /***
57       *
58       *  Destructor
59       *
60       ***/
61     ~XSerializeEngine();
62 
63     /***
64       *
65       *  Constructor for de-serialization(loading)
66       *
67       *  Application needs to make sure that the instance of
68       *  BinInputStream, persists beyond the life of this
69       *  SerializeEngine.
70       *
71       *  Param
72       *     inStream         input stream
73       *     gramPool         Grammar Pool
74       *     bufSize          the size of the internal buffer
75       *
76       ***/
77     XSerializeEngine(BinInputStream*         inStream
78                    , XMLGrammarPool* const   gramPool
79                    , XMLSize_t               bufSize = 8192 );
80 
81 
82     /***
83       *
84       *  Constructor for serialization(storing)
85       *
86       *  Application needs to make sure that the instance of
87       *  BinOutputStream, persists beyond the life of this
88       *  SerializeEngine.
89       *
90       *  Param
91       *     outStream        output stream
92       *     gramPool         Grammar Pool
93       *     bufSize          the size of the internal buffer
94       *
95       ***/
96     XSerializeEngine(BinOutputStream*        outStream
97                    , XMLGrammarPool* const   gramPool
98                    , XMLSize_t               bufSize = 8192 );
99 
100     /***
101       *
102       *  When serialization, flush out the internal buffer
103       *
104       *  Return:
105       *
106       ***/
107     void flush();
108 
109     /***
110       *
111       *  Checking if the serialize engine is doing serialization(storing)
112       *
113       *  Return: true, if it is
114       *          false, otherwise
115       *
116       ***/
117     inline bool isStoring() const;
118 
119     /***
120       *
121       *  Checking if the serialize engine is doing de-serialization(loading)
122       *
123       *  Return: true, if it is
124       *          false, otherwise
125       *
126       ***/
127     inline bool isLoading() const;
128 
129     /***
130       *
131       *  Get the GrammarPool
132       *
133       *  Return: XMLGrammarPool
134       *
135       ***/
136     XMLGrammarPool* getGrammarPool() const;
137 
138     /***
139       *
140       *  Get the StringPool
141       *
142       *  Return: XMLStringPool
143       *
144       ***/
145     XMLStringPool* getStringPool() const;
146 
147     /***
148       *
149       *  Get the embeded Memory Manager
150       *
151       *  Return: MemoryManager
152       *
153       ***/
154     MemoryManager* getMemoryManager() const;
155 
156     /***
157       *
158       *  Get the storer level (the level of the serialize engine
159       *  which created the binary stream that this serialize engine
160       *  is loading).
161       *
162       *  The level returned is meaningful only when
163       *  the engine isLoading.
164       *
165       *  Return: level
166       *
167       ***/
168     inline unsigned int getStorerLevel() const;
169 
170     /***
171       *
172       *  Write object to the internal buffer.
173       *
174       *  Param
175       *     objectToWrite:    the object to be serialized
176       *
177       *  Return:
178       *
179       ***/
180            void           write(XSerializable* const objectToWrite);
181 
182     /***
183       *
184       *  Write prototype info to the internal buffer.
185       *
186       *  Param
187       *     protoType:    instance of prototype
188       *
189       *  Return:
190       *
191       ***/
192            void           write(XProtoType* const protoType);
193 
194     /***
195       *
196       *  Write a stream of XMLByte to the internal buffer.
197       *
198       *  Param
199       *     toWrite:   the stream of XMLByte to write
200       *     writeLen:  the length of the stream
201       *
202       *  Return:
203       *
204       ***/
205            void           write(const XMLByte* const toWrite
206                                ,      XMLSize_t      writeLen);
207 
208     /***
209       *
210       *  Write a stream of XMLCh to the internal buffer.
211       *
212       *  Param
213       *     toWrite:   the stream of XMLCh to write
214       *     writeLen:  the length of the stream
215       *
216       *  Return:
217       *
218       ***/
219            void           write(const XMLCh* const toWrite
220                                ,      XMLSize_t    writeLen);
221 
222     /***
223       *
224       *  Write a stream of XMLCh to the internal buffer.
225       *
226       *  Write the bufferLen first if requested, then the length
227       *  of the stream followed by the stream.
228       *
229       *  Param
230       *     toWrite:        the stream of XMLCh to write
231       *     bufferLen:      the maximum size of the buffer
232       *     toWriteBufLen:  specify if the bufferLen need to be written or not
233       *
234       *  Return:
235       *
236       ***/
237            void           writeString(const XMLCh* const toWrite
238                                     , const XMLSize_t    bufferLen = 0
239                                     , bool               toWriteBufLen = false);
240 
241     /***
242       *
243       *  Write a stream of XMLByte to the internal buffer.
244       *
245       *  Write the bufferLen first if requested, then the length
246       *  of the stream followed by the stream.
247       *
248       *  Param
249       *     toWrite:        the stream of XMLByte to write
250       *     bufferLen:      the maximum size of the buffer
251       *     toWriteBufLen:  specify if the bufferLen need to be written or not
252       *
253       *  Return:
254       *
255       ***/
256            void           writeString(const XMLByte* const toWrite
257                                     , const XMLSize_t      bufferLen = 0
258                                     , bool                 toWriteBufLen = false);
259 
260     static const bool toWriteBufferLen;
261 
262     /***
263       *
264       *  Read/Create object from the internal buffer.
265       *
266       *  Param
267       *     protoType:    an instance of prototype of the object anticipated
268       *
269       *  Return:          to object read/created
270       *
271       ***/
272 	       XSerializable* read(XProtoType* const protoType);
273 
274     /***
275       *
276       *  Read prototype object from the internal buffer.
277       *  Verify if the same prototype object found in buffer.
278       *
279       *  Param
280       *     protoType:    an instance of prototype of the object anticipated
281       *     objTag:       the object Tag to an existing object
282       *
283       *  Return:          true  : if matching found
284       *                   false : otherwise
285       *
286       ***/
287            bool           read(XProtoType* const    protoType
288 		                     , XSerializedObjectId_t*       objTag);
289 
290     /***
291       *
292       *  Read XMLByte stream from the internal buffer.
293       *
294       *  Param
295       *     toRead:   the buffer to hold the XMLByte stream
296       *     readLen:  the length of the XMLByte to read in
297       *
298       *  Return:
299       *
300       ***/
301            void           read(XMLByte* const toRead
302                              , XMLSize_t      readLen);
303 
304     /***
305       *
306       *  Read XMLCh stream from the internal buffer.
307       *
308       *  Param
309       *     toRead:   the buffer to hold the XMLCh stream
310       *     readLen:  the length of the XMLCh to read in
311       *
312       *  Return:
313       *
314       ***/
315            void           read(XMLCh* const toRead
316                              , XMLSize_t    readLen);
317 
318     /***
319       *
320       *  Read a stream of XMLCh from the internal buffer.
321       *
322       *  Read the bufferLen first if requested, then the length
323       *  of the stream followed by the stream.
324       *
325       *  Param
326       *     toRead:       the pointer to the buffer to hold the XMLCh stream
327       *     bufferLen:    the size of the buffer created
328       *     dataLen:       the length of the stream
329       *     toReadBufLen: specify if the bufferLen need to be read or not
330       *
331       *  Return:
332       *
333       ***/
334            void           readString(XMLCh*&        toRead
335                                    , XMLSize_t&     bufferLen
336                                    , XMLSize_t&     dataLen
337                                    , bool           toReadBufLen = false);
338 
339      /***
340        *
341        *  Read a stream of XMLCh from the internal buffer.
342        *
343        *  Read the bufferLen first if requested, then the length
344        *  of the stream followed by the stream.
345        *
346        *  Param
347        *     toRead:       the pointer to the buffer to hold the XMLCh stream
348        *     bufferLen:    the size of the buffer created
349        *
350        *  Return:
351        *
352        ***/
353             inline void     readString(XMLCh*&        toRead
354                                     , XMLSize_t&      bufferLen);
355 
356      /***
357        *
358        *  Read a stream of XMLCh from the internal buffer.
359        *
360        *  Param
361        *     toRead:       the pointer to the buffer to hold the XMLCh stream
362        *
363        *  Return:
364        *
365        ***/
366             inline void      readString(XMLCh*&        toRead);
367 
368     /***
369       *
370       *  Read a stream of XMLByte from the internal buffer.
371       *
372       *  Read the bufferLen first if requested, then the length
373       *  of the stream followed by the stream.
374       *
375       *  Param
376       *     toRead:       the pointer to the buffer to hold the XMLByte stream
377       *     bufferLen:    the size of the buffer created
378       *     dataLen:       the length of the stream
379       *     toReadBufLen: specify if the bufferLen need to be read or not
380       *
381       *  Return:
382       *
383       ***/
384            void           readString(XMLByte*&      toRead
385                                    , XMLSize_t&     bufferLen
386                                    , XMLSize_t&     dataLen
387                                    , bool           toReadBufLen = false);
388 
389 
390      /***
391        *
392        *  Read a stream of XMLByte from the internal buffer.
393        *
394        *  Read the bufferLen first if requested, then the length
395        *  of the stream followed by the stream.
396        *
397        *  Param
398        *     toRead:       the pointer to the buffer to hold the XMLByte stream
399        *     bufferLen:    the size of the buffer created
400        *
401        *  Return:
402        *
403        ***/
404             inline void       readString(XMLByte*&      toRead
405                                        , XMLSize_t&     bufferLen);
406 
407      /***
408        *
409        *  Read a stream of XMLByte from the internal buffer.
410        *
411        *  Read the bufferLen first if requested, then the length
412        *  of the stream followed by the stream.
413        *
414        *  Param
415        *     toRead:       the pointer to the buffer to hold the XMLByte stream
416        *     bufferLen:    the size of the buffer created
417        *     dataLen:       the length of the stream
418        *     toReadBufLen: specify if the bufferLen need to be read or not
419        *
420        *  Return:
421        *
422        ***/
423             inline void       readString(XMLByte*&      toRead);
424 
425     /***
426       *
427       *  Check if the template object has been stored or not
428       *
429       *  Param
430       *    objectPtr:     the template object pointer
431       *
432       *  Return:          true  : the object has NOT been stored yet
433       *                   false : otherwise
434       *
435       ***/
436            bool           needToStoreObject(void* const templateObjectToWrite);
437 
438     /***
439       *
440       *  Check if the template object has been loaded or not
441       *
442       *  Param
443       *    objectPtr:     the address of the template object pointer
444       *
445       *  Return:          true  : the object has NOT been loaded yet
446       *                   false : otherwise
447       *
448       ***/
449            bool           needToLoadObject(void**       templateObjectToRead);
450 
451     /***
452       *
453       *  In the case of needToLoadObject() return true, the client
454       *  application needs to instantiate an expected template object, and
455       *  register the address to the engine.
456       *
457       *  Param
458       *    objectPtr:     the template object pointer newly instantiated
459       *
460       *  Return:
461       *
462       ***/
463            void           registerObject(void* const templateObjectToRegister);
464 
465     /***
466       *
467       *  Insertion operator for serializable classes
468       *
469       ***/
470 
471 	friend XSerializeEngine& operator<<(XSerializeEngine&
472                                       , XSerializable* const );
473 
474     /***
475       *
476       *  Insertion operators for
477       *     . basic Xerces data types
478       *     . built-in types
479       *
480       ***/
481            XSerializeEngine& operator<<(XMLByte);
482            XSerializeEngine& operator<<(XMLCh);
483 
484            XSerializeEngine& operator<<(char);
485            XSerializeEngine& operator<<(short);
486            XSerializeEngine& operator<<(int);
487            XSerializeEngine& operator<<(unsigned int);
488            XSerializeEngine& operator<<(long);
489            XSerializeEngine& operator<<(unsigned long);
490            XSerializeEngine& operator<<(float);
491            XSerializeEngine& operator<<(double);
492            XSerializeEngine& operator<<(bool);
493 
494     // These cannot be done as operators since on some platforms they
495     // may collide with int/long types.
496     //
497     void writeSize (XMLSize_t);
498     void writeInt64 (XMLInt64);
499     void writeUInt64 (XMLUInt64);
500 
501 
502     /***
503       *
504       *  Extraction operators for
505       *     . basic Xerces data types
506       *     . built-in types
507       *
508       ***/
509            XSerializeEngine& operator>>(XMLByte&);
510            XSerializeEngine& operator>>(XMLCh&);
511 
512            XSerializeEngine& operator>>(char&);
513            XSerializeEngine& operator>>(short&);
514            XSerializeEngine& operator>>(int&);
515            XSerializeEngine& operator>>(unsigned int&);
516            XSerializeEngine& operator>>(long&);
517            XSerializeEngine& operator>>(unsigned long&);
518            XSerializeEngine& operator>>(float&);
519            XSerializeEngine& operator>>(double&);
520            XSerializeEngine& operator>>(bool&);
521 
522     void readSize (XMLSize_t&);
523     void readInt64 (XMLInt64&);
524     void readUInt64 (XMLUInt64&);
525 
526     /***
527       *
528       *  Getters
529       *
530       ***/
531     inline
532     XMLSize_t       getBufSize()    const;
533 
534     inline
535     XMLSize_t       getBufCur()     const;
536 
537     inline
538     XMLSize_t       getBufCurAccumulated()     const;
539 
540     inline
541     unsigned long   getBufCount()    const;
542 
543     void                  trace(char*)     const;
544 
545 private:
546     // -----------------------------------------------------------------------
547     //  Unimplemented constructors and operators
548     // -----------------------------------------------------------------------
549 	XSerializeEngine();
550     XSerializeEngine(const XSerializeEngine&);
551 	XSerializeEngine& operator=(const XSerializeEngine&);
552 
553     /***
554       *
555       *   Store Pool Opertions
556       *
557       ***/
558            XSerializedObjectId_t  lookupStorePool(void* const objectPtr) const;
559            void                   addStorePool(void* const objectPtr);
560 
561     /***
562       *
563       *   Load Pool Opertions
564       *
565       ***/
566            XSerializable* lookupLoadPool(XSerializedObjectId_t objectTag) const;
567            void           addLoadPool(void* const objectPtr);
568 
569     /***
570       *
571       *    Intenal Buffer Operations
572       *
573       ***/
574     inline void           checkAndFillBuffer(XMLSize_t bytesNeedToRead);
575 
576     inline void           checkAndFlushBuffer(XMLSize_t bytesNeedToWrite);
577 
578            void           fillBuffer();
579 
580            void           flushBuffer();
581 
582            void           pumpCount();
583 
584     inline void           resetBuffer();
585 
586     /***
587       *
588       *    Helper
589       *
590       ***/
591     inline void            ensureStoring()                          const;
592 
593     inline void            ensureLoading()                          const;
594 
595     inline void            ensureStoreBuffer()                      const;
596 
597     inline void            ensureLoadBuffer()                       const;
598 
599     inline void            ensurePointer(void* const)               const;
600 
601     inline void            Assert(bool  toEval
602                                 , const XMLExcepts::Codes toThrow)  const;
603 
604 
605     inline XMLSize_t       calBytesNeeded(XMLSize_t)  const;
606 
607     inline XMLSize_t       alignAdjust(XMLSize_t)     const;
608 
609     inline void            alignBufCur(XMLSize_t);
610 
611     // Make XTemplateSerializer friend of XSerializeEngine so that
612     // we can call lookupStorePool and lookupLoadPool in the case of
613     // annotations.
614     friend class XTemplateSerializer;
615 
616     // -------------------------------------------------------------------------------
617     //  data
618     //
619     //  fStoreLoad:
620     //               Indicator: storing(serialization) or loading(de-serialization)
621     //
622     //  fStorerLevel:
623     //              The level of the serialize engine which created the binary
624     //              stream that this serialize engine is loading
625     //
626     //              It is set by GrammarPool when loading
627     //
628     //  fGrammarPool:
629     //               Thw owning GrammarPool which instantiate this SerializeEngine
630     //               instance
631     //
632     //  fInputStream:
633     //               Binary stream to read from (de-serialization), provided
634     //               by client application, not owned.
635     //
636     //  fOutputStream:
637     //               Binary stream to write to (serialization), provided
638     //               by client application, not owned.
639     //
640     //  fBufSize:
641     //               The size of the internal buffer
642     //
643     //  fBufStart/fBufEnd:
644     //
645     //               The internal buffer.
646     //  fBufEnd:
647     //               one beyond the last valid cell
648     //               fBufEnd === (fBufStart + fBufSize)
649     //
650     //  fBufCur:
651     //               The cursor of the buffer
652     //
653     //  fBufLoadMax:
654     //               Indicating the end of the valid content in the buffer
655     //
656     //  fStorePool:
657     //                Object collection for storing
658     //
659     //  fLoadPool:
660     //                Object collection for loading
661     //
662     //  fMapCount:
663     // -------------------------------------------------------------------------------
664     const short                            fStoreLoad;
665     unsigned int                           fStorerLevel;
666 
667     XMLGrammarPool*  const                 fGrammarPool;
668     BinInputStream*  const                 fInputStream;
669     BinOutputStream* const                 fOutputStream;
670 
671     unsigned long                          fBufCount;
672 
673     //buffer
674     const XMLSize_t                        fBufSize;
675 	XMLByte* const                         fBufStart;
676 	XMLByte* const                         fBufEnd;
677     XMLByte*                               fBufCur;
678     XMLByte*                               fBufLoadMax;
679 
680 
681 
682     /***
683      *   Map for storing object
684      *
685      *   key:   XSerializable*
686      *          XProtoType*
687      *
688      *   value: XMLInteger*, owned
689      *
690      ***/
691     RefHashTableOf<XSerializedObjectId, PtrHasher>*   fStorePool;
692 
693     /***
694      *   Vector for loading object, objects are NOT owned
695      *
696      *   data:   XSerializable*
697      *           XProtoType*
698      *
699      ***/
700     ValueVectorOf<void*>*                  fLoadPool;
701 
702     /***
703      *   object counter
704      ***/
705 	XSerializedObjectId_t                  fObjectCount;
706 
707     //to allow grammar pool to set storer level when loading
708     friend class XMLGrammarPoolImpl;
709 };
710 
isStoring() const711 inline bool XSerializeEngine::isStoring() const
712 {
713     return (fStoreLoad == mode_Store);
714 }
715 
isLoading() const716 inline bool XSerializeEngine::isLoading() const
717 {
718     return (fStoreLoad == mode_Load);
719 }
720 
operator <<(XSerializeEngine & serEng,XSerializable * const serObj)721 inline XSerializeEngine& operator<<(XSerializeEngine&       serEng
722                                   , XSerializable* const    serObj)
723 {
724 	serEng.write(serObj);
725     return serEng;
726 }
727 
ensureStoring() const728 inline void XSerializeEngine::ensureStoring() const
729 {
730 	Assert(isStoring(), XMLExcepts::XSer_Storing_Violation);
731 }
732 
ensureLoading() const733 inline void XSerializeEngine::ensureLoading() const
734 {
735 	Assert(isLoading(), XMLExcepts::XSer_Loading_Violation);
736 }
737 
738 
739 
Assert(bool toEval,const XMLExcepts::Codes toThrow) const740 inline void XSerializeEngine::Assert(bool toEval
741                                    , const XMLExcepts::Codes toThrow) const
742 {
743     if (!toEval)
744     {
745         ThrowXMLwithMemMgr(XSerializationException, toThrow, getMemoryManager());
746     }
747 
748 }
749 
readString(XMLCh * & toRead,XMLSize_t & bufferLen)750 inline void XSerializeEngine::readString(XMLCh*&        toRead
751                                        , XMLSize_t&     bufferLen)
752 {
753     XMLSize_t dummyDataLen;
754     readString(toRead, bufferLen, dummyDataLen);
755 }
756 
readString(XMLCh * & toRead)757 inline void XSerializeEngine::readString(XMLCh*&        toRead)
758 {
759     XMLSize_t dummyBufferLen;
760     XMLSize_t dummyDataLen;
761     readString(toRead, dummyBufferLen, dummyDataLen);
762 }
763 
readString(XMLByte * & toRead,XMLSize_t & bufferLen)764 inline void XSerializeEngine::readString(XMLByte*&      toRead
765                                        , XMLSize_t&     bufferLen)
766 {
767     XMLSize_t dummyDataLen;
768     readString(toRead, bufferLen, dummyDataLen);
769 }
770 
readString(XMLByte * & toRead)771 inline void XSerializeEngine::readString(XMLByte*&      toRead)
772 {
773     XMLSize_t dummyBufferLen;
774     XMLSize_t dummyDataLen;
775     readString(toRead, dummyBufferLen, dummyDataLen);
776 }
777 
778 inline
getBufSize() const779 XMLSize_t XSerializeEngine::getBufSize() const
780 {
781     return fBufSize;
782 }
783 
784 inline
getBufCur() const785 XMLSize_t XSerializeEngine::getBufCur() const
786 {
787     return (fBufCur-fBufStart);
788 }
789 
790 inline
getBufCurAccumulated() const791 XMLSize_t XSerializeEngine::getBufCurAccumulated() const
792 {
793     return (fBufCount - (isStoring() ? 0: 1)) * fBufSize + (fBufCur-fBufStart);
794 }
795 
796 inline
getBufCount() const797 unsigned long XSerializeEngine::getBufCount() const
798 {
799     return fBufCount;
800 }
801 
802 inline
getStorerLevel() const803 unsigned int XSerializeEngine::getStorerLevel() const
804 {
805     return fStorerLevel;
806 }
807 
808 /***
809  *  Ought to be nested class
810  ***/
811 class XSerializedObjectId : public XMemory
812 {
813 public:
814 
~XSerializedObjectId()815     ~XSerializedObjectId(){};
816 
817 private:
818 
XSerializedObjectId(XSerializeEngine::XSerializedObjectId_t val)819     inline XSerializedObjectId(XSerializeEngine::XSerializedObjectId_t val):
820         fData(val) { };
821 
getValue() const822     inline XSerializeEngine::XSerializedObjectId_t getValue() const {return fData; };
823 
824     friend class XSerializeEngine;
825 
826 private:
827     // -----------------------------------------------------------------------
828     //  Unimplemented constructors and operators
829     // -----------------------------------------------------------------------
830 	XSerializedObjectId();
831     XSerializedObjectId(const XSerializedObjectId&);
832 	XSerializedObjectId& operator=(const XSerializedObjectId&);
833 
834     XSerializeEngine::XSerializedObjectId_t    fData;
835 
836 };
837 
838 
839 XERCES_CPP_NAMESPACE_END
840 
841 #endif
842