#ifndef SRC_BLOB_SERIALIZER_DESERIALIZER_H_ #define SRC_BLOB_SERIALIZER_DESERIALIZER_H_ #include #include #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS // This is related to the blob that is used in snapshots and has nothing to do // with `node_blob.h`. namespace node { class BlobSerializerDeserializer { public: explicit BlobSerializerDeserializer(bool is_debug_v) : is_debug(is_debug_v) {} template void Debug(const char* format, Args&&... args) const; template std::string ToStr(const T& arg) const; template std::string GetName() const; bool is_debug = false; }; // Child classes are expected to implement T Read() where // !std::is_arithmetic_v && !std::is_same_v template class BlobDeserializer : public BlobSerializerDeserializer { public: explicit BlobDeserializer(bool is_debug_v, std::string_view s) : BlobSerializerDeserializer(is_debug_v), sink(s) {} ~BlobDeserializer() {} size_t read_total = 0; std::string_view sink; Impl* impl() { return static_cast(this); } const Impl* impl() const { return static_cast(this); } // Helper for reading numeric types. template T ReadArithmetic(); // Layout of vectors: // [ 4/8 bytes ] count // [ ... ] contents (count * size of individual elements) template std::vector ReadVector(); std::string ReadString(); // Helper for reading an array of numeric types. template void ReadArithmetic(T* out, size_t count); // Helper for reading numeric vectors. template std::vector ReadArithmeticVector(size_t count); private: // Helper for reading non-numeric vectors. template std::vector ReadNonArithmeticVector(size_t count); template T ReadElement(); }; // Child classes are expected to implement size_t Write(const T&) where // !std::is_arithmetic_v && !std::is_same_v template class BlobSerializer : public BlobSerializerDeserializer { public: explicit BlobSerializer(bool is_debug_v) : BlobSerializerDeserializer(is_debug_v) { // Currently the snapshot blob built with an empty script is around 4MB. // So use that as the default sink size. sink.reserve(4 * 1024 * 1024); } ~BlobSerializer() {} Impl* impl() { return static_cast(this); } const Impl* impl() const { return static_cast(this); } std::vector sink; // Helper for writing numeric types. template size_t WriteArithmetic(const T& data); // Layout of vectors: // [ 4/8 bytes ] count // [ ... ] contents (count * size of individual elements) template size_t WriteVector(const std::vector& data); // The layout of a written string: // [ 4/8 bytes ] length // [ |length| bytes ] contents size_t WriteString(const std::string& data); // Helper for writing an array of numeric types. template size_t WriteArithmetic(const T* data, size_t count); // Helper for writing numeric vectors. template size_t WriteArithmeticVector(const std::vector& data); private: // Helper for writing non-numeric vectors. template size_t WriteNonArithmeticVector(const std::vector& data); template size_t WriteElement(const T& data); }; } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #endif // SRC_BLOB_SERIALIZER_DESERIALIZER_H_