BsBinarySerializer.cpp 41 KB

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