E-MailRelay
gomembuf.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gomembuf.h
19///
20
21#ifndef G_OMEMBUF_H
22#define G_OMEMBUF_H
23
24#include "gdef.h"
25#include <streambuf>
26#include <algorithm>
27#include <cstring>
28
29namespace G
30{
31 class omembuf ;
32}
33
34//| \class G::omembuf
35/// An output streambuf that writes to a fixed-size char buffer.
36/// Does not support seeking.
37///
38/// Eg:
39/// \code
40/// std::array<char,10> buffer ;
41/// G::omembuf sb( &buffer[0] , buffer.size() ) ;
42/// std::ostream out( &sb ) ;
43/// \endcode
44///
45/// An alternative approach is to use std::ostringstream with
46/// pubsetbuf() but there is no guarantee that the std::stringbuf
47/// implementation has a useful override of setbuf() (ie. msvc).
48///
49class G::omembuf : public std::streambuf
50{
51public:
52 omembuf( char * p , std::size_t n ) ;
53 ///< Constructor.
54
55private: // overrides
56 std::streambuf * setbuf( char * p , std::streamsize n ) override ;
57 ///< Overridden because we can. Called by streambuf::pubsetbuf().
58
59 std::streampos seekoff( std::streamoff , std::ios_base::seekdir , std::ios_base::openmode ) override ;
60 ///< Overridden with only a partial implementation for tellp(),
61 ///< so not fully seekable. Called by streambuf::pubseekoff(),
62 ///< streambuf::tellp() etc.
63
64 std::streampos seekpos( std::streampos , std::ios_base::openmode ) override ;
65 ///< Overridden with only a partial implementation for seekp(0),
66 ///< so not fully seekable. Called by streambuf::pubseekpos().
67
68 std::streamsize xsputn( const char * p , std::streamsize n ) override ;
69 ///< Overridden for efficiency compared to multiple sputc()s.
70 ///< Called by streambuf::sputn().
71
72public:
73 ~omembuf() override = default ;
74 omembuf( const omembuf & ) = delete ;
75 omembuf( omembuf && ) = delete ;
76 void operator=( const omembuf & ) = delete ;
77 void operator=( omembuf && ) = delete ;
78} ;
79
80inline
81G::omembuf::omembuf( char * p , std::size_t n )
82{
83 setp( p , p+n ) ;
84}
85
86inline
87std::streambuf * G::omembuf::setbuf( char * p , std::streamsize n )
88{
89 setp( p , p+n ) ;
90 return this ;
91}
92
93inline
94std::streampos G::omembuf::seekoff( std::streamoff off , std::ios_base::seekdir way , std::ios_base::openmode which )
95{
96 if( off == 0 && way == std::ios_base::cur && ( which & std::ios_base::out ) )
97 return pptr() - pbase() ;
98 else
99 return -1 ;
100}
101
102inline
103std::streampos G::omembuf::seekpos( std::streampos pos , std::ios_base::openmode which )
104{
105 if( pos == 0 && ( which & std::ios_base::out ) )
106 {
107 setp( pbase() , epptr() ) ;
108 return 0 ;
109 }
110 else
111 {
112 return -1 ;
113 }
114}
115
116inline
117std::streamsize G::omembuf::xsputn( const char * p , std::streamsize n )
118{
119 char * start = pptr() ;
120 if( start == nullptr ) return 0 ;
121 std::streamsize space = epptr() - start ;
122 std::streamsize ncopy = std::min( space , n ) ;
123 std::memcpy( start , p , static_cast<std::size_t>(ncopy) ) ;
124 pbump( static_cast<int>(ncopy) ) ;
125 return ncopy ;
126}
127
128#endif
An output streambuf that writes to a fixed-size char buffer.
Definition: gomembuf.h:50
omembuf(char *p, std::size_t n)
Constructor.
Definition: gomembuf.h:81
Low-level classes.
Definition: galign.h:28