summaryrefslogtreecommitdiff
path: root/src/object/outputstream.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/object/outputstream.cc')
-rw-r--r--src/object/outputstream.cc247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/object/outputstream.cc b/src/object/outputstream.cc
new file mode 100644
index 0000000..3960a3e
--- /dev/null
+++ b/src/object/outputstream.cc
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2020 Daniel Friesel
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include "object/outputstream.h"
+
+OutputStream & OutputStream::operator<<(unsigned char c)
+{
+ *this << (unsigned long long)c;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(char c)
+{
+ put(c);
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(unsigned short number)
+{
+ *this << (unsigned long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(short number)
+{
+ *this << (long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(unsigned int number)
+{
+ *this << (unsigned long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(int number)
+{
+ *this << (long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(unsigned long number)
+{
+ *this << (unsigned long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(long number)
+{
+ *this << (long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(unsigned long long number)
+{
+ switch (base) {
+ case 2:
+ put('0');
+ put('b');
+ break;
+ case 8:
+ put('0');
+ break;
+ case 16:
+ if (number < 16) {
+ put('0');
+ }
+ break;
+ }
+
+ if (number == 0) {
+ put('0');
+ return *this;
+ }
+
+ signed int i = 0;
+ while (number > 0) {
+ if (base == 16 && number % base > 9) {
+ digit_buffer[i] = 'a' + (number % base) - 10;
+ } else {
+ digit_buffer[i] = '0' + (number % base);
+ }
+ number /= base;
+ i++;
+ }
+ i--;
+ for (; i >= 0; i--) {
+ put(digit_buffer[i]);
+ }
+ return *this;
+
+}
+
+OutputStream & OutputStream::operator<<(long long number)
+{
+ if (number < 0) {
+ put('-');
+ number *= -1;
+ }
+ *this << (unsigned long long)number;
+
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(double number)
+{
+ *this << (float)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(float number)
+{
+ printf_float(number);
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(void *pointer)
+{
+ unsigned char temp_base = base;
+ *this << hex << (long)pointer;
+ switch (temp_base) {
+ case 2:
+ *this << bin; break;
+ case 8:
+ *this << oct; break;
+ case 10:
+ *this << dec; break;
+ }
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(const char *text)
+{
+ int i = 0;
+ while (text[i] != '\0') {
+ put(text[i++]);
+ }
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(OutputStream & (*fkt) (OutputStream &))
+{
+ return fkt(*this);
+}
+
+#ifdef CONFIG_ostream
+OutputStream & OutputStream::operator<<(std::string s)
+{
+ for (auto c : s) {
+ put(c);
+ }
+ return *this;
+}
+#endif
+
+void OutputStream::setBase(uint8_t b)
+{
+ if (b == 2 || b == 8 || b == 10 || b == 16) {
+ base = b;
+ }
+}
+
+static inline char format_hex_nibble(uint8_t num)
+{
+ if (num > 9) {
+ return 'a' + num - 10;
+ }
+ return '0' + num;
+}
+
+void OutputStream::printf_uint8(uint8_t num)
+{
+ put(format_hex_nibble(num / 16));
+ put(format_hex_nibble(num % 16));
+}
+
+void OutputStream::printf_float(float num)
+{
+ if (num < 0) {
+ put('-');
+ num *= -1;
+ }
+ if (num > 1000) {
+ put('0' + (((unsigned int)num % 10000) / 1000));
+ }
+ if (num > 100) {
+ put('0' + (((unsigned int)num % 1000) / 100));
+ }
+ if (num > 10) {
+ put('0' + (((unsigned int)num % 100) / 10));
+ }
+ put('0' + ((unsigned int)num % 10));
+ put('.');
+ put('0' + ((unsigned int)(num * 10) % 10));
+ put('0' + ((unsigned int)(num * 100) % 10));
+}
+
+OutputStream & flush(OutputStream & os)
+{
+ os.flush();
+ return os;
+}
+
+OutputStream & endl(OutputStream & os)
+{
+ os.put('\n');
+ os.flush();
+ return os;
+}
+
+OutputStream & bin(OutputStream & os)
+{
+ os.setBase(2);
+ return os;
+}
+
+OutputStream & oct(OutputStream & os)
+{
+ os.setBase(8);
+ return os;
+}
+
+OutputStream & dec(OutputStream & os)
+{
+ os.setBase(10);
+ return os;
+}
+
+OutputStream & hex(OutputStream & os)
+{
+ os.setBase(16);
+ return os;
+}
+
+OutputStream & term(OutputStream & os)
+{
+ os.put('\0');
+ os.flush();
+ return os;
+}
+
+OutputStream::OutputStream()
+{
+ base = 10;
+}