From: Christian P. <cp...@us...> - 2005-07-04 23:36:24
|
Update of /cvsroot/pclasses/pclasses2/src/IO In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1650/src/IO Modified Files: Makefile.am Added Files: DataStream.cpp IODeviceStreamBuffer.cpp StreamBase.cpp StreamBuffer.cpp TextStream.cpp Log Message: - Added StreamBuffer, StreamBase - std::streams are not suitable for our needs - Added IODeviceStreamBuffer - buffers Streams and writes them to an IODevice - Added DataStream - portable data streaming - Added TextStream - unicode text streaming with on the fly codepage conversion Index: Makefile.am =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/IO/Makefile.am,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- Makefile.am 29 May 2005 17:48:31 -0000 1.12 +++ Makefile.am 4 Jul 2005 23:36:14 -0000 1.13 @@ -6,7 +6,8 @@ libpclasses_io_la_SOURCES = IOError.cpp IODevice.cpp IOStream.cpp \ IOFilter.cpp URL.cpp ZLib.cpp ZLibIOFilter.cpp BZip2.cpp BZip2IOFilter.cpp \ - IORequest.cpp IOHandler.cpp IOManager.cpp IOListener.cpp + IORequest.cpp IOHandler.cpp IOManager.cpp IOListener.cpp StreamBuffer.cpp \ + IODeviceStreamBuffer.cpp StreamBase.cpp DataStream.cpp TextStream.cpp libpclasses_io_la_LDFLAGS = -no-nundefined --- NEW FILE: TextStream.cpp --- /*************************************************************************** * Copyright (C) 2004 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "pclasses/IO/TextStream.h" #include "pclasses/IO/IODeviceStreamBuffer.h" namespace P { namespace IO { TextStream::TextStream(IO::IODevice& dev, size_t outBufferSize, size_t inBufferSize) : StreamBase(dev, outBufferSize, inBufferSize), _fmt(Dec), _width(0), _prec(0), _fillCh(' '), _converter(0) { } TextStream::TextStream(IO::StreamBuffer& buffer) throw() : StreamBase(buffer), _fmt(Dec), _width(0), _prec(0), _fillCh(' '), _converter(0) { } TextStream::~TextStream() throw() { } void TextStream::setFormat(Format fmt) throw() { _fmt = fmt; } void TextStream::setWidth(unsigned int width) throw() { _width = width; } void TextStream::setPrecision(unsigned int prec) throw() { _prec = prec; } void TextStream::setFill(Unicode::Char ch) throw() { _fillCh = ch; } void TextStream::setCodepage(const char* cp) { if(_converter) delete _converter; _converter = new Unicode::Converter(cp); } TextStream& TextStream::operator<<(Int8 val) { return *this; } TextStream& TextStream::operator<<(UInt8 val) { return *this; } TextStream& TextStream::operator<<(Int16 val) { return *this; } TextStream& TextStream::operator<<(UInt16 val) { return *this; } TextStream& TextStream::operator<<(Int32 val) { return *this; } TextStream& TextStream::operator<<(UInt32 val) { return *this; } #ifdef PCLASSES_HAVE_64BIT_INT TextStream& TextStream::operator<<(Int64 val) { return *this; } TextStream& TextStream::operator<<(UInt64 val) { return *this; } #endif TextStream& TextStream::operator<<(float val) { return *this; } TextStream& TextStream::operator<<(double val) { return *this; } #ifdef PCLASSES_HAVE_LONG_DOUBLE TextStream& TextStream::operator<<(long double val) { return *this; } #endif TextStream& TextStream::operator<<(const Unicode::Char& ch) { return *this; } TextStream& TextStream::operator<<(const Unicode::String& str) { if(!_converter) _converter = new Unicode::Converter(0); std::string cpStr = _converter->fromUnicode(str); (*this) << cpStr; return *this; } TextStream& TextStream::operator<<(const char* str) { writeRaw(str, std::strlen(str)); return *this; } TextStream& TextStream::operator<<(const std::string& str) { writeRaw(str.c_str(), str.size()); return *this; } TextStream& TextStream::operator<<(TextStream& (*__pfn)(TextStream& strm)) { (*__pfn)(*this); return *this; } TextStream& endl(TextStream& strm) { #ifdef PCLASSES_WITH_CR_LINEFEED strm << Unicode::Char::cr(); #endif strm << Unicode::Char::nl(); return strm; } TextStream& dec(TextStream& strm) { strm.setFormat(TextStream::Dec); return strm; } TextStream& hex(TextStream& strm) { strm.setFormat(TextStream::Hex); return strm; } TextStream& oct(TextStream& strm) { strm.setFormat(TextStream::Oct); return strm; } } // !namespace Unicode } // !namespace P --- NEW FILE: DataStream.cpp --- /*************************************************************************** * Copyright (C) 2005 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "pclasses/config.h" #include "pclasses/ScopedArrayPtr.h" #include "pclasses/IO/DataStream.h" #include "pclasses/IO/IODeviceStreamBuffer.h" #include <cstring> #ifdef WIN32 # define IEEE_FLOATING_POINT 1 #else #ifdef STDC_HEADERS # include <float.h> #endif #if (__STDC_IEC_559__ || (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \ && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)) # define IEEE_FLOATING_POINT 1 #else # define IEEE_FLOATING_POINT 0 #endif #endif namespace P { namespace IO { DataStream::DataStream(IODevice& dev, size_t outBufferSize, size_t inBufferSize) : StreamBase(dev, outBufferSize, inBufferSize), _byteOrder(BigEndian) { } DataStream::DataStream(StreamBuffer& buffer) throw() : StreamBase(buffer), _byteOrder(BigEndian) { } DataStream::~DataStream() throw() { } void DataStream::setByteOrder(ByteOrder b) throw() { _byteOrder = b; } DataStream::ByteOrder DataStream::byteOrder() const throw() { return _byteOrder; } template <class Type> Type byteOrderedVal(DataStream::ByteOrder byteOrder, Type val) { switch(byteOrder) { case DataStream::BigEndian: return val.bigEndian(); case DataStream::LittleEndian: return val.littleEndian(); case DataStream::Native: default: break; } return val; } template <class Type> IntType<Type> nativeOrderedVal(DataStream::ByteOrder fromByteOrder, Type val) { IntType<Type> ret; switch(fromByteOrder) { case DataStream::BigEndian: ret.setBigEndian(val); break; case DataStream::LittleEndian: ret.setLittleEndian(val); break; case DataStream::Native: default: ret = val; break; } return ret; } DataStream& DataStream::operator<<(Int8 val) { writeRaw((const char*)&val, sizeof(int8_t)); return *this; } DataStream& DataStream::operator<<(UInt8 val) { writeRaw((const char*)&val, sizeof(uint8_t)); return *this; } DataStream& DataStream::operator<<(Int16 val) { int16_t tmp = byteOrderedVal(_byteOrder, val); writeRaw((const char*)&tmp, sizeof(int16_t)); return *this; } DataStream& DataStream::operator<<(UInt16 val) { uint16_t tmp = byteOrderedVal(_byteOrder, val); writeRaw((const char*)&tmp, sizeof(uint16_t)); return *this; } DataStream& DataStream::operator<<(Int32 val) { int32_t tmp = byteOrderedVal(_byteOrder, val); writeRaw((const char*)&tmp, sizeof(int32_t)); return *this; } DataStream& DataStream::operator<<(UInt32 val) { uint32_t tmp = byteOrderedVal(_byteOrder, val); writeRaw((const char*)&tmp, sizeof(uint32_t)); return *this; } #ifdef PCLASSES_HAVE_64BIT_INT DataStream& DataStream::operator<<(Int64 val) { int64_t tmp = byteOrderedVal(_byteOrder, val); writeRaw((const char*)&tmp, sizeof(int64_t)); return *this; } DataStream& DataStream::operator<<(UInt64 val) { uint64_t tmp = byteOrderedVal(_byteOrder, val); writeRaw((const char*)&tmp, sizeof(uint64_t)); return *this; } #endif DataStream& DataStream::operator<<(float val) { #ifdef IEEE_FLOATING_POINT writeRaw((const char*)&val, sizeof(float)); #else #error "please fix me - architecture seems not IEE754" #endif return *this; } DataStream& DataStream::operator<<(double val) { #ifdef IEEE_FLOATING_POINT writeRaw((const char*)&val, sizeof(double)); #else #error "please fix me - architecture seems not IEE754" #endif return *this; } #ifdef PCLASSES_HAVE_LONG_DOUBLE DataStream& DataStream::operator<<(long double val) { #ifdef IEEE_FLOATING_POINT writeRaw((const char*)&val, sizeof(long double)); #else #error "please fix me - architecture seems not IEE754" #endif return *this; } #endif DataStream& DataStream::operator<<(const char* str) { write(str, std::strlen(str)); return *this; } DataStream& DataStream::operator<<(const std::string& str) { write(str.c_str(), str.size()); return *this; } DataStream& DataStream::operator>>(Int8& val) { readRaw((char*)&val, sizeof(int8_t)); return *this; } DataStream& DataStream::operator>>(UInt8& val) { readRaw((char*)&val, sizeof(uint8_t)); return *this; } DataStream& DataStream::operator>>(Int16& val) { int16_t tmp; readRaw((char*)&tmp, sizeof(int16_t)); val = nativeOrderedVal(_byteOrder, tmp); return *this; } DataStream& DataStream::operator>>(UInt16& val) { uint16_t tmp; readRaw((char*)&tmp, sizeof(uint16_t)); val = nativeOrderedVal(_byteOrder, tmp); return *this; } DataStream& DataStream::operator>>(Int32& val) { int32_t tmp; readRaw((char*)&tmp, sizeof(int32_t)); val = nativeOrderedVal(_byteOrder, tmp); return *this; } DataStream& DataStream::operator>>(UInt32& val) { uint32_t tmp; readRaw((char*)&tmp, sizeof(uint32_t)); val = nativeOrderedVal(_byteOrder, tmp); return *this; } #ifndef PCLASSES_HAVE_64BIT_INT DataStream& DataStream::operator>>(Int64& val) { int64_t tmp; readRaw((char*)&tmp, sizeof(int64_t)); val = nativeOrderedVal(_byteOrder, tmp); return *this; } DataStream& DataStream::operator>>(UInt64& val) { uint64_t tmp; readRaw((char*)&tmp, sizeof(uint64_t)); val = nativeOrderedVal(_byteOrder, tmp); return *this; } #endif DataStream& DataStream::operator>>(float& val) { #ifdef IEEE_FLOATING_POINT readRaw((char*)&val, sizeof(float)); #else #error "please fix me - architecture seems not IEE754" #endif return *this; } DataStream& DataStream::operator>>(double& val) { #ifdef IEEE_FLOATING_POINT readRaw((char*)&val, sizeof(double)); #else #error "please fix me - architecture seems not IEE754" #endif return *this; } #ifdef PCLASSES_HAVE_LONG_DOUBLE DataStream& DataStream::operator>>(long double& val) { #ifdef IEEE_FLOATING_POINT readRaw((char*)&val, sizeof(long double)); #else #error "please fix me - architecture seems not IEE754" #endif return *this; } #endif DataStream& DataStream::operator>>(std::string& str) { char* ret; size_t retLen; read(ret, retLen); str.assign(ret, retLen); delete[] ret; return *this; } DataStream& DataStream::write(const char* str, size_t count) throw(IOError) { DataStream::operator<<(UInt32(count)); writeRaw(str, count); DataStream::operator<<(UInt8(0)); return *this; } DataStream& DataStream::read(char*& str, size_t& count) throw(IOError) { UInt32 len; DataStream::operator>>(len); if(!eof()) { ScopedArrayPtr<char> ret(new char[len + 1]); len = readRaw(ret.get(), len + 1); str = ret.release(); str[len + 1] = 0; count = len; } else { str = new char[1]; str[0] = 0; count = 0; } return *this; } } // !namespace IO } // !namespace P --- NEW FILE: IODeviceStreamBuffer.cpp --- /*************************************************************************** * Copyright (C) 2005 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "pclasses/ScopedArrayPtr.h" #include "pclasses/IO/IODeviceStreamBuffer.h" namespace P { namespace IO { IODeviceStreamBuffer::IODeviceStreamBuffer(IODevice& dev, size_t outBufferSize, size_t inBufferSize) : _device(dev), _outBuffer(outBufferSize), _inBuffer(inBufferSize) { } IODeviceStreamBuffer::~IODeviceStreamBuffer() throw() { } IODevice& IODeviceStreamBuffer::device() const throw() { return _device; } bool IODeviceStreamBuffer::eof() const throw() { return (_inBuffer.empty() && _device.eof()); } // this methods ensures that at minimum <minCount> bytes are flushed from // the output queue to the device .... void flushBuffer(IODevice& device, CircularQueue<char>& buffer, size_t minCount = (size_t)-1) { size_t bufferSize = buffer.size(); if(minCount == (size_t)-1) minCount = bufferSize; ScopedArrayPtr<char> tmp(new char[bufferSize]); buffer.get(tmp.get(), bufferSize); size_t written = 0, totalWritten = 0; while(totalWritten < minCount) { written = device.write(tmp.get() + totalWritten, bufferSize - totalWritten); totalWritten += written; buffer.pop(written); // wait until we can write more data ... if(totalWritten < minCount && !device.isBlocking()) device.wait(IODevice::WaitOutput, (unsigned int)-1); } } // this method ensures that at mimum <minCount> bytes are flushed from // the given buffer to the device ... size_t writeRawBuffer(IODevice& device, const char* buffer, size_t count, size_t minCount) { size_t written = 0, totalWritten = 0; while(totalWritten < minCount) { written = device.write(buffer + totalWritten, count - totalWritten); totalWritten += written; // wait until we can write more data ... if(totalWritten < minCount && !device.isBlocking()) device.wait(IODevice::WaitOutput, (unsigned int)-1); } return totalWritten; } void IODeviceStreamBuffer::sync() throw(IOError) { flushBuffer(_device, _outBuffer); } void IODeviceStreamBuffer::write(const char* buffer, size_t count) throw(IOError) { size_t capacity = _outBuffer.capacity(); // the bytes will never fit into our output buffer ... if(count > capacity) { // flush the hole output buffer ... flushBuffer(_device, _outBuffer); // write as many as we can .. but minimum that our output buffer can hold // the rest of it ... size_t written = writeRawBuffer(_device, buffer, count, count - capacity); // buffer unwritten bytes ... _outBuffer.push(buffer + written, count - written); } else { size_t size = _outBuffer.size(); // flush bytes from the output buffer until the bytes fit ... if(size + count > capacity) { size_t flushBytes = (size + count) - capacity; flushBuffer(_device, _outBuffer, flushBytes); } // buffer the bytes ... _outBuffer.push(buffer, count); } } size_t IODeviceStreamBuffer::read(char* buffer, size_t count) throw(IOError) { return 0; //@todo } } // !namespace IO } // !namespace P --- NEW FILE: StreamBuffer.cpp --- /*************************************************************************** * Copyright (C) 2005 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "pclasses/IO/StreamBuffer.h" namespace P { namespace IO { StreamBuffer::StreamBuffer() { } StreamBuffer::~StreamBuffer() throw() { } } // !namespace IO } // !namespace P --- NEW FILE: StreamBase.cpp --- /*************************************************************************** * Copyright (C) 2005 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "pclasses/IO/StreamBase.h" #include "pclasses/IO/StreamBuffer.h" #include "pclasses/IO/IODeviceStreamBuffer.h" namespace P { namespace IO { StreamBase::StreamBase(IODevice& dev, size_t outBufferSize, size_t inBufferSize) : _ownBuffer(true), _buffer(new IODeviceStreamBuffer(dev, outBufferSize, inBufferSize)) { } StreamBase::StreamBase(StreamBuffer& buffer) throw() : _ownBuffer(false), _buffer(&buffer) { } StreamBase::~StreamBase() throw() { try { _buffer->sync(); } catch(...) { } if(_ownBuffer) { delete _buffer; _buffer = 0; } } StreamBuffer& StreamBase::buffer() const throw() { return *_buffer; } bool StreamBase::eof() const throw() { return _buffer->eof(); } void StreamBase::sync() throw(IOError) { _buffer->sync(); } void StreamBase::writeRaw(const char* buffer, size_t count) throw(IOError) { _buffer->write(buffer, count); } size_t StreamBase::readRaw(char* buffer, size_t count) throw(IOError) { return _buffer->read(buffer, count); } } // !namespace IO } // !namespace P |