00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #if defined HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030
00031
00032
00033 #include "io_decorators.h"
00034 #include "utils.h"
00035 #include "zlib.h"
00036
00037 using namespace dami;
00038
00039 void io::WindowedReader::setWindow(pos_type beg, size_type size)
00040 {
00041 ID3D_NOTICE( "WindowedReader::setWindow() [beg, size] = [" <<
00042 this->getBeg() << ", " << size << "]" );
00043 pos_type cur = this->getCur();
00044
00045
00046 this->setEnd(_reader.getEnd());
00047
00048
00049 this->setBeg(beg);
00050
00051
00052
00053 this->setCur(beg);
00054 ID3D_NOTICE( "WindowedReader::setWindow(): after setCur(beg), cur = "<<
00055 this->getCur() );
00056
00057 this->skipChars(size);
00058 ID3D_NOTICE( "WindowedReader::setWindow(): after skipChars, cur = " <<
00059 this->getCur() );
00060
00061 this->setEnd(this->getCur());
00062
00063 ID3D_NOTICE( "WindowedReader::setWindow() [beg, cur, end] = [" << this->getBeg() << ", " << this->getCur() << ", " << this->getEnd() << "]" );
00064
00065
00066
00067 this->setCur(cur);
00068 }
00069
00070 ID3_Reader::pos_type io::WindowedReader::setBeg(pos_type beg)
00071 {
00072
00073
00074 if (beg <= this->getEnd() && beg >= _reader.getBeg())
00075 {
00076 _beg = beg;
00077 }
00078 else if (beg > this->getEnd())
00079 {
00080 ID3D_WARNING( "WindowedReader::setBeg() failed, [beg, _end] = " <<
00081 beg << ", " << this->getEnd() << "]" );
00082 }
00083 else
00084 {
00085 ID3D_WARNING( "WindowedReader::setBeg() failed, [beg, _beg] = " <<
00086 beg << ", " << this->getBeg() << "]" );
00087 }
00088 return _beg;
00089 }
00090
00091 ID3_Reader::pos_type io::WindowedReader::setEnd(pos_type end)
00092 {
00093
00094
00095 if (this->getBeg() <= end && end <= _reader.getEnd())
00096 {
00097 _end = end;
00098 }
00099 else
00100 {
00101 ID3D_WARNING( "WindowedReader::setEnd() failed, end = " << end );
00102 ID3D_WARNING( "WindowedReader::setEnd() failed, beg = " <<
00103 this->getBeg() );
00104 ID3D_WARNING( "WindowedReader::setEnd() failed, super.end = " <<
00105 _reader.getEnd() );
00106
00107 }
00108 return _end;
00109 }
00110
00111 ID3_Reader::int_type io::WindowedReader::readChar()
00112 {
00113 int_type ch = END_OF_READER;
00114 if (this->inWindow())
00115 {
00116 ch = _reader.readChar();
00117 }
00118 else
00119 {
00120 ID3D_WARNING( "io::WindowedReader::readChar: not in window, " <<
00121 "pos = " << this->getCur() << ", window = [" <<
00122 this->getBeg() << ", " << this->getEnd() << "]");
00123 }
00124 return ch;
00125 }
00126
00127 ID3_Reader::int_type io::WindowedReader::peekChar()
00128 {
00129 int_type ch = END_OF_READER;
00130 if (this->inWindow())
00131 {
00132 ch = _reader.peekChar();
00133 }
00134 return ch;
00135 }
00136
00137 ID3_Reader::size_type io::WindowedReader::readChars(char_type buf[], size_type len)
00138 {
00139 pos_type cur = this->getCur();
00140 size_type size = 0;
00141 if (this->inWindow(cur))
00142 {
00143 size = _reader.readChars(buf, min<size_type>(len, _end - cur));
00144 }
00145 return size;
00146 }
00147
00148 ID3_Reader::size_type io::CharReader::readChars(char_type buf[], size_type len)
00149 {
00150 size_type numChars = 0;
00151 ID3D_NOTICE( "CharReader::readChars(): len = " << len );
00152 for (; numChars < len; ++numChars)
00153 {
00154 if (this->atEnd())
00155 {
00156 break;
00157 }
00158 char_type ch = this->readChar();
00159 if (buf != NULL)
00160 {
00161 buf[numChars] = ch;
00162 }
00163 }
00164 ID3D_NOTICE( "CharReader::readChars(): numChars = " << len );
00165 return numChars;
00166 }
00167
00168 ID3_Reader::int_type io::LineFeedReader::readChar()
00169 {
00170 if (this->atEnd())
00171 {
00172 return END_OF_READER;
00173 }
00174 char_type ch = _reader.readChar();
00175 if (ch == 0x0D && this->peekChar() == 0x0A)
00176 {
00177 ID3D_NOTICE( "LineFeedReader::readChar(): found CRLF at pos " <<
00178 this->getCur() );
00179 ch = _reader.readChar();
00180 }
00181 return ch;
00182 };
00183
00184 ID3_Reader::int_type io::UnsyncedReader::readChar()
00185 {
00186 if (this->atEnd())
00187 {
00188 return END_OF_READER;
00189 }
00190 char_type ch = _reader.readChar();
00191 if (ch == 0xFF && this->peekChar() == 0x00)
00192 {
00193 ID3D_NOTICE( "UnsyncedReader::readChar(): found sync at pos " <<
00194 this->getCur() );
00195 _reader.readChar();
00196 }
00197 return ch;
00198 }
00199
00200 io::CompressedReader::CompressedReader(ID3_Reader& reader, size_type newSize)
00201 : _uncompressed(new char_type[newSize])
00202 {
00203 size_type oldSize = reader.remainingBytes();
00204
00205 BString binary = readBinary(reader, oldSize);
00206
00207 ::uncompress(_uncompressed,
00208 reinterpret_cast<luint*>(&newSize),
00209 reinterpret_cast<const uchar*>(binary.data()),
00210 oldSize);
00211 this->setBuffer(_uncompressed, newSize);
00212 }
00213
00214 io::CompressedReader::~CompressedReader()
00215 {
00216 delete [] _uncompressed;
00217 }
00218
00219 ID3_Writer::int_type io::UnsyncedWriter::writeChar(char_type ch)
00220 {
00221 if (_last == 0xFF && (ch == 0x00 || ch >= 0xE0))
00222 {
00223 _writer.writeChar('\0');
00224 _numSyncs++;
00225 }
00226 _last = _writer.writeChar(ch);
00227 return _last;
00228 }
00229
00230 void io::UnsyncedWriter::flush()
00231 {
00232 if (_last == 0xFF)
00233 {
00234 _last = _writer.writeChar('\0');
00235 _numSyncs++;
00236 }
00237 _writer.flush();
00238 }
00239
00240 ID3_Writer::size_type
00241 io::UnsyncedWriter::writeChars(const char_type buf[], size_type len)
00242 {
00243 pos_type beg = this->getCur();
00244 ID3D_NOTICE( "UnsyncedWriter::writeChars(): len = " << len );
00245 for (size_t i = 0; i < len; ++i)
00246 {
00247 if (this->atEnd())
00248 {
00249 break;
00250 }
00251 this->writeChar(buf[i]);
00252 }
00253 size_type numChars = this->getCur() - beg;
00254 ID3D_NOTICE( "CharWriter::writeChars(): numChars = " << numChars );
00255 return numChars;
00256 }
00257
00258 void io::CompressedWriter::flush()
00259 {
00260 if (_data.size() == 0)
00261 {
00262 return;
00263 }
00264 const char_type* data = reinterpret_cast<const char_type*>(_data.data());
00265 size_type dataSize = _data.size();
00266 _origSize = dataSize;
00267
00268
00269
00270 unsigned long newDataSize = dataSize + (dataSize / 10) + 12;
00271 char_type* newData = new char_type[newDataSize];
00272 if (::compress(newData, &newDataSize, data, dataSize) != Z_OK)
00273 {
00274
00275 ID3D_WARNING("io::CompressedWriter: error compressing");
00276 _writer.writeChars(data, dataSize);
00277 }
00278 else if (newDataSize < dataSize)
00279 {
00280 ID3D_NOTICE("io::CompressedWriter: compressed size = " << newDataSize << ", original size = " << dataSize );
00281 _writer.writeChars(newData, newDataSize);
00282 }
00283 else
00284 {
00285 ID3D_NOTICE("io::CompressedWriter: no compression!compressed size = " << newDataSize << ", original size = " << dataSize );
00286 _writer.writeChars(data, dataSize);
00287 }
00288 delete [] newData;
00289 _data.erase();
00290 }
00291
00292 ID3_Writer::size_type
00293 io::CompressedWriter::writeChars(const char_type buf[], size_type len)
00294 {
00295 ID3D_NOTICE("io::CompressedWriter: writing chars: " << len );
00296 _data.append(buf, len);
00297 return len;
00298 }