BsBinarySerializer.cpp 40 KB

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