BsBinarySerializer.cpp 40 KB

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