Skip to content

Commit afb2b7a

Browse files
committed
fix: made required changes.
1 parent 8b8f915 commit afb2b7a

File tree

1 file changed

+138
-44
lines changed

1 file changed

+138
-44
lines changed

others/serialization.cpp

Lines changed: 138 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,38 @@
11
/**
2-
* @file
3-
* @brief A simple Serializer and Deserializer utility for fundamental data
4-
* types and strings.
2+
* @file serialization.cpp
3+
* @brief Utility for binary serialization and deserialization of fundamental
4+
* data types and strings.
5+
* @details
6+
* Binary serialization converts data into its binary format for
7+
* efficient storage and transmission, which is more compact and faster than
8+
* text-based formats. This utility handles fundamental types like integers,
9+
* doubles, and characters by writing their binary representation directly to a
10+
* file using `reinterpret_cast`.
11+
*
12+
* ### Serializing:
13+
* - **Fundamental Types**: Written directly in their binary form.
14+
* - **Strings**: The string's length is written first, followed by the string
15+
* data, and a `|` delimiter to mark the end.
16+
*
17+
* ### Deserializing:
18+
* - **Fundamental Types**: Reads the binary data back into the appropriate
19+
* type.
20+
* - **Strings**: Reads the string's length, followed by the string data, and
21+
* checks for the `|` delimiter. An error is raised if the delimiter is missing.
22+
*
23+
* @author [SharonIV0X86](https://github.com/SharonIV0X86)
524
*/
25+
626
#include <cassert> // for assert
727
#include <cstdint> // for std::uint32_t
28+
#include <cstdio> // for std::remove()
829
#include <fstream> // for std::ifstream std::ofstream
930
#include <iostream> // for std::ios std::cout std::cerr
1031
#include <string> // for std::string
1132
#include <type_traits> // for std::is_fundamental
1233

1334
/**
35+
* @class Serializer
1436
* @brief A utility class for serializing fundamental data types and strings to
1537
* a binary file.
1638
*/
@@ -104,60 +126,132 @@ class Deserializer {
104126
* @return void
105127
*/
106128
void tests() {
107-
std::ofstream outFile("test_output.bin", std::ios::binary);
108-
if (!outFile) {
109-
std::cerr << "Error opening file for output.\n";
110-
return;
111-
}
129+
try {
130+
std::ofstream outFile("test_output.bin", std::ios::binary);
131+
if (!outFile) {
132+
throw std::runtime_error("Error opening file for output.");
133+
}
134+
135+
int testInt = 12345;
136+
double testDouble = 9876.54321;
137+
char testChar = 'A';
138+
std::string testString = "Testing String Serialization!";
139+
140+
// Serialize the data
141+
Serializer::serialize(outFile, testInt);
142+
Serializer::serialize(outFile, testDouble);
143+
Serializer::serialize(outFile, testChar);
144+
Serializer::serialize(outFile, testString);
145+
146+
outFile.close();
112147

113-
int testInt = 12345;
114-
double testDouble = 9876.54321;
115-
char testChar = 'A';
116-
std::string testString = "Testing String Serialization!";
148+
std::ifstream inFile("test_output.bin", std::ios::binary);
149+
if (!inFile) {
150+
throw std::runtime_error("Error opening file for input.");
151+
}
152+
153+
int intResult;
154+
double doubleResult;
155+
char charResult;
156+
std::string stringResult;
157+
158+
// Deserialize the data
159+
Deserializer::deserialize(inFile, intResult);
160+
Deserializer::deserialize(inFile, doubleResult);
161+
Deserializer::deserialize(inFile, charResult);
162+
Deserializer::deserialize(inFile, stringResult);
117163

118-
// Serialize the data
119-
Serializer::serialize(outFile, testInt);
120-
Serializer::serialize(outFile, testDouble);
121-
Serializer::serialize(outFile, testChar);
122-
Serializer::serialize(outFile, testString);
164+
inFile.close();
123165

124-
outFile.close();
166+
// Assert that the original and deserialized values are the same
167+
assert(testInt == intResult);
168+
assert(testDouble == doubleResult);
169+
assert(testChar == charResult);
170+
assert(testString == stringResult);
125171

126-
std::ifstream inFile("test_output.bin", std::ios::binary);
127-
if (!inFile) {
128-
std::cerr << "Error opening file for input.\n";
129-
return;
172+
std::cout << "All tests passed!\n";
173+
} catch (const std::exception &e) {
174+
std::cerr << "Test failed: " << e.what() << std::endl;
130175
}
131176

132-
int intResult;
133-
double doubleResult;
134-
char charResult;
135-
std::string stringResult;
177+
// Test for file opening failure
178+
try {
179+
std::ifstream inFile("non_existent_file.bin", std::ios::binary);
180+
if (!inFile) {
181+
throw std::runtime_error("Error opening non-existent file.");
182+
}
183+
} catch (const std::runtime_error &e) {
184+
assert(std::string(e.what()) == "Error opening non-existent file.");
185+
std::cout << "File opening error test passed!\n";
186+
}
136187

137-
// Deserialize the data
138-
Deserializer::deserialize(inFile, intResult);
139-
Deserializer::deserialize(inFile, doubleResult);
140-
Deserializer::deserialize(inFile, charResult);
141-
Deserializer::deserialize(inFile, stringResult);
188+
// Test for deserialization failure (e.g., wrong file format)
189+
try {
190+
std::ofstream outFile("wrong_format.bin", std::ios::binary);
191+
outFile << "This is not serialized data"; // Writing incorrect data
192+
outFile.close();
142193

143-
inFile.close();
194+
std::ifstream inFile("wrong_format.bin", std::ios::binary);
195+
if (!inFile) {
196+
throw std::runtime_error("Error opening file for input.");
197+
}
144198

145-
// Assert that the original and deserialized values are the same
146-
assert(testInt == intResult);
147-
assert(testDouble == doubleResult);
148-
assert(testChar == charResult);
149-
assert(testString == stringResult);
199+
int intResult;
200+
// Deserialize expecting binary data, this should fail
201+
Deserializer::deserialize(inFile, intResult);
150202

151-
std::cout << "All tests passed!\n";
203+
inFile.close();
204+
} catch (const std::exception &e) {
205+
std::cout << "Deserialization error test passed: " << e.what()
206+
<< std::endl;
207+
}
208+
209+
// Test for string too large error
210+
try {
211+
std::ofstream outFile("large_string.bin", std::ios::binary);
212+
std::string largeString(1024 * 1024 + 1,
213+
'A'); // String larger than 1MB
214+
Serializer::serialize(outFile,
215+
largeString); // Should succeed in serialization
216+
outFile.close();
217+
218+
std::ifstream inFile("large_string.bin", std::ios::binary);
219+
std::string deserializedString;
220+
Deserializer::deserialize(
221+
inFile, deserializedString); // Should fail in deserialization
222+
inFile.close();
223+
} catch (const std::runtime_error &e) {
224+
assert(std::string(e.what()) ==
225+
"Deserialized string length is too large.");
226+
std::cout << "Large string error test passed!\n";
227+
}
228+
229+
// Test for missing delimiter
230+
try {
231+
std::ofstream outFile("missing_delimiter.bin", std::ios::binary);
232+
std::string testString = "Test String";
233+
std::uint32_t length = testString.size();
234+
outFile.write(reinterpret_cast<const char *>(&length), sizeof(length));
235+
outFile.write(testString.c_str(), length); // No delimiter
236+
outFile.close();
237+
238+
std::ifstream inFile("missing_delimiter.bin", std::ios::binary);
239+
std::string deserializedString;
240+
Deserializer::deserialize(inFile, deserializedString); // Should fail
241+
inFile.close();
242+
} catch (const std::runtime_error &e) {
243+
assert(std::string(e.what()) ==
244+
"Delimiter '|' not found after string.");
245+
std::cout << "Missing delimiter error test passed!\n";
246+
}
247+
// Clean up temporary files that were created during testing.
248+
std::remove("test_output.bin");
249+
std::remove("wrong_format.bin");
250+
std::remove("large_string.bin");
251+
std::remove("missing_delimiter.bin");
152252
}
153253

154254
int main() {
155255
tests();
156-
157256
return 0;
158257
}
159-
160-
/**
161-
* @brief A test suite to perform extensive testing on the Serializer and
162-
* Deserializer.
163-
*/

0 commit comments

Comments
 (0)