BsBinarySerializer.cpp 41 KB

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