src/frame_parse.cpp

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

Generated on Mon Aug 20 17:48:46 2007 for id3lib by  doxygen 1.5.2