diff options
Diffstat (limited to 'src/object/outputstream.cc')
-rw-r--r-- | src/object/outputstream.cc | 247 |
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; +} |