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 #include "frame_impl.h"
00032 #include "id3/io_decorators.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;
00044 ID3_V2Spec spec = frame.GetSpec();
00045
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
00057 ID3D_WARNING( "ID3_FrameImpl::Parse(): out of data at postion " <<
00058 rdr.getCur() );
00059 if (iLoop == iFields)
00060 {
00061
00062
00063
00064 break;
00065 }
00066 return false;
00067 }
00068
00069 if (NULL == fp)
00070 {
00071
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
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
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
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
00160 this->_ClearFields();
00161 this->_InitFields();
00162
00163 bool success = false;
00164
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