|
Packit |
8a864e |
// Copyright (c) 1994 James Clark
|
|
Packit |
8a864e |
// See the file COPYING for copying permission.
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#include "splib.h"
|
|
Packit |
8a864e |
#include "OutputCharStream.h"
|
|
Packit |
8a864e |
#include "CodingSystem.h"
|
|
Packit |
8a864e |
#include "macros.h"
|
|
Packit |
8a864e |
#include <stdio.h>
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#ifdef SP_NAMESPACE
|
|
Packit |
8a864e |
namespace SP_NAMESPACE {
|
|
Packit |
8a864e |
#endif
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
OutputCharStream::OutputCharStream()
|
|
Packit |
8a864e |
: ptr_(0), end_(0)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
OutputCharStream::~OutputCharStream()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void OutputCharStream::setEscaper(Escaper)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
OutputCharStream &OutputCharStream::write(const Char *s, size_t n)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
for (;;) {
|
|
Packit |
8a864e |
size_t spare = end_ - ptr_;
|
|
Packit |
8a864e |
if (n <= spare) {
|
|
Packit |
8a864e |
memcpy(ptr_, s, n*sizeof(Char));
|
|
Packit |
8a864e |
ptr_ += n;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (spare > 0) {
|
|
Packit |
8a864e |
memcpy(ptr_, s, spare*sizeof(Char));
|
|
Packit |
8a864e |
ptr_ += spare;
|
|
Packit |
8a864e |
s += spare;
|
|
Packit |
8a864e |
n -= spare;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
n--;
|
|
Packit |
8a864e |
flushBuf(*s++);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
return *this;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
OutputCharStream &OutputCharStream::operator<<(const char *s)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
while (*s)
|
|
Packit |
8a864e |
put(*s++);
|
|
Packit |
8a864e |
return *this;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
// FIXME Avoid stdio
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
OutputCharStream &OutputCharStream::operator<<(unsigned long n)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
char buf[sizeof(unsigned long)*3 + 1];
|
|
Packit |
8a864e |
sprintf(buf, "%lu", n);
|
|
Packit |
8a864e |
return *this << buf;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
OutputCharStream &OutputCharStream::operator<<(int n)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
char buf[sizeof(int)*3 + 2];
|
|
Packit |
8a864e |
sprintf(buf, "%d", n);
|
|
Packit |
8a864e |
return *this << buf;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
EncodeOutputCharStream::EncodeOutputCharStream()
|
|
Packit |
8a864e |
: buf_(0), byteStream_(0), escaper_(0)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
EncodeOutputCharStream::EncodeOutputCharStream(OutputByteStream *byteStream,
|
|
Packit |
8a864e |
const OutputCodingSystem *codingSystem)
|
|
Packit |
8a864e |
: buf_(0),
|
|
Packit |
8a864e |
byteStream_(byteStream),
|
|
Packit |
8a864e |
escaper_(0),
|
|
Packit |
8a864e |
ownedEncoder_(codingSystem->makeEncoder())
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
encoder_ = ownedEncoder_.pointer();
|
|
Packit |
8a864e |
encoder_->setUnencodableHandler(this);
|
|
Packit |
8a864e |
allocBuf(codingSystem->fixedBytesPerChar());
|
|
Packit |
8a864e |
encoder_->startFile(byteStream_);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
EncodeOutputCharStream::EncodeOutputCharStream(OutputByteStream *byteStream,
|
|
Packit |
8a864e |
Encoder *encoder)
|
|
Packit |
8a864e |
: buf_(0),
|
|
Packit |
8a864e |
byteStream_(byteStream),
|
|
Packit |
8a864e |
escaper_(0),
|
|
Packit |
8a864e |
encoder_(encoder)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
allocBuf(0);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
EncodeOutputCharStream::~EncodeOutputCharStream()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (byteStream_)
|
|
Packit |
8a864e |
flush();
|
|
Packit |
8a864e |
delete [] buf_;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void EncodeOutputCharStream::open(OutputByteStream *byteStream,
|
|
Packit |
8a864e |
const OutputCodingSystem *codingSystem)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (byteStream_)
|
|
Packit |
8a864e |
flush();
|
|
Packit |
8a864e |
byteStream_ = byteStream;
|
|
Packit |
8a864e |
ownedEncoder_ = codingSystem->makeEncoder();
|
|
Packit |
8a864e |
encoder_ = ownedEncoder_.pointer();
|
|
Packit |
8a864e |
encoder_->setUnencodableHandler(this);
|
|
Packit |
8a864e |
delete [] buf_;
|
|
Packit |
8a864e |
buf_ = 0;
|
|
Packit |
8a864e |
ptr_ = end_ = buf_;
|
|
Packit |
8a864e |
allocBuf(codingSystem->fixedBytesPerChar());
|
|
Packit |
8a864e |
encoder_->startFile(byteStream_);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void EncodeOutputCharStream::flush()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
if (ptr_ > buf_) {
|
|
Packit |
8a864e |
encoder_->output(buf_, ptr_ - buf_, byteStream_);
|
|
Packit |
8a864e |
ptr_ = buf_;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
byteStream_->flush();
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void EncodeOutputCharStream::flushBuf(Char c)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
ASSERT(buf_ != 0);
|
|
Packit |
8a864e |
encoder_->output(buf_, ptr_ - buf_, byteStream_);
|
|
Packit |
8a864e |
ptr_ = buf_;
|
|
Packit |
8a864e |
*ptr_++ = c;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void EncodeOutputCharStream::allocBuf(int bytesPerChar)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
const int blockSize = 1024;
|
|
Packit |
8a864e |
size_t bufSize = bytesPerChar ? blockSize/bytesPerChar : blockSize;
|
|
Packit |
8a864e |
ptr_ = buf_ = new Char[bufSize];
|
|
Packit |
8a864e |
end_ = buf_ + bufSize;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void EncodeOutputCharStream::setEscaper(Escaper f)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
escaper_ = f;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void EncodeOutputCharStream::handleUnencodable(Char c, OutputByteStream *)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
EncodeOutputCharStream tem(byteStream_, encoder_);
|
|
Packit |
8a864e |
if (escaper_)
|
|
Packit |
8a864e |
(*escaper_)(tem, c);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
StrOutputCharStream::StrOutputCharStream()
|
|
Packit |
8a864e |
: buf_(0), bufSize_(0)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
sync(0);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
StrOutputCharStream::~StrOutputCharStream()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
delete [] buf_;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void StrOutputCharStream::extractString(StringC &str)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
str.assign(buf_, ptr_ - buf_);
|
|
Packit |
8a864e |
sync(0);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void StrOutputCharStream::flushBuf(Char c)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
size_t used = ptr_ - buf_;
|
|
Packit |
8a864e |
size_t oldSize = bufSize_;
|
|
Packit |
8a864e |
bufSize_ = oldSize ? 2*oldSize : 10;
|
|
Packit |
8a864e |
Char *oldBuf = buf_;
|
|
Packit |
8a864e |
buf_ = new Char[bufSize_];
|
|
Packit |
8a864e |
if (oldSize) {
|
|
Packit |
8a864e |
memcpy(buf_, oldBuf, oldSize * sizeof(Char));
|
|
Packit |
8a864e |
delete [] oldBuf;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
sync(used);
|
|
Packit |
8a864e |
*ptr_++ = c;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void StrOutputCharStream::flush()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void StrOutputCharStream::sync(size_t length)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
ptr_ = buf_ + length;
|
|
Packit |
8a864e |
end_ = buf_ + bufSize_;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
RecordOutputCharStream::RecordOutputCharStream(OutputCharStream *os)
|
|
Packit |
8a864e |
: os_(os)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
ptr_ = buf_;
|
|
Packit |
8a864e |
end_ = buf_ + bufSize_;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
RecordOutputCharStream::~RecordOutputCharStream()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
outputBuf();
|
|
Packit |
8a864e |
delete os_;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void RecordOutputCharStream::setEscaper(Escaper f)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
os_->setEscaper(f);
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void RecordOutputCharStream::flush()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
outputBuf();
|
|
Packit |
8a864e |
os_->flush();
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void RecordOutputCharStream::flushBuf(Char c)
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
outputBuf();
|
|
Packit |
8a864e |
*ptr_++ = c;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
void RecordOutputCharStream::outputBuf()
|
|
Packit |
8a864e |
{
|
|
Packit |
8a864e |
Char *start = buf_;
|
|
Packit |
8a864e |
Char *p = start;
|
|
Packit |
8a864e |
while (p < ptr_) {
|
|
Packit |
8a864e |
switch (*p) {
|
|
Packit |
8a864e |
case '\r': // translate RE to newline
|
|
Packit |
8a864e |
if (start < p)
|
|
Packit |
8a864e |
os_->write(start, p - start);
|
|
Packit |
8a864e |
start = ++p;
|
|
Packit |
8a864e |
*os_ << newline;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
case '\n': // ignore RS
|
|
Packit |
8a864e |
if (start < p)
|
|
Packit |
8a864e |
os_->write(start, p - start);
|
|
Packit |
8a864e |
start = ++p;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
default:
|
|
Packit |
8a864e |
++p;
|
|
Packit |
8a864e |
break;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
if (start < p)
|
|
Packit |
8a864e |
os_->write(start, p - start);
|
|
Packit |
8a864e |
ptr_ = buf_;
|
|
Packit |
8a864e |
end_ = buf_ + bufSize_;
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
|
|
Packit |
8a864e |
#ifdef SP_NAMESPACE
|
|
Packit |
8a864e |
}
|
|
Packit |
8a864e |
#endif
|