11cb0ef41Sopenharmony_ci#ifndef SRC_BLOB_SERIALIZER_DESERIALIZER_H_
21cb0ef41Sopenharmony_ci#define SRC_BLOB_SERIALIZER_DESERIALIZER_H_
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ci#include <string>
51cb0ef41Sopenharmony_ci#include <vector>
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci// This is related to the blob that is used in snapshots and has nothing to do
101cb0ef41Sopenharmony_ci// with `node_blob.h`.
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace node {
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciclass BlobSerializerDeserializer {
151cb0ef41Sopenharmony_ci public:
161cb0ef41Sopenharmony_ci  explicit BlobSerializerDeserializer(bool is_debug_v) : is_debug(is_debug_v) {}
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci  template <typename... Args>
191cb0ef41Sopenharmony_ci  void Debug(const char* format, Args&&... args) const;
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci  template <typename T>
221cb0ef41Sopenharmony_ci  std::string ToStr(const T& arg) const;
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci  template <typename T>
251cb0ef41Sopenharmony_ci  std::string GetName() const;
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci  bool is_debug = false;
281cb0ef41Sopenharmony_ci};
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci// Child classes are expected to implement T Read<T>() where
311cb0ef41Sopenharmony_ci// !std::is_arithmetic_v<T> && !std::is_same_v<T, std::string>
321cb0ef41Sopenharmony_citemplate <typename Impl>
331cb0ef41Sopenharmony_ciclass BlobDeserializer : public BlobSerializerDeserializer {
341cb0ef41Sopenharmony_ci public:
351cb0ef41Sopenharmony_ci  explicit BlobDeserializer(bool is_debug_v, std::string_view s)
361cb0ef41Sopenharmony_ci      : BlobSerializerDeserializer(is_debug_v), sink(s) {}
371cb0ef41Sopenharmony_ci  ~BlobDeserializer() {}
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  size_t read_total = 0;
401cb0ef41Sopenharmony_ci  std::string_view sink;
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  Impl* impl() { return static_cast<Impl*>(this); }
431cb0ef41Sopenharmony_ci  const Impl* impl() const { return static_cast<const Impl*>(this); }
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  // Helper for reading numeric types.
461cb0ef41Sopenharmony_ci  template <typename T>
471cb0ef41Sopenharmony_ci  T ReadArithmetic();
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  // Layout of vectors:
501cb0ef41Sopenharmony_ci  // [ 4/8 bytes ] count
511cb0ef41Sopenharmony_ci  // [   ...     ] contents (count * size of individual elements)
521cb0ef41Sopenharmony_ci  template <typename T>
531cb0ef41Sopenharmony_ci  std::vector<T> ReadVector();
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  std::string ReadString();
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  // Helper for reading an array of numeric types.
581cb0ef41Sopenharmony_ci  template <typename T>
591cb0ef41Sopenharmony_ci  void ReadArithmetic(T* out, size_t count);
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  // Helper for reading numeric vectors.
621cb0ef41Sopenharmony_ci  template <typename Number>
631cb0ef41Sopenharmony_ci  std::vector<Number> ReadArithmeticVector(size_t count);
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci private:
661cb0ef41Sopenharmony_ci  // Helper for reading non-numeric vectors.
671cb0ef41Sopenharmony_ci  template <typename T>
681cb0ef41Sopenharmony_ci  std::vector<T> ReadNonArithmeticVector(size_t count);
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  template <typename T>
711cb0ef41Sopenharmony_ci  T ReadElement();
721cb0ef41Sopenharmony_ci};
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci// Child classes are expected to implement size_t Write<T>(const T&) where
751cb0ef41Sopenharmony_ci// !std::is_arithmetic_v<T> && !std::is_same_v<T, std::string>
761cb0ef41Sopenharmony_citemplate <typename Impl>
771cb0ef41Sopenharmony_ciclass BlobSerializer : public BlobSerializerDeserializer {
781cb0ef41Sopenharmony_ci public:
791cb0ef41Sopenharmony_ci  explicit BlobSerializer(bool is_debug_v)
801cb0ef41Sopenharmony_ci      : BlobSerializerDeserializer(is_debug_v) {
811cb0ef41Sopenharmony_ci    // Currently the snapshot blob built with an empty script is around 4MB.
821cb0ef41Sopenharmony_ci    // So use that as the default sink size.
831cb0ef41Sopenharmony_ci    sink.reserve(4 * 1024 * 1024);
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci  ~BlobSerializer() {}
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  Impl* impl() { return static_cast<Impl*>(this); }
881cb0ef41Sopenharmony_ci  const Impl* impl() const { return static_cast<const Impl*>(this); }
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  std::vector<char> sink;
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  // Helper for writing numeric types.
931cb0ef41Sopenharmony_ci  template <typename T>
941cb0ef41Sopenharmony_ci  size_t WriteArithmetic(const T& data);
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  // Layout of vectors:
971cb0ef41Sopenharmony_ci  // [ 4/8 bytes ] count
981cb0ef41Sopenharmony_ci  // [   ...     ] contents (count * size of individual elements)
991cb0ef41Sopenharmony_ci  template <typename T>
1001cb0ef41Sopenharmony_ci  size_t WriteVector(const std::vector<T>& data);
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  // The layout of a written string:
1031cb0ef41Sopenharmony_ci  // [  4/8 bytes     ] length
1041cb0ef41Sopenharmony_ci  // [ |length| bytes ] contents
1051cb0ef41Sopenharmony_ci  size_t WriteString(const std::string& data);
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  // Helper for writing an array of numeric types.
1081cb0ef41Sopenharmony_ci  template <typename T>
1091cb0ef41Sopenharmony_ci  size_t WriteArithmetic(const T* data, size_t count);
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci  // Helper for writing numeric vectors.
1121cb0ef41Sopenharmony_ci  template <typename Number>
1131cb0ef41Sopenharmony_ci  size_t WriteArithmeticVector(const std::vector<Number>& data);
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci private:
1161cb0ef41Sopenharmony_ci  // Helper for writing non-numeric vectors.
1171cb0ef41Sopenharmony_ci  template <typename T>
1181cb0ef41Sopenharmony_ci  size_t WriteNonArithmeticVector(const std::vector<T>& data);
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  template <typename T>
1211cb0ef41Sopenharmony_ci  size_t WriteElement(const T& data);
1221cb0ef41Sopenharmony_ci};
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci}  // namespace node
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci#endif  // SRC_BLOB_SERIALIZER_DESERIALIZER_H_
129