Skip to content

Commit 14b794a

Browse files
committed
feat: added serializers
1 parent 0ecb6bd commit 14b794a

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed

others/serialization.cpp

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#include <fstream>
2+
#include <iostream>
3+
#include <string>
4+
5+
/**
6+
* @file
7+
* @brief A simple Serializer and Deserializer utility for fundamental data
8+
* types and strings.
9+
*/
10+
11+
12+
class Serializer {
13+
public:
14+
/**
15+
* Serializes fundamental data types (like int, float, double, etc.) to a
16+
* binary file.
17+
* @tparam T The type of the data to be serialized.
18+
* @param out The output stream (std::ofstream).
19+
* @param data The data to be serialized.
20+
*
21+
* @note This function only works for fundamental types (primitives).
22+
*/
23+
template <typename T>
24+
static void serialize(std::ofstream &out, const T &data) {
25+
static_assert(
26+
std::is_fundamental<T>::value,
27+
"Non-fundamental types are not allowed for this function!");
28+
out.write(reinterpret_cast<const char *>(&data), sizeof(T));
29+
}
30+
31+
/**
32+
* Serializes a string to a binary file.
33+
* @param out The output stream (std::ofstream).
34+
* @param data The string to be serialized.
35+
*
36+
* The string is serialized by first storing its length, followed by the
37+
* content.
38+
*/
39+
static void serialize(std::ofstream &out, const std::string &data) {
40+
ssize_t length = data.size();
41+
serialize(out, length); // Serialize the length of the string.
42+
out.write(data.c_str(), length); // Serialize the string characters.
43+
out.put('|'); // Add a delimiter to denote the end of the string.
44+
}
45+
};
46+
47+
/**
48+
* @class Deserializer
49+
* A utility class for deserializing data from a binary file.
50+
*/
51+
class Deserializer {
52+
public:
53+
/**
54+
* Deserializes fundamental data types (like int, float, double, etc.) from
55+
* a binary file.
56+
* @tparam T The type of the data to be deserialized.
57+
* @param in The input stream (std::ifstream).
58+
* @param data The variable where the deserialized data will be stored.
59+
*
60+
* @note This function only works for fundamental types (primitives).
61+
*/
62+
template <typename T>
63+
static void deserialize(std::ifstream &in, T &data) {
64+
static_assert(
65+
std::is_fundamental<T>::value,
66+
"Non-fundamental types are not allowed for this function!");
67+
in.read(reinterpret_cast<char *>(&data), sizeof(T));
68+
}
69+
70+
/**
71+
* Deserializes a string from a binary file.
72+
* @param in The input stream (std::ifstream).
73+
* @param data The string where the deserialized content will be stored.
74+
*
75+
* The string is deserialized by reading its length, followed by the
76+
* characters, and finally validating the delimiter throws error if the
77+
* delimiter '|' is not found.
78+
*/
79+
static void deserialize(std::ifstream &in, std::string &data) {
80+
ssize_t length;
81+
deserialize(in, length); // Deserialize the length of the string.
82+
83+
if (length > 1024 * 1024) // Sanity check to prevent huge strings.
84+
{
85+
throw std::runtime_error(
86+
"Deserialized string length is too large.");
87+
}
88+
89+
data.resize(length); // Resize the string to fit the incoming data.
90+
in.read(&data[0], length); // Read the string characters.
91+
char delimiter;
92+
in.get(delimiter); // Check the delimiter.
93+
if (delimiter != '|') {
94+
throw std::runtime_error("Delimiter '|' not found after string.");
95+
}
96+
}
97+
};
98+
99+
void runTests();
100+
101+
/**
102+
* Demonstrates the use of Serializer and Deserializer for fundamental types and
103+
* strings.
104+
*/
105+
int main() {
106+
std::ofstream outFile("output.bin", std::ios::binary);
107+
std::ifstream inFile("output.bin", std::ios::binary);
108+
109+
if (!outFile || !inFile) {
110+
std::cerr << "Error opening files.\n";
111+
return 1;
112+
}
113+
114+
// Data to be serialized.
115+
int num = 42;
116+
float pi = 3.14159f;
117+
std::string message = "Hello, Sharon!";
118+
119+
Serializer::serialize(outFile, num);
120+
Serializer::serialize(outFile, pi);
121+
Serializer::serialize(outFile, message);
122+
outFile.close();
123+
124+
int numRead;
125+
float piRead;
126+
std::string messageRead;
127+
128+
// Deserialize the data.
129+
Deserializer::deserialize(inFile, numRead);
130+
Deserializer::deserialize(inFile, piRead);
131+
Deserializer::deserialize(inFile, messageRead);
132+
inFile.close();
133+
134+
std::cout << "Deserialized int: " << numRead << "\n";
135+
std::cout << "Deserialized float: " << piRead << "\n";
136+
std::cout << "Deserialized string: " << messageRead << "\n";
137+
138+
return 0;
139+
}
140+
141+
/**
142+
* @brief A test suite to perform extensive testing on the Serializer and
143+
* Deserializer.
144+
*/
145+
void runTests() {
146+
std::ofstream outFile("test_output.bin", std::ios::binary);
147+
if (!outFile) {
148+
std::cerr << "Error opening file for output.\n";
149+
return;
150+
}
151+
152+
int testInt = 12345;
153+
double testDouble = 9876.54321;
154+
char testChar = 'A';
155+
std::string testString = "Testing String Serialization!";
156+
157+
// Serialize the data
158+
Serializer::serialize(outFile, testInt);
159+
Serializer::serialize(outFile, testDouble);
160+
Serializer::serialize(outFile, testChar);
161+
Serializer::serialize(outFile, testString);
162+
163+
outFile.close();
164+
165+
std::ifstream inFile("test_output.bin", std::ios::binary);
166+
if (!inFile) {
167+
std::cerr << "Error opening file for input.\n";
168+
return;
169+
}
170+
171+
int intResult;
172+
double doubleResult;
173+
char charResult;
174+
std::string stringResult;
175+
176+
// Deserialize the data
177+
Deserializer::deserialize(inFile, intResult);
178+
Deserializer::deserialize(inFile, doubleResult);
179+
Deserializer::deserialize(inFile, charResult);
180+
Deserializer::deserialize(inFile, stringResult);
181+
182+
inFile.close();
183+
184+
std::cout << "Test Int: " << intResult << "\n";
185+
std::cout << "Test Double: " << doubleResult << "\n";
186+
std::cout << "Test Char: " << charResult << "\n";
187+
std::cout << "Test String: " << stringResult << "\n";
188+
}

0 commit comments

Comments
 (0)