2
0

BsBinarySerializer.cpp 42 KB

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