Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

src/io_decorators.cpp

Go to the documentation of this file.
00001 // $Id: io_decorators.cpp,v 1.2 2000/10/29 01:37:29 eldamitri Exp $
00002 
00003 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
00004 // Copyright 1999, 2000  Scott Thomas Haug
00005 
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Library General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or (at your
00009 // option) any later version.
00010 //
00011 // This library is distributed in the hope that it will be useful, but WITHOUT
00012 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014 // License for more details.
00015 //
00016 // You should have received a copy of the GNU Library General Public License
00017 // along with this library; if not, write to the Free Software Foundation,
00018 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00019 
00020 // The id3lib authors encourage improvements and optimisations to be sent to
00021 // the id3lib coordinator.  Please see the README file for details on where to
00022 // send such submissions.  See the AUTHORS file for a list of people who have
00023 // contributed to id3lib.  See the ChangeLog file for a list of changes to
00024 // id3lib.  These files are distributed with id3lib at
00025 // http://download.sourceforge.net/id3lib/
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   // reset the end marker so as to avoid errors
00046   this->setEnd(_reader.getEnd());
00047   
00048   // set the beginning marker
00049   this->setBeg(beg);
00050   
00051   // since the characters might be more than a byte in size, we need to 
00052   // manually get all the chars to set the window appropriately
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   // reset the stream
00067   this->setCur(cur);
00068 }
00069 
00070 ID3_Reader::pos_type io::WindowedReader::setBeg(pos_type beg)
00071 {
00072   // make sure the position we want to set to isn't past the current
00073   // end position or the superclass's beginning position
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   // make sure the position we want to set to isn't beforen the current
00094   // beginning position or the superclass's end position
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   // The zlib documentation specifies that the destination size needs to
00268   // be an unsigned long at least 0.1% larger than the source buffer,
00269   // plus 12 bytes
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     // log this
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 }

Generated at Sat Sep 8 15:51:09 2001 for id3lib by doxygen1.2.8 written by Dimitri van Heesch, © 1997-2001