diff --git a/Foundation/src/Base64Decoder.cpp b/Foundation/src/Base64Decoder.cpp index bf2c06459..21cb6c97e 100644 --- a/Foundation/src/Base64Decoder.cpp +++ b/Foundation/src/Base64Decoder.cpp @@ -1,7 +1,7 @@ // // Base64Decoder.cpp // -// $Id: //poco/svn/Foundation/src/Base64Decoder.cpp#2 $ +// $Id: //poco/1.4/Foundation/src/Base64Decoder.cpp#2 $ // // Library: Foundation // Package: Streams @@ -47,15 +47,20 @@ unsigned char Base64DecoderBuf::IN_ENCODING[256]; bool Base64DecoderBuf::IN_ENCODING_INIT = false; -Base64DecoderBuf::Base64DecoderBuf(std::istream& istr): - _groupLength(0), - _groupIndex(0), - _istr(istr) +namespace { - static FastMutex mutex; - FastMutex::ScopedLock lock(mutex); - if (!IN_ENCODING_INIT) - { + static FastMutex mutex; +} + + +Base64DecoderBuf::Base64DecoderBuf(std::istream& istr): + _groupLength(0), + _groupIndex(0), + _buf(*istr.rdbuf()) +{ + FastMutex::ScopedLock lock(mutex); + if (!IN_ENCODING_INIT) + { for (unsigned i = 0; i < sizeof(IN_ENCODING); i++) { IN_ENCODING[i] = 0xFF; @@ -85,19 +90,19 @@ int Base64DecoderBuf::readFromDevice() { unsigned char buffer[4]; int c; - if ((c = readOne()) == -1) return -1; - buffer[0] = (unsigned char) c; - if (IN_ENCODING[buffer[0]] == 0xFF) throw DataFormatException(); - if ((c = readOne()) == -1) return -1; - buffer[1] = (unsigned char) c; - if (IN_ENCODING[buffer[1]] == 0xFF) throw DataFormatException(); - if ((c = readOne()) == -1) return -1; - buffer[2] = c; - if (IN_ENCODING[buffer[2]] == 0xFF) throw DataFormatException(); - if ((c = readOne()) == -1) return -1; - buffer[3] = c; - if (IN_ENCODING[buffer[3]] == 0xFF) throw DataFormatException(); - + if ((c = readOne()) == -1) return -1; + buffer[0] = (unsigned char) c; + if (IN_ENCODING[buffer[0]] == 0xFF) throw DataFormatException(); + if ((c = readOne()) == -1) throw DataFormatException(); + buffer[1] = (unsigned char) c; + if (IN_ENCODING[buffer[1]] == 0xFF) throw DataFormatException(); + if ((c = readOne()) == -1) throw DataFormatException(); + buffer[2] = c; + if (IN_ENCODING[buffer[2]] == 0xFF) throw DataFormatException(); + if ((c = readOne()) == -1) throw DataFormatException(); + buffer[3] = c; + if (IN_ENCODING[buffer[3]] == 0xFF) throw DataFormatException(); + _group[0] = (IN_ENCODING[buffer[0]] << 2) | (IN_ENCODING[buffer[1]] >> 4); _group[1] = ((IN_ENCODING[buffer[1]] & 0x0F) << 4) | (IN_ENCODING[buffer[2]] >> 2); _group[2] = (IN_ENCODING[buffer[2]] << 6) | IN_ENCODING[buffer[3]]; @@ -116,10 +121,10 @@ int Base64DecoderBuf::readFromDevice() int Base64DecoderBuf::readOne() { - int ch = _istr.get(); - while (ch == ' ' || ch == '\r' || ch == '\t' || ch == '\n') - ch = _istr.get(); - return ch; + int ch = _buf.sbumpc(); + while (ch == ' ' || ch == '\r' || ch == '\t' || ch == '\n') + ch = _buf.sbumpc(); + return ch; } diff --git a/Foundation/src/Base64Encoder.cpp b/Foundation/src/Base64Encoder.cpp index 80ce12146..178469458 100644 --- a/Foundation/src/Base64Encoder.cpp +++ b/Foundation/src/Base64Encoder.cpp @@ -1,7 +1,7 @@ // // Base64Encoder.cpp // -// $Id: //poco/svn/Foundation/src/Base64Encoder.cpp#2 $ +// $Id: //poco/1.4/Foundation/src/Base64Encoder.cpp#2 $ // // Library: Foundation // Package: Streams @@ -54,10 +54,10 @@ const unsigned char Base64EncoderBuf::OUT_ENCODING[64] = Base64EncoderBuf::Base64EncoderBuf(std::ostream& ostr): - _groupLength(0), - _pos(0), - _lineLength(72), - _ostr(ostr) + _groupLength(0), + _pos(0), + _lineLength(72), + _buf(*ostr.rdbuf()) { } @@ -88,58 +88,63 @@ int Base64EncoderBuf::getLineLength() const int Base64EncoderBuf::writeToDevice(char c) { - _group[_groupLength++] = (unsigned char) c; - if (_groupLength == 3) - { - unsigned char idx; - idx = _group[0] >> 2; - _ostr.put(OUT_ENCODING[idx]); - idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4); - _ostr.put(OUT_ENCODING[idx]); - idx = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6); - _ostr.put(OUT_ENCODING[idx]); - idx = _group[2] & 0x3F; - _ostr.put(OUT_ENCODING[idx]); - _pos += 4; - if (_lineLength > 0 && _pos >= _lineLength) - { - _ostr << "\r\n"; - _pos = 0; - } - _groupLength = 0; - } - return _ostr ? charToInt(c) : -1; + static const int eof = std::char_traits::eof(); + + _group[_groupLength++] = (unsigned char) c; + if (_groupLength == 3) + { + unsigned char idx; + idx = _group[0] >> 2; + if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; + idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4); + if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; + idx = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6); + if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; + idx = _group[2] & 0x3F; + if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; + _pos += 4; + if (_lineLength > 0 && _pos >= _lineLength) + { + if (_buf.sputc('\r') == eof) return eof; + if (_buf.sputc('\n') == eof) return eof; + _pos = 0; + } + _groupLength = 0; + } + return charToInt(c); } int Base64EncoderBuf::close() { - sync(); - if (_groupLength == 1) - { - _group[1] = 0; - unsigned char idx; - idx = _group[0] >> 2; - _ostr.put(OUT_ENCODING[idx]); - idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4); - _ostr.put(OUT_ENCODING[idx]); - _ostr << "=="; - } - else if (_groupLength == 2) - { - _group[2] = 0; - unsigned char idx; - idx = _group[0] >> 2; - _ostr.put(OUT_ENCODING[idx]); - idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4); - _ostr.put(OUT_ENCODING[idx]); - idx = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6); - _ostr.put(OUT_ENCODING[idx]); - _ostr.put('='); - } - _ostr.flush(); - _groupLength = 0; - return _ostr ? 0 : -1; + static const int eof = std::char_traits::eof(); + + if (sync() == eof) return eof; + if (_groupLength == 1) + { + _group[1] = 0; + unsigned char idx; + idx = _group[0] >> 2; + if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; + idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4); + if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; + if (_buf.sputc('=') == eof) return eof; + if (_buf.sputc('=') == eof) return eof; + } + else if (_groupLength == 2) + { + _group[2] = 0; + unsigned char idx; + idx = _group[0] >> 2; + if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; + idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4); + if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; + idx = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6); + if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof; + if (_buf.sputc('=') == eof) return eof; + } + _groupLength = 0; + return _buf.pubsync(); } diff --git a/Foundation/src/BinaryReader.cpp b/Foundation/src/BinaryReader.cpp index c84cc729a..c87bafdc8 100644 --- a/Foundation/src/BinaryReader.cpp +++ b/Foundation/src/BinaryReader.cpp @@ -1,7 +1,7 @@ // // BinaryReader.cpp // -// $Id: //poco/svn/Foundation/src/BinaryReader.cpp#2 $ +// $Id: //poco/1.4/Foundation/src/BinaryReader.cpp#1 $ // // Library: Foundation // Package: Streams @@ -36,16 +36,32 @@ #include "Poco/BinaryReader.h" #include "Poco/ByteOrder.h" +#include "Poco/TextEncoding.h" +#include "Poco/TextConverter.h" +#include namespace Poco { BinaryReader::BinaryReader(std::istream& istr, StreamByteOrder byteOrder): - _istr(istr) + _istr(istr), + _pTextConverter(0) { #if defined(POCO_ARCH_BIG_ENDIAN) - _flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER); + _flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER); +#else + _flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER); +#endif +} + + +BinaryReader::BinaryReader(std::istream& istr, TextEncoding& encoding, StreamByteOrder byteOrder): + _istr(istr), + _pTextConverter(new TextConverter(encoding, Poco::TextEncoding::global())) +{ +#if defined(POCO_ARCH_BIG_ENDIAN) + _flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER); #else _flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER); #endif @@ -54,6 +70,7 @@ BinaryReader::BinaryReader(std::istream& istr, StreamByteOrder byteOrder): BinaryReader::~BinaryReader() { + delete _pTextConverter; } @@ -199,17 +216,24 @@ BinaryReader& BinaryReader::operator >> (UInt64& value) BinaryReader& BinaryReader::operator >> (std::string& value) { - UInt32 size = 0; - read7BitEncoded(size); - value.clear(); - value.reserve(size); - while (size--) - { - char c; - _istr.read(&c, 1); - value += c; - } - return *this; + UInt32 size = 0; + read7BitEncoded(size); + value.clear(); + if (!_istr.good()) return *this; + value.reserve(size); + while (size--) + { + char c; + if (!_istr.read(&c, 1).good()) break; + value += c; + } + if (_pTextConverter) + { + std::string converted; + _pTextConverter->convert(value, converted); + std::swap(value, converted); + } + return *this; } @@ -255,22 +279,28 @@ void BinaryReader::read7BitEncoded(UInt64& value) #endif -void BinaryReader::readRaw(int length, std::string& value) +void BinaryReader::readRaw(std::streamsize length, std::string& value) { - value.clear(); - value.reserve(length); - while (length--) - { - char c; - _istr.read(&c, 1); - value += c; - } + value.clear(); + value.reserve(static_cast(length)); + while (length--) + { + char c; + if (!_istr.read(&c, 1).good()) break; + value += c; + } +} + + +void BinaryReader::readRaw(char* buffer, std::streamsize length) +{ + _istr.read(buffer, length); } void BinaryReader::readBOM() { - UInt16 bom; + UInt16 bom; _istr.read((char*) &bom, sizeof(bom)); _flipBytes = bom != 0xFEFF; } diff --git a/Foundation/src/BinaryWriter.cpp b/Foundation/src/BinaryWriter.cpp index a7ed95779..e99ba44d6 100644 --- a/Foundation/src/BinaryWriter.cpp +++ b/Foundation/src/BinaryWriter.cpp @@ -1,7 +1,7 @@ // // BinaryWriter.cpp // -// $Id: //poco/svn/Foundation/src/BinaryWriter.cpp#2 $ +// $Id: //poco/1.4/Foundation/src/BinaryWriter.cpp#1 $ // // Library: Foundation // Package: Streams @@ -36,6 +36,8 @@ #include "Poco/BinaryWriter.h" #include "Poco/ByteOrder.h" +#include "Poco/TextEncoding.h" +#include "Poco/TextConverter.h" #include @@ -43,10 +45,23 @@ namespace Poco { BinaryWriter::BinaryWriter(std::ostream& ostr, StreamByteOrder byteOrder): - _ostr(ostr) + _ostr(ostr), + _pTextConverter(0) { #if defined(POCO_ARCH_BIG_ENDIAN) - _flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER); + _flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER); +#else + _flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER); +#endif +} + + +BinaryWriter::BinaryWriter(std::ostream& ostr, TextEncoding& encoding, StreamByteOrder byteOrder): + _ostr(ostr), + _pTextConverter(new TextConverter(Poco::TextEncoding::global(), encoding)) +{ +#if defined(POCO_ARCH_BIG_ENDIAN) + _flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER); #else _flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER); #endif @@ -55,6 +70,7 @@ BinaryWriter::BinaryWriter(std::ostream& ostr, StreamByteOrder byteOrder): BinaryWriter::~BinaryWriter() { + delete _pTextConverter; } @@ -256,20 +272,43 @@ BinaryWriter& BinaryWriter::operator << (UInt64 value) BinaryWriter& BinaryWriter::operator << (const std::string& value) { - UInt32 length = (UInt32) value.size(); - write7BitEncoded(length); - _ostr.write(value.data(), length); - return *this; + if (_pTextConverter) + { + std::string converted; + _pTextConverter->convert(value, converted); + UInt32 length = (UInt32) converted.size(); + write7BitEncoded(length); + _ostr.write(converted.data(), length); + } + else + { + UInt32 length = (UInt32) value.size(); + write7BitEncoded(length); + _ostr.write(value.data(), length); + } + return *this; } BinaryWriter& BinaryWriter::operator << (const char* value) { - poco_check_ptr (value); - UInt32 length = (UInt32) std::strlen(value); - write7BitEncoded(length); - _ostr.write(value, length); - return *this; + poco_check_ptr (value); + + if (_pTextConverter) + { + std::string converted; + _pTextConverter->convert(value, static_cast(std::strlen(value)), converted); + UInt32 length = (UInt32) converted.size(); + write7BitEncoded(length); + _ostr.write(converted.data(), length); + } + else + { + UInt32 length = static_cast(std::strlen(value)); + write7BitEncoded(length); + _ostr.write(value, length); + } + return *this; } @@ -311,9 +350,15 @@ void BinaryWriter::writeRaw(const std::string& rawData) } +void BinaryWriter::writeRaw(const char* buffer, std::streamsize length) +{ + _ostr.write(buffer, length); +} + + void BinaryWriter::writeBOM() { - UInt16 value = 0xFEFF; + UInt16 value = 0xFEFF; if (_flipBytes) value = ByteOrder::flipBytes(value); _ostr.write((const char*) &value, sizeof(value)); }