Commit 45d21205 authored by Davis King's avatar Davis King

Added the vectorstream object.

parent 259a4542
// Copyright (C) 2012 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_VECTORSTReAM__
#define DLIB_VECTORSTReAM__
#include "vectorstream/vectorstream.h"
#endif // DLIB_VECTORSTReAM__
// Copyright (C) 2012 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_VECTORStREAM_H__
#define DLIB_VECTORStREAM_H__
#include "vectorstream_abstract.h"
#include <cstring>
#include <iostream>
#include <streambuf>
#include <vector>
#include <cstdio>
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_)
{}
// ------------------------ 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
)
{
const size_type num = std::min<size_type>(n, buffer.size()-read_pos);
if (num > 0)
{
std::memcpy(s, &buffer[read_pos], num);
read_pos += num;
}
return num;
}
};
public:
vectorstream (
std::vector<char>& buffer
) :
std::iostream(&buf),
buf(buffer)
{}
private:
vector_streambuf buf;
};
}
#endif // DLIB_VECTORStREAM_H__
// Copyright (C) 2012 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_VECTORStREAM_ABSTRACT_H__
#ifdef DLIB_VECTORStREAM_ABSTRACT_H__
#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.
!*/
};
}
#endif // DLIB_VECTORStREAM_ABSTRACT_H__
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