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