blob: 3f96f57152217f31e73f33550dacbf724129f518 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
// file : butl/fdstream -*- C++ -*-
// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
#ifndef BUTL_FDSTREAM
#define BUTL_FDSTREAM
#include <istream>
#include <ostream>
namespace butl
{
// An iostream that is initialized with a file descriptor rather than
// a file name.
//
// Notes and limitations:
//
// - char only
// - input or output but not both
// - no support for put back
// - throws std::system_error in case of a read()/write() error
// - not movable, though can be easily supported
//
class fdbuf: public std::basic_streambuf<char>
{
public:
virtual
~fdbuf ();
fdbuf () = default;
fdbuf (int fd) {open (fd);}
fdbuf (const fdbuf&) = delete;
fdbuf& operator= (const fdbuf&) = delete;
void
close ();
void
open (int fd);
bool
is_open () const {return fd_ != -1;}
public:
using int_type = std::basic_streambuf<char>::int_type;
using traits_type = std::basic_streambuf<char>::traits_type;
// basic_streambuf input interface.
//
public:
virtual std::streamsize
showmanyc ();
virtual int_type
underflow ();
private:
bool
load ();
// basic_streambuf output interface.
//
public:
virtual int_type
overflow (int_type);
virtual int
sync ();
private:
bool
save ();
private:
int fd_ = -1;
char buf_[2048];
};
class fdstream_base
{
protected:
fdstream_base () = default;
fdstream_base (int fd): buf_ (fd) {}
protected:
fdbuf buf_;
};
class ifdstream: fdstream_base, public std::istream
{
public:
ifdstream (): std::istream (&buf_) {}
ifdstream (int fd): fdstream_base (fd), std::istream (&buf_) {}
void close () {buf_.close ();}
void open (int fd) {buf_.open (fd);}
bool is_open () const {return buf_.is_open ();}
};
class ofdstream: fdstream_base, public std::ostream
{
public:
ofdstream (): std::ostream (&buf_) {}
ofdstream (int fd): fdstream_base (fd), std::ostream (&buf_) {}
void close () {flush (); buf_.close ();}
void open (int fd) {buf_.open (fd);}
bool is_open () const {return buf_.is_open ();}
};
}
#endif // BUTL_FDSTREAM
|