// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. #pragma once #include "Stream.h" #include "Engine/Core/Templates.h" struct CommonValue; struct Variant; struct VariantType; class ISerializable; class ScriptingObject; /// /// Base class for all data write streams /// class FLAXENGINE_API WriteStream : public Stream { public: /// /// Writes bytes to the stream /// /// Data to write /// Amount of bytes to write virtual void WriteBytes(const void* data, uint32 bytes) = 0; public: // Writes byte to the stream // @param data Data to write FORCE_INLINE void WriteByte(byte data) { WriteBytes(&data, sizeof(byte)); } // Writes bool to the stream // @param data Data to write FORCE_INLINE void WriteBool(bool data) { WriteBytes(&data, sizeof(bool)); } // Writes char to the stream // @param data Data to write FORCE_INLINE void WriteChar(char data) { WriteBytes(&data, sizeof(char)); } // Writes Char to the stream // @param data Data to write FORCE_INLINE void WriteChar(Char data) { WriteBytes(&data, sizeof(Char)); } // Writes uint8 to the stream // @param data Data to write FORCE_INLINE void WriteUint8(uint8 data) { WriteBytes(&data, sizeof(uint8)); } // Writes int8 to the stream // @param data Data to write FORCE_INLINE void WriteInt8(int8 data) { WriteBytes(&data, sizeof(int8)); } // Writes uint16 to the stream // @param data Data to write FORCE_INLINE void WriteUint16(uint16 data) { WriteBytes(&data, sizeof(uint16)); } // Writes int16 to the stream // @param data Data to write FORCE_INLINE void WriteInt16(int16 data) { WriteBytes(&data, sizeof(int16)); } // Writes uint32 to the stream // @param data Data to write FORCE_INLINE void WriteUint32(uint32 data) { WriteBytes(&data, sizeof(uint32)); } // Writes int32 to the stream // @param data Data to write FORCE_INLINE void WriteInt32(int32 data) { WriteBytes(&data, sizeof(int32)); } // Writes int64 to the stream // @param data Data to write FORCE_INLINE void WriteInt64(int64 data) { WriteBytes(&data, sizeof(int64)); } // Writes uint64 to the stream // @param data Data to write FORCE_INLINE void WriteUint64(uint64 data) { WriteBytes(&data, sizeof(uint64)); } // Writes float to the stream // @param data Data to write FORCE_INLINE void WriteFloat(float data) { WriteBytes(&data, sizeof(float)); } // Writes double to the stream // @param data Data to write FORCE_INLINE void WriteDouble(double data) { WriteBytes(&data, sizeof(double)); } public: // Writes text to the stream // @param data Text to write // @param length Text length void WriteText(const char* text, int32 length) { WriteBytes((const void*)text, sizeof(char) * length); } // Writes text to the stream // @param data Text to write // @param length Text length void WriteText(const Char* text, int32 length) { WriteBytes((const void*)text, sizeof(Char) * length); } // Write UTF BOM character sequence void WriteBOM() { WriteByte(0xEF); WriteByte(0xBB); WriteByte(0xBF); } // Writes text to the stream // @param data Text to write void WriteText(const StringView& text); void WriteText(const StringAnsiView& text); public: void Write(const StringView& data); void Write(const StringView& data, int16 lock); void Write(const StringAnsiView& data); void Write(const StringAnsiView& data, int8 lock); void Write(const CommonValue& data); void Write(const VariantType& data); void Write(const Variant& data); template FORCE_INLINE typename TEnableIf, TNot>>::Value>::Type Write(const T& data) { WriteBytes((const void*)&data, sizeof(T)); } template typename TEnableIf::Value>::Type Write(const T* data) { uint32 id[4] = { 0 }; if (data) memcpy(id, &data->GetID(), sizeof(id)); WriteBytes(id, sizeof(id)); } template void Write(const Array& data) { const int32 size = data.Count(); WriteInt32(size); if (size > 0) { if (TIsPODType::Value && !TIsPointer::Value) WriteBytes(data.Get(), size * sizeof(T)); else { for (int32 i = 0; i < size; i++) Write(data[i]); } } } template void Write(const Dictionary& data) { const int32 count = data.Count(); WriteInt32(count); if (count > 0) { for (const auto& e : data) { Write(e.Key); Write(e.Value); } } } /// /// Serializes object to Json and writes it as a raw data (ver+length+bytes). /// /// Writes version number, data length and actual data bytes to the stream. /// The object to serialize. /// The instance of the object to compare with and serialize only the modified properties. If null, then serialize all properties. void WriteJson(ISerializable* obj, const void* otherObj = nullptr); public: // Writes String to the stream /// [Deprecated on 11.10.2022, expires on 11.10.2024] // @param data Data to write void WriteString(const StringView& data); // Writes String to the stream /// [Deprecated on 11.10.2022, expires on 11.10.2024] // @param data Data to write // @param lock Characters pass in the stream void WriteString(const StringView& data, int16 lock); // Writes Ansi String to the stream /// [Deprecated on 11.10.2022, expires on 11.10.2024] // @param data Data to write void WriteStringAnsi(const StringAnsiView& data); // Writes Ansi String to the stream /// [Deprecated on 11.10.2022, expires on 11.10.2024] // @param data Data to write // @param lock Characters pass in the stream void WriteStringAnsi(const StringAnsiView& data, int8 lock); // Writes CommonValue to the stream /// [Deprecated on 11.10.2022, expires on 11.10.2024] // @param data Data to write void WriteCommonValue(const CommonValue& data); // Writes VariantType to the stream /// [Deprecated on 11.10.2022, expires on 11.10.2024] // @param data Data to write void WriteVariantType(const VariantType& data); // Writes Variant to the stream /// [Deprecated on 11.10.2022, expires on 11.10.2024] // @param data Data to write void WriteVariant(const Variant& data); /// /// Write data array /// [Deprecated on 11.10.2022, expires on 11.10.2024] /// /// Array to write template FORCE_INLINE void WriteArray(const Array& data) { Write(data); } public: // Serialization of math types with float or double depending on the context (must match deserialization) // Set useDouble=true to explicitly use 64-bit precision for serialized data void WriteBoundingBox(const BoundingBox& box, bool useDouble = false); void WriteBoundingSphere(const BoundingSphere& sphere, bool useDouble = false); void WriteTransform(const Transform& transform, bool useDouble = false); void WriteRay(const Ray& ray, bool useDouble = false); public: // [Stream] bool CanWrite() override { return true; } };