VirtualBox

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

Last change on this file since 96354 was 96354, checked in by vboxsync, 2 years ago

IPRT/nocrt: Defined cout and cerr; implemented ostream::flush and fixed a compile issue. bugref:10261

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