1// vi:set ft=cpp: -*- Mode: C++ -*- 2/** 3 * \file 4 * \brief Basic IO stream 5 */ 6/* 7 * (c) 2009 Alexander Warg <warg@os.inf.tu-dresden.de> 8 * economic rights: Technische Universität Dresden (Germany) 9 * 10 * This file is part of TUD:OS and distributed under the terms of the 11 * GNU General Public License 2. 12 * Please see the COPYING-GPL-2 file for details. 13 * 14 * As a special exception, you may use this file as part of a free software 15 * library without restriction. Specifically, if other files instantiate 16 * templates or use macros or inline functions from this file, or you compile 17 * this file and link it with other files to produce an executable, this 18 * file does not by itself cause the resulting executable to be covered by 19 * the GNU General Public License. This exception does not however 20 * invalidate any other reasons why the executable file might be covered by 21 * the GNU General Public License. 22 */ 23#pragma once 24 25namespace L4 { 26 27 /** 28 * \brief Modifier class for the IO stream. 29 * 30 * An IO Modifier can be used to change properties of an IO stream 31 * for example the number format. 32 */ 33 class IOModifier 34 { 35 public: 36 IOModifier(int x) : mod(x) {} 37 bool operator == (IOModifier o) { return mod == o.mod; } 38 bool operator != (IOModifier o) { return mod != o.mod; } 39 int mod; 40 }; 41 42 /** 43 * \internal 44 * \brief Backend to write or read stream data. 45 */ 46 class IOBackend 47 { 48 public: 49 typedef int Mode; 50 51 protected: 52 friend class BasicOStream; 53 54 IOBackend() 55 : int_mode(10) 56 {} 57 58 virtual ~IOBackend() {} 59 60 virtual void write(char const *str, unsigned len) = 0; 61 62 private: 63 void write(IOModifier m); 64 void write(long long int c, int len); 65 void write(long long unsigned c, int len); 66 void write(long long unsigned c, unsigned char base = 10, 67 unsigned char len = 0, char pad = ' '); 68 69 Mode mode() const 70 { return int_mode; } 71 72 void mode(Mode m) 73 { int_mode = m; } 74 75 int int_mode; 76 }; 77 78 /** 79 * \internal 80 * \brief Write-only backend for stream data. 81 */ 82 class BasicOStream 83 { 84 public: 85 BasicOStream(IOBackend *b) 86 : iob(b) 87 {} 88 89 void write(char const *str, unsigned len) 90 { 91 if (iob) 92 iob->write(str, len); 93 } 94 95 void write(long long int c, int len) 96 { 97 if (iob) 98 iob->write(c, len); 99 } 100 101 void write(long long unsigned c, unsigned char base = 10, 102 unsigned char len = 0, char pad = ' ') 103 { 104 if (iob) 105 iob->write(c, base, len, pad); 106 } 107 108 void write(long long unsigned c, int len) 109 { 110 if (iob) 111 iob->write(c, len); 112 } 113 114 void write(IOModifier m) 115 { 116 if (iob) 117 iob->write(m); 118 } 119 120 IOBackend::Mode be_mode() const 121 { 122 if (iob) 123 return iob->mode(); 124 return 0; 125 } 126 127 void be_mode(IOBackend::Mode m) 128 { 129 if (iob) 130 iob->mode(m); 131 } 132 133 private: 134 IOBackend *iob; 135 }; 136 137 /** 138 * \internal 139 * \brief Container class describing a the number format. 140 */ 141 class IONumFmt 142 { 143 public: 144 IONumFmt(unsigned long long n, unsigned char base = 10, 145 unsigned char len = 0, char pad = ' ') 146 : n(n), base(base), len(len), pad(pad) 147 {} 148 149 BasicOStream &print(BasicOStream &o) const; 150 151 private: 152 unsigned long long n; 153 unsigned char base, len; 154 char pad; 155 }; 156 157 inline IONumFmt n_hex(unsigned long long n) { return IONumFmt(n, 16); } 158 159 /** 160 * \brief Modifies the stream to print numbers as hexadecimal values. 161 */ 162 extern IOModifier const hex; 163 164 /** 165 * \brief Modifies the stream to print numbers as decimal values. 166 */ 167 extern IOModifier const dec; 168 169 inline 170 BasicOStream &IONumFmt::print(BasicOStream &o) const 171 { 172 o.write(n, base, len, pad); 173 return o; 174 } 175} 176 177 178// Implementation 179 180inline 181L4::BasicOStream & 182operator << (L4::BasicOStream &s, char const * const str) 183{ 184 if (!str) 185 { 186 s.write("(NULL)", 6); 187 return s; 188 } 189 190 unsigned l = 0; 191 for (; str[l] != 0; l++) 192 ; 193 s.write(str, l); 194 return s; 195} 196 197inline 198L4::BasicOStream & 199operator << (L4::BasicOStream &s, signed short u) 200{ 201 s.write((long long signed)u, -1); 202 return s; 203} 204 205inline 206L4::BasicOStream & 207operator << (L4::BasicOStream &s, signed u) 208{ 209 s.write((long long signed)u, -1); 210 return s; 211} 212 213inline 214L4::BasicOStream & 215operator << (L4::BasicOStream &s, signed long u) 216{ 217 s.write((long long signed)u, -1); 218 return s; 219} 220 221inline 222L4::BasicOStream & 223operator << (L4::BasicOStream &s, signed long long u) 224{ 225 s.write(u, -1); 226 return s; 227} 228 229inline 230L4::BasicOStream & 231operator << (L4::BasicOStream &s, unsigned short u) 232{ 233 s.write((long long unsigned)u, -1); 234 return s; 235} 236 237inline 238L4::BasicOStream & 239operator << (L4::BasicOStream &s, unsigned u) 240{ 241 s.write((long long unsigned)u, -1); 242 return s; 243} 244 245inline 246L4::BasicOStream & 247operator << (L4::BasicOStream &s, unsigned long u) 248{ 249 s.write((long long unsigned)u, -1); 250 return s; 251} 252 253inline 254L4::BasicOStream & 255operator << (L4::BasicOStream &s, unsigned long long u) 256{ 257 s.write(u, -1); 258 return s; 259} 260 261inline 262L4::BasicOStream & 263operator << (L4::BasicOStream &s, void const *u) 264{ 265 long unsigned x = (long unsigned)u; 266 L4::IOBackend::Mode mode = s.be_mode(); 267 s.write(L4::hex); 268 s.write((long long unsigned)x, -1); 269 s.be_mode(mode); 270 return s; 271} 272 273inline 274L4::BasicOStream & 275operator << (L4::BasicOStream &s, L4::IOModifier m) 276{ 277 s.write(m); 278 return s; 279} 280 281inline 282L4::BasicOStream & 283operator << (L4::BasicOStream &s, char c) 284{ 285 s.write(&c, 1); 286 return s; 287} 288 289inline 290L4::BasicOStream & 291operator << (L4::BasicOStream &o, L4::IONumFmt const &n) 292{ return n.print(o); } 293