You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
5.7 KiB

1 year ago
  1. /**
  2. * @file IObject.h
  3. * @brief Object system types and interfaces.
  4. * @copyright VisionLabs LLC
  5. * @date 25.06.2014
  6. * */
  7. #pragma once
  8. #include "IRefCounted.h"
  9. #include "Types.h"
  10. namespace fsdk {
  11. /**
  12. * @addtogroup CoreGroup SDK core interfaces
  13. * @brief Common interfaces and macros shared across all SDK objects.
  14. * @{
  15. * */
  16. struct ISettingsProvider;
  17. /**
  18. * @brief Archive interface.
  19. * @details Archives abstract data storage and IO operations.
  20. *
  21. * @note IArchive is not derived from IRefCounted and does not force any lifetime control. It is up to user to
  22. * implement it.
  23. *
  24. * @note SDK ojects that use IArchive for serialization purposes do call only write() (during saving) or only
  25. * read() (during loading) but never both during the same process unless otherwise is explicitly stated.
  26. *
  27. * @note During saving or loading SDK objects are free to write or read their data in chunks; e.g. there may be
  28. * several sequential calls to write() in scope of a single serialization request. Any IArchive implementation
  29. * should be aware of this.
  30. * */
  31. struct IArchive {
  32. /**
  33. * @brief Write bytes to archive.
  34. * @param [in] data pointer to memory to write.
  35. * @param [in] size data size.
  36. * @return true if succeeded, false otherwise.
  37. * */
  38. virtual bool write(const void* data, size_t size) = 0;
  39. /**
  40. * @brief Read bytes from archive.
  41. * @param [in] data pointer to memory to read to.
  42. * @param [in] size data size.
  43. * @return true if succeeded, false otherwise.
  44. * */
  45. virtual bool read(void* data, size_t size) = 0;
  46. /**
  47. * @brief Set size hint.
  48. * @param [in] hint size hint.
  49. * */
  50. virtual void setSizeHint(size_t hint) { ((void)hint); }
  51. virtual ~IArchive() = default;
  52. };
  53. /**
  54. * @brief Serializable object interface.
  55. * @details Provides common functions for all serializable objects.
  56. * */
  57. struct ISerializableObject : IRefCounted {
  58. /**
  59. * @brief Serialization nerror codes.
  60. * */
  61. enum class Error : uint32_t {
  62. Ok, //!< Ok
  63. Size, //!< Not enough space
  64. Signature, //!< Invalid signature
  65. ArchiveRead, //!< Error during archive reading,
  66. InputArchive, //!< Input archive is nullptr
  67. ArchiveWrite, //!< Error during archive writing,
  68. };
  69. /**
  70. * @brief Serialization flags.
  71. * @details These flags control advanced options and should not be set to anything else from Default in
  72. * normal conditions.
  73. * @note The same set of flags should be specified for both save() and load().
  74. * */
  75. enum Flags {
  76. /** @brief Default serialization mode. */
  77. Default = 0,
  78. /**
  79. * @brief Omit object signature.
  80. * @details Helps to save space if there are several objects of the same type coming in a stream or
  81. * where type is known for sure.
  82. * @note This effectively disables signature check on loading. This may cause undefined results in
  83. * case of mismatched input data.
  84. * */
  85. NoSignature = 1
  86. };
  87. /**
  88. * @brief Estimate size of this object binary data.
  89. * @param [inout] sizer sizer object to append result to.
  90. * @param [in] flags [optional] serialization flags @see Flags.
  91. * */
  92. virtual void getSize(Sizer& sizer, uint32_t flags = Default) const noexcept = 0;
  93. /**
  94. * @brief Load object from archive.
  95. * @param [in] archive archive to read from.
  96. * @param [in] flags [optional] serialization flags @see Flags.
  97. * @return Result with error code specified by ISerializableObject::SerializationError.
  98. * @note This method pass exceptions from user defined IArchive, but doesnt throw its own
  99. * @see Result and ISerializableObject::SerializationError.
  100. * */
  101. virtual Result<Error> load(IArchive* archive, uint32_t flags = Default) = 0;
  102. /**
  103. * @brief Save object to archive.
  104. * @param [in] archive archive to write to.
  105. * @param [in] flags [optional] serialization flags @see Flags.
  106. * @return Result with error code specified by ISerializableObject::SerializationError.
  107. * @note This method pass exceptions from user defined IArchive, but doesnt throw its own
  108. * @see Result and ISerializableObject::SerializationError.
  109. * */
  110. virtual Result<Error> save(IArchive* archive, uint32_t flags = Default) const = 0;
  111. };
  112. /**
  113. * @brief Specialized for ISerializableObject::SerializationError.
  114. * */
  115. template<>
  116. struct ErrorTraits<ISerializableObject::Error> {
  117. static bool isOk(ISerializableObject::Error error) noexcept {
  118. return error == ISerializableObject::Error::Ok;
  119. }
  120. static const char* toString (ISerializableObject::Error error) noexcept {
  121. switch(error) {
  122. case ISerializableObject::Error::Ok : return "Ok";
  123. case ISerializableObject::Error::Size: return "Size error";
  124. case ISerializableObject::Error::Signature: return "Signature error";
  125. case ISerializableObject::Error::ArchiveRead: return "Error during archive reading";
  126. case ISerializableObject::Error::InputArchive: return "Input archive is nullptr";
  127. case ISerializableObject::Error::ArchiveWrite: return "Error during archive writing";
  128. default: return "Unknown error";
  129. }
  130. }
  131. };
  132. /**
  133. * @brief Data storage object interface helper.
  134. * */
  135. struct IDataStorageObject : ISerializableObject {
  136. /**
  137. * @brief Clear object data.
  138. * @note This does not necessarily mean deallocation; it is defined by implementation how to manage
  139. * data memory.
  140. * */
  141. virtual void clear() noexcept = 0;
  142. /**
  143. * @brief Get parent object (one that has created this).
  144. * @note Any returned interfaces will have their reference count incremented by one, so be sure to
  145. * call release() on the returned pointer(s) before they are freed or else you will have a memory
  146. * leak.
  147. * @return pointer to the parent object.
  148. * */
  149. virtual IRefCounted* getParentObject() const noexcept = 0;
  150. };
  151. /** @} */
  152. }