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 "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;
00045 ID3_V2Spec spec = frame.GetSpec();
00046
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
00056 ID3D_WARNING( "ID3_FrameImpl::Parse(): out of data at postion " <<
00057 rdr.getCur() );
00058 if(fp->GetType() == ID3FTY_TEXTSTRING)
00059 {
00060
00061
00062 break;
00063 }
00064
00065 return false;
00066 }
00067
00068 if (NULL == fp)
00069 {
00070
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
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
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
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
00159 this->_ClearFields();
00160 this->_InitFields();
00161
00162 bool success = false;
00163
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 }