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