#ifndef IOSTREAM_
#define IOSTREAM_
#include <new>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "algorithm"
#include "streambuf"
namespace std {
/** Super naive ostream implementation, doesn't even support streambufs */
class ostream
{
public:
typedef ostream& (*ostream_fptr) (ostream&);
ostream(streambuf* new_sbuf)
: sbuf(new_sbuf)
{
assert(sbuf != NULL);
}
~ostream()
{
sbuf->sync();
}
void write(const char* str)
{
size_t len = strlen(str);
write(str, len);
}
void write(const char* str, size_t len)
{
do {
size_t ilen = min(len, size_t(sbuf->epptr() - sbuf->pptr()));
if(ilen == 0) {
sbuf->overflow(streambuf::eof);
ilen = min(len, size_t(sbuf->epptr() - sbuf->pptr()));
}
memcpy(sbuf->pptr(), str, ilen);
sbuf->pbump(static_cast<int>(ilen));
str += ilen;
len -= ilen;
} while(len > 0);
}
void flush()
{
sbuf->sync();
}
ostream& operator<<(ostream_fptr f)
{
return f(*this);
}
streambuf* rdbuf()
{
return sbuf;
}
private:
streambuf* sbuf;
};
static inline ostream& operator<<(ostream& out, const char* str)
{
out.write(str);
return out;
}
static inline ostream& operator<<(ostream& out, int v)
{
char buf[20];
snprintf(buf, sizeof(buf), "%d", v);
out.write(buf);
return out;
}
static inline ostream& operator<<(ostream& out, unsigned int v)
{
char buf[20];
snprintf(buf, sizeof(buf), "%u", v);
out.write(buf);
return out;
}
static inline ostream& operator<<(ostream& out, long v)
{
char buf[20];
snprintf(buf, sizeof(buf), "%ld", v);
out.write(buf);
return out;
}
static inline ostream& operator<<(ostream& out, unsigned long v)
{
char buf[20];
snprintf(buf, sizeof(buf), "%lu", v);
out.write(buf);
return out;
}
static inline ostream& operator<<(ostream& out, float v)
{
char buf[30];
snprintf(buf, sizeof(buf), "%f", v);
out.write(buf);
return out;
}
static inline ostream& endl(ostream& out)
{
out << "\n";
out.flush();
return out;
}
static inline ostream& flush(ostream& out)
{
out.flush();
return out;
}
class fstreambuf : public streambuf
{
public:
fstreambuf(FILE* newfile)
: file(newfile)
{
setp(buf, buf + sizeof(buf) - 1);
setg(NULL, NULL, NULL);
}
virtual ~fstreambuf()
{
sync();
}
virtual int overflow(int c)
{
size_t len = size_t(pptr() - pbase());
if(c != EOF) {
*pptr() = c;
++len;
}
// anything to send out
if(len > 0) {
const char* data = pbase();
if(fwrite(data, 1, len, file) != len) {
return EOF;
}
setp(buf, buf + sizeof(buf) - 1);
}
fflush(file);
return 0;
}
virtual int sync()
{
return overflow(eof);
}
private:
FILE* file;
char buf[80];
};
extern fstreambuf stdoutbuf;
extern ostream cout;
extern ostream cerr;
}
#endif /*IOSTREAM_*/