actual/packages/node-libofx/OpenSP-1.5.2/lib/OutputCharStream.cxx
2022-04-28 22:44:38 -04:00

261 lines
4.8 KiB
C++

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