ObjectStreamOut.h 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Jolt/ObjectStream/ObjectStream.h>
  5. #include <Jolt/Core/RTTI.h>
  6. JPH_SUPPRESS_WARNINGS_STD_BEGIN
  7. #include <queue>
  8. #include <fstream>
  9. #include <unordered_set>
  10. #include <unordered_map>
  11. JPH_SUPPRESS_WARNINGS_STD_END
  12. JPH_NAMESPACE_BEGIN
  13. /// ObjectStreamOut contains all logic for writing an object to disk. It is the base
  14. /// class for the text and binary output streams (ObjectStreamTextOut and ObjectStreamBinaryOut).
  15. class ObjectStreamOut : public IObjectStreamOut
  16. {
  17. private:
  18. struct ObjectInfo;
  19. public:
  20. /// Main function to write an object to a stream
  21. template <class T>
  22. static bool sWriteObject(ostream &inStream, ObjectStream::EStreamType inType, const T &inObject)
  23. {
  24. // Create the output stream
  25. bool result = false;
  26. ObjectStreamOut *stream = ObjectStreamOut::Open(inType, inStream);
  27. if (stream)
  28. {
  29. // Write the object to the stream
  30. result = stream->Write((void *)&inObject, GetRTTI(&inObject));
  31. delete stream;
  32. }
  33. return result;
  34. }
  35. /// Main function to write an object to a file
  36. template <class T>
  37. static bool sWriteObject(const char *inFileName, ObjectStream::EStreamType inType, const T &inObject)
  38. {
  39. ofstream stream;
  40. stream.open(inFileName, ofstream::out | ofstream::trunc | ofstream::binary);
  41. if (!stream.is_open())
  42. return false;
  43. return sWriteObject(stream, inType, inObject);
  44. }
  45. //////////////////////////////////////////////////////
  46. // EVERYTHING BELOW THIS SHOULD NOT DIRECTLY BE CALLED
  47. //////////////////////////////////////////////////////
  48. ///@name Serialization operations
  49. bool Write(const void *inObject, const RTTI *inRTTI);
  50. void WriteObject(const void *inObject);
  51. void QueueRTTI(const RTTI *inRTTI);
  52. void WriteRTTI(const RTTI *inRTTI);
  53. virtual void WriteClassData(const RTTI *inRTTI, const void *inInstance) override;
  54. virtual void WritePointerData(const RTTI *inRTTI, const void *inPointer) override;
  55. protected:
  56. /// Static constructor
  57. static ObjectStreamOut * Open(EStreamType inType, ostream &inStream);
  58. /// Constructor
  59. explicit ObjectStreamOut(ostream &inStream);
  60. ostream & mStream;
  61. private:
  62. struct ObjectInfo
  63. {
  64. ObjectInfo() : mIdentifier(0), mRTTI(nullptr) { }
  65. ObjectInfo(Identifier inIdentifier, const RTTI *inRTTI) : mIdentifier(inIdentifier), mRTTI(inRTTI) { }
  66. Identifier mIdentifier;
  67. const RTTI * mRTTI;
  68. };
  69. using IdentifierMap = unordered_map<const void *, ObjectInfo>;
  70. using ClassSet = unordered_set<const RTTI *>;
  71. using ObjectQueue = queue<const void *>;
  72. using ClassQueue = queue<const RTTI *>;
  73. Identifier mNextIdentifier = sNullIdentifier + 1; ///< Next free identifier for this stream
  74. IdentifierMap mIdentifierMap; ///< Links object pointer to an identifier
  75. ObjectQueue mObjectQueue; ///< Queue of objects to be written
  76. ClassSet mClassSet; ///< List of classes already written
  77. ClassQueue mClassQueue; ///< List of classes waiting to be written
  78. };
  79. JPH_NAMESPACE_END