153 lines
3.3 KiB
C++
153 lines
3.3 KiB
C++
#include "outerrstream.h"
|
|
#include "ustringformat.h" // for vsnprintf (in string::format)
|
|
|
|
namespace ustl
|
|
{
|
|
|
|
coutclass cout_obj;
|
|
coutclass cerr_obj;
|
|
coutclass& cout = cout_obj;
|
|
coutclass& cerr = cerr_obj;
|
|
|
|
void coutclass::init()
|
|
{
|
|
new (&cout_obj) coutclass(&kprintf);
|
|
new (&cerr_obj) coutclass(&kprintfd);
|
|
}
|
|
|
|
|
|
/// Creates an output string stream linked to the given memory area.
|
|
coutclass::coutclass (void* p __attribute__((unused)), size_t n __attribute__((unused)))
|
|
: ostream (),
|
|
m_Flags (0),
|
|
m_Width (0),
|
|
m_Base (10),
|
|
m_Precision (2),
|
|
m_kprintf(&kprintf)
|
|
{
|
|
exceptions (goodbit);
|
|
}
|
|
/// Creates an output string stream linked to the given memory area.
|
|
coutclass::coutclass (void* p __attribute__((unused)), size_t n __attribute__((unused)), void (*m_kprintf)(const char*, ...))
|
|
: ostream (),
|
|
m_Flags (0),
|
|
m_Width (0),
|
|
m_Base (10),
|
|
m_Precision (2),
|
|
m_kprintf(m_kprintf)
|
|
{
|
|
exceptions (goodbit);
|
|
}
|
|
|
|
/// Creates an output string stream, initializing the buffer with v.
|
|
coutclass::coutclass ()
|
|
: ostream (),
|
|
m_Flags (0),
|
|
m_Width (0),
|
|
m_Base (10),
|
|
m_Precision (2),
|
|
m_kprintf(&kprintf)
|
|
{
|
|
exceptions (goodbit);
|
|
}
|
|
|
|
/// Creates an output string stream, initializing the buffer with v.
|
|
coutclass::coutclass (void (*m_kprintf)(const char*, ...))
|
|
: ostream (),
|
|
m_Flags (0),
|
|
m_Width (0),
|
|
m_Base (10),
|
|
m_Precision (2),
|
|
m_kprintf(m_kprintf)
|
|
{
|
|
exceptions (goodbit);
|
|
}
|
|
|
|
/// Writes a single character into the stream.
|
|
void coutclass::iwrite (uint8_t v)
|
|
{
|
|
//debug(SCHEDULER, "writing single character: %d\n", v);
|
|
m_kprintf("%c", v);
|
|
}
|
|
|
|
/// Writes the contents of \p buffer of \p size into the stream.
|
|
coutclass& coutclass::write (const void* buffer, size_type sz)
|
|
{
|
|
kprintf("%.*s",(int)sz,(const char*)buffer);
|
|
return (*this);
|
|
}
|
|
|
|
/// Simple decimal encoding of \p n into \p fmt.
|
|
inline char* coutclass::encode_dec (char* fmt, uint32_t n) const
|
|
{
|
|
do {
|
|
*fmt++ = '0' + n % 10;
|
|
} while (n /= 10);
|
|
return (fmt);
|
|
}
|
|
|
|
/// Generates a sprintf format string for the given type.
|
|
void coutclass::fmtstring (char* fmt, const char* typestr, bool bInteger) const
|
|
{
|
|
*fmt++ = '%';
|
|
if (m_Width)
|
|
fmt = encode_dec (fmt, m_Width);
|
|
if (m_Flags & left)
|
|
*fmt++ = '-';
|
|
if (!bInteger) {
|
|
*fmt++ = '.';
|
|
fmt = encode_dec (fmt, m_Precision);
|
|
}
|
|
while (*typestr)
|
|
*fmt++ = *typestr++;
|
|
if (bInteger) {
|
|
if (m_Base == 16)
|
|
fmt[-1] = 'X';
|
|
else if (m_Base == 8)
|
|
fmt[-1] = 'o';
|
|
} else {
|
|
if (m_Flags & scientific)
|
|
fmt[-1] = 'E';
|
|
}
|
|
*fmt = 0;
|
|
}
|
|
|
|
/// Writes \p v into the stream as utf8
|
|
void coutclass::iwrite (wchar_t v)
|
|
{
|
|
char buffer [8];
|
|
*utf8out(buffer) = v;
|
|
write (buffer, Utf8Bytes(v));
|
|
}
|
|
|
|
/// Writes value \p v into the stream as text.
|
|
void coutclass::iwrite (bool v)
|
|
{
|
|
static const char tf[2][8] = { "false", "true" };
|
|
write (tf[v], 5 - v);
|
|
}
|
|
|
|
/// Equivalent to a sprintf on the string.
|
|
int coutclass::format (const char* fmt, ...)
|
|
{
|
|
va_list args;
|
|
va_start (args, fmt);
|
|
m_kprintf(fmt, args);
|
|
va_end (args);
|
|
return (0);
|
|
}
|
|
|
|
/// Links to string \p l as resizable.
|
|
void coutclass::link (void* p, size_type n)
|
|
{
|
|
assert ((p || !n) && "The output string buffer must not be read-only");
|
|
}
|
|
|
|
/// Attempts to create more output space. Returns remaining().
|
|
coutclass::size_type coutclass::overflow (size_type n __attribute__((unused)))
|
|
{
|
|
return remaining();
|
|
}
|
|
|
|
}
|