Go to the documentation of this file.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