1 #ifndef SRC_BLOB_SERIALIZER_DESERIALIZER_H_ 2 #define SRC_BLOB_SERIALIZER_DESERIALIZER_H_ 3 4 #include <string> 5 #include <vector> 6 7 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 8 9 // This is related to the blob that is used in snapshots and has nothing to do 10 // with `node_blob.h`. 11 12 namespace node { 13 14 class BlobSerializerDeserializer { 15 public: BlobSerializerDeserializer(bool is_debug_v)16 explicit BlobSerializerDeserializer(bool is_debug_v) : is_debug(is_debug_v) {} 17 18 template <typename... Args> 19 void Debug(const char* format, Args&&... args) const; 20 21 template <typename T> 22 std::string ToStr(const T& arg) const; 23 24 template <typename T> 25 std::string GetName() const; 26 27 bool is_debug = false; 28 }; 29 30 // Child classes are expected to implement T Read<T>() where 31 // !std::is_arithmetic_v<T> && !std::is_same_v<T, std::string> 32 template <typename Impl> 33 class BlobDeserializer : public BlobSerializerDeserializer { 34 public: BlobDeserializer(bool is_debug_v,std::string_view s)35 explicit BlobDeserializer(bool is_debug_v, std::string_view s) 36 : BlobSerializerDeserializer(is_debug_v), sink(s) {} ~BlobDeserializer()37 ~BlobDeserializer() {} 38 39 size_t read_total = 0; 40 std::string_view sink; 41 impl()42 Impl* impl() { return static_cast<Impl*>(this); } impl()43 const Impl* impl() const { return static_cast<const Impl*>(this); } 44 45 // Helper for reading numeric types. 46 template <typename T> 47 T ReadArithmetic(); 48 49 // Layout of vectors: 50 // [ 4/8 bytes ] count 51 // [ ... ] contents (count * size of individual elements) 52 template <typename T> 53 std::vector<T> ReadVector(); 54 55 std::string ReadString(); 56 57 // Helper for reading an array of numeric types. 58 template <typename T> 59 void ReadArithmetic(T* out, size_t count); 60 61 // Helper for reading numeric vectors. 62 template <typename Number> 63 std::vector<Number> ReadArithmeticVector(size_t count); 64 65 private: 66 // Helper for reading non-numeric vectors. 67 template <typename T> 68 std::vector<T> ReadNonArithmeticVector(size_t count); 69 70 template <typename T> 71 T ReadElement(); 72 }; 73 74 // Child classes are expected to implement size_t Write<T>(const T&) where 75 // !std::is_arithmetic_v<T> && !std::is_same_v<T, std::string> 76 template <typename Impl> 77 class BlobSerializer : public BlobSerializerDeserializer { 78 public: BlobSerializer(bool is_debug_v)79 explicit BlobSerializer(bool is_debug_v) 80 : BlobSerializerDeserializer(is_debug_v) { 81 // Currently the snapshot blob built with an empty script is around 4MB. 82 // So use that as the default sink size. 83 sink.reserve(4 * 1024 * 1024); 84 } ~BlobSerializer()85 ~BlobSerializer() {} 86 impl()87 Impl* impl() { return static_cast<Impl*>(this); } impl()88 const Impl* impl() const { return static_cast<const Impl*>(this); } 89 90 std::vector<char> sink; 91 92 // Helper for writing numeric types. 93 template <typename T> 94 size_t WriteArithmetic(const T& data); 95 96 // Layout of vectors: 97 // [ 4/8 bytes ] count 98 // [ ... ] contents (count * size of individual elements) 99 template <typename T> 100 size_t WriteVector(const std::vector<T>& data); 101 102 // The layout of a written string: 103 // [ 4/8 bytes ] length 104 // [ |length| bytes ] contents 105 size_t WriteString(const std::string& data); 106 107 // Helper for writing an array of numeric types. 108 template <typename T> 109 size_t WriteArithmetic(const T* data, size_t count); 110 111 // Helper for writing numeric vectors. 112 template <typename Number> 113 size_t WriteArithmeticVector(const std::vector<Number>& data); 114 115 private: 116 // Helper for writing non-numeric vectors. 117 template <typename T> 118 size_t WriteNonArithmeticVector(const std::vector<T>& data); 119 120 template <typename T> 121 size_t WriteElement(const T& data); 122 }; 123 124 } // namespace node 125 126 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 127 128 #endif // SRC_BLOB_SERIALIZER_DESERIALIZER_H_ 129