summaryrefslogtreecommitdiffstats
path: root/include/iprt/nocrt/ostream
diff options
context:
space:
mode:
Diffstat (limited to 'include/iprt/nocrt/ostream')
-rw-r--r--include/iprt/nocrt/ostream280
1 files changed, 280 insertions, 0 deletions
diff --git a/include/iprt/nocrt/ostream b/include/iprt/nocrt/ostream
new file mode 100644
index 00000000..98820e27
--- /dev/null
+++ b/include/iprt/nocrt/ostream
@@ -0,0 +1,280 @@
+/** @file
+ * IPRT / No-CRT - Minimal C++ ostream header.
+ */
+
+/*
+ * Copyright (C) 2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+#ifndef VBOX_INCLUDED_SRC_nocrt_ostream
+#define VBOX_INCLUDED_SRC_nocrt_ostream
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+/* Currently all in the ios header. */
+#include <iprt/nocrt/ios>
+
+namespace std
+{
+ /**
+ * Basic output stream.
+ */
+ template<typename a_CharType, typename a_CharTraits /*= std::char_traits<a_CharType>*/ >
+ class basic_ostream : public basic_ios<a_CharType, a_CharTraits>
+ {
+ protected:
+ /** Sentry class that performs pre and post output work. */
+ class sentry
+ {
+ private:
+ basic_ostream &m_rParent;
+
+ public:
+ explicit sentry(basic_ostream &a_rParent)
+ : m_rParent(a_rParent)
+ {
+ if (a_rParent.good())
+ {
+ basic_ostream *pTiedStream = a_rParent.tie();
+ if (!pTiedStream)
+ { /* likely? */ }
+ else
+ {
+ pTiedStream->flush();
+ if (!pTiedStream->good())
+ a_rParent.setstate(failbit);
+ }
+ }
+ }
+
+ explicit operator bool() const
+ {
+ return m_rParent.good();
+ }
+
+ ~sentry()
+ {
+ if ( (m_rParent.flags() & std::ios_base::unitbuf)
+ && m_rParent.good())
+ m_rParent.rdbuf()->pubsync();
+ }
+ };
+
+ public:
+ explicit basic_ostream(std::basic_streambuf<a_CharType,a_CharTraits> *a_pBuf)
+ : basic_ios(a_pBuf)
+ { }
+
+ /** For cerr initialization.
+ * @internal */
+ explicit basic_ostream(std::basic_streambuf<a_CharType,a_CharTraits> *a_pBuf,
+ std::basic_ostream<a_CharType, a_CharTraits> *a_pTiedStream,
+ bool a_fUnbuffered)
+ : basic_ios(a_pBuf)
+ {
+ m_pTiedStream = a_pTiedStream;
+ if (!a_fUnbuffered)
+ setf(std::ios_base::unitbuf);
+ }
+
+ private:
+ basic_ostream(basic_ostream const &a_rSrc); /* not copyable */
+ basic_ostream &operator=(basic_ostream const &a_rSrc); /* not copyable */
+
+ public:
+ virtual ~basic_ostream()
+ {
+ }
+
+ public:
+ basic_ostream &put(char_type a_ch)
+ {
+ sentry PrePost(*this);
+ if (PrePost)
+ {
+ if (m_pBuf->sputc(a_ch) == traits_type::eof())
+ m_fState |= badbit;
+ }
+ return *this;
+ }
+
+ basic_ostream &write(const char_type *a_pchSrc, std::streamsize a_cchToWrite)
+ {
+ sentry PrePost(*this);
+ if (PrePost)
+ {
+ std::streamsize cchWritten = m_pBuf->sputn(a_pchSrc, a_cchToWrite);
+ if (cchWritten != a_cchToWrite)
+ m_fState |= badbit;
+ }
+ return *this;
+ }
+
+ basic_ostream &flush()
+ {
+ if (m_pBuf)
+ m_pBuf->pubsync();
+ return *this;
+ }
+
+ pos_type tellp() RT_NOEXCEPT;
+ basic_ostream &seekp(pos_type a_off) RT_NOEXCEPT;
+ basic_ostream &seekp(off_type a_off, seekdir enmDir) RT_NOEXCEPT;
+
+ /** @name Internal support methods
+ * @{ */
+ inline basic_ostream &intWrite(const char *a_pchSrc, std::streamsize a_cchToWrite); /**< Internal method outputting char buffers. */
+
+ /** @returns 8, 10 or 16. */
+ inline unsigned intGetIntegerBase() const RT_NOEXCEPT
+ {
+ switch (m_fFlags & basefield)
+ {
+ default:
+ case dec: return 10;
+ case hex: return 16;
+ case oct: return 8;
+ }
+ }
+
+ /** @returns RTSTR_F_XXX . */
+ inline unsigned intGetIntegerFlags() const RT_NOEXCEPT
+ {
+ unsigned fFlags = 0;
+ if (m_fFlags & uppercase)
+ fFlags |= RTSTR_F_CAPITAL;
+ if (m_fFlags & showbase)
+ fFlags |= RTSTR_F_SPECIAL;
+ if (m_fFlags & showpos)
+ fFlags |= RTSTR_F_PLUS;
+ return fFlags;
+ }
+
+ basic_ostream &formatInteger(uint64_t a_uValue, uint32_t a_fFlags, unsigned a_uBase = 0)
+ {
+ a_fFlags |= intGetIntegerFlags();
+ char szTmp[72];
+ int cchTmp = RTStrFormatNumber(szTmp, a_uValue, !a_uBase ? intGetIntegerBase() : a_uBase, 0, 0, a_fFlags);
+
+ /** @todo apply cchWidth and padding. */
+
+ return intWrite(szTmp, cchTmp);
+ }
+
+ /** @} */
+ };
+
+ /** @name Character and string output.
+ * @{ */
+ /** @todo not sure if this really works... */
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, char a_ch)
+ {
+ return a_rDst.put(a_ch);
+ }
+
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, const char *a_psz)
+ {
+ return a_rDst.intWrite(a_psz, strlen(a_psz));
+ }
+ /** @} */
+
+ /** @name Integer formatting.
+ * @{ */
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, signed char a_iValue)
+ {
+ return a_rDst.formatInteger(a_iValue, RTSTR_F_8BIT | RTSTR_F_VALSIGNED);
+ }
+
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned char a_uValue)
+ {
+ return a_rDst.formatInteger(a_uValue, RTSTR_F_8BIT);
+ }
+
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, short a_iValue)
+ {
+ return a_rDst.formatInteger(a_iValue, RTSTR_F_16BIT | RTSTR_F_VALSIGNED);
+ }
+
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned short a_uValue)
+ {
+ return a_rDst.formatInteger(a_uValue, RTSTR_F_16BIT);
+ }
+
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, int a_iValue)
+ {
+ return a_rDst.formatInteger(a_iValue, RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
+ }
+
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned int a_uValue)
+ {
+ return a_rDst.formatInteger(a_uValue, RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
+ }
+
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, long a_iValue)
+ {
+ return a_rDst.formatInteger(a_iValue, (sizeof(a_iValue) > sizeof(int32_t) ? RTSTR_F_64BIT : RTSTR_F_32BIT));
+ }
+
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned long a_uValue)
+ {
+ return a_rDst.formatInteger(a_uValue,
+ RTSTR_F_VALSIGNED | (sizeof(a_uValue) > sizeof(uint32_t) ? RTSTR_F_64BIT : RTSTR_F_32BIT));
+ }
+
+ template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
+ basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, void const *a_pvValue)
+ {
+ return a_rDst.formatInteger((uintptr_t)a_pvValue,
+ (sizeof(a_pvValue) > sizeof(uint32_t) ? RTSTR_F_64BIT : RTSTR_F_32BIT), 16);
+ }
+ /** @} */
+
+ template<>
+ inline basic_ostream<char> &basic_ostream<char>::intWrite(const char *a_pchSrc, std::streamsize a_cchToWrite)
+ {
+ return write(a_pchSrc, a_cchToWrite);
+ }
+
+
+}
+
+#endif /* !VBOX_INCLUDED_SRC_nocrt_ostream */
+