GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: XSerializeEngine.cpp 834826 2009-11-11 10:03:53Z borisk $ 00020 */ 00021 00022 00023 // --------------------------------------------------------------------------- 00024 // Includes 00025 // --------------------------------------------------------------------------- 00026 #include <xercesc/internal/XSerializeEngine.hpp> 00027 #include <xercesc/internal/XSerializable.hpp> 00028 #include <xercesc/internal/XProtoType.hpp> 00029 00030 #include <xercesc/framework/XMLGrammarPool.hpp> 00031 #include <xercesc/framework/BinOutputStream.hpp> 00032 #include <xercesc/util/BinInputStream.hpp> 00033 00034 #include <stdio.h> 00035 #include <assert.h> 00036 00037 XERCES_CPP_NAMESPACE_BEGIN 00038 00039 const bool XSerializeEngine::toWriteBufferLen = true; 00040 const bool XSerializeEngine::toReadBufferLen = true; 00041 00042 static const unsigned long noDataFollowed = (unsigned long)-1; 00043 00044 static const XSerializeEngine::XSerializedObjectId_t fgNullObjectTag = 0; // indicating null ptrs 00045 static const XSerializeEngine::XSerializedObjectId_t fgNewClassTag = 0xFFFFFFFF; // indicating new class 00046 static const XSerializeEngine::XSerializedObjectId_t fgTemplateObjTag = 0xFFFFFFFE; // indicating template object 00047 static const XSerializeEngine::XSerializedObjectId_t fgClassMask = 0x80000000; // indicates class tag 00048 static const XSerializeEngine::XSerializedObjectId_t fgMaxObjectCount = 0x3FFFFFFD; 00049 00050 #define TEST_THROW_ARG1(condition, data, err_msg) \ 00051 if (condition) \ 00052 { \ 00053 XMLCh value1[64]; \ 00054 XMLString::sizeToText(data, value1, 65, 10, getMemoryManager()); \ 00055 ThrowXMLwithMemMgr1(XSerializationException \ 00056 , err_msg \ 00057 , value1 \ 00058 , getMemoryManager()); \ 00059 } 00060 00061 #define TEST_THROW_ARG2(condition, data1, data2, err_msg) \ 00062 if (condition) \ 00063 { \ 00064 XMLCh value1[64]; \ 00065 XMLCh value2[64]; \ 00066 XMLString::sizeToText(data1, value1, 65, 10, getMemoryManager()); \ 00067 XMLString::sizeToText(data2, value2, 65, 10, getMemoryManager()); \ 00068 ThrowXMLwithMemMgr2(XSerializationException \ 00069 , err_msg \ 00070 , value1 \ 00071 , value2 \ 00072 , getMemoryManager()); \ 00073 } 00074 00075 // --------------------------------------------------------------------------- 00076 // Constructor and Destructor 00077 // --------------------------------------------------------------------------- 00078 XSerializeEngine::~XSerializeEngine() 00079 { 00080 if (isStoring()) 00081 { 00082 flush(); 00083 delete fStorePool; 00084 } 00085 else 00086 { 00087 delete fLoadPool; 00088 } 00089 00090 getMemoryManager()->deallocate(fBufStart); 00091 00092 } 00093 00094 XSerializeEngine::XSerializeEngine(BinInputStream* inStream 00095 , XMLGrammarPool* const gramPool 00096 , XMLSize_t bufSize) 00097 :fStoreLoad(mode_Load) 00098 ,fStorerLevel(0) 00099 ,fGrammarPool(gramPool) 00100 ,fInputStream(inStream) 00101 ,fOutputStream(0) 00102 ,fBufCount(0) 00103 ,fBufSize(bufSize) 00104 ,fBufStart( (XMLByte*) gramPool->getMemoryManager()->allocate(bufSize)) 00105 ,fBufEnd(0) 00106 ,fBufCur(fBufStart) 00107 ,fBufLoadMax(fBufStart) 00108 ,fStorePool(0) 00109 ,fLoadPool( new (gramPool->getMemoryManager()) ValueVectorOf<void*>(29, gramPool->getMemoryManager(), false)) 00110 ,fObjectCount(0) 00111 { 00112 /*** 00113 * initialize buffer from the inStream 00114 ***/ 00115 fillBuffer(); 00116 00117 } 00118 00119 XSerializeEngine::XSerializeEngine(BinOutputStream* outStream 00120 , XMLGrammarPool* const gramPool 00121 , XMLSize_t bufSize) 00122 :fStoreLoad(mode_Store) 00123 ,fStorerLevel(0) 00124 ,fGrammarPool(gramPool) 00125 ,fInputStream(0) 00126 ,fOutputStream(outStream) 00127 ,fBufCount(0) 00128 ,fBufSize(bufSize) 00129 ,fBufStart((XMLByte*) gramPool->getMemoryManager()->allocate(bufSize)) 00130 ,fBufEnd(fBufStart+bufSize) 00131 ,fBufCur(fBufStart) 00132 ,fBufLoadMax(0) 00133 ,fStorePool( new (gramPool->getMemoryManager()) RefHashTableOf<XSerializedObjectId, PtrHasher>(29, true, gramPool->getMemoryManager()) ) 00134 ,fLoadPool(0) 00135 ,fObjectCount(0) 00136 { 00137 resetBuffer(); 00138 00139 //initialize store pool 00140 fStorePool->put(0, new (gramPool->getMemoryManager()) XSerializedObjectId(fgNullObjectTag)); 00141 00142 } 00143 00144 void XSerializeEngine::flush() 00145 { 00146 if (isStoring()) 00147 flushBuffer(); 00148 00149 } 00150 00151 // --------------------------------------------------------------------------- 00152 // Storing 00153 // --------------------------------------------------------------------------- 00154 void XSerializeEngine::write(XSerializable* const objectToWrite) 00155 { 00156 ensureStoring(); 00157 //don't ensurePointer here !!! 00158 00159 XSerializedObjectId_t objIndex = 0; 00160 00161 if (!objectToWrite) // null pointer 00162 { 00163 *this << fgNullObjectTag; 00164 } 00165 else if (0 != (objIndex = lookupStorePool((void*) objectToWrite))) 00166 { 00167 // writing an object reference tag 00168 *this << objIndex; 00169 } 00170 else 00171 { 00172 // write protoType first 00173 XProtoType* protoType = objectToWrite->getProtoType(); 00174 write(protoType); 00175 00176 // put the object into StorePool 00177 addStorePool((void*)objectToWrite); 00178 00179 // ask the object to serialize itself 00180 objectToWrite->serialize(*this); 00181 } 00182 00183 } 00184 00185 void XSerializeEngine::write(XProtoType* const protoType) 00186 { 00187 ensureStoring(); 00188 ensurePointer(protoType); 00189 00190 XSerializedObjectId_t objIndex = lookupStorePool((void*)protoType); 00191 00192 if (objIndex) 00193 { 00194 //protoType seen in the store pool 00195 *this << (fgClassMask | objIndex); 00196 } 00197 else 00198 { 00199 // store protoType 00200 *this << fgNewClassTag; 00201 protoType->store(*this); 00202 addStorePool((void*)protoType); 00203 } 00204 00205 } 00206 00207 /*** 00208 * 00209 ***/ 00210 void XSerializeEngine::write(const XMLCh* const toWrite 00211 , XMLSize_t writeLen) 00212 { 00213 write((XMLByte*)toWrite, (sizeof(XMLCh)/sizeof(XMLByte)) * writeLen); 00214 } 00215 00216 00217 void XSerializeEngine::write(const XMLByte* const toWrite 00218 , XMLSize_t writeLen) 00219 { 00220 ensureStoring(); 00221 ensurePointer((void*)toWrite); 00222 ensureStoreBuffer(); 00223 00224 if (writeLen == 0) 00225 return; 00226 00227 /*** 00228 * If the available space is sufficient, write it up 00229 ***/ 00230 XMLSize_t bufAvail = fBufEnd - fBufCur; 00231 00232 if (writeLen <= bufAvail) 00233 { 00234 memcpy(fBufCur, toWrite, writeLen); 00235 fBufCur += writeLen; 00236 return; 00237 } 00238 00239 const XMLByte* tempWrite = (const XMLByte*) toWrite; 00240 XMLSize_t writeRemain = writeLen; 00241 00242 // fill up the avaiable space and flush 00243 memcpy(fBufCur, tempWrite, bufAvail); 00244 tempWrite += bufAvail; 00245 writeRemain -= bufAvail; 00246 flushBuffer(); 00247 00248 // write chunks of fBufSize 00249 while (writeRemain >= fBufSize) 00250 { 00251 memcpy(fBufCur, tempWrite, fBufSize); 00252 tempWrite += fBufSize; 00253 writeRemain -= fBufSize; 00254 flushBuffer(); 00255 } 00256 00257 // write the remaining if any 00258 if (writeRemain) 00259 { 00260 memcpy(fBufCur, tempWrite, writeRemain); 00261 fBufCur += writeRemain; 00262 } 00263 00264 } 00265 00266 /*** 00267 * 00268 * Storage scheme (normal): 00269 * 00270 * < 00271 * 1st integer: bufferLen (optional) 00272 * 2nd integer: dataLen 00273 * bytes following: 00274 * > 00275 * 00276 * Storage scheme (special): 00277 * < 00278 * only integer: noDataFollowed 00279 * > 00280 */ 00281 00282 void XSerializeEngine::writeString(const XMLCh* const toWrite 00283 , const XMLSize_t bufferLen 00284 , bool toWriteBufLen) 00285 { 00286 if (toWrite) 00287 { 00288 if (toWriteBufLen) 00289 *this<<(unsigned long)bufferLen; 00290 00291 XMLSize_t strLen = XMLString::stringLen(toWrite); 00292 *this<<(unsigned long)strLen; 00293 00294 write(toWrite, strLen); 00295 } 00296 else 00297 { 00298 *this<<noDataFollowed; 00299 } 00300 00301 } 00302 00303 void XSerializeEngine::writeString(const XMLByte* const toWrite 00304 , const XMLSize_t bufferLen 00305 , bool toWriteBufLen) 00306 { 00307 00308 if (toWrite) 00309 { 00310 if (toWriteBufLen) 00311 *this<<(unsigned long)bufferLen; 00312 00313 XMLSize_t strLen = XMLString::stringLen((char*)toWrite); 00314 *this<<(unsigned long)strLen; 00315 write(toWrite, strLen); 00316 } 00317 else 00318 { 00319 *this<<noDataFollowed; 00320 } 00321 00322 } 00323 00324 // --------------------------------------------------------------------------- 00325 // Loading 00326 // --------------------------------------------------------------------------- 00327 XSerializable* XSerializeEngine::read(XProtoType* const protoType) 00328 { 00329 ensureLoading(); 00330 ensurePointer(protoType); 00331 00332 XSerializedObjectId_t objectTag; 00333 XSerializable* objRet; 00334 00335 if (! read(protoType, &objectTag)) 00336 { 00337 /*** 00338 * We hava a reference to an existing object in 00339 * load pool, get it. 00340 */ 00341 objRet = lookupLoadPool(objectTag); 00342 } 00343 else 00344 { 00345 // create the object from the prototype 00346 objRet = protoType->fCreateObject(getMemoryManager()); 00347 Assert((objRet != 0), XMLExcepts::XSer_CreateObject_Fail); 00348 00349 // put it into load pool 00350 addLoadPool(objRet); 00351 00352 // de-serialize it 00353 objRet->serialize(*this); 00354 00355 } 00356 00357 return objRet; 00358 } 00359 00360 bool XSerializeEngine::read(XProtoType* const protoType 00361 , XSerializedObjectId_t* objectTagRet) 00362 { 00363 ensureLoading(); 00364 ensurePointer(protoType); 00365 00366 XSerializedObjectId_t obTag; 00367 00368 *this >> obTag; 00369 00370 // object reference tag found 00371 if (!(obTag & fgClassMask)) 00372 { 00373 *objectTagRet = obTag; 00374 return false; 00375 } 00376 00377 if (obTag == fgNewClassTag) 00378 { 00379 // what follows fgNewClassTag is the prototype object info 00380 // for the object anticipated, go and verify the info 00381 XProtoType::load(*this, protoType->fClassName, getMemoryManager()); 00382 00383 addLoadPool((void*)protoType); 00384 } 00385 else 00386 { 00387 // what follows class tag is an XSerializable object 00388 XSerializedObjectId_t classIndex = (obTag & ~fgClassMask); 00389 XSerializedObjectId_t loadPoolSize = (XSerializedObjectId_t)fLoadPool->size(); 00390 00391 if ((classIndex == 0 ) || (classIndex > loadPoolSize)) 00392 { 00393 XMLCh value1[64]; 00394 XMLCh value2[64]; 00395 XMLString::binToText(classIndex, value1, 65, 10, getMemoryManager()); 00396 XMLString::binToText(loadPoolSize, value2, 65, 10, getMemoryManager()); 00397 ThrowXMLwithMemMgr2(XSerializationException 00398 , XMLExcepts::XSer_Inv_ClassIndex 00399 , value1 00400 , value2 00401 , getMemoryManager()); 00402 } 00403 00404 ensurePointer(lookupLoadPool(classIndex)); 00405 } 00406 00407 return true; 00408 } 00409 00410 void XSerializeEngine::read(XMLCh* const toRead 00411 , XMLSize_t readLen) 00412 { 00413 read((XMLByte*)toRead, (sizeof(XMLCh)/sizeof(XMLByte))*readLen); 00414 } 00415 00416 void XSerializeEngine::read(XMLByte* const toRead 00417 , XMLSize_t readLen) 00418 { 00419 ensureLoading(); 00420 ensurePointer(toRead); 00421 ensureLoadBuffer(); 00422 00423 if (readLen == 0) 00424 return; 00425 00426 /*** 00427 * If unread is sufficient, read it up 00428 ***/ 00429 XMLSize_t dataAvail = fBufLoadMax - fBufCur; 00430 00431 if (readLen <= dataAvail) 00432 { 00433 memcpy(toRead, fBufCur, readLen); 00434 fBufCur += readLen; 00435 return; 00436 } 00437 00438 /*** 00439 * 00440 * fillBuffer will discard anything left in the buffer 00441 * before it asks the inputStream to fill in the buffer, 00442 * so we need to readup everything in the buffer before 00443 * calling fillBuffer 00444 * 00445 ***/ 00446 XMLByte* tempRead = (XMLByte*) toRead; 00447 XMLSize_t readRemain = readLen; 00448 00449 // read the unread 00450 memcpy(tempRead, fBufCur, dataAvail); 00451 tempRead += dataAvail; 00452 readRemain -= dataAvail; 00453 00454 // read chunks of fBufSize 00455 while (readRemain >= fBufSize) 00456 { 00457 fillBuffer(); 00458 memcpy(tempRead, fBufCur, fBufSize); 00459 tempRead += fBufSize; 00460 readRemain -= fBufSize; 00461 } 00462 00463 // read the remaining if any 00464 if (readRemain) 00465 { 00466 fillBuffer(); 00467 memcpy(tempRead, fBufCur, readRemain); 00468 fBufCur += readRemain; 00469 } 00470 00471 } 00472 00473 /*** 00474 * 00475 * Storage scheme (normal): 00476 * 00477 * < 00478 * 1st integer: bufferLen (optional) 00479 * 2nd integer: dataLen 00480 * bytes following: 00481 * > 00482 * 00483 * Storage scheme (special): 00484 * < 00485 * only integer: noDataFollowed 00486 * > 00487 */ 00488 void XSerializeEngine::readString(XMLCh*& toRead 00489 , XMLSize_t& bufferLen 00490 , XMLSize_t& dataLen 00491 , bool toReadBufLen) 00492 { 00493 /*** 00494 * Check if any data written 00495 ***/ 00496 unsigned long tmp; 00497 *this>>tmp; 00498 bufferLen=tmp; 00499 00500 if (bufferLen == noDataFollowed) 00501 { 00502 toRead = 0; 00503 bufferLen = 0; 00504 dataLen = 0; 00505 return; 00506 } 00507 00508 if (toReadBufLen) 00509 { 00510 *this>>tmp; 00511 dataLen=tmp; 00512 } 00513 else 00514 { 00515 dataLen = bufferLen++; 00516 } 00517 00518 toRead = (XMLCh*) getMemoryManager()->allocate(bufferLen * sizeof(XMLCh)); 00519 read(toRead, dataLen); 00520 toRead[dataLen] = 0; 00521 } 00522 00523 void XSerializeEngine::readString(XMLByte*& toRead 00524 , XMLSize_t& bufferLen 00525 , XMLSize_t& dataLen 00526 , bool toReadBufLen) 00527 { 00528 /*** 00529 * Check if any data written 00530 ***/ 00531 unsigned long tmp; 00532 *this>>tmp; 00533 bufferLen=tmp; 00534 if (bufferLen == noDataFollowed) 00535 { 00536 toRead = 0; 00537 bufferLen = 0; 00538 dataLen = 0; 00539 return; 00540 } 00541 00542 if (toReadBufLen) 00543 { 00544 *this>>tmp; 00545 dataLen=tmp; 00546 } 00547 else 00548 { 00549 dataLen = bufferLen++; 00550 } 00551 00552 toRead = (XMLByte*) getMemoryManager()->allocate(bufferLen * sizeof(XMLByte)); 00553 read(toRead, dataLen); 00554 toRead[dataLen] = 0; 00555 00556 } 00557 00558 // --------------------------------------------------------------------------- 00559 // Insertion & Extraction 00560 // --------------------------------------------------------------------------- 00561 00562 XSerializeEngine& XSerializeEngine::operator<<(XMLCh xch) 00563 { 00564 checkAndFlushBuffer(calBytesNeeded(sizeof(XMLCh))); 00565 00566 alignBufCur(sizeof(XMLCh)); 00567 *(XMLCh*)fBufCur = xch; 00568 fBufCur += sizeof(XMLCh); 00569 return *this; 00570 } 00571 00572 XSerializeEngine& XSerializeEngine::operator>>(XMLCh& xch) 00573 { 00574 checkAndFillBuffer(calBytesNeeded(sizeof(XMLCh))); 00575 00576 alignBufCur(sizeof(XMLCh)); 00577 xch = *(XMLCh*)fBufCur; 00578 fBufCur += sizeof(XMLCh); 00579 return *this; 00580 } 00581 00582 XSerializeEngine& XSerializeEngine::operator<<(XMLByte by) 00583 { 00584 checkAndFlushBuffer(sizeof(XMLByte)); 00585 00586 *(XMLByte*)fBufCur = by; 00587 fBufCur += sizeof(XMLByte); 00588 return *this; 00589 } 00590 00591 XSerializeEngine& XSerializeEngine::operator>>(XMLByte& by) 00592 { 00593 checkAndFillBuffer(sizeof(XMLByte)); 00594 00595 by = *(XMLByte*)fBufCur; 00596 fBufCur += sizeof(XMLByte); 00597 return *this; 00598 } 00599 00600 XSerializeEngine& XSerializeEngine::operator<<(bool b) 00601 { 00602 checkAndFlushBuffer(sizeof(bool)); 00603 00604 *(bool*)fBufCur = b; 00605 fBufCur += sizeof(bool); 00606 return *this; 00607 } 00608 00609 XSerializeEngine& XSerializeEngine::operator>>(bool& b) 00610 { 00611 checkAndFillBuffer(sizeof(bool)); 00612 00613 b = *(bool*)fBufCur; 00614 fBufCur += sizeof(bool); 00615 return *this; 00616 } 00617 00618 void XSerializeEngine::writeSize (XMLSize_t t) 00619 { 00620 checkAndFlushBuffer(sizeof(t)); 00621 00622 memcpy(fBufCur, &t, sizeof(t)); 00623 fBufCur += sizeof(t); 00624 } 00625 00626 void XSerializeEngine::writeInt64 (XMLInt64 t) 00627 { 00628 checkAndFlushBuffer(sizeof(t)); 00629 00630 memcpy(fBufCur, &t, sizeof(t)); 00631 fBufCur += sizeof(t); 00632 } 00633 00634 void XSerializeEngine::writeUInt64 (XMLUInt64 t) 00635 { 00636 checkAndFlushBuffer(sizeof(t)); 00637 00638 memcpy(fBufCur, &t, sizeof(t)); 00639 fBufCur += sizeof(t); 00640 } 00641 00642 void XSerializeEngine::readSize (XMLSize_t& t) 00643 { 00644 checkAndFillBuffer(sizeof(t)); 00645 00646 memcpy(&t, fBufCur, sizeof(t)); 00647 fBufCur += sizeof(t); 00648 } 00649 00650 void XSerializeEngine::readInt64 (XMLInt64& t) 00651 { 00652 checkAndFillBuffer(sizeof(t)); 00653 00654 memcpy(&t, fBufCur, sizeof(t)); 00655 fBufCur += sizeof(t); 00656 } 00657 00658 void XSerializeEngine::readUInt64 (XMLUInt64& t) 00659 { 00660 checkAndFillBuffer(sizeof(t)); 00661 00662 memcpy(&t, fBufCur, sizeof(t)); 00663 fBufCur += sizeof(t); 00664 } 00665 00666 XSerializeEngine& XSerializeEngine::operator<<(char ch) 00667 { 00668 return XSerializeEngine::operator<<((XMLByte)ch); 00669 } 00670 00671 XSerializeEngine& XSerializeEngine::operator>>(char& ch) 00672 { 00673 return XSerializeEngine::operator>>((XMLByte&)ch); 00674 } 00675 00676 XSerializeEngine& XSerializeEngine::operator<<(short sh) 00677 { 00678 checkAndFlushBuffer(calBytesNeeded(sizeof(short))); 00679 00680 alignBufCur(sizeof(short)); 00681 *(short*)fBufCur = sh; 00682 fBufCur += sizeof(short); 00683 return *this; 00684 } 00685 00686 XSerializeEngine& XSerializeEngine::operator>>(short& sh) 00687 { 00688 checkAndFillBuffer(calBytesNeeded(sizeof(short))); 00689 00690 alignBufCur(sizeof(short)); 00691 sh = *(short*)fBufCur; 00692 fBufCur += sizeof(short); 00693 return *this; 00694 } 00695 00696 XSerializeEngine& XSerializeEngine::operator<<(int i) 00697 { 00698 checkAndFlushBuffer(calBytesNeeded(sizeof(int))); 00699 00700 alignBufCur(sizeof(int)); 00701 *(int*)fBufCur = i; 00702 fBufCur += sizeof(int); 00703 return *this; 00704 } 00705 00706 XSerializeEngine& XSerializeEngine::operator>>(int& i) 00707 { 00708 checkAndFillBuffer(calBytesNeeded(sizeof(int))); 00709 00710 alignBufCur(sizeof(int)); 00711 i = *(int*)fBufCur; 00712 fBufCur += sizeof(int); 00713 return *this; 00714 } 00715 00716 XSerializeEngine& XSerializeEngine::operator<<(unsigned int ui) 00717 { 00718 00719 checkAndFlushBuffer(calBytesNeeded(sizeof(unsigned int))); 00720 00721 alignBufCur(sizeof(unsigned int)); 00722 *(unsigned int*)fBufCur = ui; 00723 fBufCur += sizeof(unsigned int); 00724 return *this; 00725 } 00726 00727 XSerializeEngine& XSerializeEngine::operator>>(unsigned int& ui) 00728 { 00729 00730 checkAndFillBuffer(calBytesNeeded(sizeof(unsigned int))); 00731 00732 alignBufCur(sizeof(unsigned int)); 00733 ui = *(unsigned int*)fBufCur; 00734 fBufCur += sizeof(unsigned int); 00735 return *this; 00736 } 00737 00738 XSerializeEngine& XSerializeEngine::operator<<(long l) 00739 { 00740 checkAndFlushBuffer(calBytesNeeded(sizeof(long))); 00741 00742 alignBufCur(sizeof(long)); 00743 *(long*)fBufCur = l; 00744 fBufCur += sizeof(long); 00745 return *this; 00746 } 00747 00748 XSerializeEngine& XSerializeEngine::operator>>(long& l) 00749 { 00750 checkAndFillBuffer(calBytesNeeded(sizeof(long))); 00751 00752 alignBufCur(sizeof(long)); 00753 l = *(long*)fBufCur; 00754 fBufCur += sizeof(long); 00755 return *this; 00756 } 00757 00758 XSerializeEngine& XSerializeEngine::operator<<(unsigned long ul) 00759 { 00760 checkAndFlushBuffer(calBytesNeeded(sizeof(unsigned long))); 00761 00762 alignBufCur(sizeof(unsigned long)); 00763 *(unsigned long*)fBufCur = ul; 00764 fBufCur += sizeof(unsigned long); 00765 return *this; 00766 } 00767 00768 XSerializeEngine& XSerializeEngine::operator>>(unsigned long& ul) 00769 { 00770 checkAndFillBuffer(calBytesNeeded(sizeof(unsigned long))); 00771 00772 alignBufCur(sizeof(unsigned long)); 00773 ul = *(unsigned long*)fBufCur; 00774 fBufCur += sizeof(unsigned long); 00775 return *this; 00776 } 00777 00778 XSerializeEngine& XSerializeEngine::operator<<(float f) 00779 { 00780 checkAndFlushBuffer(calBytesNeeded(sizeof(float))); 00781 00782 alignBufCur(sizeof(float)); 00783 *(float*)fBufCur = *(float*)&f; 00784 fBufCur += sizeof(float); 00785 return *this; 00786 } 00787 00788 XSerializeEngine& XSerializeEngine::operator>>(float& f) 00789 { 00790 checkAndFillBuffer(calBytesNeeded(sizeof(float))); 00791 00792 alignBufCur(sizeof(float)); 00793 *(float*)&f = *(float*)fBufCur; 00794 fBufCur += sizeof(float); 00795 return *this; 00796 } 00797 00798 XSerializeEngine& XSerializeEngine::operator<<(double d) 00799 { 00800 checkAndFlushBuffer(calBytesNeeded(sizeof(double))); 00801 00802 alignBufCur(sizeof(double)); 00803 *(double*)fBufCur = *(double*)&d; 00804 fBufCur += sizeof(double); 00805 return *this; 00806 } 00807 00808 XSerializeEngine& XSerializeEngine::operator>>(double& d) 00809 { 00810 checkAndFillBuffer(calBytesNeeded(sizeof(double))); 00811 00812 alignBufCur(sizeof(double)); 00813 *(double*)&d = *(double*)fBufCur; 00814 fBufCur += sizeof(double); 00815 return *this; 00816 } 00817 00818 // --------------------------------------------------------------------------- 00819 // StorePool/LoadPool Opertions 00820 // --------------------------------------------------------------------------- 00821 XSerializeEngine::XSerializedObjectId_t 00822 XSerializeEngine::lookupStorePool(void* const objToLookup) const 00823 { 00824 //0 indicating object is not in the StorePool 00825 XSerializedObjectId* data = fStorePool->get(objToLookup); 00826 return (XSerializeEngine::XSerializedObjectId_t) (data ? data->getValue() : 0); 00827 00828 } 00829 00830 void XSerializeEngine::addStorePool(void* const objToAdd) 00831 { 00832 pumpCount(); 00833 fStorePool->put(objToAdd, new (fGrammarPool->getMemoryManager()) XSerializedObjectId(fObjectCount)); 00834 } 00835 00836 XSerializable* XSerializeEngine::lookupLoadPool(XSerializedObjectId_t objectTag) const 00837 { 00838 00839 /*** 00840 * an object tag read from the binary refering to 00841 * an object beyond the upper most boundary of the load pool 00842 ***/ 00843 00844 if (objectTag > fLoadPool->size()) 00845 { 00846 XMLCh value1[64]; 00847 XMLCh value2[64]; 00848 XMLString::binToText(objectTag, value1, 65, 10, getMemoryManager()); 00849 XMLString::sizeToText(fLoadPool->size(), value2, 65, 10, getMemoryManager()); 00850 ThrowXMLwithMemMgr2(XSerializationException 00851 , XMLExcepts::XSer_LoadPool_UppBnd_Exceed 00852 , value1 00853 , value2 00854 , getMemoryManager()); 00855 } 00856 00857 if (objectTag == 0) 00858 return 0; 00859 00860 /*** 00861 * A non-null object tag starts from 1 while fLoadPool starts from 0 00862 ***/ 00863 return (XSerializable*) fLoadPool->elementAt(objectTag - 1); 00864 } 00865 00866 void XSerializeEngine::addLoadPool(void* const objToAdd) 00867 { 00868 00869 TEST_THROW_ARG2( (fLoadPool->size() != fObjectCount) 00870 , fObjectCount 00871 , fLoadPool->size() 00872 , XMLExcepts::XSer_LoadPool_NoTally_ObjCnt 00873 ) 00874 00875 pumpCount(); 00876 fLoadPool->addElement(objToAdd); 00877 00878 } 00879 00880 void XSerializeEngine::pumpCount() 00881 { 00882 if (fObjectCount >= fgMaxObjectCount) 00883 { 00884 XMLCh value1[64]; 00885 XMLCh value2[64]; 00886 XMLString::sizeToText(fObjectCount, value1, 65, 10, getMemoryManager()); 00887 XMLString::binToText(fgMaxObjectCount, value2, 65, 10, getMemoryManager()); 00888 ThrowXMLwithMemMgr2(XSerializationException 00889 , XMLExcepts::XSer_ObjCount_UppBnd_Exceed 00890 , value1 00891 , value2 00892 , getMemoryManager()); 00893 } 00894 00895 fObjectCount++; 00896 00897 } 00898 00899 // --------------------------------------------------------------------------- 00900 // Buffer Opertions 00901 // --------------------------------------------------------------------------- 00902 /*** 00903 * 00904 * Though client may need only miniBytesNeeded, we always request 00905 * a full size reading from our inputStream. 00906 * 00907 * Whatever possibly left in the buffer is abandoned, such as in 00908 * the case of CheckAndFillBuffer() 00909 * 00910 ***/ 00911 void XSerializeEngine::fillBuffer() 00912 { 00913 ensureLoading(); 00914 ensureLoadBuffer(); 00915 00916 resetBuffer(); 00917 00918 XMLSize_t bytesRead = fInputStream->readBytes(fBufStart, fBufSize); 00919 00920 /*** 00921 * InputStream MUST fill in the exact amount of bytes as requested 00922 * to do: combine the checking and create a new exception code later 00923 ***/ 00924 TEST_THROW_ARG2( (bytesRead < fBufSize) 00925 , bytesRead 00926 , fBufSize 00927 , XMLExcepts::XSer_InStream_Read_LT_Req 00928 ) 00929 00930 TEST_THROW_ARG2( (bytesRead > fBufSize) 00931 , bytesRead 00932 , fBufSize 00933 , XMLExcepts::XSer_InStream_Read_OverFlow 00934 ) 00935 00936 fBufLoadMax = fBufStart + fBufSize; 00937 fBufCur = fBufStart; 00938 00939 ensureLoadBuffer(); 00940 00941 fBufCount++; 00942 } 00943 00944 /*** 00945 * 00946 * Flush out whatever left in the buffer, from 00947 * fBufStart to fBufEnd. 00948 * 00949 ***/ 00950 void XSerializeEngine::flushBuffer() 00951 { 00952 ensureStoring(); 00953 ensureStoreBuffer(); 00954 00955 fOutputStream->writeBytes(fBufStart, fBufSize); 00956 fBufCur = fBufStart; 00957 00958 resetBuffer(); 00959 ensureStoreBuffer(); 00960 00961 fBufCount++; 00962 } 00963 00964 inline void XSerializeEngine::checkAndFlushBuffer(XMLSize_t bytesNeedToWrite) 00965 { 00966 TEST_THROW_ARG1( (bytesNeedToWrite <= 0) 00967 , bytesNeedToWrite 00968 , XMLExcepts::XSer_Inv_checkFlushBuffer_Size 00969 ) 00970 00971 // fBufStart ... fBufCur ...fBufEnd 00972 if ((fBufCur + bytesNeedToWrite) > fBufEnd) 00973 flushBuffer(); 00974 } 00975 00976 inline void XSerializeEngine::checkAndFillBuffer(XMLSize_t bytesNeedToRead) 00977 { 00978 00979 TEST_THROW_ARG1( (bytesNeedToRead <= 0) 00980 , bytesNeedToRead 00981 , XMLExcepts::XSer_Inv_checkFillBuffer_Size 00982 ) 00983 00984 // fBufStart ... fBufCur ...fBufLoadMax 00985 if ((fBufCur + bytesNeedToRead) > fBufLoadMax) 00986 { 00987 fillBuffer(); 00988 } 00989 00990 } 00991 00992 inline void XSerializeEngine::ensureStoreBuffer() const 00993 { 00994 XMLSize_t a = (XMLSize_t) (fBufCur - fBufStart); 00995 XMLSize_t b = (XMLSize_t) (fBufEnd - fBufCur); 00996 00997 TEST_THROW_ARG2 ( !((fBufStart <= fBufCur) && (fBufCur <= fBufEnd)) 00998 , a 00999 , b 01000 , XMLExcepts::XSer_StoreBuffer_Violation 01001 ) 01002 01003 } 01004 01005 inline void XSerializeEngine::ensureLoadBuffer() const 01006 { 01007 XMLSize_t a = (XMLSize_t) (fBufCur - fBufStart); 01008 XMLSize_t b = (XMLSize_t) (fBufLoadMax - fBufCur); 01009 01010 TEST_THROW_ARG2 ( !((fBufStart <= fBufCur) && (fBufCur <= fBufLoadMax)) 01011 , a 01012 , b 01013 , XMLExcepts::XSer_LoadBuffer_Violation 01014 ) 01015 01016 } 01017 01018 inline void XSerializeEngine::ensurePointer(void* const ptr) const 01019 { 01020 01021 TEST_THROW_ARG1( (ptr == 0) 01022 , 0 01023 , XMLExcepts::XSer_Inv_Null_Pointer 01024 ) 01025 01026 } 01027 01028 inline void XSerializeEngine::resetBuffer() 01029 { 01030 memset(fBufStart, 0, fBufSize * sizeof(XMLByte)); 01031 } 01032 01033 // --------------------------------------------------------------------------- 01034 // Template object 01035 // --------------------------------------------------------------------------- 01036 /*** 01037 * 01038 * Search the store pool to see if the address has been seen before or not. 01039 * 01040 * If yes, write the corresponding object Tag to the internal buffer 01041 * and return true. 01042 * 01043 * Otherwise, add the address to the store pool and return false 01044 * to notifiy the client application code to store the template object. 01045 * 01046 ***/ 01047 bool XSerializeEngine::needToStoreObject(void* const templateObjectToWrite) 01048 { 01049 ensureStoring(); //don't ensurePointer here !!! 01050 01051 XSerializedObjectId_t objIndex = 0; 01052 01053 if (!templateObjectToWrite) 01054 { 01055 *this << fgNullObjectTag; // null pointer 01056 return false; 01057 } 01058 else if (0 != (objIndex = lookupStorePool(templateObjectToWrite))) 01059 { 01060 *this << objIndex; // write an object reference tag 01061 return false; 01062 } 01063 else 01064 { 01065 *this << fgTemplateObjTag; // write fgTemplateObjTag to denote that actual 01066 // template object follows 01067 addStorePool(templateObjectToWrite); // put the address into StorePool 01068 return true; 01069 } 01070 01071 } 01072 01073 bool XSerializeEngine::needToLoadObject(void** templateObjectToRead) 01074 { 01075 ensureLoading(); 01076 01077 XSerializedObjectId_t obTag; 01078 01079 *this >> obTag; 01080 01081 if (obTag == fgTemplateObjTag) 01082 { 01083 /*** 01084 * what follows fgTemplateObjTag is the actual template object 01085 * We need the client application to create a template object 01086 * and register it through registerObject(), and deserialize 01087 * template object 01088 ***/ 01089 return true; 01090 } 01091 else 01092 { 01093 /*** 01094 * We hava a reference to an existing template object, get it. 01095 */ 01096 *templateObjectToRead = lookupLoadPool(obTag); 01097 return false; 01098 } 01099 01100 } 01101 01102 void XSerializeEngine::registerObject(void* const templateObjectToRegister) 01103 { 01104 ensureLoading(); 01105 addLoadPool(templateObjectToRegister); 01106 } 01107 01108 XMLGrammarPool* XSerializeEngine::getGrammarPool() const 01109 { 01110 return fGrammarPool; 01111 } 01112 01113 XMLStringPool* XSerializeEngine::getStringPool() const 01114 { 01115 return fGrammarPool->getURIStringPool(); 01116 } 01117 01118 MemoryManager* XSerializeEngine::getMemoryManager() const 01119 { 01120 //todo: changed to return fGrammarPool->getMemoryManager() 01121 return fGrammarPool ? fGrammarPool->getMemoryManager() : XMLPlatformUtils::fgMemoryManager; 01122 } 01123 01124 // 01125 // Based on the current position (fBufCur), calculated the needed size 01126 // to read/write 01127 // 01128 inline XMLSize_t XSerializeEngine::alignAdjust(XMLSize_t size) const 01129 { 01130 XMLSize_t remainder = (XMLSize_t) fBufCur % size; 01131 return (remainder == 0) ? 0 : (size - remainder); 01132 } 01133 01134 // Adjust the fBufCur 01135 inline void XSerializeEngine::alignBufCur(XMLSize_t size) 01136 { 01137 fBufCur+=alignAdjust(size); 01138 assert(((XMLSize_t) fBufCur % size)==0); 01139 } 01140 01141 inline XMLSize_t XSerializeEngine::calBytesNeeded(XMLSize_t size) const 01142 { 01143 return (alignAdjust(size) + size); 01144 } 01145 01146 void XSerializeEngine::trace(char* /*funcName*/) const 01147 { 01148 return; 01149 01150 /* 01151 if (isStoring()) 01152 printf("\n funcName=<%s>, storing, count=<%lu>, postion=<%lu>\n", funcName, fBufCount, getBufCurAccumulated()); 01153 else 01154 printf("\n funcName=<%s>, loading, count=<%lu>, postion=<%lu>\n", funcName, fBufCount, getBufCurAccumulated()); 01155 */ 01156 } 01157 01158 XERCES_CPP_NAMESPACE_END