BsBinarySerializer.cpp 42 KB

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