VirtualBox

source: vbox/trunk/include/iprt/nocrt/ostream@ 98103

Last change on this file since 98103 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
Line 
1/** @file
2 * IPRT / No-CRT - Minimal C++ ostream header.
3 */
4
5/*
6 * Copyright (C) 2022-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef VBOX_INCLUDED_SRC_nocrt_ostream
37#define VBOX_INCLUDED_SRC_nocrt_ostream
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42/* Currently all in the ios header. */
43#include <iprt/nocrt/ios>
44
45namespace std
46{
47 /**
48 * Basic output stream.
49 */
50 template<typename a_CharType, typename a_CharTraits /*= std::char_traits<a_CharType>*/ >
51 class basic_ostream : public basic_ios<a_CharType, a_CharTraits>
52 {
53 protected:
54 /** Sentry class that performs pre and post output work. */
55 class sentry
56 {
57 private:
58 basic_ostream &m_rParent;
59
60 public:
61 explicit sentry(basic_ostream &a_rParent)
62 : m_rParent(a_rParent)
63 {
64 if (a_rParent.good())
65 {
66 basic_ostream *pTiedStream = a_rParent.tie();
67 if (!pTiedStream)
68 { /* likely? */ }
69 else
70 {
71 pTiedStream->flush();
72 if (!pTiedStream->good())
73 a_rParent.setstate(failbit);
74 }
75 }
76 }
77
78 explicit operator bool() const
79 {
80 return m_rParent.good();
81 }
82
83 ~sentry()
84 {
85 if ( (m_rParent.flags() & std::ios_base::unitbuf)
86 && m_rParent.good())
87 m_rParent.rdbuf()->pubsync();
88 }
89 };
90
91 public:
92 explicit basic_ostream(std::basic_streambuf<a_CharType,a_CharTraits> *a_pBuf)
93 : basic_ios(a_pBuf)
94 { }
95
96 /** For cerr initialization.
97 * @internal */
98 explicit basic_ostream(std::basic_streambuf<a_CharType,a_CharTraits> *a_pBuf,
99 std::basic_ostream<a_CharType, a_CharTraits> *a_pTiedStream,
100 bool a_fUnbuffered)
101 : basic_ios(a_pBuf)
102 {
103 m_pTiedStream = a_pTiedStream;
104 if (!a_fUnbuffered)
105 setf(std::ios_base::unitbuf);
106 }
107
108 private:
109 basic_ostream(basic_ostream const &a_rSrc); /* not copyable */
110 basic_ostream &operator=(basic_ostream const &a_rSrc); /* not copyable */
111
112 public:
113 virtual ~basic_ostream()
114 {
115 }
116
117 public:
118 basic_ostream &put(char_type a_ch)
119 {
120 sentry PrePost(*this);
121 if (PrePost)
122 {
123 if (m_pBuf->sputc(a_ch) == traits_type::eof())
124 m_fState |= badbit;
125 }
126 return *this;
127 }
128
129 basic_ostream &write(const char_type *a_pchSrc, std::streamsize a_cchToWrite)
130 {
131 sentry PrePost(*this);
132 if (PrePost)
133 {
134 std::streamsize cchWritten = m_pBuf->sputn(a_pchSrc, a_cchToWrite);
135 if (cchWritten != a_cchToWrite)
136 m_fState |= badbit;
137 }
138 return *this;
139 }
140
141 basic_ostream &flush()
142 {
143 if (m_pBuf)
144 m_pBuf->pubsync();
145 return *this;
146 }
147
148 pos_type tellp() RT_NOEXCEPT;
149 basic_ostream &seekp(pos_type a_off) RT_NOEXCEPT;
150 basic_ostream &seekp(off_type a_off, seekdir enmDir) RT_NOEXCEPT;
151
152 /** @name Internal support methods
153 * @{ */
154 inline basic_ostream &intWrite(const char *a_pchSrc, std::streamsize a_cchToWrite); /**< Internal method outputting char buffers. */
155
156 /** @returns 8, 10 or 16. */
157 inline unsigned intGetIntegerBase() const RT_NOEXCEPT
158 {
159 switch (m_fFlags & basefield)
160 {
161 default:
162 case dec: return 10;
163 case hex: return 16;
164 case oct: return 8;
165 }
166 }
167
168 /** @returns RTSTR_F_XXX . */
169 inline unsigned intGetIntegerFlags() const RT_NOEXCEPT
170 {
171 unsigned fFlags = 0;
172 if (m_fFlags & uppercase)
173 fFlags |= RTSTR_F_CAPITAL;
174 if (m_fFlags & showbase)
175 fFlags |= RTSTR_F_SPECIAL;
176 if (m_fFlags & showpos)
177 fFlags |= RTSTR_F_PLUS;
178 return fFlags;
179 }
180
181 basic_ostream &formatInteger(uint64_t a_uValue, uint32_t a_fFlags, unsigned a_uBase = 0)
182 {
183 a_fFlags |= intGetIntegerFlags();
184 char szTmp[72];
185 int cchTmp = RTStrFormatNumber(szTmp, a_uValue, !a_uBase ? intGetIntegerBase() : a_uBase, 0, 0, a_fFlags);
186
187 /** @todo apply cchWidth and padding. */
188
189 return intWrite(szTmp, cchTmp);
190 }
191
192 /** @} */
193 };
194
195 /** @name Character and string output.
196 * @{ */
197 /** @todo not sure if this really works... */
198 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
199 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, char a_ch)
200 {
201 return a_rDst.put(a_ch);
202 }
203
204 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
205 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, const char *a_psz)
206 {
207 return a_rDst.intWrite(a_psz, strlen(a_psz));
208 }
209 /** @} */
210
211 /** @name Integer formatting.
212 * @{ */
213 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
214 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, signed char a_iValue)
215 {
216 return a_rDst.formatInteger(a_iValue, RTSTR_F_8BIT | RTSTR_F_VALSIGNED);
217 }
218
219 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
220 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned char a_uValue)
221 {
222 return a_rDst.formatInteger(a_uValue, RTSTR_F_8BIT);
223 }
224
225 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
226 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, short a_iValue)
227 {
228 return a_rDst.formatInteger(a_iValue, RTSTR_F_16BIT | RTSTR_F_VALSIGNED);
229 }
230
231 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
232 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned short a_uValue)
233 {
234 return a_rDst.formatInteger(a_uValue, RTSTR_F_16BIT);
235 }
236
237 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
238 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, int a_iValue)
239 {
240 return a_rDst.formatInteger(a_iValue, RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
241 }
242
243 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
244 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned int a_uValue)
245 {
246 return a_rDst.formatInteger(a_uValue, RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
247 }
248
249 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
250 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, long a_iValue)
251 {
252 return a_rDst.formatInteger(a_iValue, (sizeof(a_iValue) > sizeof(int32_t) ? RTSTR_F_64BIT : RTSTR_F_32BIT));
253 }
254
255 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
256 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned long a_uValue)
257 {
258 return a_rDst.formatInteger(a_uValue,
259 RTSTR_F_VALSIGNED | (sizeof(a_uValue) > sizeof(uint32_t) ? RTSTR_F_64BIT : RTSTR_F_32BIT));
260 }
261
262 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
263 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, void const *a_pvValue)
264 {
265 return a_rDst.formatInteger((uintptr_t)a_pvValue,
266 (sizeof(a_pvValue) > sizeof(uint32_t) ? RTSTR_F_64BIT : RTSTR_F_32BIT), 16);
267 }
268 /** @} */
269
270 template<>
271 inline basic_ostream<char> &basic_ostream<char>::intWrite(const char *a_pchSrc, std::streamsize a_cchToWrite)
272 {
273 return write(a_pchSrc, a_cchToWrite);
274 }
275
276
277}
278
279#endif /* !VBOX_INCLUDED_SRC_nocrt_ostream */
280
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette