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

src/frame_parse.cpp

Go to the documentation of this file.
00001 // $Id: frame_parse.cpp,v 1.31 2001/08/05 21:18:26 abscess 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 "frame_impl.h"
00034 #include "utils.h"
00035 #include "io_decorators.h"
00036 
00037 using namespace dami;
00038 
00039 namespace
00040 {
00041   bool parseFields(ID3_Reader& rdr, ID3_FrameImpl& frame)
00042   {
00043     io::ExitTrigger et(rdr);
00044     ID3_TextEnc enc = ID3TE_ASCII;  // set the default encoding 
00045     ID3_V2Spec spec = frame.GetSpec(); 
00046     // parse the frame's fields  
00047     ID3D_NOTICE( "ID3_FrameImpl::Parse(): num_fields = " << 
00048                  frame.NumFields() );
00049     for (ID3_FrameImpl::iterator fi = frame.begin(); fi != frame.end(); ++fi)
00050     {
00051       ID3_Field* fp = *fi;
00052 
00053       if (rdr.atEnd())
00054       { 
00055         // there's no remaining data to parse! 
00056         ID3D_WARNING( "ID3_FrameImpl::Parse(): out of data at postion " <<
00057                       rdr.getCur() );
00058         if(fp->GetType() == ID3FTY_TEXTSTRING)  //correct handling of winamp-esque empty frames
00059                 {
00060                         // Exit the loop (don't just return true).
00061                         // This will set the current "pointer" of the reader to the correct value
00062                         break;
00063                 }
00064 
00065         return false;
00066       } 
00067       
00068       if (NULL == fp)
00069       {
00070         // Ack!  Why is the field NULL?  Log this...
00071         ID3D_WARNING( "ID3_FrameImpl::Parse(): field is null" );
00072         continue;
00073       }
00074       
00075       if (!fp->InScope(spec)) 
00076       {
00077         ID3D_NOTICE( "ID3_FrameImpl::Parse(): field is not in scope" );
00078         // continue with the rest of the fields
00079         continue; 
00080       }
00081       
00082       ID3D_NOTICE( "ID3_FrameImpl::Parse(): setting enc to " << enc );
00083       fp->SetEncoding(enc);
00084       ID3_Reader::pos_type beg = rdr.getCur();
00085       et.setExitPos(beg);
00086       ID3D_NOTICE( "ID3_FrameImpl::Parse(): parsing field, cur = " << beg );
00087       ID3D_NOTICE( "ID3_FrameImpl::Parse(): parsing field, end = " << 
00088                    rdr.getEnd() );
00089       if (!fp->Parse(rdr) || rdr.getCur() == beg) 
00090       { 
00091         // nothing to parse!  ack!  parse error... 
00092         ID3D_WARNING( "ID3_FrameImpl::Parse(): no data parsed, bad parse" );
00093         return false;
00094       }
00095       
00096       if (fp->GetID() == ID3FN_TEXTENC)  
00097       {
00098         enc = static_cast<ID3_TextEnc>(fp->Get());  
00099         ID3D_NOTICE( "ID3_FrameImpl::Parse(): found encoding = " << enc );
00100       }
00101     }
00102     et.setExitPos(rdr.getCur());
00103     
00104     return true;
00105   }
00106 };
00107 
00108 bool ID3_FrameImpl::Parse(ID3_Reader& reader) 
00109 { 
00110   io::ExitTrigger et(reader);
00111   ID3D_NOTICE( "ID3_FrameImpl::Parse(): reader.getBeg() = " << reader.getBeg() );
00112   ID3D_NOTICE( "ID3_FrameImpl::Parse(): reader.getCur() = " << reader.getCur() );
00113   ID3D_NOTICE( "ID3_FrameImpl::Parse(): reader.getEnd() = " << reader.getEnd() );
00114   ID3_Reader::pos_type beg = reader.getCur();
00115 
00116   if (!_hdr.Parse(reader) || reader.getCur() == beg)  
00117   { 
00118     ID3D_WARNING( "ID3_FrameImpl::Parse(): no header to parse" );
00119     return false; 
00120   }
00121   ID3D_NOTICE( "ID3_FrameImpl::Parse(): after hdr, getCur() = " << reader.getCur() );
00122   ID3D_NOTICE( "ID3_FrameImpl::Parse(): found frame! id = " << _hdr.GetTextID() );
00123 
00124   // data is the part of the frame buffer that appears after the header  
00125   const size_t dataSize = _hdr.GetDataSize();
00126   ID3D_NOTICE( "ID3_FrameImpl::Parse(): dataSize = " << dataSize );
00127   if (reader.getEnd() < beg + dataSize)
00128   {
00129     ID3D_WARNING( "ID3_FrameImpl::Parse(): not enough data to parse frame" );
00130     return false;
00131   }
00132   io::WindowedReader wr(reader, dataSize);
00133   ID3D_NOTICE( "ID3_FrameImpl::Parse(): window getBeg() = " << wr.getBeg() );
00134   ID3D_NOTICE( "ID3_FrameImpl::Parse(): window getCur() = " << wr.getCur() );
00135   ID3D_NOTICE( "ID3_FrameImpl::Parse(): window getEnd() = " << wr.getEnd() );
00136   
00137   unsigned long origSize = 0;
00138   if (_hdr.GetCompression())
00139   {
00140     origSize = io::readBENumber(reader, sizeof(uint32));
00141     ID3D_NOTICE( "ID3_FrameImpl::Parse(): frame is compressed, origSize = " << origSize );
00142   }
00143 
00144   if (_hdr.GetEncryption())
00145   {
00146     char ch = wr.readChar();
00147     this->SetEncryptionID(ch);
00148     ID3D_NOTICE( "ID3_FrameImpl::Parse(): frame is encrypted, encryption_id = " << (int) ch );
00149   }
00150 
00151   if (_hdr.GetGrouping())
00152   {
00153     char ch = wr.readChar();
00154     this->SetGroupingID(ch);
00155     ID3D_NOTICE( "ID3_FrameImpl::Parse(): frame is encrypted, grouping_id = " << (int) ch );
00156   }
00157 
00158   // set the type of frame based on the parsed header  
00159   this->_ClearFields(); 
00160   this->_InitFields(); 
00161 
00162   bool success = false;
00163   // expand out the data if it's compressed 
00164   if (!_hdr.GetCompression())
00165   {
00166     success = parseFields(wr, *this);
00167   }
00168   else
00169   {
00170     io::CompressedReader csr(wr, origSize);
00171     success = parseFields(csr, *this);
00172   }
00173   et.setExitPos(wr.getCur());
00174 
00175   _changed = false;
00176   return true;
00177 } 

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