282 lines
5.0 KiB
C++
282 lines
5.0 KiB
C++
// vi:set ft=cpp: -*- Mode: C++ -*-
|
|
/**
|
|
* \file
|
|
* \brief Basic IO stream
|
|
*/
|
|
/*
|
|
* (c) 2009 Alexander Warg <warg@os.inf.tu-dresden.de>
|
|
* economic rights: Technische Universität Dresden (Germany)
|
|
*
|
|
* License: see LICENSE.spdx (in this directory or the directories above)
|
|
*/
|
|
#pragma once
|
|
|
|
namespace L4 {
|
|
|
|
/**
|
|
* \brief Modifier class for the IO stream.
|
|
*
|
|
* An IO Modifier can be used to change properties of an IO stream
|
|
* for example the number format.
|
|
*/
|
|
class IOModifier
|
|
{
|
|
public:
|
|
IOModifier(int x) : mod(x) {}
|
|
bool operator == (IOModifier o) { return mod == o.mod; }
|
|
bool operator != (IOModifier o) { return mod != o.mod; }
|
|
int mod;
|
|
};
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Backend to write or read stream data.
|
|
*/
|
|
class IOBackend
|
|
{
|
|
public:
|
|
typedef int Mode;
|
|
|
|
protected:
|
|
friend class BasicOStream;
|
|
|
|
IOBackend()
|
|
: int_mode(10)
|
|
{}
|
|
|
|
virtual ~IOBackend() {}
|
|
|
|
virtual void write(char const *str, unsigned len) = 0;
|
|
|
|
private:
|
|
void write(IOModifier m);
|
|
void write(long long int c, int len);
|
|
void write(long long unsigned c, int len);
|
|
void write(long long unsigned c, unsigned char base = 10,
|
|
unsigned char len = 0, char pad = ' ');
|
|
|
|
Mode mode() const
|
|
{ return int_mode; }
|
|
|
|
void mode(Mode m)
|
|
{ int_mode = m; }
|
|
|
|
int int_mode;
|
|
};
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Write-only backend for stream data.
|
|
*/
|
|
class BasicOStream
|
|
{
|
|
public:
|
|
BasicOStream(IOBackend *b)
|
|
: iob(b)
|
|
{}
|
|
|
|
void write(char const *str, unsigned len)
|
|
{
|
|
if (iob)
|
|
iob->write(str, len);
|
|
}
|
|
|
|
void write(long long int c, int len)
|
|
{
|
|
if (iob)
|
|
iob->write(c, len);
|
|
}
|
|
|
|
void write(long long unsigned c, unsigned char base = 10,
|
|
unsigned char len = 0, char pad = ' ')
|
|
{
|
|
if (iob)
|
|
iob->write(c, base, len, pad);
|
|
}
|
|
|
|
void write(long long unsigned c, int len)
|
|
{
|
|
if (iob)
|
|
iob->write(c, len);
|
|
}
|
|
|
|
void write(IOModifier m)
|
|
{
|
|
if (iob)
|
|
iob->write(m);
|
|
}
|
|
|
|
IOBackend::Mode be_mode() const
|
|
{
|
|
if (iob)
|
|
return iob->mode();
|
|
return 0;
|
|
}
|
|
|
|
void be_mode(IOBackend::Mode m)
|
|
{
|
|
if (iob)
|
|
iob->mode(m);
|
|
}
|
|
|
|
private:
|
|
IOBackend *iob;
|
|
};
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Container class describing a the number format.
|
|
*/
|
|
class IONumFmt
|
|
{
|
|
public:
|
|
IONumFmt(unsigned long long n, unsigned char base = 10,
|
|
unsigned char len = 0, char pad = ' ')
|
|
: n(n), base(base), len(len), pad(pad)
|
|
{}
|
|
|
|
BasicOStream &print(BasicOStream &o) const;
|
|
|
|
private:
|
|
unsigned long long n;
|
|
unsigned char base, len;
|
|
char pad;
|
|
};
|
|
|
|
inline IONumFmt n_hex(unsigned long long n) { return IONumFmt(n, 16); }
|
|
|
|
/**
|
|
* \brief Modifies the stream to print numbers as hexadecimal values.
|
|
*/
|
|
extern IOModifier const hex;
|
|
|
|
/**
|
|
* \brief Modifies the stream to print numbers as decimal values.
|
|
*/
|
|
extern IOModifier const dec;
|
|
|
|
inline
|
|
BasicOStream &IONumFmt::print(BasicOStream &o) const
|
|
{
|
|
o.write(n, base, len, pad);
|
|
return o;
|
|
}
|
|
}
|
|
|
|
|
|
// Implementation
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, char const * const str)
|
|
{
|
|
if (!str)
|
|
{
|
|
s.write("(NULL)", 6);
|
|
return s;
|
|
}
|
|
|
|
unsigned l = 0;
|
|
for (; str[l] != 0; l++)
|
|
;
|
|
s.write(str, l);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, signed short u)
|
|
{
|
|
s.write(static_cast<long long signed>(u), -1);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, signed u)
|
|
{
|
|
s.write(static_cast<long long signed>(u), -1);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, signed long u)
|
|
{
|
|
s.write(static_cast<long long signed>(u), -1);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, signed long long u)
|
|
{
|
|
s.write(u, -1);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, unsigned short u)
|
|
{
|
|
s.write(static_cast<long long unsigned>(u), -1);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, unsigned u)
|
|
{
|
|
s.write(static_cast<long long unsigned>(u), -1);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, unsigned long u)
|
|
{
|
|
s.write(static_cast<long long unsigned>(u), -1);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, unsigned long long u)
|
|
{
|
|
s.write(u, -1);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, void const *u)
|
|
{
|
|
long unsigned x = reinterpret_cast<long unsigned>(u);
|
|
L4::IOBackend::Mode mode = s.be_mode();
|
|
s.write(L4::hex);
|
|
s.write(static_cast<long long unsigned>(x), -1);
|
|
s.be_mode(mode);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, L4::IOModifier m)
|
|
{
|
|
s.write(m);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &s, char c)
|
|
{
|
|
s.write(&c, 1);
|
|
return s;
|
|
}
|
|
|
|
inline
|
|
L4::BasicOStream &
|
|
operator << (L4::BasicOStream &o, L4::IONumFmt const &n)
|
|
{ return n.print(o); }
|