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