diff options
Diffstat (limited to 'ml/dlib/dlib/vectorstream')
-rw-r--r-- | ml/dlib/dlib/vectorstream/unserialize.h | 98 | ||||
-rw-r--r-- | ml/dlib/dlib/vectorstream/unserialize_abstract.h | 58 | ||||
-rw-r--r-- | ml/dlib/dlib/vectorstream/vectorstream.h | 138 | ||||
-rw-r--r-- | ml/dlib/dlib/vectorstream/vectorstream_abstract.h | 62 |
4 files changed, 356 insertions, 0 deletions
diff --git a/ml/dlib/dlib/vectorstream/unserialize.h b/ml/dlib/dlib/vectorstream/unserialize.h new file mode 100644 index 000000000..dbfe5584b --- /dev/null +++ b/ml/dlib/dlib/vectorstream/unserialize.h @@ -0,0 +1,98 @@ +// Copyright (C) 2016 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_uNSERIALIZE_Hh_ +#define DLIB_uNSERIALIZE_Hh_ + +#include "unserialize_abstract.h" + +#include "../serialize.h" +#include "../algs.h" +#include "vectorstream.h" + + + +namespace dlib +{ + class unserialize : public std::istream + { + class mystreambuf : public std::streambuf + { + typedef std::vector<char>::size_type size_type; + size_type read_pos; // buffer[read_pos] == next byte to read from buffer + public: + std::vector<char> buffer; + std::istream& str; + + template <typename T> + mystreambuf( + const T& item, + std::istream& str_ + ) : + read_pos(0), + str(str_) + { + // put the item into our buffer. + vectorstream vstr(buffer); + serialize(item, vstr); + } + + + // ------------------------ INPUT FUNCTIONS ------------------------ + + int_type underflow( + ) + { + if (read_pos < buffer.size()) + return static_cast<unsigned char>(buffer[read_pos]); + else + return str.peek(); + } + + int_type uflow( + ) + { + if (read_pos < buffer.size()) + return static_cast<unsigned char>(buffer[read_pos++]); + else + return str.get(); + } + + std::streamsize xsgetn ( + char* s, + std::streamsize n + ) + { + if (read_pos < buffer.size()) + { + const size_type num = std::min<size_type>(n, buffer.size()-read_pos); + std::memcpy(s, &buffer[read_pos], num); + read_pos += num; + return num; + } + else + { + return str.rdbuf()->sgetn(s,n); + } + return 0; + } + + }; + + public: + + template <typename T> + unserialize ( + const T& item, + std::istream& str + ) : + std::istream(&buf), + buf(item, str) + {} + + private: + mystreambuf buf; + }; +} + +#endif // DLIB_uNSERIALIZE_Hh_ + diff --git a/ml/dlib/dlib/vectorstream/unserialize_abstract.h b/ml/dlib/dlib/vectorstream/unserialize_abstract.h new file mode 100644 index 000000000..b7d67836c --- /dev/null +++ b/ml/dlib/dlib/vectorstream/unserialize_abstract.h @@ -0,0 +1,58 @@ +// Copyright (C) 2016 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#undef DLIB_uNSERIALIZE_ABSTRACT_Hh_ +#ifdef DLIB_uNSERIALIZE_ABSTRACT_Hh_ + +#include "../serialize.h" +#include <iostream> + +namespace dlib +{ + class unserialize : public std::istream + { + /*! + WHAT THIS OBJECT REPRESENTS + This is a tool that allows you to effectively put an object you just + deserialized from a stream back into the stream. Its use is best + illustrated via an example. + + void example(std::istream& in) + { + // Suppose that in contains serialized copies of three "some_type" + // objects. You could read them as follows: + some_type obj1, obj2, obj3; + + deserialize(obj1, in); // reads obj1 from stream. + deserialize(obj2, in); // reads obj2 from stream. + + unserialize in2(obj2, in); // make the in2 stream that has obj2 at its front. + deserialize(obj2, in2); // reads obj2 from stream again. + deserialize(obj3, in2); // reads obj3 from stream. + } + + The reason unserialize is useful is because it allows you to peek at the + next object in a stream and potentially do something different based on + what object is coming next, but still allowing subsequent deserialize() + statements to be undisturbed by the fact that you peeked at the data. + !*/ + + public: + + template <typename T> + unserialize ( + const T& item, + std::istream& in + ); + /*! + requires + - T must be serializable + ensures + - The bytes in this stream begin with a serialized copy of item followed + immediately by the bytes in the given istream. + !*/ + }; +} + +#endif // DLIB_uNSERIALIZE_ABSTRACT_Hh_ + + diff --git a/ml/dlib/dlib/vectorstream/vectorstream.h b/ml/dlib/dlib/vectorstream/vectorstream.h new file mode 100644 index 000000000..a1b7b8b07 --- /dev/null +++ b/ml/dlib/dlib/vectorstream/vectorstream.h @@ -0,0 +1,138 @@ +// Copyright (C) 2012 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_VECTORStREAM_Hh_ +#define DLIB_VECTORStREAM_Hh_ + +#include "vectorstream_abstract.h" + +#include <cstring> +#include <iostream> +#include <streambuf> +#include <vector> +#include <cstdio> +#include "../algs.h" + + +#ifdef _MSC_VER +// Disable the warning about inheriting from std::iostream 'via dominance' since this warning is a warning about +// visual studio conforming to the standard and is ignorable. See http://connect.microsoft.com/VisualStudio/feedback/details/733720/inheriting-from-std-fstream-produces-c4250-warning +// for further details if interested. +#pragma warning(disable : 4250) +#endif // _MSC_VER + +namespace dlib +{ + class vectorstream : public std::iostream + { + class vector_streambuf : public std::streambuf + { + typedef std::vector<char>::size_type size_type; + size_type read_pos; // buffer[read_pos] == next byte to read from buffer + public: + std::vector<char>& buffer; + + vector_streambuf( + std::vector<char>& buffer_ + ) : + read_pos(0), + buffer(buffer_) + {} + + + void seekg(size_type pos) + { + read_pos = pos; + } + + // ------------------------ OUTPUT FUNCTIONS ------------------------ + + int_type overflow ( int_type c) + { + if (c != EOF) buffer.push_back(static_cast<char>(c)); + return c; + } + + std::streamsize xsputn ( const char* s, std::streamsize num) + { + buffer.insert(buffer.end(), s, s+num); + return num; + } + + // ------------------------ INPUT FUNCTIONS ------------------------ + + int_type underflow( + ) + { + if (read_pos < buffer.size()) + return static_cast<unsigned char>(buffer[read_pos]); + else + return EOF; + } + + int_type uflow( + ) + { + if (read_pos < buffer.size()) + return static_cast<unsigned char>(buffer[read_pos++]); + else + return EOF; + } + + int_type pbackfail( + int_type c + ) + { + // if they are trying to push back a character that they didn't read last + // that is an error + const unsigned long prev = read_pos-1; + if (c != EOF && prev < buffer.size() && + c != static_cast<unsigned char>(buffer[prev])) + { + return EOF; + } + + read_pos = prev; + return 1; + } + + std::streamsize xsgetn ( + char* s, + std::streamsize n + ) + { + if (read_pos < buffer.size()) + { + const size_type num = std::min<size_type>(n, buffer.size()-read_pos); + std::memcpy(s, &buffer[read_pos], num); + read_pos += num; + return num; + } + return 0; + } + + }; + + public: + + vectorstream ( + std::vector<char>& buffer + ) : + std::iostream(&buf), + buf(buffer) + {} + + std::istream& seekg ( + std::streampos pos + ) + { + buf.seekg(pos); + return *this; + } + + private: + vector_streambuf buf; + }; +} + +#endif // DLIB_VECTORStREAM_Hh_ + diff --git a/ml/dlib/dlib/vectorstream/vectorstream_abstract.h b/ml/dlib/dlib/vectorstream/vectorstream_abstract.h new file mode 100644 index 000000000..f5fe1004c --- /dev/null +++ b/ml/dlib/dlib/vectorstream/vectorstream_abstract.h @@ -0,0 +1,62 @@ +// Copyright (C) 2012 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#undef DLIB_VECTORStREAM_ABSTRACT_Hh_ +#ifdef DLIB_VECTORStREAM_ABSTRACT_Hh_ + +#include <iostream> +#include <vector> + +namespace dlib +{ + class vectorstream : public std::iostream + { + /*! + WHAT THIS OBJECT REPRESENTS + This is an iostream object that reads and writes from an in-memory buffer. + It functions very much the same way as the std::stringstream object. + However, while the std::stringstream holds its buffer internally and it can + only be accessed by copying it out, the vectorstream uses an external + std::vector<char> as its buffer. That is, it holds a reference to an + external vector and does not contain any internal buffers of its own. + + This object is useful as a slightly more efficient alternative to the + std::stringstream since you can avoid the overhead of copying buffer + contents to and from the stream. This is particularly useful when used as + a source or target for serialization routines. + !*/ + + public: + + vectorstream ( + std::vector<char>& buffer + ); + /*! + ensures + - This object will use the given vector as its read/write buffer. That is: + - Any data written to this stream will be appended to the given buffer + - Any data read from this stream is read from the given buffer, + starting with buffer[0], then buffer[1], and so on. Just like + std::stringstream, writes to the stream do not move the position of + the next byte that will be read from the buffer. + - This constructor does not copy the buffer. Only a reference to it will + be used. Therefore, any time data is written to this stream it will + immediately show up in the buffer. + !*/ + + std::istream& seekg ( + std::streampos pos + ); + /*! + ensures + - The next read from this object will read from the position buffer[pos], + where buffer is the std::vector given to this object's constructor. Note + that if pos >= buffer.size() then the next read will simply return EOF. + - returns *this + !*/ + + }; +} + +#endif // DLIB_VECTORStREAM_ABSTRACT_Hh_ + + |