dlib C++ Library - vectorstream.h

// 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"
#include "../assert.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
 {
 template<typename CharType>
 class vector_streambuf : public std::streambuf
 {
 typedef typename std::vector<CharType>::size_type size_type;
 size_type read_pos = 0; // buffer[read_pos] == next byte to read from buffer
 public:
 std::vector<CharType>& buffer;
 vector_streambuf(
 std::vector<CharType>& buffer_
 ) :
 read_pos(0),
 buffer(buffer_) 
 {}
 void seekg(size_type pos)
 {
 read_pos = pos;
 }
 pos_type seekpos(pos_type pos, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
 {
 return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode);
 }
 pos_type seekoff(off_type off, std::ios_base::seekdir dir,
 std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out )
 {
 DLIB_CASSERT(mode == std::ios_base::in, "vectorstream does not support std::ios_base::out");
 switch (dir)
 {
 case std::ios_base::beg:
 read_pos = off;
 break;
 case std::ios_base::cur:
 read_pos += off;
 break;
 case std::ios_base::end:
 read_pos = buffer.size() + off;
 break;
 default:
 break;
 }
 return pos_type(read_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 auto 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(0),
 buf1(buffer),
 buf2(dummy2),
 buf3(dummy3)
 {
 rdbuf(&buf1);
 }
 
 vectorstream (
 std::vector<int8_t>& buffer
 ) : std::iostream(0),
 buf1(dummy1),
 buf2(buffer),
 buf3(dummy3)
 {
 rdbuf(&buf2);
 }
 
 vectorstream (
 std::vector<uint8_t>& buffer
 ) : std::iostream(0),
 buf1(dummy1),
 buf2(dummy2),
 buf3(buffer)
 {
 rdbuf(&buf3);
 }
 
 vectorstream(const vectorstream& ori) = delete;
 vectorstream(vectorstream&& item) = delete;
 
 private:
 std::vector<char> dummy1;
 std::vector<int8_t> dummy2;
 std::vector<uint8_t> dummy3;
 vector_streambuf<char> buf1;
 vector_streambuf<int8_t> buf2;
 vector_streambuf<uint8_t> buf3;
 };
}
#endif // DLIB_VECTORStREAM_Hh_

AltStyle によって変換されたページ (->オリジナル) /