BsBinarySerializer.cpp 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334
  1. #include "BsBinarySerializer.h"
  2. #include "BsException.h"
  3. #include "BsDebug.h"
  4. #include "BsIReflectable.h"
  5. #include "BsRTTIType.h"
  6. #include "BsRTTIField.h"
  7. #include "BsRTTIPlainField.h"
  8. #include "BsRTTIReflectableField.h"
  9. #include "BsRTTIReflectablePtrField.h"
  10. #include "BsRTTIManagedDataBlockField.h"
  11. #include <unordered_set>
  12. /**
  13. * @brief A macro that represents a block of code that gets used a lot inside
  14. * encodeInternal. It checks if the buffer has enough space, and if it does
  15. * it copies the data from the specified location and increments the needed
  16. * pointers and counters. If there is not enough space the buffer is flushed
  17. * (hopefully to make some space). If there is still not enough space the entire
  18. * encoding process ends.
  19. *
  20. * @param dataPtr Pointer to data which to copy.
  21. * @param size Size of the data to copy
  22. */
  23. #define COPY_TO_BUFFER(dataIter, size) \
  24. if((*bytesWritten + size##) > bufferLength) \
  25. { \
  26. mTotalBytesWritten += *bytesWritten; \
  27. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength); \
  28. if(buffer == nullptr || bufferLength < size##) return nullptr; \
  29. *bytesWritten = 0; \
  30. } \
  31. \
  32. memcpy(buffer, dataIter##, size##); \
  33. buffer += size##; \
  34. *bytesWritten += size##;
  35. namespace BansheeEngine
  36. {
  37. BinarySerializer::BinarySerializer()
  38. :mLastUsedObjectId(1)
  39. {
  40. }
  41. void BinarySerializer::encode(IReflectable* object, UINT8* buffer, UINT32 bufferLength,
  42. UINT32* bytesWritten, std::function<UINT8*(UINT8*, UINT32, UINT32&)> flushBufferCallback, bool shallow)
  43. {
  44. mObjectsToEncode.clear();
  45. mObjectAddrToId.clear();
  46. mLastUsedObjectId = 1;
  47. *bytesWritten = 0;
  48. mTotalBytesWritten = 0;
  49. UINT8* bufferStart = buffer;
  50. Vector<std::shared_ptr<IReflectable>> encodedObjects;
  51. UINT32 objectId = findOrCreatePersistentId(object);
  52. // Encode primary object and its value types
  53. buffer = encodeInternal(object, objectId, buffer, bufferLength, bytesWritten, flushBufferCallback, shallow);
  54. if(buffer == nullptr)
  55. {
  56. BS_EXCEPT(InternalErrorException,
  57. "Destination buffer is null or not large enough.");
  58. }
  59. // Encode pointed to objects and their value types
  60. UnorderedSet<UINT32> serializedObjects;
  61. while(true)
  62. {
  63. auto iter = mObjectsToEncode.begin();
  64. bool foundObjectToProcess = false;
  65. for(iter; iter != mObjectsToEncode.end(); ++iter)
  66. {
  67. auto foundExisting = serializedObjects.find(iter->objectId);
  68. if(foundExisting != serializedObjects.end())
  69. continue; // Already processed
  70. std::shared_ptr<IReflectable> curObject = iter->object;
  71. UINT32 curObjectid = iter->objectId;
  72. serializedObjects.insert(curObjectid);
  73. mObjectsToEncode.erase(iter);
  74. buffer = encodeInternal(curObject.get(), curObjectid, buffer,
  75. bufferLength, bytesWritten, flushBufferCallback, shallow);
  76. if(buffer == nullptr)
  77. {
  78. BS_EXCEPT(InternalErrorException,
  79. "Destination buffer is null or not large enough.");
  80. }
  81. foundObjectToProcess = true;
  82. // Ensure we keep a reference to the object so it isn't released.
  83. // The system assigns unique IDs to IReflectable objects based on pointer
  84. // addresses but if objects get released then same address could be assigned twice.
  85. // Note: To get around this I could assign unique IDs to IReflectable objects
  86. encodedObjects.push_back(curObject);
  87. break; // Need to start over as mObjectsToSerialize was possibly modified
  88. }
  89. if(!foundObjectToProcess) // We're done
  90. break;
  91. }
  92. // Final flush
  93. if(*bytesWritten > 0)
  94. {
  95. mTotalBytesWritten += *bytesWritten;
  96. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
  97. }
  98. *bytesWritten = mTotalBytesWritten;
  99. encodedObjects.clear();
  100. mObjectsToEncode.clear();
  101. mObjectAddrToId.clear();
  102. }
  103. std::shared_ptr<IReflectable> BinarySerializer::decode(UINT8* data, UINT32 dataLength)
  104. {
  105. mObjectMap.clear();
  106. UINT32 dummy = 0;
  107. SPtr<SerializedObject> intermediateObject = _decodeIntermediate(data, dataLength, dummy);
  108. if (intermediateObject == nullptr)
  109. return nullptr;
  110. SPtr<IReflectable> rootObject;
  111. RTTITypeBase* type = IReflectable::_getRTTIfromTypeId(intermediateObject->getRootTypeId());
  112. if (type != nullptr)
  113. {
  114. rootObject = type->newRTTIObject();
  115. auto iterNewObj = mObjectMap.insert(std::make_pair(intermediateObject, ObjectToDecode(rootObject, intermediateObject)));
  116. decodeInternal(rootObject, intermediateObject);
  117. iterNewObj.first->second.isDecoded = true;
  118. }
  119. // Go through the remaining objects (should be only ones with weak refs)
  120. for(auto iter = mObjectMap.begin(); iter != mObjectMap.end(); ++iter)
  121. {
  122. ObjectToDecode& objToDecode = iter->second;
  123. if(objToDecode.isDecoded)
  124. continue;
  125. decodeInternal(objToDecode.object, objToDecode.serializedObject);
  126. objToDecode.isDecoded = true;
  127. }
  128. mObjectMap.clear();
  129. return rootObject;
  130. }
  131. UINT8* BinarySerializer::encodeInternal(IReflectable* object, UINT32 objectId, UINT8* buffer, UINT32& bufferLength,
  132. UINT32* bytesWritten, std::function<UINT8*(UINT8*, UINT32, UINT32&)> flushBufferCallback, bool shallow)
  133. {
  134. RTTITypeBase* si = object->getRTTI();
  135. bool isBaseClass = false;
  136. // If an object has base classes, we need to iterate through all of them
  137. do
  138. {
  139. si->onSerializationStarted(object);
  140. // Encode object ID & type
  141. ObjectMetaData objectMetaData = encodeObjectMetaData(objectId, si->getRTTIId(), isBaseClass);
  142. COPY_TO_BUFFER(&objectMetaData, sizeof(ObjectMetaData))
  143. int numFields = si->getNumFields();
  144. for(int i = 0; i < numFields; i++)
  145. {
  146. RTTIField* curGenericField = si->getField(i);
  147. // Copy field ID & other meta-data like field size and type
  148. int metaData = encodeFieldMetaData(curGenericField->mUniqueId, curGenericField->getTypeSize(),
  149. curGenericField->mIsVectorType, curGenericField->mType, curGenericField->hasDynamicSize());
  150. COPY_TO_BUFFER(&metaData, META_SIZE)
  151. if(curGenericField->mIsVectorType)
  152. {
  153. UINT32 arrayNumElems = curGenericField->getArraySize(object);
  154. // Copy num vector elements
  155. COPY_TO_BUFFER(&arrayNumElems, NUM_ELEM_FIELD_SIZE)
  156. switch(curGenericField->mType)
  157. {
  158. case SerializableFT_ReflectablePtr:
  159. {
  160. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  161. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  162. {
  163. std::shared_ptr<IReflectable> childObject;
  164. if (!shallow)
  165. childObject = curField->getArrayValue(object, arrIdx);
  166. UINT32 objId = registerObjectPtr(childObject);
  167. COPY_TO_BUFFER(&objId, sizeof(UINT32))
  168. }
  169. break;
  170. }
  171. case SerializableFT_Reflectable:
  172. {
  173. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  174. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  175. {
  176. IReflectable& childObject = curField->getArrayValue(object, arrIdx);
  177. buffer = complexTypeToBuffer(&childObject, buffer, bufferLength,
  178. bytesWritten, flushBufferCallback, shallow);
  179. if(buffer == nullptr)
  180. {
  181. si->onSerializationEnded(object);
  182. return nullptr;
  183. }
  184. }
  185. break;
  186. }
  187. case SerializableFT_Plain:
  188. {
  189. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  190. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  191. {
  192. UINT32 typeSize = 0;
  193. if(curField->hasDynamicSize())
  194. typeSize = curField->getArrayElemDynamicSize(object, arrIdx);
  195. else
  196. typeSize = curField->getTypeSize();
  197. if ((*bytesWritten + typeSize) > bufferLength)
  198. {
  199. UINT8* tempBuffer = (UINT8*)stackAlloc(typeSize);
  200. curField->arrayElemToBuffer(object, arrIdx, tempBuffer);
  201. buffer = dataBlockToBuffer(tempBuffer, typeSize, buffer, bufferLength, bytesWritten, flushBufferCallback);
  202. if (buffer == nullptr || bufferLength == 0)
  203. {
  204. stackDeallocLast(tempBuffer);
  205. si->onSerializationEnded(object);
  206. return nullptr;
  207. }
  208. stackDeallocLast(tempBuffer);
  209. }
  210. else
  211. {
  212. curField->arrayElemToBuffer(object, arrIdx, buffer);
  213. buffer += typeSize;
  214. *bytesWritten += typeSize;
  215. }
  216. }
  217. break;
  218. }
  219. default:
  220. BS_EXCEPT(InternalErrorException,
  221. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  222. ", Is array: " + toString(curGenericField->mIsVectorType));
  223. }
  224. }
  225. else
  226. {
  227. switch(curGenericField->mType)
  228. {
  229. case SerializableFT_ReflectablePtr:
  230. {
  231. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  232. std::shared_ptr<IReflectable> childObject;
  233. if (!shallow)
  234. childObject = curField->getValue(object);
  235. UINT32 objId = registerObjectPtr(childObject);
  236. COPY_TO_BUFFER(&objId, sizeof(UINT32))
  237. break;
  238. }
  239. case SerializableFT_Reflectable:
  240. {
  241. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  242. IReflectable& childObject = curField->getValue(object);
  243. buffer = complexTypeToBuffer(&childObject, buffer, bufferLength,
  244. bytesWritten, flushBufferCallback, shallow);
  245. if(buffer == nullptr)
  246. {
  247. si->onSerializationEnded(object);
  248. return nullptr;
  249. }
  250. break;
  251. }
  252. case SerializableFT_Plain:
  253. {
  254. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  255. UINT32 typeSize = 0;
  256. if(curField->hasDynamicSize())
  257. typeSize = curField->getDynamicSize(object);
  258. else
  259. typeSize = curField->getTypeSize();
  260. if ((*bytesWritten + typeSize) > bufferLength)
  261. {
  262. UINT8* tempBuffer = (UINT8*)stackAlloc(typeSize);
  263. curField->toBuffer(object, tempBuffer);
  264. buffer = dataBlockToBuffer(tempBuffer, typeSize, buffer, bufferLength, bytesWritten, flushBufferCallback);
  265. if (buffer == nullptr || bufferLength == 0)
  266. {
  267. stackDeallocLast(tempBuffer);
  268. si->onSerializationEnded(object);
  269. return nullptr;
  270. }
  271. stackDeallocLast(tempBuffer);
  272. }
  273. else
  274. {
  275. curField->toBuffer(object, buffer);
  276. buffer += typeSize;
  277. *bytesWritten += typeSize;
  278. }
  279. break;
  280. }
  281. case SerializableFT_DataBlock:
  282. {
  283. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  284. ManagedDataBlock value = curField->getValue(object);
  285. // Data block size
  286. UINT32 dataBlockSize = value.getSize();
  287. COPY_TO_BUFFER(&dataBlockSize, sizeof(UINT32))
  288. // Data block data
  289. UINT8* dataToStore = value.getData();
  290. buffer = dataBlockToBuffer(dataToStore, dataBlockSize, buffer, bufferLength, bytesWritten, flushBufferCallback);
  291. if (buffer == nullptr || bufferLength == 0)
  292. {
  293. si->onSerializationEnded(object);
  294. return nullptr;
  295. }
  296. break;
  297. }
  298. default:
  299. BS_EXCEPT(InternalErrorException,
  300. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  301. ", Is array: " + toString(curGenericField->mIsVectorType));
  302. }
  303. }
  304. }
  305. si->onSerializationEnded(object);
  306. si = si->getBaseClass();
  307. isBaseClass = true;
  308. } while(si != nullptr); // Repeat until we reach the top of the inheritance hierarchy
  309. return buffer;
  310. }
  311. SPtr<SerializedObject> BinarySerializer::_decodeIntermediate(UINT8* data, UINT32 dataLength, UINT32& bytesRead)
  312. {
  313. mInterimObjectMap.clear();
  314. SPtr<SerializedObject> rootObj;
  315. bool hasMore = decodeIntermediateInternal(data, dataLength, bytesRead, rootObj);
  316. while (hasMore)
  317. {
  318. UINT8* dataPtr = data + bytesRead;
  319. SPtr<SerializedObject> dummyObj;
  320. hasMore = decodeIntermediateInternal(dataPtr, dataLength, bytesRead, dummyObj);
  321. }
  322. return rootObj;
  323. }
  324. bool BinarySerializer::decodeIntermediateInternal(UINT8* data, UINT32 dataLength, UINT32& bytesRead, SPtr<SerializedObject>& output)
  325. {
  326. if ((bytesRead + sizeof(ObjectMetaData)) > dataLength)
  327. {
  328. BS_EXCEPT(InternalErrorException,
  329. "Error decoding data.");
  330. }
  331. ObjectMetaData objectMetaData;
  332. objectMetaData.objectMeta = 0;
  333. objectMetaData.typeId = 0;
  334. memcpy(&objectMetaData, data, sizeof(ObjectMetaData));
  335. data += sizeof(ObjectMetaData);
  336. bytesRead += sizeof(ObjectMetaData);
  337. UINT32 objectId = 0;
  338. UINT32 objectTypeId = 0;
  339. bool objectIsBaseClass = false;
  340. decodeObjectMetaData(objectMetaData, objectId, objectTypeId, objectIsBaseClass);
  341. if (objectIsBaseClass)
  342. {
  343. BS_EXCEPT(InternalErrorException, "Encountered a base-class object while looking for a new object. " \
  344. "Base class objects are only supposed to be parts of a larger object.");
  345. }
  346. RTTITypeBase* rtti = IReflectable::_getRTTIfromTypeId(objectTypeId);
  347. SerializedSubObject* serializedSubObject = nullptr;
  348. if (rtti != nullptr)
  349. {
  350. if (objectId > 0)
  351. {
  352. auto iterFind = mInterimObjectMap.find(objectId);
  353. if (iterFind == mInterimObjectMap.end())
  354. {
  355. output = bs_shared_ptr<SerializedObject>();
  356. mInterimObjectMap.insert(std::make_pair(objectId, output));
  357. }
  358. else
  359. output = iterFind->second;
  360. }
  361. else // Not a reflectable ptr referenced object
  362. output = bs_shared_ptr<SerializedObject>();
  363. output->subObjects.push_back(SerializedSubObject());
  364. serializedSubObject = &output->subObjects.back();
  365. serializedSubObject->typeId = objectTypeId;
  366. }
  367. while (bytesRead < dataLength)
  368. {
  369. int metaData = -1;
  370. if ((bytesRead + META_SIZE) > dataLength)
  371. {
  372. BS_EXCEPT(InternalErrorException,
  373. "Error decoding data.");
  374. }
  375. memcpy((void*)&metaData, data, META_SIZE);
  376. if (isObjectMetaData(metaData)) // We've reached a new object
  377. {
  378. if ((bytesRead + sizeof(ObjectMetaData)) > dataLength)
  379. {
  380. BS_EXCEPT(InternalErrorException,
  381. "Error decoding data.");
  382. }
  383. ObjectMetaData objMetaData;
  384. objMetaData.objectMeta = 0;
  385. objMetaData.typeId = 0;
  386. memcpy(&objMetaData, data, sizeof(ObjectMetaData));
  387. UINT32 objId = 0;
  388. UINT32 objTypeId = 0;
  389. bool objIsBaseClass = false;
  390. decodeObjectMetaData(objMetaData, objId, objTypeId, objIsBaseClass);
  391. // If it's a base class, get base class RTTI and handle that
  392. if (objIsBaseClass)
  393. {
  394. if (rtti != nullptr)
  395. rtti = rtti->getBaseClass();
  396. // Saved and current base classes don't match, so just skip over all that data
  397. if (rtti == nullptr || rtti->getRTTIId() != objTypeId)
  398. {
  399. rtti = nullptr;
  400. }
  401. if (rtti != nullptr)
  402. {
  403. output->subObjects.push_back(SerializedSubObject());
  404. serializedSubObject = &output->subObjects.back();
  405. serializedSubObject->typeId = objTypeId;
  406. }
  407. data += sizeof(ObjectMetaData);
  408. bytesRead += sizeof(ObjectMetaData);
  409. continue;
  410. }
  411. else
  412. {
  413. if (objId != 0)
  414. return true;
  415. // Objects with ID == 0 represent complex types serialized by value, but they should only get serialized
  416. // if we encounter a field with one, not by just iterating through the file.
  417. BS_EXCEPT(InternalErrorException, "Object with ID 0 encountered. Cannot proceed with serialization.");
  418. }
  419. }
  420. data += META_SIZE;
  421. bytesRead += META_SIZE;
  422. bool isArray;
  423. SerializableFieldType fieldType;
  424. UINT16 fieldId;
  425. UINT8 fieldSize;
  426. bool hasDynamicSize;
  427. decodeFieldMetaData(metaData, fieldId, fieldSize, isArray, fieldType, hasDynamicSize);
  428. RTTIField* curGenericField = nullptr;
  429. if (rtti != nullptr)
  430. curGenericField = rtti->findField(fieldId);
  431. if (curGenericField != nullptr)
  432. {
  433. if (!hasDynamicSize && curGenericField->getTypeSize() != fieldSize)
  434. {
  435. BS_EXCEPT(InternalErrorException,
  436. "Data type mismatch. Type size stored in file and actual type size don't match. ("
  437. + toString(curGenericField->getTypeSize()) + " vs. " + toString(fieldSize) + ")");
  438. }
  439. if (curGenericField->mIsVectorType != isArray)
  440. {
  441. BS_EXCEPT(InternalErrorException,
  442. "Data type mismatch. One is array, other is a single type.");
  443. }
  444. if (curGenericField->mType != fieldType)
  445. {
  446. BS_EXCEPT(InternalErrorException,
  447. "Data type mismatch. Field types don't match. " + toString(UINT32(curGenericField->mType)) + " vs. " + toString(UINT32(fieldType)));
  448. }
  449. }
  450. SPtr<SerializedInstance> serializedEntry;
  451. int arrayNumElems = 1;
  452. if (isArray)
  453. {
  454. if ((bytesRead + NUM_ELEM_FIELD_SIZE) > dataLength)
  455. {
  456. BS_EXCEPT(InternalErrorException,
  457. "Error decoding data.");
  458. }
  459. memcpy((void*)&arrayNumElems, data, NUM_ELEM_FIELD_SIZE);
  460. data += NUM_ELEM_FIELD_SIZE;
  461. bytesRead += NUM_ELEM_FIELD_SIZE;
  462. SPtr<SerializedArray> serializedArray;
  463. if (curGenericField != nullptr)
  464. {
  465. serializedArray = bs_shared_ptr<SerializedArray>();
  466. serializedArray->numElements = arrayNumElems;
  467. serializedEntry = serializedArray;
  468. }
  469. switch (fieldType)
  470. {
  471. case SerializableFT_ReflectablePtr:
  472. {
  473. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  474. for (int i = 0; i < arrayNumElems; i++)
  475. {
  476. if ((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  477. {
  478. BS_EXCEPT(InternalErrorException,
  479. "Error decoding data.");
  480. }
  481. int childObjectId = 0;
  482. memcpy(&childObjectId, data, COMPLEX_TYPE_FIELD_SIZE);
  483. data += COMPLEX_TYPE_FIELD_SIZE;
  484. bytesRead += COMPLEX_TYPE_FIELD_SIZE;
  485. if (curField != nullptr)
  486. {
  487. SPtr<SerializedObject> serializedArrayEntry = nullptr;
  488. if (childObjectId > 0)
  489. {
  490. auto findObj = mInterimObjectMap.find(childObjectId);
  491. if (findObj == mInterimObjectMap.end())
  492. {
  493. serializedArrayEntry = bs_shared_ptr<SerializedObject>();
  494. mInterimObjectMap.insert(std::make_pair(childObjectId, serializedArrayEntry));
  495. }
  496. else
  497. serializedArrayEntry = findObj->second;
  498. }
  499. SerializedArrayEntry arrayEntry;
  500. arrayEntry.serialized = serializedArrayEntry;
  501. arrayEntry.index = i;
  502. serializedArray->entries[i] = arrayEntry;
  503. }
  504. }
  505. break;
  506. }
  507. case SerializableFT_Reflectable:
  508. {
  509. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  510. for (int i = 0; i < arrayNumElems; i++)
  511. {
  512. if ((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  513. {
  514. BS_EXCEPT(InternalErrorException,
  515. "Error decoding data.");
  516. }
  517. UINT32 complexTypeSize = 0;
  518. memcpy(&complexTypeSize, data, COMPLEX_TYPE_FIELD_SIZE);
  519. data += COMPLEX_TYPE_FIELD_SIZE;
  520. bytesRead += COMPLEX_TYPE_FIELD_SIZE;
  521. if (curField != nullptr && complexTypeSize > 0)
  522. {
  523. UINT32 dummy = 0;
  524. SPtr<SerializedObject> serializedArrayEntry;
  525. decodeIntermediateInternal(data, complexTypeSize, dummy, serializedArrayEntry);
  526. SerializedArrayEntry arrayEntry;
  527. arrayEntry.serialized = serializedArrayEntry;
  528. arrayEntry.index = i;
  529. serializedArray->entries[i] = arrayEntry;
  530. }
  531. data += complexTypeSize;
  532. bytesRead += complexTypeSize;
  533. }
  534. break;
  535. }
  536. case SerializableFT_Plain:
  537. {
  538. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  539. for (int i = 0; i < arrayNumElems; i++)
  540. {
  541. UINT32 typeSize = fieldSize;
  542. if (hasDynamicSize)
  543. memcpy(&typeSize, data, sizeof(UINT32));
  544. if (curField != nullptr)
  545. {
  546. SPtr<SerializedField> serializedField = bs_shared_ptr<SerializedField>();
  547. serializedField->value = data;
  548. serializedField->size = typeSize;
  549. SerializedArrayEntry arrayEntry;
  550. arrayEntry.serialized = serializedField;
  551. arrayEntry.index = i;
  552. serializedArray->entries[i] = arrayEntry;
  553. }
  554. data += typeSize;
  555. bytesRead += typeSize;
  556. }
  557. break;
  558. }
  559. default:
  560. BS_EXCEPT(InternalErrorException,
  561. "Error decoding data. Encountered a type I don't know how to decode. Type: " + toString(UINT32(fieldType)) +
  562. ", Is array: " + toString(isArray));
  563. }
  564. }
  565. else
  566. {
  567. switch (fieldType)
  568. {
  569. case SerializableFT_ReflectablePtr:
  570. {
  571. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  572. if ((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  573. {
  574. BS_EXCEPT(InternalErrorException,
  575. "Error decoding data.");
  576. }
  577. int childObjectId = 0;
  578. memcpy(&childObjectId, data, COMPLEX_TYPE_FIELD_SIZE);
  579. data += COMPLEX_TYPE_FIELD_SIZE;
  580. bytesRead += COMPLEX_TYPE_FIELD_SIZE;
  581. if (curField != nullptr)
  582. {
  583. SPtr<SerializedObject> serializedField = nullptr;
  584. if (childObjectId > 0)
  585. {
  586. auto findObj = mInterimObjectMap.find(childObjectId);
  587. if (findObj == mInterimObjectMap.end())
  588. {
  589. serializedField = bs_shared_ptr<SerializedObject>();
  590. mInterimObjectMap.insert(std::make_pair(childObjectId, serializedField));
  591. }
  592. else
  593. serializedField = findObj->second;
  594. }
  595. serializedEntry = serializedField;
  596. }
  597. break;
  598. }
  599. case SerializableFT_Reflectable:
  600. {
  601. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  602. if ((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  603. {
  604. BS_EXCEPT(InternalErrorException,
  605. "Error decoding data.");
  606. }
  607. UINT32 complexTypeSize = 0;
  608. memcpy(&complexTypeSize, data, COMPLEX_TYPE_FIELD_SIZE);
  609. data += COMPLEX_TYPE_FIELD_SIZE;
  610. bytesRead += COMPLEX_TYPE_FIELD_SIZE;
  611. if (curField != nullptr && complexTypeSize > 0)
  612. {
  613. UINT32 dummy = 0;
  614. SPtr<SerializedObject> serializedChildObj;
  615. decodeIntermediateInternal(data, complexTypeSize, dummy, serializedChildObj);
  616. serializedEntry = serializedChildObj;
  617. }
  618. data += complexTypeSize;
  619. bytesRead += complexTypeSize;
  620. break;
  621. }
  622. case SerializableFT_Plain:
  623. {
  624. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  625. UINT32 typeSize = fieldSize;
  626. if (hasDynamicSize)
  627. memcpy(&typeSize, data, sizeof(UINT32));
  628. if (curField != nullptr)
  629. {
  630. SPtr<SerializedField> serializedField = bs_shared_ptr<SerializedField>();
  631. serializedField->value = data;
  632. serializedField->size = typeSize;
  633. serializedEntry = serializedField;
  634. }
  635. data += typeSize;
  636. bytesRead += typeSize;
  637. break;
  638. }
  639. case SerializableFT_DataBlock:
  640. {
  641. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  642. if ((bytesRead + DATA_BLOCK_TYPE_FIELD_SIZE) > dataLength)
  643. {
  644. BS_EXCEPT(InternalErrorException,
  645. "Error decoding data.");
  646. }
  647. // Data block size
  648. UINT32 dataBlockSize = 0;
  649. memcpy(&dataBlockSize, data, DATA_BLOCK_TYPE_FIELD_SIZE);
  650. data += DATA_BLOCK_TYPE_FIELD_SIZE;
  651. bytesRead += DATA_BLOCK_TYPE_FIELD_SIZE;
  652. if ((bytesRead + dataBlockSize) > dataLength)
  653. {
  654. BS_EXCEPT(InternalErrorException,
  655. "Error decoding data.");
  656. }
  657. // Data block data
  658. if (curField != nullptr)
  659. {
  660. SPtr<SerializedField> serializedField = bs_shared_ptr<SerializedField>();
  661. serializedField->value = data;
  662. serializedField->size = dataBlockSize;
  663. serializedEntry = serializedField;
  664. }
  665. data += dataBlockSize;
  666. bytesRead += dataBlockSize;
  667. break;
  668. }
  669. default:
  670. BS_EXCEPT(InternalErrorException,
  671. "Error decoding data. Encountered a type I don't know how to decode. Type: " + toString(UINT32(fieldType)) +
  672. ", Is array: " + toString(isArray));
  673. }
  674. }
  675. if (serializedEntry != nullptr)
  676. {
  677. SerializedEntry entry;
  678. entry.fieldId = curGenericField->mUniqueId;
  679. entry.serialized = serializedEntry;
  680. serializedSubObject->entries.insert(std::make_pair(curGenericField->mUniqueId, entry));
  681. }
  682. }
  683. return false;
  684. }
  685. void BinarySerializer::decodeInternal(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& serializableObject)
  686. {
  687. UINT32 numSubObjects = (UINT32)serializableObject->subObjects.size();
  688. Vector<RTTITypeBase*> rttiTypes;
  689. for (UINT32 subObjectIdx = 0; subObjectIdx < numSubObjects; subObjectIdx++)
  690. {
  691. const SerializedSubObject& subObject = serializableObject->subObjects[subObjectIdx];
  692. RTTITypeBase* rtti = IReflectable::_getRTTIfromTypeId(subObject.typeId);
  693. if (rtti == nullptr)
  694. continue;
  695. rtti->onDeserializationStarted(object.get());
  696. rttiTypes.push_back(rtti);
  697. UINT32 numFields = rtti->getNumFields();
  698. for (UINT32 fieldIdx = 0; fieldIdx < numFields; fieldIdx++)
  699. {
  700. RTTIField* curGenericField = rtti->getField(fieldIdx);
  701. auto iterFindFieldData = subObject.entries.find(curGenericField->mUniqueId);
  702. if (iterFindFieldData == subObject.entries.end())
  703. continue;
  704. SPtr<SerializedInstance> entryData = iterFindFieldData->second.serialized;
  705. if (curGenericField->isArray())
  706. {
  707. SPtr<SerializedArray> arrayData = std::static_pointer_cast<SerializedArray>(entryData);
  708. UINT32 arrayNumElems = (UINT32)arrayData->numElements;
  709. curGenericField->setArraySize(object.get(), arrayNumElems);
  710. switch (curGenericField->mType)
  711. {
  712. case SerializableFT_ReflectablePtr:
  713. {
  714. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  715. for (auto& arrayElem : arrayData->entries)
  716. {
  717. SPtr<SerializedObject> arrayElemData = std::static_pointer_cast<SerializedObject>(arrayElem.second.serialized);
  718. RTTITypeBase* childRtti = nullptr;
  719. if (arrayElemData != nullptr)
  720. childRtti = IReflectable::_getRTTIfromTypeId(arrayElemData->getRootTypeId());
  721. if (childRtti != nullptr)
  722. {
  723. auto findObj = mObjectMap.find(arrayElemData);
  724. if (findObj == mObjectMap.end())
  725. {
  726. SPtr<IReflectable> newObject = childRtti->newRTTIObject();
  727. findObj = mObjectMap.insert(std::make_pair(arrayElemData, ObjectToDecode(newObject, arrayElemData))).first;
  728. }
  729. ObjectToDecode& objToDecode = findObj->second;
  730. bool needsDecoding = (curField->getFlags() & RTTI_Flag_WeakRef) == 0 && !objToDecode.isDecoded;
  731. if (needsDecoding)
  732. {
  733. decodeInternal(objToDecode.object, objToDecode.serializedObject);
  734. objToDecode.isDecoded = true;
  735. }
  736. curField->setArrayValue(object.get(), arrayElem.first, objToDecode.object);
  737. }
  738. else
  739. {
  740. curField->setArrayValue(object.get(), arrayElem.first, nullptr);
  741. }
  742. }
  743. }
  744. break;
  745. case SerializableFT_Reflectable:
  746. {
  747. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  748. for (auto& arrayElem : arrayData->entries)
  749. {
  750. SPtr<SerializedObject> arrayElemData = std::static_pointer_cast<SerializedObject>(arrayElem.second.serialized);
  751. RTTITypeBase* childRtti = nullptr;
  752. if (arrayElemData != nullptr)
  753. childRtti = IReflectable::_getRTTIfromTypeId(arrayElemData->getRootTypeId());
  754. if (childRtti != nullptr)
  755. {
  756. SPtr<IReflectable> newObject = childRtti->newRTTIObject();
  757. decodeInternal(newObject, arrayElemData);
  758. curField->setArrayValue(object.get(), arrayElem.first, *newObject);
  759. }
  760. }
  761. break;
  762. }
  763. case SerializableFT_Plain:
  764. {
  765. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  766. for (auto& arrayElem : arrayData->entries)
  767. {
  768. SPtr<SerializedField> fieldData = std::static_pointer_cast<SerializedField>(arrayElem.second.serialized);
  769. if (fieldData != nullptr)
  770. {
  771. curField->arrayElemFromBuffer(object.get(), arrayElem.first, fieldData->value);
  772. }
  773. }
  774. }
  775. break;
  776. }
  777. }
  778. else
  779. {
  780. switch (curGenericField->mType)
  781. {
  782. case SerializableFT_ReflectablePtr:
  783. {
  784. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  785. SPtr<SerializedObject> fieldObjectData = std::static_pointer_cast<SerializedObject>(entryData);
  786. RTTITypeBase* childRtti = nullptr;
  787. if (fieldObjectData != nullptr)
  788. childRtti = IReflectable::_getRTTIfromTypeId(fieldObjectData->getRootTypeId());
  789. if (childRtti != nullptr)
  790. {
  791. auto findObj = mObjectMap.find(fieldObjectData);
  792. if (findObj == mObjectMap.end())
  793. {
  794. SPtr<IReflectable> newObject = childRtti->newRTTIObject();
  795. findObj = mObjectMap.insert(std::make_pair(fieldObjectData, ObjectToDecode(newObject, fieldObjectData))).first;
  796. }
  797. ObjectToDecode& objToDecode = findObj->second;
  798. bool needsDecoding = (curField->getFlags() & RTTI_Flag_WeakRef) == 0 && !objToDecode.isDecoded;
  799. if (needsDecoding)
  800. {
  801. decodeInternal(objToDecode.object, objToDecode.serializedObject);
  802. objToDecode.isDecoded = true;
  803. }
  804. curField->setValue(object.get(), objToDecode.object);
  805. }
  806. else
  807. {
  808. curField->setValue(object.get(), nullptr);
  809. }
  810. }
  811. break;
  812. case SerializableFT_Reflectable:
  813. {
  814. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  815. SPtr<SerializedObject> fieldObjectData = std::static_pointer_cast<SerializedObject>(entryData);
  816. RTTITypeBase* childRtti = nullptr;
  817. if (fieldObjectData != nullptr)
  818. childRtti = IReflectable::_getRTTIfromTypeId(fieldObjectData->getRootTypeId());
  819. if (childRtti != nullptr)
  820. {
  821. SPtr<IReflectable> newObject = childRtti->newRTTIObject();
  822. decodeInternal(newObject, fieldObjectData);
  823. curField->setValue(object.get(), *newObject);
  824. }
  825. break;
  826. }
  827. case SerializableFT_Plain:
  828. {
  829. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  830. SPtr<SerializedField> fieldData = std::static_pointer_cast<SerializedField>(entryData);
  831. if (fieldData != nullptr)
  832. {
  833. curField->fromBuffer(object.get(), fieldData->value);
  834. }
  835. }
  836. break;
  837. case SerializableFT_DataBlock:
  838. {
  839. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  840. SPtr<SerializedField> fieldData = std::static_pointer_cast<SerializedField>(entryData);
  841. if (fieldData != nullptr)
  842. {
  843. UINT8* dataCopy = curField->allocate(object.get(), fieldData->size); // TODO - Low priority. I need to read files better, so I
  844. memcpy(dataCopy, fieldData->value, fieldData->size); // can just pass the buffer pointer directly without copying (possibly large amounts of data)
  845. ManagedDataBlock value(dataCopy, fieldData->size); // Not managed because I assume the owner class will decide whether to delete the data or keep it
  846. curField->setValue(object.get(), value);
  847. }
  848. break;
  849. }
  850. }
  851. }
  852. }
  853. }
  854. for (auto iterFind = rttiTypes.rbegin(); iterFind != rttiTypes.rend(); ++iterFind)
  855. {
  856. (*iterFind)->onDeserializationEnded(object.get());
  857. }
  858. }
  859. // TODO - This needs serious fixing, it doesn't account for all properties
  860. UINT32 BinarySerializer::getObjectSize(IReflectable* object)
  861. {
  862. if(object == nullptr)
  863. return 0;
  864. UINT32 objectSize = 0;
  865. RTTITypeBase* si = object->getRTTI();
  866. do
  867. {
  868. // Object ID + type data
  869. objectSize += sizeof(ObjectMetaData);
  870. int numFields = si->getNumFields();
  871. for(int i = 0; i < numFields; i++)
  872. {
  873. RTTIField* curGenericField = si->getField(i);
  874. // Field meta data
  875. objectSize += sizeof(UINT32);
  876. if(curGenericField->mIsVectorType)
  877. {
  878. UINT32 arrayNumElems = curGenericField->getArraySize(object);
  879. // Num array elems
  880. objectSize += sizeof(UINT32);
  881. switch(curGenericField->mType)
  882. {
  883. case SerializableFT_ReflectablePtr:
  884. {
  885. objectSize += sizeof(UINT32) * arrayNumElems;
  886. break;
  887. }
  888. case SerializableFT_Reflectable:
  889. {
  890. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  891. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  892. {
  893. IReflectable& childObject = curField->getArrayValue(object, arrIdx);
  894. objectSize += sizeof(UINT32); // Complex type size
  895. objectSize += getObjectSize(&childObject);
  896. }
  897. break;
  898. }
  899. case SerializableFT_Plain:
  900. {
  901. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  902. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  903. {
  904. UINT32 typeSize = 0;
  905. if(curField->hasDynamicSize())
  906. typeSize = curField->getArrayElemDynamicSize(object, arrIdx);
  907. else
  908. typeSize = curField->getTypeSize();
  909. objectSize += typeSize;
  910. }
  911. break;
  912. }
  913. default:
  914. BS_EXCEPT(InternalErrorException,
  915. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  916. ", Is array: " + toString(curGenericField->mIsVectorType));
  917. }
  918. }
  919. else
  920. {
  921. switch(curGenericField->mType)
  922. {
  923. case SerializableFT_ReflectablePtr:
  924. {
  925. objectSize += sizeof(UINT32);
  926. break;
  927. }
  928. case SerializableFT_Reflectable:
  929. {
  930. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  931. IReflectable& childObject = curField->getValue(object);
  932. objectSize += sizeof(UINT32); // Complex type size
  933. objectSize += getObjectSize(&childObject);
  934. break;
  935. }
  936. case SerializableFT_Plain:
  937. {
  938. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  939. UINT32 typeSize = 0;
  940. if(curField->hasDynamicSize())
  941. typeSize = curField->getDynamicSize(object);
  942. else
  943. typeSize = curField->getTypeSize();
  944. objectSize += typeSize;
  945. break;
  946. }
  947. case SerializableFT_DataBlock:
  948. {
  949. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  950. ManagedDataBlock value = curField->getValue(object);
  951. // Data block size
  952. UINT32 dataBlockSize = value.getSize();
  953. objectSize += sizeof(UINT32) + dataBlockSize;
  954. break;
  955. }
  956. default:
  957. BS_EXCEPT(InternalErrorException,
  958. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  959. ", Is array: " + toString(curGenericField->mIsVectorType));
  960. }
  961. }
  962. }
  963. si = si->getBaseClass();
  964. } while (si != nullptr);
  965. return objectSize;
  966. }
  967. UINT32 BinarySerializer::encodeFieldMetaData(UINT16 id, UINT8 size, bool array, SerializableFieldType type, bool hasDynamicSize)
  968. {
  969. // If O == 0 - Meta contains field information (Encoded using this method)
  970. //// Encoding: IIII IIII IIII IIII SSSS SSSS xxYP DCAO
  971. //// I - Id
  972. //// S - Size
  973. //// C - Complex
  974. //// A - Array
  975. //// D - Data block
  976. //// P - Complex ptr
  977. //// O - Object descriptor
  978. //// Y - Plain field has dynamic size
  979. return (id << 16 | size << 8 |
  980. (array ? 0x02 : 0) |
  981. ((type == SerializableFT_DataBlock) ? 0x04 : 0) |
  982. ((type == SerializableFT_Reflectable) ? 0x08 : 0) |
  983. ((type == SerializableFT_ReflectablePtr) ? 0x10 : 0) |
  984. (hasDynamicSize ? 0x20 : 0)); // TODO - Low priority. Technically I could encode this much more tightly, and use var-ints for ID
  985. }
  986. void BinarySerializer::decodeFieldMetaData(UINT32 encodedData, UINT16& id, UINT8& size, bool& array, SerializableFieldType& type, bool& hasDynamicSize)
  987. {
  988. if(isObjectMetaData(encodedData))
  989. {
  990. BS_EXCEPT(InternalErrorException,
  991. "Meta data represents an object description but is trying to be decoded as a field descriptor.");
  992. }
  993. hasDynamicSize = (encodedData & 0x20) != 0;
  994. if((encodedData & 0x10) != 0)
  995. type = SerializableFT_ReflectablePtr;
  996. else if((encodedData & 0x08) != 0)
  997. type = SerializableFT_Reflectable;
  998. else if((encodedData & 0x04) != 0)
  999. type = SerializableFT_DataBlock;
  1000. else
  1001. type = SerializableFT_Plain;
  1002. array = (encodedData & 0x02) != 0;
  1003. size = (UINT8)((encodedData >> 8) & 0xFF);
  1004. id = (UINT16)((encodedData >> 16) & 0xFFFF);
  1005. }
  1006. BinarySerializer::ObjectMetaData BinarySerializer::encodeObjectMetaData(UINT32 objId, UINT32 objTypeId, bool isBaseClass)
  1007. {
  1008. // If O == 1 - Meta contains object instance information (Encoded using encodeObjectMetaData)
  1009. //// Encoding: SSSS SSSS SSSS SSSS xxxx xxxx xxxx xxBO
  1010. //// S - Size of the object identifier
  1011. //// O - Object descriptor
  1012. //// B - Base class indicator
  1013. if(objId > 1073741823)
  1014. {
  1015. BS_EXCEPT(InvalidParametersException, "Object ID is larger than we can store (max 30 bits): " + toString(objId));
  1016. }
  1017. ObjectMetaData metaData;
  1018. metaData.objectMeta = (objId << 2) | (isBaseClass ? 0x02 : 0) | 0x01;
  1019. metaData.typeId = objTypeId;
  1020. return metaData;
  1021. }
  1022. void BinarySerializer::decodeObjectMetaData(BinarySerializer::ObjectMetaData encodedData, UINT32& objId, UINT32& objTypeId, bool& isBaseClass)
  1023. {
  1024. if(!isObjectMetaData(encodedData.objectMeta))
  1025. {
  1026. BS_EXCEPT(InternalErrorException,
  1027. "Meta data represents a field description but is trying to be decoded as an object descriptor.");
  1028. }
  1029. objId = (encodedData.objectMeta >> 2) & 0x3FFFFFFF;
  1030. isBaseClass = (encodedData.objectMeta & 0x02) != 0;
  1031. objTypeId = encodedData.typeId;
  1032. }
  1033. bool BinarySerializer::isObjectMetaData(UINT32 encodedData)
  1034. {
  1035. return ((encodedData & 0x01) != 0);
  1036. }
  1037. UINT8* BinarySerializer::complexTypeToBuffer(IReflectable* object, UINT8* buffer, UINT32& bufferLength,
  1038. UINT32* bytesWritten, std::function<UINT8*(UINT8*, UINT32, UINT32&)> flushBufferCallback, bool shallow)
  1039. {
  1040. int complexTypeSize = 0;
  1041. if(object != nullptr)
  1042. complexTypeSize = getObjectSize(object);
  1043. COPY_TO_BUFFER(&complexTypeSize, COMPLEX_TYPE_FIELD_SIZE)
  1044. if(object != nullptr)
  1045. return encodeInternal(object, 0, buffer, bufferLength, bytesWritten, flushBufferCallback, shallow);
  1046. return buffer;
  1047. }
  1048. UINT8* BinarySerializer::dataBlockToBuffer(UINT8* data, UINT32 size, UINT8* buffer, UINT32& bufferLength, UINT32* bytesWritten,
  1049. std::function<UINT8*(UINT8* buffer, UINT32 bytesWritten, UINT32& newBufferSize)> flushBufferCallback)
  1050. {
  1051. UINT32 remainingSize = size;
  1052. while (remainingSize > 0)
  1053. {
  1054. UINT32 remainingSpaceInBuffer = bufferLength - *bytesWritten;
  1055. if (remainingSize <= remainingSpaceInBuffer)
  1056. {
  1057. COPY_TO_BUFFER(data, remainingSize);
  1058. remainingSize = 0;
  1059. }
  1060. else
  1061. {
  1062. memcpy(buffer, data, remainingSpaceInBuffer);
  1063. buffer += remainingSpaceInBuffer;
  1064. *bytesWritten += remainingSpaceInBuffer;
  1065. data += remainingSpaceInBuffer;
  1066. remainingSize -= remainingSpaceInBuffer;
  1067. mTotalBytesWritten += *bytesWritten;
  1068. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
  1069. if (buffer == nullptr || bufferLength == 0)
  1070. return nullptr;
  1071. *bytesWritten = 0;
  1072. }
  1073. }
  1074. return buffer;
  1075. }
  1076. UINT32 BinarySerializer::findOrCreatePersistentId(IReflectable* object)
  1077. {
  1078. void* ptrAddress = (void*)object;
  1079. auto findIter = mObjectAddrToId.find(ptrAddress);
  1080. if(findIter != mObjectAddrToId.end())
  1081. return findIter->second;
  1082. UINT32 objId = mLastUsedObjectId++;
  1083. mObjectAddrToId.insert(std::make_pair(ptrAddress, objId));
  1084. return objId;
  1085. }
  1086. UINT32 BinarySerializer::registerObjectPtr(std::shared_ptr<IReflectable> object)
  1087. {
  1088. if(object == nullptr)
  1089. return 0;
  1090. void* ptrAddress = (void*)object.get();
  1091. auto iterFind = mObjectAddrToId.find(ptrAddress);
  1092. if(iterFind == mObjectAddrToId.end())
  1093. {
  1094. UINT32 objId = findOrCreatePersistentId(object.get());
  1095. mObjectsToEncode.push_back(ObjectToEncode(objId, object));
  1096. mObjectAddrToId.insert(std::make_pair(ptrAddress, objId));
  1097. return objId;
  1098. }
  1099. return iterFind->second;
  1100. }
  1101. }
  1102. #undef COPY_TO_BUFFER