1
Files
lecture-operating-system-de…/c_os/lib/OutStream.cc
2022-04-24 22:27:48 +02:00

213 lines
6.6 KiB
C++
Executable File

/*****************************************************************************
* *
* 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;
}