CmBinarySerializer.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. #include "CmBinarySerializer.h"
  2. #include "CmException.h"
  3. #include "CmIReflectable.h"
  4. #include "CmRTTIType.h"
  5. #include "CmRTTIField.h"
  6. #include "CmRTTIPlainField.h"
  7. #include "CmRTTIReflectableField.h"
  8. #include "CmRTTIReflectablePtrField.h"
  9. #include "CmRTTIManagedDataBlockField.h"
  10. #include <unordered_set>
  11. /**
  12. * @brief A macro that represents a block of code that gets used a lot inside
  13. * encodeInternal. It checks if the buffer has enough space, and if it does
  14. * it copies the data from the specified location and increments the needed
  15. * pointers and counters. If there is not enough space the buffer is flushed
  16. * (hopefully to make some space). If there is still not enough space the entire
  17. * encoding process ends.
  18. *
  19. * @param dataPtr Pointer to data which to copy.
  20. * @param size Size of the data to copy
  21. */
  22. #define COPY_TO_BUFFER(dataPtr, size) \
  23. if((*bytesWritten + size##) > bufferLength) \
  24. { \
  25. mTotalBytesWritten += *bytesWritten; \
  26. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength); \
  27. if(buffer == nullptr || bufferLength < size##) return nullptr; \
  28. *bytesWritten = 0; \
  29. } \
  30. \
  31. memcpy(buffer, dataPtr##, size##); \
  32. buffer += size##; \
  33. *bytesWritten += size##;
  34. namespace CamelotEngine
  35. {
  36. BinarySerializer::BinarySerializer()
  37. :mLastUsedObjectId(1)
  38. {
  39. }
  40. void BinarySerializer::encode(IReflectable* object, UINT8* buffer, UINT32 bufferLength, int* bytesWritten, boost::function<UINT8*(UINT8*, int, UINT32&)> flushBufferCallback)
  41. {
  42. mObjectsToEncode.clear();
  43. mObjectAddrToId.clear();
  44. mLastUsedObjectId = 1;
  45. *bytesWritten = 0;
  46. mTotalBytesWritten = 0;
  47. UINT8* bufferStart = buffer;
  48. UINT32 objectId = findOrCreatePersistentId(object);
  49. // Encode primary object and its value types
  50. buffer = encodeInternal(object, objectId, buffer, bufferLength, bytesWritten, flushBufferCallback);
  51. if(buffer == nullptr)
  52. {
  53. CM_EXCEPT(InternalErrorException,
  54. "Destination buffer is null or not large enough.");
  55. }
  56. // Encode pointed to objects and their value types
  57. std::unordered_set<UINT32> serializedObjects;
  58. while(true)
  59. {
  60. auto iter = mObjectsToEncode.begin();
  61. bool foundObjectToProcess = false;
  62. for(iter; iter != mObjectsToEncode.end(); ++iter)
  63. {
  64. auto foundExisting = serializedObjects.find(iter->objectId);
  65. if(foundExisting != serializedObjects.end())
  66. continue; // Already processed
  67. IReflectable* curObject = iter->object;
  68. buffer = encodeInternal(curObject, iter->objectId, buffer, bufferLength, bytesWritten, flushBufferCallback);
  69. if(buffer == nullptr)
  70. {
  71. CM_EXCEPT(InternalErrorException,
  72. "Destination buffer is null or not large enough.");
  73. }
  74. serializedObjects.insert(iter->objectId);
  75. mObjectsToEncode.erase(iter);
  76. foundObjectToProcess = true;
  77. break; // Need to start over as mObjectsToSerialize was possibly modified
  78. }
  79. if(!foundObjectToProcess) // We're done
  80. break;
  81. }
  82. // Final flush
  83. if(*bytesWritten > 0)
  84. {
  85. mTotalBytesWritten += *bytesWritten;
  86. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
  87. }
  88. *bytesWritten = mTotalBytesWritten;
  89. }
  90. void BinarySerializer::decode(IReflectable* object, UINT8* data, UINT32 dataLength)
  91. {
  92. mPtrsToResolve.clear();
  93. mDecodedObjects.clear();
  94. // Create initial object + all other objects that are being referenced.
  95. // Use fields to find the type of referenced object.
  96. UINT32 bytesRead = 0;
  97. while(decodeInternal(object, data, dataLength, bytesRead))
  98. {
  99. data += bytesRead;
  100. UINT8* localDataPtr = data;
  101. UINT32 localBytesRead = bytesRead;
  102. if((bytesRead + sizeof(UINT32)) > dataLength)
  103. {
  104. CM_EXCEPT(InternalErrorException,
  105. "Error decoding data.");
  106. }
  107. UINT32 objectMetaData = 0;
  108. memcpy(&objectMetaData, localDataPtr, sizeof(UINT32));
  109. localDataPtr += sizeof(UINT32);
  110. localBytesRead += sizeof(UINT32);
  111. UINT32 objectId = 0;
  112. decodeObjectMetaData(objectMetaData, objectId);
  113. object = nullptr;
  114. if(objectId != 0)
  115. {
  116. auto iterFind = std::find_if(mPtrsToResolve.begin(), mPtrsToResolve.end(), [objectId](PtrToResolve x) { return x.id == objectId; });
  117. if(iterFind != mPtrsToResolve.end())
  118. object = iterFind->field->newObject();
  119. }
  120. }
  121. for(auto iter = mPtrsToResolve.begin(); iter != mPtrsToResolve.end(); ++iter)
  122. {
  123. IReflectable* resolvedObject = nullptr;
  124. PtrToResolve curPtr = *iter;
  125. if(curPtr.id != 0)
  126. {
  127. auto iterFind = mDecodedObjects.find(curPtr.id);
  128. if(iterFind != mDecodedObjects.end())
  129. resolvedObject = iterFind->second;
  130. }
  131. if(curPtr.field->mIsVectorType)
  132. curPtr.field->setArrayValue(curPtr.object, curPtr.arrIdx, resolvedObject);
  133. else
  134. curPtr.field->setValue(curPtr.object, resolvedObject);
  135. }
  136. }
  137. UINT8* BinarySerializer::encodeInternal(IReflectable* object, UINT32 objectId, UINT8* buffer, UINT32& bufferLength, int* bytesWritten, boost::function<UINT8*(UINT8*, int, UINT32&)> flushBufferCallback)
  138. {
  139. static const UINT32 META_SIZE = 4; // Meta field size
  140. static const UINT32 NUM_ELEM_FIELD_SIZE = 4; // Size of the field storing number of array elements
  141. static const UINT32 COMPLEX_TYPE_SIZE = 4; // Size of the field storing the size of a child complex type
  142. RTTITypeBase* si = object->getRTTI();
  143. // Encode object ID if it has one
  144. UINT32 objectMetaData = encodeObjectMetaData(objectId);
  145. COPY_TO_BUFFER(&objectMetaData, sizeof(UINT32))
  146. int numFields = si->getNumFields();
  147. for(int i = 0; i < numFields; i++)
  148. {
  149. RTTIField* curGenericField = si->getField(i);
  150. // Copy field ID & other meta-data like field size and type
  151. int metaData = encodeFieldMetaData(curGenericField->mUniqueId, curGenericField->getTypeSize(), curGenericField->mIsVectorType, curGenericField->mType);
  152. COPY_TO_BUFFER(&metaData, META_SIZE)
  153. if(curGenericField->mIsVectorType)
  154. {
  155. UINT32 arrayNumElems = curGenericField->getArraySize(object);
  156. // Copy num vector elements
  157. COPY_TO_BUFFER(&arrayNumElems, NUM_ELEM_FIELD_SIZE)
  158. switch(curGenericField->mType)
  159. {
  160. case SerializableFT_ReflectablePtr:
  161. {
  162. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  163. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  164. {
  165. IReflectable* childObject = curField->getArrayValue(object, arrIdx);
  166. UINT32 objId = registerObjectPtr(childObject);
  167. COPY_TO_BUFFER(&objId, sizeof(UINT32))
  168. }
  169. break;
  170. }
  171. case SerializableFT_Reflectable:
  172. {
  173. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  174. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  175. {
  176. IReflectable& childObject = curField->getArrayValue(object, arrIdx);
  177. buffer = complexTypeToBuffer(&childObject, buffer, bufferLength, bytesWritten, flushBufferCallback);
  178. if(buffer == nullptr)
  179. return nullptr;
  180. }
  181. break;
  182. }
  183. case SerializableFT_Plain:
  184. {
  185. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  186. UINT32 typeSize = curField->getTypeSize();
  187. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  188. {
  189. if((*bytesWritten + typeSize) > bufferLength)
  190. {
  191. mTotalBytesWritten += *bytesWritten;
  192. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
  193. if(buffer == nullptr || bufferLength < typeSize) return nullptr;
  194. *bytesWritten = 0;
  195. }
  196. curField->arrayElemToBuffer(object, arrIdx, buffer);
  197. buffer += typeSize;
  198. *bytesWritten += typeSize;
  199. }
  200. break;
  201. }
  202. default:
  203. CM_EXCEPT(InternalErrorException,
  204. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  205. ", Is array: " + toString(curGenericField->mIsVectorType));
  206. }
  207. }
  208. else
  209. {
  210. switch(curGenericField->mType)
  211. {
  212. case SerializableFT_ReflectablePtr:
  213. {
  214. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  215. IReflectable* childObject = curField->getValue(object);
  216. UINT32 objId = registerObjectPtr(childObject);
  217. COPY_TO_BUFFER(&objId, sizeof(UINT32))
  218. break;
  219. }
  220. case SerializableFT_Reflectable:
  221. {
  222. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  223. IReflectable& childObject = curField->getValue(object);
  224. buffer = complexTypeToBuffer(&childObject, buffer, bufferLength, bytesWritten, flushBufferCallback);
  225. if(buffer == nullptr)
  226. return nullptr;
  227. break;
  228. }
  229. case SerializableFT_Plain:
  230. {
  231. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  232. UINT32 typeSize = curField->getTypeSize();
  233. if((*bytesWritten + typeSize) > bufferLength)
  234. {
  235. mTotalBytesWritten += *bytesWritten;
  236. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
  237. if(buffer == nullptr || bufferLength < typeSize) return nullptr;
  238. *bytesWritten = 0;
  239. }
  240. curField->toBuffer(object, buffer);
  241. buffer += typeSize;
  242. *bytesWritten += typeSize;
  243. break;
  244. }
  245. case SerializableFT_DataBlock:
  246. {
  247. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  248. ManagedDataBlock value = curField->getValue(object);
  249. // Data block size
  250. UINT32 dataBlockSize = value.getSize();
  251. COPY_TO_BUFFER(&dataBlockSize, sizeof(UINT32))
  252. // Data block data
  253. UINT8* dataToStore = value.getData();
  254. UINT32 remainingSize = dataBlockSize;
  255. while(remainingSize > 0)
  256. {
  257. UINT32 remainingSpaceInBuffer = bufferLength - *bytesWritten;
  258. if(remainingSize <= remainingSpaceInBuffer)
  259. {
  260. COPY_TO_BUFFER(dataToStore, remainingSize);
  261. remainingSize = 0;
  262. }
  263. else
  264. {
  265. memcpy(buffer, dataToStore, remainingSpaceInBuffer);
  266. buffer += remainingSpaceInBuffer;
  267. *bytesWritten += remainingSpaceInBuffer;
  268. dataToStore += remainingSpaceInBuffer;
  269. remainingSize -= remainingSpaceInBuffer;
  270. mTotalBytesWritten += *bytesWritten;
  271. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
  272. if(buffer == nullptr || bufferLength == 0) return nullptr;
  273. *bytesWritten = 0;
  274. }
  275. }
  276. break;
  277. }
  278. default:
  279. CM_EXCEPT(InternalErrorException,
  280. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  281. ", Is array: " + toString(curGenericField->mIsVectorType));
  282. }
  283. }
  284. }
  285. return buffer;
  286. }
  287. bool BinarySerializer::decodeInternal(IReflectable* object, UINT8* data, UINT32 dataLength, UINT32& bytesRead)
  288. {
  289. static const int META_SIZE = 4; // Meta field size
  290. static const int NUM_ELEM_FIELD_SIZE = 4; // Size of the field storing number of array elements
  291. static const int COMPLEX_TYPE_FIELD_SIZE = 4; // Size of the field storing the size of a child complex type
  292. static const int DATA_BLOCK_TYPE_FIELD_SIZE = 4;
  293. RTTITypeBase* si = nullptr;
  294. if(object != nullptr)
  295. si = object->getRTTI();
  296. if((bytesRead + sizeof(UINT32)) > dataLength)
  297. {
  298. CM_EXCEPT(InternalErrorException,
  299. "Error decoding data.");
  300. }
  301. UINT32 objectMetaData = 0;
  302. memcpy(&objectMetaData, data, sizeof(UINT32));
  303. data += sizeof(UINT32);
  304. bytesRead += sizeof(UINT32);
  305. UINT32 objectId = 0;
  306. decodeObjectMetaData(objectMetaData, objectId);
  307. if(object != nullptr && objectId != 0)
  308. mDecodedObjects.insert(std::make_pair(objectId, object));
  309. while(bytesRead < dataLength)
  310. {
  311. int metaData = -1;
  312. if((bytesRead + META_SIZE) > dataLength)
  313. {
  314. CM_EXCEPT(InternalErrorException,
  315. "Error decoding data.");
  316. }
  317. memcpy((void*)&metaData, data, META_SIZE);
  318. if(isObjectMetaData(metaData)) // We've reached a new object
  319. {
  320. UINT32 objId = 0;
  321. decodeObjectMetaData(metaData, objId);
  322. if(objId != 0) // Objects with 0 ID represent complex types serialized by value, in which case we just decode them on the spot
  323. return true;
  324. }
  325. data += META_SIZE;
  326. bytesRead += META_SIZE;
  327. bool isArray;
  328. SerializableFieldType fieldType;
  329. UINT16 fieldId;
  330. UINT8 fieldSize;
  331. decodeFieldMetaData(metaData, fieldId, fieldSize, isArray, fieldType);
  332. RTTIField* curGenericField = nullptr;
  333. if(si != nullptr)
  334. curGenericField = si->findField(fieldId);
  335. if(curGenericField != nullptr)
  336. {
  337. if(curGenericField->getTypeSize() != fieldSize)
  338. {
  339. CM_EXCEPT(InternalErrorException,
  340. "Data type mismatch. Type size stored in file and actual type size don't match. ("
  341. + toString(curGenericField->getTypeSize()) + " vs. " + toString(fieldSize) + ")");
  342. }
  343. if(curGenericField->mIsVectorType != isArray)
  344. {
  345. CM_EXCEPT(InternalErrorException,
  346. "Data type mismatch. One is array, other is a single type.");
  347. }
  348. if(curGenericField->mType != fieldType)
  349. {
  350. CM_EXCEPT(InternalErrorException,
  351. "Data type mismatch. Field types don't match. " + toString(UINT32(curGenericField->mType)) + " vs. " + toString(UINT32(fieldType)));
  352. }
  353. }
  354. int arrayNumElems = 1;
  355. if(isArray)
  356. {
  357. if((bytesRead + NUM_ELEM_FIELD_SIZE) > dataLength)
  358. {
  359. CM_EXCEPT(InternalErrorException,
  360. "Error decoding data.");
  361. }
  362. memcpy((void*)&arrayNumElems, data, NUM_ELEM_FIELD_SIZE);
  363. data += NUM_ELEM_FIELD_SIZE;
  364. bytesRead += NUM_ELEM_FIELD_SIZE;
  365. if(curGenericField != nullptr)
  366. curGenericField->setArraySize(object, arrayNumElems);
  367. switch(fieldType)
  368. {
  369. case SerializableFT_ReflectablePtr:
  370. {
  371. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  372. for(int i = 0; i < arrayNumElems; i++)
  373. {
  374. if((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  375. {
  376. CM_EXCEPT(InternalErrorException,
  377. "Error decoding data.");
  378. }
  379. int objectId = 0;
  380. memcpy(&objectId, data, COMPLEX_TYPE_FIELD_SIZE);
  381. data += COMPLEX_TYPE_FIELD_SIZE;
  382. bytesRead += COMPLEX_TYPE_FIELD_SIZE;
  383. if(curField != nullptr)
  384. mPtrsToResolve.push_back(PtrToResolve(curField, object, objectId, i));
  385. }
  386. break;
  387. }
  388. case SerializableFT_Reflectable:
  389. {
  390. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  391. for(int i = 0; i < arrayNumElems; i++)
  392. {
  393. if((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  394. {
  395. CM_EXCEPT(InternalErrorException,
  396. "Error decoding data.");
  397. }
  398. int complexTypeSize = COMPLEX_TYPE_FIELD_SIZE;
  399. if(curField != nullptr)
  400. {
  401. IReflectable* complexType = complexTypeFromBuffer(curField, data, &complexTypeSize);
  402. curField->setArrayValue(object, i, *complexType);
  403. delete complexType;
  404. }
  405. data += complexTypeSize;
  406. bytesRead += complexTypeSize;
  407. }
  408. break;
  409. }
  410. case SerializableFT_Plain:
  411. {
  412. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  413. for(int i = 0; i < arrayNumElems; i++)
  414. {
  415. if(curField != nullptr)
  416. curField->arrayElemFromBuffer(object, i, data);
  417. data += fieldSize;
  418. bytesRead += fieldSize;
  419. }
  420. break;
  421. }
  422. default:
  423. CM_EXCEPT(InternalErrorException,
  424. "Error decoding data. Encountered a type I don't know how to decode. Type: " + toString(UINT32(fieldType)) +
  425. ", Is array: " + toString(isArray));
  426. }
  427. }
  428. else
  429. {
  430. switch(fieldType)
  431. {
  432. case SerializableFT_ReflectablePtr:
  433. {
  434. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  435. if((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  436. {
  437. CM_EXCEPT(InternalErrorException,
  438. "Error decoding data.");
  439. }
  440. int objectId = 0;
  441. memcpy(&objectId, data, COMPLEX_TYPE_FIELD_SIZE);
  442. data += COMPLEX_TYPE_FIELD_SIZE;
  443. bytesRead += COMPLEX_TYPE_FIELD_SIZE;
  444. if(curField != nullptr)
  445. mPtrsToResolve.push_back(PtrToResolve(curField, object, objectId));
  446. break;
  447. }
  448. case SerializableFT_Reflectable:
  449. {
  450. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  451. if((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  452. {
  453. CM_EXCEPT(InternalErrorException,
  454. "Error decoding data.");
  455. }
  456. int complexTypeSize = COMPLEX_TYPE_FIELD_SIZE;
  457. if(curField != nullptr)
  458. {
  459. IReflectable* complexType = complexTypeFromBuffer(curField, data, &complexTypeSize);
  460. curField->setValue(object, *complexType);
  461. delete complexType;
  462. }
  463. data += complexTypeSize;
  464. bytesRead += complexTypeSize;
  465. break;
  466. }
  467. case SerializableFT_Plain:
  468. {
  469. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  470. if(curField != nullptr)
  471. curField->fromBuffer(object, data);
  472. data += fieldSize;
  473. bytesRead += fieldSize;
  474. break;
  475. }
  476. case SerializableFT_DataBlock:
  477. {
  478. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  479. if((bytesRead + DATA_BLOCK_TYPE_FIELD_SIZE) > dataLength)
  480. {
  481. CM_EXCEPT(InternalErrorException,
  482. "Error decoding data.");
  483. }
  484. // Data block size
  485. UINT32 dataBlockSize = 0;
  486. memcpy(&dataBlockSize, data, DATA_BLOCK_TYPE_FIELD_SIZE);
  487. data += DATA_BLOCK_TYPE_FIELD_SIZE;
  488. bytesRead += DATA_BLOCK_TYPE_FIELD_SIZE;
  489. if((bytesRead + dataBlockSize) > dataLength)
  490. {
  491. CM_EXCEPT(InternalErrorException,
  492. "Error decoding data.");
  493. }
  494. // Data block data
  495. if(curField != nullptr)
  496. {
  497. UINT8* dataCopy = new UINT8[dataBlockSize]; // TODO - Low priority. I need to read files better, so I
  498. memcpy(dataCopy, data, dataBlockSize); // can just pass the buffer pointer directly without copying (possibly large amounts of data)
  499. ManagedDataBlock value(dataCopy, dataBlockSize, false); // Not managed because I assume the owner class will decide whether to delete the data or keep it
  500. curField->setValue(object, value);
  501. }
  502. data += dataBlockSize;
  503. bytesRead += dataBlockSize;
  504. break;
  505. }
  506. default:
  507. CM_EXCEPT(InternalErrorException,
  508. "Error decoding data. Encountered a type I don't know how to decode. Type: " + toString(UINT32(fieldType)) +
  509. ", Is array: " + toString(isArray));
  510. }
  511. }
  512. }
  513. return false;
  514. }
  515. UINT32 BinarySerializer::getObjectSize(IReflectable* object)
  516. {
  517. if(object == nullptr)
  518. return 0;
  519. UINT32 objectSize = 0;
  520. RTTITypeBase* si = object->getRTTI();
  521. // Object ID
  522. objectSize += sizeof(UINT32);
  523. int numFields = si->getNumFields();
  524. for(int i = 0; i < numFields; i++)
  525. {
  526. RTTIField* curGenericField = si->getField(i);
  527. // Field meta data
  528. objectSize += sizeof(UINT32);
  529. if(curGenericField->mIsVectorType)
  530. {
  531. UINT32 arrayNumElems = curGenericField->getArraySize(object);
  532. // Num array elems
  533. objectSize += sizeof(UINT32);
  534. switch(curGenericField->mType)
  535. {
  536. case SerializableFT_ReflectablePtr:
  537. {
  538. objectSize += sizeof(UINT32) * arrayNumElems;
  539. break;
  540. }
  541. case SerializableFT_Reflectable:
  542. {
  543. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  544. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  545. {
  546. IReflectable& childObject = curField->getArrayValue(object, arrIdx);
  547. objectSize += getObjectSize(&childObject);
  548. }
  549. break;
  550. }
  551. case SerializableFT_Plain:
  552. {
  553. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  554. objectSize += arrayNumElems * curField->getTypeSize();
  555. break;
  556. }
  557. default:
  558. CM_EXCEPT(InternalErrorException,
  559. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  560. ", Is array: " + toString(curGenericField->mIsVectorType));
  561. }
  562. }
  563. else
  564. {
  565. switch(curGenericField->mType)
  566. {
  567. case SerializableFT_ReflectablePtr:
  568. {
  569. objectSize += sizeof(UINT32);
  570. break;
  571. }
  572. case SerializableFT_Reflectable:
  573. {
  574. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  575. IReflectable& childObject = curField->getValue(object);
  576. objectSize += getObjectSize(&childObject);
  577. break;
  578. }
  579. case SerializableFT_Plain:
  580. {
  581. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  582. objectSize += curField->getTypeSize();
  583. break;
  584. }
  585. case SerializableFT_DataBlock:
  586. {
  587. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  588. ManagedDataBlock value = curField->getValue(object);
  589. // Data block size
  590. UINT32 dataBlockSize = value.getSize();
  591. objectSize += sizeof(UINT32) + dataBlockSize;
  592. break;
  593. }
  594. default:
  595. CM_EXCEPT(InternalErrorException,
  596. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  597. ", Is array: " + toString(curGenericField->mIsVectorType));
  598. }
  599. }
  600. }
  601. return objectSize;
  602. }
  603. UINT32 BinarySerializer::encodeFieldMetaData(UINT16 id, UINT8 size, bool array, SerializableFieldType type)
  604. {
  605. // If O == 0 - Meta contains field information (Encoded using this method)
  606. //// Encoding: IIII IIII IIII IIII SSSS SSSS xxxP DCAO
  607. //// I - Id
  608. //// S - Size
  609. //// C - Complex
  610. //// A - Array
  611. //// D - Data block
  612. //// P - Complex ptr
  613. //// O - Object descriptor
  614. return (id << 16 | size << 8 |
  615. (array ? 0x02 : 0) |
  616. ((type == SerializableFT_DataBlock) ? 0x04 : 0) |
  617. ((type == SerializableFT_Reflectable) ? 0x08 : 0) |
  618. ((type == SerializableFT_ReflectablePtr) ? 0x10 : 0)); // TODO - Low priority. Technically I could encode this much more tightly, and use var-ints for ID
  619. }
  620. void BinarySerializer::decodeFieldMetaData(UINT32 encodedData, UINT16& id, UINT8& size, bool& array, SerializableFieldType& type)
  621. {
  622. if(isObjectMetaData(encodedData))
  623. {
  624. CM_EXCEPT(InternalErrorException,
  625. "Meta data represents an object description but is trying to be decoded as a field descriptor.");
  626. }
  627. if((encodedData & 0x10) != 0)
  628. type = SerializableFT_ReflectablePtr;
  629. else if((encodedData & 0x08) != 0)
  630. type = SerializableFT_Reflectable;
  631. else if((encodedData & 0x04) != 0)
  632. type = SerializableFT_DataBlock;
  633. else
  634. type = SerializableFT_Plain;
  635. array = (encodedData & 0x02) != 0;
  636. size = (UINT8)((encodedData >> 8) & 0xFF);
  637. id = (UINT16)((encodedData >> 16) & 0xFFFF);
  638. }
  639. UINT32 BinarySerializer::encodeObjectMetaData(UINT32 objId)
  640. {
  641. // If O == 1 - Meta contains object instance information (Encoded using encodeObjectMetaData)
  642. //// Encoding: SSSS SSSS SSSS SSSS xxxx xxxx xxxx xxxO
  643. //// S - Size of the object identifier
  644. //// O - Object descriptor
  645. return (objId << 1) | 0x01;
  646. }
  647. void BinarySerializer::decodeObjectMetaData(UINT32 encodedData, UINT32& objId)
  648. {
  649. if(!isObjectMetaData(encodedData))
  650. {
  651. CM_EXCEPT(InternalErrorException,
  652. "Meta data represents a field description but is trying to be decoded as an object descriptor.");
  653. }
  654. objId = (encodedData >> 1) & 0x7FFFFFFF;
  655. }
  656. bool BinarySerializer::isObjectMetaData(UINT32 encodedData)
  657. {
  658. return ((encodedData & 0x01) != 0);
  659. }
  660. UINT8* BinarySerializer::complexTypeToBuffer(IReflectable* object, UINT8* buffer, UINT32& bufferLength, int* bytesWritten, boost::function<UINT8*(UINT8*, int, UINT32&)> flushBufferCallback)
  661. {
  662. static const UINT32 COMPLEX_TYPE_FIELD_SIZE = 4; // Size of the field storing the size of a child complex type
  663. int complexTypeSize = 0;
  664. if(object != nullptr)
  665. complexTypeSize = getObjectSize(object);
  666. COPY_TO_BUFFER(&complexTypeSize, COMPLEX_TYPE_FIELD_SIZE)
  667. if(object != nullptr)
  668. return encodeInternal(object, 0, buffer, bufferLength, bytesWritten, flushBufferCallback);
  669. return buffer;
  670. }
  671. IReflectable* BinarySerializer::complexTypeFromBuffer(RTTIReflectableFieldBase* field, UINT8* data, int* complexTypeSize)
  672. {
  673. static const int COMPLEX_TYPE_FIELD_SIZE = 4; // Size of the field storing the size of a child complex type
  674. memcpy(complexTypeSize, data, COMPLEX_TYPE_FIELD_SIZE);
  675. data += COMPLEX_TYPE_FIELD_SIZE;
  676. IReflectable* emptyObject = nullptr;
  677. if(*complexTypeSize > 0)
  678. {
  679. emptyObject = field->newObject();
  680. UINT32 dummy = 0;
  681. decodeInternal(emptyObject, data, *complexTypeSize, dummy);
  682. }
  683. *complexTypeSize += COMPLEX_TYPE_FIELD_SIZE;
  684. return emptyObject;
  685. }
  686. UINT32 BinarySerializer::findOrCreatePersistentId(IReflectable* object)
  687. {
  688. UINT32 ptrAddress = (UINT32)object;
  689. auto findIter = mObjectAddrToId.find(ptrAddress);
  690. if(findIter != mObjectAddrToId.end())
  691. return findIter->second;
  692. UINT32 objId = mLastUsedObjectId++;
  693. mObjectAddrToId.insert(std::make_pair(ptrAddress, objId));
  694. return objId;
  695. }
  696. UINT32 BinarySerializer::registerObjectPtr(IReflectable* object)
  697. {
  698. if(object == nullptr)
  699. return 0;
  700. UINT32 ptrAddress = (UINT32)object;
  701. auto iterFind = mObjectAddrToId.find(ptrAddress);
  702. if(iterFind == mObjectAddrToId.end())
  703. {
  704. UINT32 objId = findOrCreatePersistentId(object);
  705. mObjectsToEncode.push_back(ObjectToEncode(objId, object));
  706. mObjectAddrToId.insert(std::make_pair(ptrAddress, objId));
  707. return objId;
  708. }
  709. return iterFind->second;
  710. }
  711. }
  712. #undef COPY_TO_BUFFER