2
0

BsBinarySerializer.cpp 40 KB

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