BsBinarySerializer.cpp 41 KB

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