mirror of
https://github.com/davisking/dlib.git
synced 2024-11-01 10:14:53 +08:00
Changed the serialization code for C-strings so that they don't save the null terminator
byte. This makes their serialization format the same as the format for std::string. I had to revert the previous mod for this because it didn't work in visual studio. This change fixes that. The code should still be able to read all previously serialized data correctly. Moreover, any char arrays that aren't null terminated will still be read and written in their entirety.
This commit is contained in:
parent
06bf7e0e38
commit
f3ce10594f
103
dlib/serialize.h
103
dlib/serialize.h
@ -1207,6 +1207,41 @@ namespace dlib
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
size_t length
|
||||
>
|
||||
inline void serialize (
|
||||
const char (&array)[length],
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
if (length != 0 && array[length-1] == '\0')
|
||||
{
|
||||
// If this is a null terminated string then don't serialize the trailing null.
|
||||
// We do this so that the serialization format for C-strings is the same as
|
||||
// std::string.
|
||||
serialize(length-1, out);
|
||||
out.write(array, length-1);
|
||||
if (!out)
|
||||
throw serialization_error("Error serializing a C-style string");
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
serialize(length,out);
|
||||
}
|
||||
catch (serialization_error& e)
|
||||
{
|
||||
throw serialization_error(e.info + "\n while serializing a C style array");
|
||||
}
|
||||
if (length != 0)
|
||||
out.write(array, length);
|
||||
if (!out)
|
||||
throw serialization_error("Error serializing a C-style string");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
@ -1237,6 +1272,45 @@ namespace dlib
|
||||
throw serialization_error("Error deserializing a C style array, lengths do not match");
|
||||
}
|
||||
|
||||
template <
|
||||
size_t length
|
||||
>
|
||||
inline void deserialize (
|
||||
char (&array)[length],
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
size_t size;
|
||||
try
|
||||
{
|
||||
deserialize(size,in);
|
||||
}
|
||||
catch (serialization_error& e)
|
||||
{
|
||||
throw serialization_error(e.info + "\n while deserializing a C style array");
|
||||
}
|
||||
|
||||
if (size == length)
|
||||
{
|
||||
in.read(array, size);
|
||||
if (!in)
|
||||
throw serialization_error("Error deserializing a C-style array");
|
||||
}
|
||||
else if (size+1 == length)
|
||||
{
|
||||
// In this case we are deserializing a C-style array so we need to add the null
|
||||
// terminator.
|
||||
in.read(array, size);
|
||||
array[size] = '\0';
|
||||
if (!in)
|
||||
throw serialization_error("Error deserializing a C-style string");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw serialization_error("Error deserializing a C style array, lengths do not match");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
@ -1281,17 +1355,6 @@ namespace dlib
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
inline void serialize(const char* item, std::ostream& out)
|
||||
{
|
||||
// We serialize literal strings the same way we serialize std::string, that is, we
|
||||
// write the data but no trailing 0 byte.
|
||||
const unsigned long length = strlen(item);
|
||||
serialize(length, out);
|
||||
out.write(item, length);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class proxy_serialize
|
||||
@ -1313,24 +1376,6 @@ namespace dlib
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t length>
|
||||
proxy_serialize& operator<<(const char (&item)[length])
|
||||
{
|
||||
// We serialize char arrays like we do all other arrays. That is, we write
|
||||
// every element.
|
||||
serialize(length, *fout);
|
||||
fout->write(item, length);
|
||||
return *this;
|
||||
}
|
||||
|
||||
proxy_serialize& operator<<(const char* item)
|
||||
{
|
||||
// We serialize literal strings the same way we serialize std::string, that is,
|
||||
// we write the data but no trailing 0 byte.
|
||||
serialize(item, *fout);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
shared_ptr<std::ofstream> fout;
|
||||
};
|
||||
|
@ -953,14 +953,15 @@ namespace
|
||||
buf[4] = 3;
|
||||
buf[5] = 3;
|
||||
|
||||
dlib::serialize("ser_test_string.dat") << str1 << buf << "morestuff";
|
||||
dlib::serialize("ser_test_string.dat") << str1 << buf << "morestuff" << "";
|
||||
|
||||
string str2, str3;
|
||||
string str2, str3, str4;
|
||||
char buf2[6];
|
||||
memset(buf2,0,sizeof(buf2));
|
||||
dlib::deserialize("ser_test_string.dat") >> str2 >> buf2 >> str3;
|
||||
dlib::deserialize("ser_test_string.dat") >> str2 >> buf2 >> str3 >> str4;
|
||||
DLIB_TEST(str2 == "stuff");
|
||||
DLIB_TEST(str3 == "morestuff");
|
||||
DLIB_TEST(str4 == "");
|
||||
DLIB_TEST(buf2[0] == 0);
|
||||
DLIB_TEST(buf2[1] == 1);
|
||||
DLIB_TEST(buf2[2] == 2);
|
||||
|
Loading…
Reference in New Issue
Block a user