Blame lib/OutputCharStream.cxx

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