E-MailRelay
gomembuf.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 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
28namespace G
29{
30 template <typename Tchar> class basic_omembuf ;
31 using omembuf = basic_omembuf<char> ;
32 using womembuf = basic_omembuf<wchar_t> ;
33}
34
35//| \class G::basic_omembuf
36/// An output streambuf that writes to a fixed-size char buffer.
37/// Does not support seeking.
38///
39/// Eg:
40/// \code
41/// std::array<char,10> buffer ;
42/// G::basic_omembuf<char> sb( buffer.data() , buffer.size() ) ;
43/// std::ostream out( &sb ) ;
44/// \endcode
45///
46/// An alternative approach is to use std::ostringstream with
47/// pubsetbuf() but there is no guarantee that the std::stringbuf
48/// implementation has a useful override of setbuf() (ie. msvc).
49///
50template <typename Tchar>
51class G::basic_omembuf : public std::basic_streambuf<Tchar,std::char_traits<Tchar>>
52{
53public:
54 using base_type = std::basic_streambuf<Tchar,std::char_traits<Tchar>> ;
55
56 basic_omembuf( Tchar * p , std::size_t n ) ;
57 ///< Constructor.
58
59private: // overrides
60 std::streambuf * setbuf( Tchar * p , std::streamsize n ) override ;
61 ///< Overridden because we can. Called by streambuf::pubsetbuf().
62
63 std::streampos seekoff( std::streamoff , std::ios_base::seekdir , std::ios_base::openmode ) override ;
64 ///< Overridden with only a partial implementation for tellp(),
65 ///< so not fully seekable. Called by streambuf::pubseekoff(),
66 ///< streambuf::tellp() etc.
67
68 std::streampos seekpos( std::streampos , std::ios_base::openmode ) override ;
69 ///< Overridden with only a partial implementation for seekp(0),
70 ///< so not fully seekable. Called by streambuf::pubseekpos().
71
72 std::streamsize xsputn( const Tchar * p , std::streamsize n ) override ;
73 ///< Overridden for efficiency compared to multiple sputc()s.
74 ///< Called by streambuf::sputn().
75
76public:
77 ~basic_omembuf() override = default ;
78 basic_omembuf( const basic_omembuf<Tchar> & ) = delete ;
79 basic_omembuf( basic_omembuf<Tchar> && ) = delete ;
80 basic_omembuf<Tchar> & operator=( const basic_omembuf<Tchar> & ) = delete ;
81 basic_omembuf<Tchar> & operator=( basic_omembuf<Tchar> && ) = delete ;
82} ;
83
84template <typename Tchar>
85G::basic_omembuf<Tchar>::basic_omembuf( Tchar * p , std::size_t n )
86{
87 base_type::setp( p , p+n ) ;
88}
89
90template <typename Tchar>
91std::streambuf * G::basic_omembuf<Tchar>::setbuf( Tchar * p , std::streamsize n )
92{
93 base_type::setp( p , p+n ) ;
94 return this ;
95}
96
97template <typename Tchar>
98std::streampos G::basic_omembuf<Tchar>::seekoff( std::streamoff off , std::ios_base::seekdir way , std::ios_base::openmode which )
99{
100 if( off == 0 && way == std::ios_base::cur && ( which & std::ios_base::out ) ) // NOLINT
101 return base_type::pptr() - base_type::pbase() ;
102 else
103 return -1 ;
104}
105
106template <typename Tchar>
107std::streampos G::basic_omembuf<Tchar>::seekpos( std::streampos pos , std::ios_base::openmode which )
108{
109 if( pos == 0 && ( which & std::ios_base::out ) ) // NOLINT
110 {
111 base_type::setp( base_type::pbase() , base_type::epptr() ) ;
112 return 0 ;
113 }
114 else
115 {
116 return -1 ;
117 }
118}
119
120template <typename Tchar>
121std::streamsize G::basic_omembuf<Tchar>::xsputn( const Tchar * p , std::streamsize n )
122{
123 Tchar * start = base_type::pptr() ;
124 if( start == nullptr ) return 0 ;
125 std::streamsize space = base_type::epptr() - start ;
126 std::streamsize ncopy = std::min( space , n ) ;
127 std::copy_n( p , static_cast<std::size_t>(ncopy) , start ) ;
128 base_type::pbump( static_cast<int>(ncopy) ) ;
129 return ncopy ;
130}
131
132#endif
An output streambuf that writes to a fixed-size char buffer.
Definition: gomembuf.h:52
basic_omembuf(Tchar *p, std::size_t n)
Constructor.
Definition: gomembuf.h:85
Low-level classes.
Definition: garg.h:36