"git@developer.sourcefind.cn:OpenDAS/apex.git" did not exist on "59e992da71b678fbdbeb6181f8dd8fd81bdc495b"
Unverified Commit ab346ddf authored by pfeatherstone's avatar pfeatherstone Committed by GitHub
Browse files

Extended proxy_(de)serialize objects to work with stringstream, ostringstream,...


Extended proxy_(de)serialize objects to work with stringstream, ostringstream, istringstream and vector<char> (#2181)

* [DLIB] extended proxy objects to work with strinstream, istringstream, ostringstream and vector<char>

* [DLIB]  - use std::istream and std::ostream instead of std::istringstream, std::ostringstream and std::stringstream.
		- put back the filename member variable for better error messages

* [DLIB]  - review requirement
Co-authored-by: default avatarpf <pf@pf-ubuntu-dev>
parent fa818b9a
...@@ -203,6 +203,7 @@ ...@@ -203,6 +203,7 @@
#include "unicode.h" #include "unicode.h"
#include "byte_orderer.h" #include "byte_orderer.h"
#include "float_details.h" #include "float_details.h"
#include "vectorstream.h"
namespace dlib namespace dlib
{ {
...@@ -1588,40 +1589,66 @@ namespace dlib ...@@ -1588,40 +1589,66 @@ namespace dlib
public: public:
explicit proxy_serialize ( explicit proxy_serialize (
const std::string& filename const std::string& filename
) ) : fout_optional_owning_ptr(new std::ofstream(filename.c_str(), std::ios::binary)),
fout(*fout_optional_owning_ptr)
{ {
fout.reset(new std::ofstream(filename.c_str(), std::ios::binary)); if (!fout)
if (!(*fout))
throw serialization_error("Unable to open " + filename + " for writing."); throw serialization_error("Unable to open " + filename + " for writing.");
} }
explicit proxy_serialize (
std::vector<char>& buf
) : fout_optional_owning_ptr(new vectorstream(buf)),
fout(*fout_optional_owning_ptr)
{
}
explicit proxy_serialize (
std::ostream& ss
) : fout_optional_owning_ptr(nullptr),
fout(ss)
{}
template <typename T> template <typename T>
inline proxy_serialize& operator<<(const T& item) inline proxy_serialize& operator<<(const T& item)
{ {
serialize(item, *fout); serialize(item, fout);
return *this; return *this;
} }
private: private:
std::shared_ptr<std::ofstream> fout; std::unique_ptr<std::ostream> fout_optional_owning_ptr;
std::ostream& fout;
}; };
class proxy_deserialize class proxy_deserialize
{ {
public: public:
explicit proxy_deserialize ( explicit proxy_deserialize (
const std::string& filename const std::string& filename_
) : filename(filename) ) : filename(filename_),
fin_optional_owning_ptr(new std::ifstream(filename.c_str(), std::ios::binary)),
fin(*fin_optional_owning_ptr)
{ {
fin.reset(new std::ifstream(filename.c_str(), std::ios::binary)); if (!fin)
if (!(*fin))
throw serialization_error("Unable to open " + filename + " for reading."); throw serialization_error("Unable to open " + filename + " for reading.");
init();
}
// read the file header into a buffer and then seek back to the start of the explicit proxy_deserialize (
// file. std::vector<char>& buf
fin->read(file_header,4); ) : fin_optional_owning_ptr(new vectorstream(buf)),
fin->clear(); fin(*fin_optional_owning_ptr)
fin->seekg(0); {
init();
}
explicit proxy_deserialize (
std::istream& ss
) : fin_optional_owning_ptr(nullptr),
fin(ss)
{
init();
} }
template <typename T> template <typename T>
...@@ -1637,14 +1664,26 @@ namespace dlib ...@@ -1637,14 +1664,26 @@ namespace dlib
} }
private: private:
void init()
{
// read the file header into a buffer and then seek back to the start of the
// file.
fin.read(file_header,4);
fin.clear();
fin.seekg(0);
}
private:
template <typename T> template <typename T>
inline proxy_deserialize& doit(T&& item) inline proxy_deserialize& doit(T&& item)
{ {
try try
{ {
if (fin->peek() == EOF) if (fin.peek() == EOF)
throw serialization_error("No more objects were in the file!"); throw serialization_error("No more objects were in the stream!");
deserialize(std::forward<T>(item), *fin); deserialize(std::forward<T>(item), fin);
} }
catch (serialization_error& e) catch (serialization_error& e)
{ {
...@@ -1652,28 +1691,27 @@ namespace dlib ...@@ -1652,28 +1691,27 @@ namespace dlib
if (looks_like_a_compressed_file()) if (looks_like_a_compressed_file())
suffix = "\n *** THIS LOOKS LIKE A COMPRESSED FILE. DID YOU FORGET TO DECOMPRESS IT? *** \n"; suffix = "\n *** THIS LOOKS LIKE A COMPRESSED FILE. DID YOU FORGET TO DECOMPRESS IT? *** \n";
const std::string stream_description = filename.empty() ? "stream" : "file '" + filename + "'";
if (objects_read == 0) if (objects_read == 0)
{ {
throw serialization_error("An error occurred while trying to read the first" throw serialization_error("An error occurred while trying to read the first"
" object from the file " + filename + ".\nERROR: " + e.info + "\n" + suffix); " object from the " + stream_description + ".\nERROR: " + e.info + "\n" + suffix);
} }
else if (objects_read == 1) else if (objects_read == 1)
{ {
throw serialization_error("An error occurred while trying to read the second" throw serialization_error("An error occurred while trying to read the second"
" object from the file " + filename + " object from the " + stream_description + ".\nERROR: " + e.info + "\n" + suffix);
".\nERROR: " + e.info + "\n" + suffix);
} }
else if (objects_read == 2) else if (objects_read == 2)
{ {
throw serialization_error("An error occurred while trying to read the third" throw serialization_error("An error occurred while trying to read the third"
" object from the file " + filename + " object from the " + stream_description + ".\nERROR: " + e.info + "\n" + suffix);
".\nERROR: " + e.info + "\n" + suffix);
} }
else else
{ {
throw serialization_error("An error occurred while trying to read the " + throw serialization_error("An error occurred while trying to read the " +
std::to_string(objects_read+1) + "th object from the file " + filename + std::to_string(objects_read+1) + "th object from the " + stream_description + ".\nERROR: " + e.info + "\n" + suffix);
".\nERROR: " + e.info + "\n" + suffix);
} }
} }
++objects_read; ++objects_read;
...@@ -1681,8 +1719,9 @@ namespace dlib ...@@ -1681,8 +1719,9 @@ namespace dlib
} }
int objects_read = 0; int objects_read = 0;
std::string filename; const std::string filename = "";
std::shared_ptr<std::ifstream> fin; std::unique_ptr<std::istream> fin_optional_owning_ptr;
std::istream& fin;
// We don't need to look at the file header. However, it's here because people // We don't need to look at the file header. However, it's here because people
// keep posting questions to the dlib forums asking why they get file load errors. // keep posting questions to the dlib forums asking why they get file load errors.
...@@ -1708,8 +1747,16 @@ namespace dlib ...@@ -1708,8 +1747,16 @@ namespace dlib
inline proxy_serialize serialize(const std::string& filename) inline proxy_serialize serialize(const std::string& filename)
{ return proxy_serialize(filename); } { return proxy_serialize(filename); }
inline proxy_serialize serialize(std::ostream& ss)
{ return proxy_serialize(ss); }
inline proxy_serialize serialize(std::vector<char>& buf)
{ return proxy_serialize(buf); }
inline proxy_deserialize deserialize(const std::string& filename) inline proxy_deserialize deserialize(const std::string& filename)
{ return proxy_deserialize(filename); } { return proxy_deserialize(filename); }
inline proxy_deserialize deserialize(std::istream& ss)
{ return proxy_deserialize(ss); }
inline proxy_deserialize deserialize(std::vector<char>& buf)
{ return proxy_deserialize(buf); }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -1054,7 +1054,7 @@ namespace ...@@ -1054,7 +1054,7 @@ namespace
} }
} }
void test_macros() void test_macros_and_serializers()
{ {
my_custom_type t1, t2, t3, t4; my_custom_type t1, t2, t3, t4;
t1.a = 1; t1.a = 1;
...@@ -1069,6 +1069,7 @@ namespace ...@@ -1069,6 +1069,7 @@ namespace
v1.v.push_back(t1); v1.v.push_back(t1);
v1.v.push_back(t2); v1.v.push_back(t2);
{
dlib::serialize("serialization_test_macros.dat") << t1 << t2 << v1; dlib::serialize("serialization_test_macros.dat") << t1 << t2 << v1;
dlib::deserialize("serialization_test_macros.dat") >> t3 >> t4 >> v2; dlib::deserialize("serialization_test_macros.dat") >> t3 >> t4 >> v2;
...@@ -1077,6 +1078,38 @@ namespace ...@@ -1077,6 +1078,38 @@ namespace
DLIB_TEST(v1 == v2); DLIB_TEST(v1 == v2);
} }
{
std::stringstream ss;
dlib::serialize(ss) << t1 << t2 << v1;
dlib::deserialize(ss) >> t3 >> t4 >> v2;
DLIB_TEST(t1 == t3);
DLIB_TEST(t2 == t4);
DLIB_TEST(v1 == v2);
}
{
std::ostringstream sout;
dlib::serialize(sout) << t1 << t2 << v1;
std::istringstream sin(sout.str());
dlib::deserialize(sin) >> t3 >> t4 >> v2;
DLIB_TEST(t1 == t3);
DLIB_TEST(t2 == t4);
DLIB_TEST(v1 == v2);
}
{
std::vector<char> buf;
dlib::serialize(buf) << t1 << t2 << v1;
dlib::deserialize(buf) >> t3 >> t4 >> v2;
DLIB_TEST(t1 == t3);
DLIB_TEST(t2 == t4);
DLIB_TEST(v1 == v2);
}
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
class serialize_tester : public tester class serialize_tester : public tester
...@@ -1105,7 +1138,7 @@ namespace ...@@ -1105,7 +1138,7 @@ namespace
test_array2d_and_matrix_serialization(); test_array2d_and_matrix_serialization();
test_strings(); test_strings();
test_std_array(); test_std_array();
test_macros(); test_macros_and_serializers();
} }
} a; } a;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment