/***************************************************************************** * * * O U T S T R E A M * * * *---------------------------------------------------------------------------* * Beschreibung: Die Klasse OutStream enthaelt die Definition des * * << Operators fuer die wichtigsten der vordefinierten * * Datentypen und realisiert somit die bekannte Ausgabe- * * funktion der C++ iO_Stream Bibliothek. Zur Zeit wird * * die Darstellung von Zeichen, Zeichenketten und ganzen * * Zahlen unterstuetzt. Ein weiterer << Operator erlaubt * * die Verwendung von Manipulatoren. * * * * Neben der Klasse OutStream sind hier auch die * * Manipulatoren hex, dec, oct und bin fuer die Wahl der * * Basis bei der Zahlendarstellung, sowie endl fuer den * * Zeilenumbruch definiert. * * * * Autor: Olaf Spinczyk, TU Dortmund * * Aenderungen von Michael Schoettner, HHU, 1.8.16 * *****************************************************************************/ #include "lib/OutStream.h" // NOTE: I added this, stream manipulators with arg OutStream& OutStream::operator<<(const fillw& w) { this->fill_width = w.w; return *this; } OutStream& OutStream::operator<<(const fillc& c) { this->fill_char = c.c; return *this; } // NOTE: I added this, fixed width printing void OutStream::put(char c) { if (this->fill_width == 0) { StringBuffer::put(c); } else if (this->fill_used == this->fill_width - 1) { // This indicates that content has been cut StringBuffer::put('@'); this->fill_use_char(); } else if (this->fill_used == this->fill_width) { // do nothing } else { StringBuffer::put(c); this->fill_use_char(); } } void OutStream::fill_finalize() { if (this->fill_width == 0 || this->fill_used == this->fill_width) { // do nothing } else if (this->fill_used > this->fill_width) { // should never happen } else { for (unsigned char i = 0; i < this->fill_width - this->fill_used; ++i) { StringBuffer::put(this->fill_char); } } this->fill_used = 0; } void OutStream::fill_use_char() { if (this->fill_width == 0) { return; } this->fill_used++; } // // Zeichen und Zeichenketten in Stream ausgeben // OutStream& OutStream::operator<<(char c) { put(c); if (c != '\n') { // endl() doesn't has access to StringBuffer::put(), so ignore \n here this->fill_finalize(); // NOTE: I added this } return *this; } // TODO: shouldn't this be printed as number? OutStream& OutStream::operator<<(unsigned char c) { return *this << (char)c; } OutStream& OutStream::operator<<(char* string) { char* pos = string; while (*pos) { put(*pos); pos++; } this->fill_finalize(); // NOTE: I added this return *this; } // // Ganzer Zahlen im Zahlensystem zur Basis base in Stream ausgeveb // Alle vorzeichenbehafteten Datentypen werden als long dargestellt, // Alle vorzeichenlosen als unsigned long. OutStream& OutStream::operator<<(short ival) { return *this << (long)ival; } OutStream& OutStream::operator<<(unsigned short ival) { return *this << (unsigned long)ival; } OutStream& OutStream::operator<<(int ival) { return *this << (long)ival; } OutStream& OutStream::operator<<(unsigned int ival) { return *this << (unsigned long)ival; } // Darstellung eine vorzeichenbehafteten ganzen Zahl. OutStream& OutStream::operator<<(long ival) { // Bei negativen Werten wird ein Minuszeichen ausgegeben. if (ival < 0) { put('-'); ival = -ival; } // Dann wird der Absolutwert als vorzeichenlose Zahl ausgegeben. return *this << (unsigned long)ival; } // Darstellung einer vorzeichenlosen ganzen Zahl. OutStream& OutStream::operator<<(unsigned long ival) { unsigned long div; char digit; if (base == 8) { put('0'); // oktale Zahlen erhalten eine fuehrende Null } else if (base == 16) { put('0'); // hexadezimale Zahlen ein "0x" put('x'); } // Bestimmung der groessten Potenz der gewaehlten Zahlenbasis, die // noch kleiner als die darzustellende Zahl ist. for (div = 1; ival / div >= (unsigned long)base; div *= base) ; // ziffernweise Ausgabe der Zahl for (; div > 0; div /= (unsigned long)base) { digit = ival / div; if (digit < 10) { put('0' + digit); } else { put('a' + digit - 10); } ival %= div; } this->fill_finalize(); // NOTE: I added this return *this; } // Darstellung eines Zeigers als hexadezimale ganze Zahl OutStream& OutStream::operator<<(void* ptr) { int oldbase = base; base = 16; *this << (unsigned long)ptr; base = oldbase; return *this; } // Aufruf einer Manipulatorfunktion OutStream& OutStream::operator<<(OutStream& (*f)(OutStream&)) { return f(*this); } // // Manipulatorfunktionen // // Die folgenden Funktionen erhalten und liefern jeweils eine Referenz auf // ein OutStream Objekt. Da die Klasse O_Stream einen Operator << fuer // derartige Funktionen definiert, koennen sie mit Hilfe dieses Operators // aufgerufen und sogar in weitere Eingaben eingebettet werden. // Aufgabe der Manipulatoren ist, die Darstellung der nachfolgenden Ausgaben // zu beeinflussen, z.B durch die Wahl des Zahlensystems. // Fuege einen Zeilenumbruch in die Ausgabe ein. OutStream& endl(OutStream& os) { os << '\n'; os.flush(); return os; } // Waehlt das binaere Zahlensystem aus. OutStream& bin(OutStream& os) { os.base = 2; return os; } // Waehlt das oktale Zahlensystem aus. OutStream& oct(OutStream& os) { os.base = 8; return os; } // Waehlt das dezimale Zahlensystem aus. OutStream& dec(OutStream& os) { os.base = 10; return os; } // Waehlt das hexadezimale Zahlensystem aus. OutStream& hex(OutStream& os) { os.base = 16; return os; }