/ lib / Serialization / Serialization.h
Serialization.h
 1  #pragma once
 2  #include <HardwareSerial.h>
 3  #include <SdFat.h>
 4  
 5  #include <iostream>
 6  
 7  namespace serialization {
 8  template <typename T>
 9  static void writePod(std::ostream& os, const T& value) {
10    os.write(reinterpret_cast<const char*>(&value), sizeof(T));
11  }
12  
13  template <typename T>
14  static void writePod(FsFile& file, const T& value) {
15    file.write(reinterpret_cast<const uint8_t*>(&value), sizeof(T));
16  }
17  
18  template <typename T>
19  static void readPod(std::istream& is, T& value) {
20    is.read(reinterpret_cast<char*>(&value), sizeof(T));
21  }
22  
23  template <typename T>
24  static void readPod(FsFile& file, T& value) {
25    file.read(reinterpret_cast<uint8_t*>(&value), sizeof(T));
26  }
27  
28  template <typename T>
29  [[nodiscard]] static bool readPodChecked(FsFile& file, T& value) {
30    return file.read(reinterpret_cast<uint8_t*>(&value), sizeof(T)) == sizeof(T);
31  }
32  
33  static void writeString(std::ostream& os, const std::string& s) {
34    const uint32_t len = s.size();
35    writePod(os, len);
36    os.write(s.data(), len);
37  }
38  
39  static void writeString(FsFile& file, const std::string& s) {
40    const uint32_t len = s.size();
41    writePod(file, len);
42    file.write(reinterpret_cast<const uint8_t*>(s.data()), len);
43  }
44  
45  [[nodiscard]] static bool readString(std::istream& is, std::string& s) {
46    uint32_t len;
47    readPod(is, len);
48    if (!is.good()) {
49      s.clear();
50      return false;
51    }
52    if (len > 65536) {  // Sanity check: no string should be > 64KB
53      s.clear();
54      is.setstate(std::ios::failbit);
55      return false;
56    }
57    s.resize(len);
58    is.read(&s[0], len);
59    return is.good();
60  }
61  
62  [[nodiscard]] static bool readString(FsFile& file, std::string& s) {
63    uint32_t len;
64    if (file.read(reinterpret_cast<uint8_t*>(&len), sizeof(len)) != sizeof(len)) {
65      s.clear();
66      return false;
67    }
68    if (len > 65536) {  // Sanity check: no string should be > 64KB
69      Serial.printf("[SER] String length %u exceeds max, file corrupt\n", len);
70      s.clear();
71      return false;
72    }
73    s.resize(len);
74    if (len > 0 && file.read(reinterpret_cast<uint8_t*>(&s[0]), len) != static_cast<int>(len)) {
75      s.clear();
76      return false;
77    }
78    return true;
79  }
80  
81  template <typename T>
82  static void readPodValidated(FsFile& file, T& value, T maxValue) {
83    T temp;
84    file.read(reinterpret_cast<uint8_t*>(&temp), sizeof(T));
85    if (temp < maxValue) {
86      value = temp;
87    }
88  }
89  }  // namespace serialization