VirtualBox

source: vbox/trunk/include/iprt/nocrt/ios@ 99828

Last change on this file since 99828 was 99828, checked in by vboxsync, 19 months ago

*: A bunch of adjustments that allows using /permissive- with Visual C++ (qt 6.x necessity).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.8 KB
Line 
1/** @file
2 * IPRT / No-CRT - Minimal C++ ios 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_ios
37#define VBOX_INCLUDED_SRC_nocrt_ios
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/nocrt/iosfwd>
43#include <iprt/nocrt/string>
44
45/** @todo something for cdecl.h */
46#define RTNOCRT_IOS_ENUM_BIT_OPS(a_EnumType, a_IntType) \
47 inline a_EnumType operator~(a_EnumType a_fLeft) RT_NOEXCEPT \
48 { return a_EnumType(~static_cast<a_IntType>(a_fLeft)); } \
49 \
50 inline a_EnumType operator&(a_EnumType a_fLeft, a_EnumType a_fRight) RT_NOEXCEPT \
51 { return a_EnumType(static_cast<a_IntType>(a_fLeft) & static_cast<a_IntType>(a_fRight)); } \
52 inline a_EnumType operator|(a_EnumType a_fLeft, a_EnumType a_fRight) RT_NOEXCEPT \
53 { return a_EnumType(static_cast<a_IntType>(a_fLeft) | static_cast<a_IntType>(a_fRight)); } \
54 inline a_EnumType operator^(a_EnumType a_fLeft, a_EnumType a_fRight) RT_NOEXCEPT \
55 { return a_EnumType(static_cast<a_IntType>(a_fLeft) ^ static_cast<a_IntType>(a_fRight)); } \
56 \
57 inline const a_EnumType &operator&=(a_EnumType &a_rfLeft, a_EnumType a_fRight) RT_NOEXCEPT \
58 { return a_rfLeft = a_rfLeft & a_fRight; } \
59 inline const a_EnumType &operator|=(a_EnumType &a_rfLeft, a_EnumType a_fRight) RT_NOEXCEPT \
60 { return a_rfLeft = a_rfLeft | a_fRight; } \
61 inline const a_EnumType &operator^=(a_EnumType &a_rfLeft, a_EnumType a_fRight) RT_NOEXCEPT \
62 { return a_rfLeft = a_rfLeft ^ a_fRight; } \
63
64namespace std
65{
66 typedef ptrdiff_t streamsize;
67
68 /**
69 * I/O stream format flags.
70 */
71 class rtNoCrtIosEnums
72 {
73 public:
74 enum fmtflags
75 {
76 /* int: */
77 dec = 0x00000001,
78 oct = 0x00000002,
79 hex = 0x00000004,
80 basefield = 0x00000007,
81 /* float: */
82 scientific = 0x00000010,
83 fixed = 0x00000020,
84 floatfield = 0x00000030,
85 /* int and float output tweaks: */
86 showbase = 0x00000100,
87 showpoint = 0x00000200,
88 showpos = 0x00000400,
89 /* bool: */
90 boolalpha = 0x00000800,
91 /* adjustment: */
92 left = 0x00001000,
93 right = 0x00002000,
94 internal = 0x00004000,
95 adjustfield = 0x00007000,
96 /* misc: */
97 skipws = 0x00010000,
98 unitbuf = 0x00020000,
99 uppercase = 0x00040000,
100 };
101
102 enum seekdir
103 {
104 beg = 1,
105 end,
106 cur,
107 };
108
109 enum openmode
110 {
111 app = 1,
112 binary,
113 in,
114 out,
115 trunc,
116 ate
117 };
118
119 enum iostate
120 {
121 goodbit = 0,
122 badbit = 1,
123 failbit = 2,
124 eofbit = 4
125 };
126 };
127 RTNOCRT_IOS_ENUM_BIT_OPS(rtNoCrtIosEnums::fmtflags, int)
128 RTNOCRT_IOS_ENUM_BIT_OPS(rtNoCrtIosEnums::seekdir, int)
129 RTNOCRT_IOS_ENUM_BIT_OPS(rtNoCrtIosEnums::openmode, int)
130 RTNOCRT_IOS_ENUM_BIT_OPS(rtNoCrtIosEnums::iostate, int)
131
132
133 /**
134 * I/O stream base class.
135 */
136 class ios_base : public rtNoCrtIosEnums
137 {
138 public:
139 //typedef rtNoCrtIosFmtFlags fmtflags;
140 //typedef rtNoCrtIosSeekDir seekdir;
141 //typedef rtNoCrtIosOpenMode openmode;
142 //typedef rtNoCrtIosState iostate;
143
144 protected:
145 streamsize m_cWidth;
146 streamsize m_cPrecision;
147 fmtflags m_fFlags;
148 iostate m_fState;
149
150 protected:
151 ios_base()
152 : m_cWidth(0)
153 , m_cPrecision(0)
154 , m_fFlags(dec | skipws)
155 , m_fState(goodbit)
156 {
157 }
158 private:
159 ios_base(const ios_base &); /* not copyable */
160 ios_base &operator=(const ios_base &); /* not copyable */
161
162 public:
163 virtual ~ios_base()
164 {
165 }
166
167 streamsize width() const RT_NOEXCEPT
168 {
169 return m_cWidth;
170 }
171
172 streamsize width(streamsize a_cWidth) RT_NOEXCEPT
173 {
174 streamsize cOldWidth = m_cWidth;
175 m_cWidth = a_cWidth;
176 return cOldWidth;
177 }
178
179 streamsize precision() const RT_NOEXCEPT
180 {
181 return m_cPrecision;
182 }
183
184 streamsize precision(streamsize a_cPrecision) RT_NOEXCEPT
185 {
186 streamsize cOldPrecision = m_cPrecision;
187 m_cPrecision = a_cPrecision;
188 return cOldPrecision;
189 }
190
191 fmtflags flags() const RT_NOEXCEPT
192 {
193 return m_fFlags;
194 }
195
196 fmtflags flags(fmtflags a_fNew) RT_NOEXCEPT
197 {
198 fmtflags const fOld = m_fFlags;
199 m_fFlags = a_fNew;
200 return fOld;
201 }
202
203 fmtflags setf(fmtflags a_fAdd) RT_NOEXCEPT
204 {
205 fmtflags const fOld = m_fFlags;
206 m_fFlags = static_cast<fmtflags>(fOld | a_fAdd);
207 return fOld;
208 }
209
210 fmtflags setf(fmtflags a_fAdd, fmtflags a_fMask) RT_NOEXCEPT
211 {
212 fmtflags const fOld = m_fFlags;
213 m_fFlags = static_cast<fmtflags>((fOld & ~a_fMask) | (a_fAdd & a_fMask));
214 return fOld;
215 }
216
217 void unsetf(fmtflags a_fClear) RT_NOEXCEPT
218 {
219 m_fFlags = static_cast<fmtflags>(m_fFlags & ~a_fClear);
220 }
221 };
222
223
224 /**
225 * Stream buffer.
226 */
227 template<typename a_CharType, typename a_CharTraits /*= std::char_traits<a_CharType>*/ >
228 class basic_streambuf
229 {
230 public:
231 typedef a_CharType char_type;
232 typedef a_CharTraits traits_type;
233 typedef typename a_CharTraits::int_type int_type;
234 typedef typename a_CharTraits::pos_type pos_type;
235 typedef typename a_CharTraits::off_type off_type;
236
237 protected:
238 /** @name Put buffering
239 * @{ */
240 char_type *m_pachPut; /**< The put buffer pointer. */
241 std::size_t m_cchPut; /**< Put buffer size. */
242 std::size_t m_offPutNext; /**< The current put buffer position (where to write next). */
243 std::size_t m_offPutStart; /**< Where the buffered put sequence starts. */
244
245 void setp(char_type *a_pachNewBuf, char_type *a_pachNewBufEnd)
246 {
247 Assert((uintptr_t)a_pachNewBuf <= (uintptr_t)a_pachNewBufEnd);
248 m_pachPut = a_pachNewBuf;
249 m_cchPut = static_cast<std::size_t>(a_pachNewBufEnd - a_pachNewBuf);
250 m_offPutNext = 0;
251 m_offPutStart = 0;
252 }
253
254 char_type *pbbase() const RT_NOEXCEPT
255 {
256 Assert(m_offPutNext >= m_offPutStart); Assert(m_offPutNext <= m_cchPut); Assert(m_offPutStart <= m_cchPut);
257 return &m_pachPut[m_offPutStart];
258 }
259
260 char_type *pptr() const RT_NOEXCEPT
261 {
262 Assert(m_offPutNext <= m_cchPut);
263 return &m_pachPut[m_offPutNext];
264 }
265
266 char_type *epptr() const RT_NOEXCEPT
267 {
268 return &m_pachPut[m_cchPut];
269 }
270
271 void pbump(int a_cchAdvance) const RT_NOEXCEPT
272 {
273 Assert(m_offPutNext <= m_cchPut);
274 m_offPutNext += a_cchAdvance;
275 Assert(m_offPutNext <= m_cchPut);
276 }
277 /** @} */
278
279 protected:
280 basic_streambuf() RT_NOEXCEPT
281 : m_pachPut(NULL)
282 , m_cchPut(0)
283 , m_offPutNext(0)
284 , m_offPutStart(0)
285 {
286 }
287
288 basic_streambuf(const basic_streambuf &a_rSrc) RT_NOEXCEPT
289 : m_pachPut(a_rSrc.m_pachPut)
290 , m_cchPut(a_rSrc.m_cchPut)
291 , m_offPutNext(a_rSrc.m_offPutNext)
292 , m_offPutStart(a_rSrc.m_offPutStart)
293 {
294 }
295
296 public:
297 virtual ~basic_streambuf()
298 {
299 }
300
301 /** @name Positioning
302 * @{ */
303 protected:
304 virtual basic_streambuf *setbuf(char_type *a_pchBuf, std::streamsize a_cchBuf)
305 {
306 RT_NOREF(a_pchBuf, a_cchBuf);
307 return this;
308 }
309 public:
310 basic_streambuf *pubsetbuf(char_type *a_pchBuf, std::streamsize a_cchBuf)
311 {
312 return setbuf(a_pchBuf, a_cchBuf);
313 }
314
315 protected:
316 virtual pos_type seekoff(off_type a_off, std::ios_base::seekdir a_enmDir,
317 std::ios_base::openmode a_enmTarget = ios_base::in | ios_base::out)
318 {
319 RT_NOREF(a_off, a_enmDir, a_enmTarget);
320 return pos_type(off_type(-1));
321 }
322 public:
323 pos_type pubseekoff(off_type a_off, std::ios_base::seekdir a_enmDir,
324 std::ios_base::openmode a_enmTarget = ios_base::in | ios_base::out)
325 {
326 return seekoff(a_off, a_enmDir, a_enmTarget);
327 }
328
329 protected:
330 virtual pos_type seekpos(pos_type a_pos, std::ios_base::openmode a_enmTarget = ios_base::in | ios_base::out)
331 {
332 RT_NOREF(a_pos, a_enmTarget);
333 return pos_type(off_type(-1));
334 }
335 public:
336 pos_type pubseekpos(pos_type a_pos, std::ios_base::openmode a_enmTarget = ios_base::in | ios_base::out)
337 {
338 return seekpos(a_pos, a_enmTarget);
339 }
340
341 protected:
342 virtual int sync()
343 {
344 return 0;
345 }
346 public:
347 pos_type pubsync()
348 {
349 return sync();
350 }
351 /** @} */
352
353 /** @name Output
354 * @{ */
355 protected:
356 virtual int_type overflow(int_type a_iChar)
357 {
358 RT_NOREF(a_iChar);
359 return traits_type::eof();
360 }
361
362 virtual std::streamsize xsputn(char_type const *a_pchSrc, std::streamsize a_cchSrc)
363 {
364 std::streamsize cchWritten = 0;
365 while (a_cchSrc > 0)
366 {
367 std::size_t cchCopied = m_cchPut - m_offPutNext;
368 if (cchCopied > 0)
369 {
370 cchCopied = RT_MIN(cchCopied, static_cast<std::size_t>(a_cchSrc));
371 traits_type::copy(&m_pachPut[m_offPutNext], a_pchSrc, cchCopied);
372 m_cchPut += cchCopied;
373 }
374 else
375 {
376 if (overflow(traits_type::to_int_type(m_pachPut[m_offPutNext])) != traits_type::eof())
377 cchCopied = 1;
378 else
379 break;
380 }
381 a_pchSrc += cchCopied;
382 a_cchSrc -= cchCopied;
383 }
384 return cchWritten;
385 }
386
387 public:
388 int_type sputc(char_type a_ch)
389 {
390 if (m_offPutNext < m_cchPut)
391 {
392 m_pachPut[m_offPutNext++] = a_ch;
393 return traits_type::to_int_type(a_ch);
394 }
395 return overflow(traits_type::to_int_type(a_ch));
396 }
397
398 std::streamsize sputn(char_type const *a_pchSrc, std::streamsize a_cchSrc)
399 {
400 AssertReturn(a_cchSrc >= 0, 0);
401 return xsputn(a_pchSrc, a_cchSrc);
402 }
403
404 /** @} */
405
406 /** @todo add the remaining members... */
407 };
408
409
410 /**
411 * Basic I/O stream.
412 */
413 template<typename a_CharType, typename a_CharTraits /*= std::char_traits<a_CharType>*/ >
414 class basic_ios : public ios_base
415 {
416 public:
417 typedef a_CharType char_type;
418 typedef a_CharTraits traits_type;
419 typedef typename a_CharTraits::int_type int_type;
420 typedef typename a_CharTraits::pos_type pos_type;
421 typedef typename a_CharTraits::off_type off_type;
422
423 protected:
424 basic_streambuf<a_CharType, a_CharTraits> *m_pBuf;
425 basic_ostream<a_CharType, a_CharTraits> *m_pTiedStream;
426
427 protected:
428 void init(std::basic_streambuf<a_CharType, a_CharTraits> *a_pBuf)
429 {
430 m_pBuf = a_pBuf;
431 m_cWidth = 0;
432 m_cPrecision = 6;
433 m_fFlags = ios_base::dec | ios_base::skipws;
434 m_fState = ios_base::goodbit;
435 }
436
437 public:
438 basic_ios()
439 : ios_base()
440 , m_pBuf(NULL)
441 , m_pTiedStream(NULL)
442 {
443 }
444
445 basic_ios(std::basic_streambuf<a_CharType, a_CharTraits> *a_pBuf)
446 : ios_base()
447 , m_pBuf(NULL)
448 , m_pTiedStream(NULL)
449 {
450 init(a_pBuf);
451 }
452 private:
453 basic_ios(const basic_ios &a_rSrc); /* not copyable */
454 basic_ios &operator=(const basic_ios &a_rSrc); /* not copyable */
455
456 public:
457 virtual ~basic_ios()
458 {
459 }
460
461 /** @name State methods
462 * @{ */
463 bool good() const RT_NOEXCEPT { return m_fState == ios_base::goodbit; }
464 bool fail() const RT_NOEXCEPT { return (m_fState & (ios_base::failbit | ios_base::badbit)) != ios_base::goodbit; }
465 bool bad() const RT_NOEXCEPT { return (m_fState & ios_base::badbit) == ios_base::badbit; }
466 bool eof() const RT_NOEXCEPT { return (m_fState & ios_base::eofbit) != ios_base::eofbit; }
467#if RT_CPLUSPLUS_PREREQ(201100)
468 operator bool() const RT_NOEXCEPT { return good(); }
469#else
470 operator void*() const RT_NOEXCEPT { return good() ? NULL : this; }
471#endif
472 bool operator!() const RT_NOEXCEPT { return fail(); }
473
474 iostate rdstate() const RT_NOEXCEPT
475 {
476 return m_fState;
477 }
478
479 void clear(iostate a_fNewState = goodbit)
480 {
481 m_fState = a_fNewState;
482 if (!m_pBuf)
483 m_fState |= badbit;
484 /** @todo failure exception */
485 }
486
487 void setstate(iostate a_fNewState)
488 {
489 clear(m_fState | a_fNewState);
490 }
491 /** @} */
492
493 /** @name Misc
494 * @{ */
495 std::basic_streambuf<a_CharType, a_CharTraits> *rdbuf() const RT_NOEXCEPT
496 {
497 return m_pBuf;
498 }
499
500 std::basic_streambuf<a_CharType, a_CharTraits> *rdbuf(std::basic_streambuf<a_CharType, a_CharTraits> *a_pNewBuf) RT_NOEXCEPT
501 {
502 std::basic_streambuf<a_CharType, a_CharTraits> *pOldBuf = m_pBuf;
503 m_pBuf = a_pNewBuf;
504 return pOldBuf;
505 }
506
507 std::basic_ostream<a_CharType, a_CharTraits> *tie() const
508 {
509 return m_pTiedStream;
510 }
511
512 std::basic_ostream<a_CharType, a_CharTraits> tie(std::basic_ostream<a_CharType, a_CharTraits> *a_pNew) const RT_NOEXCEPT
513 {
514 std::basic_ostream<a_CharType, a_CharTraits> * const pOld = m_pTiedStream;
515 m_pTiedStream = a_pNew;
516 return pOld;
517 }
518 /** @} */
519
520 /** @todo implement the rest... */
521 };
522}
523
524#endif /* !VBOX_INCLUDED_SRC_nocrt_ios */
525
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