// Copyright (c) 1997 James Clark // See the file COPYING for copying permission. #include "splib.h" #include "OutputByteStream.h" #include #ifdef SP_INCLUDE_IO_H #include // for open, fstat, lseek, read prototypes #endif #ifdef SP_INCLUDE_UNISTD_H #include #endif #ifdef SP_INCLUDE_OSFCN_H #include #endif #include #include #include #include #ifdef SP_WIDE_SYSTEM #define STRICT #include #endif #ifndef O_CREAT #ifdef _O_CREAT #define O_CREAT _O_CREAT #endif #endif #ifndef O_WRONLY #ifdef _O_WRONLY #define O_WRONLY _O_WRONLY #endif #endif #ifndef O_TRUNC #ifdef _O_TRUNC #define O_TRUNC _O_TRUNC #endif #endif #ifndef O_BINARY #ifdef _O_BINARY #define O_BINARY _O_BINARY #else #define O_BINARY 0 #endif #endif #ifndef S_IRUSR #if defined(S_IREAD) #define S_IRUSR S_IREAD #elif defined(_S_IREAD) #define S_IRUSR _S_IREAD #else #define S_IRUSR 0400 #endif #endif #ifndef S_IWUSR #if defined(S_IWRITE) #define S_IWUSR S_IWRITE #elif defined(_S_IWRITE) #define S_IWUSR _S_IWRITE #else #define S_IWUSR 0200 #endif #endif #ifndef S_IRGRP #if defined(S_IREAD) #define S_IRGRP S_IREAD #elif defined(_S_IREAD) #define S_IRGRP _S_IREAD #else #define S_IRGRP 0040 #endif #endif #ifndef S_IWGRP #if defined(S_IWRITE) #define S_IWGRP S_IWRITE #elif defined(_S_IWRITE) #define S_IWGRP _S_IWRITE #else #define S_IWGRP 0020 #endif #endif #ifndef S_IROTH #if defined(S_IREAD) #define S_IROTH S_IREAD #elif defined(_S_IREAD) #define S_IROTH _S_IREAD #else #define S_IROTH 0004 #endif #endif #ifndef S_IWOTH #if defined(S_IWRITE) #define S_IWOTH S_IWRITE #elif defined(_S_IWRITE) #define S_IWOTH _S_IWRITE #else #define S_IWOTH 0002 #endif #endif #ifdef SP_NAMESPACE namespace SP_NAMESPACE { #endif const int openFlags = O_CREAT|O_WRONLY|O_TRUNC|O_BINARY; const int protMode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; const int bufSize = 8192; OutputByteStream::OutputByteStream() : ptr_(0), end_(0) { } OutputByteStream::~OutputByteStream() { } void OutputByteStream::sputn(const char *s, size_t n) { for (; n > 0; n--, s++) sputc(*s); } OutputByteStream &OutputByteStream::operator<<(long n) { char buf[32]; sprintf(buf, "%ld", n); return *this << buf; } OutputByteStream &OutputByteStream::operator<<(unsigned long n) { char buf[32]; sprintf(buf, "%lu", n); return *this << buf; } OutputByteStream &OutputByteStream::operator<<(const char *s) { while (*s) sputc(*s++); return *this; } StrOutputByteStream::StrOutputByteStream() { } void StrOutputByteStream::extractString(String &str) { if (ptr_) buf_.resize(ptr_ - &buf_[0]); str.resize(0); buf_.swap(str); ptr_ = end_ = 0; } void StrOutputByteStream::flush() { } void StrOutputByteStream::flushBuf(char c) { if (!ptr_) { buf_.resize(16); ptr_ = &buf_[0]; } else { size_t i = ptr_ - &buf_[0]; buf_.resize(buf_.size()*2); ptr_ = &buf_[0] + i; } end_ = &buf_[0] + buf_.size(); *ptr_++ = c; } FileOutputByteStream::FileOutputByteStream() : fd_(-1) { } FileOutputByteStream::FileOutputByteStream(int fd, Boolean closeFd) : fd_(-1) { attach(fd, closeFd); } FileOutputByteStream::~FileOutputByteStream() { close(); } #ifdef SP_WIDE_SYSTEM Boolean FileOutputByteStream::open(const wchar_t *filename) { int fd = _wopen(filename, openFlags, protMode); if (fd >= 0) return attach(fd); // _wopen will always fail on Windows 95 String buf; int len = WideCharToMultiByte(CP_ACP, 0, filename, -1, 0, 0, 0, 0); buf.resize(len + 1); WideCharToMultiByte(CP_ACP, 0, filename, -1, buf.begin(), len, 0, 0); buf[len] = '\0'; return attach(::open(buf.data(), openFlags, protMode)); } #else /* not SP_WIDE_SYSTEM */ Boolean FileOutputByteStream::open(const char *filename) { return attach(::open(filename, openFlags, protMode)); } #endif /* not SP_WIDE_SYSTEM */ Boolean FileOutputByteStream::attach(int fd, Boolean closeFd) { close(); fd_ = fd; closeFd_ = closeFd; return fd_ >= 0; } Boolean FileOutputByteStream::close() { if (fd_ < 0) return 0; flush(); int fd = fd_; fd_ = -1; if (!closeFd_) return 1; return ::close(fd) == 0; } void FileOutputByteStream::flush() { if (!buf_.size()) { if (fd_ < 0) return; buf_.resize(bufSize); ptr_ = &buf_[0]; end_ = ptr_ + buf_.size(); } size_t n = ptr_ - &buf_[0]; const char *s = buf_.data(); while (n > 0) { int nw = ::write(fd_, s, n); if (nw < 0) break; n -= nw; s += nw; } ptr_ = &buf_[0]; } void FileOutputByteStream::flushBuf(char c) { flush(); *ptr_++ = c; } #ifdef SP_NAMESPACE } #endif