id3lib 3.8.3

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

frame_parse.cpp
Go to the documentation of this file.
1 // $Id: frame_parse.cpp,v 1.34 2002/07/06 13:53:18 t1mpy Exp $
2
3 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
4 // Copyright 1999, 2000 Scott Thomas Haug
5
6 // This library is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU Library General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or (at your
9 // option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful, but WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 // License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public License
17 // along with this library; if not, write to the Free Software Foundation,
18 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 // The id3lib authors encourage improvements and optimisations to be sent to
21 // the id3lib coordinator. Please see the README file for details on where to
22 // send such submissions. See the AUTHORS file for a list of people who have
23 // contributed to id3lib. See the ChangeLog file for a list of changes to
24 // id3lib. These files are distributed with id3lib at
25 // http://download.sourceforge.net/id3lib/
26
27 #if defined HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include "frame_impl.h"
32 #include "id3/io_decorators.h" //has "readers.h" "io_helpers.h" "utils.h"
33
34 using namespace dami;
35
36 namespace
37 {
38 bool parseFields(ID3_Reader& rdr, ID3_FrameImpl& frame)
39 {
40 int iLoop;
41 int iFields;
42 io::ExitTrigger et(rdr);
43 ID3_TextEnc enc = ID3TE_ASCII; // set the default encoding
44 ID3_V2Spec spec = frame.GetSpec();
45 // parse the frame's fields
46 iFields = frame.NumFields();
47 ID3D_NOTICE( "ID3_FrameImpl::Parse(): num_fields = " << iFields );
48 iLoop = 0;
49 for (ID3_FrameImpl::iterator fi = frame.begin(); fi != frame.end(); ++fi)
50 {
51 ID3_Field* fp = *fi;
52 ++iLoop;
53
54 if (rdr.atEnd())
55 {
56 // there's no remaining data to parse!
57 ID3D_WARNING( "ID3_FrameImpl::Parse(): out of data at postion " <<
58 rdr.getCur() );
59 if (iLoop == iFields)
60 {
61 //if we are at the last field, (the 'data' field) it's apparently
62 //an empty tag used for filling up padding, it's no problem
63 //break will set the current 'cursor' to the right spot outside the for loop
64 break;
65 }
66 return false;
67 }
68
69 if (NULL == fp)
70 {
71 // Ack! Why is the field NULL? Log this...
72 ID3D_WARNING( "ID3_FrameImpl::Parse(): field is null" );
73 continue;
74 }
75
76 if (!fp->InScope(spec))
77 {
78 ID3D_NOTICE( "ID3_FrameImpl::Parse(): field is not in scope" );
79 // continue with the rest of the fields
80 continue;
81 }
82
83 ID3D_NOTICE( "ID3_FrameImpl::Parse(): setting enc to " << enc );
84 fp->SetEncoding(enc);
85 ID3_Reader::pos_type beg = rdr.getCur();
86 et.setExitPos(beg);
87 ID3D_NOTICE( "ID3_FrameImpl::Parse(): parsing field, cur = " << beg );
88 ID3D_NOTICE( "ID3_FrameImpl::Parse(): parsing field, end = " <<
89 rdr.getEnd() );
90 if (!fp->Parse(rdr) || rdr.getCur() == beg)
91 {
92 // nothing to parse! ack! parse error...
93 ID3D_WARNING( "ID3_FrameImpl::Parse(): no data parsed, bad parse" );
94 return false;
95 }
96
97 if (fp->GetID() == ID3FN_TEXTENC)
98 {
99 enc = static_cast<ID3_TextEnc>(fp->Get());
100 ID3D_NOTICE( "ID3_FrameImpl::Parse(): found encoding = " << enc );
101 }
102 }
103 et.setExitPos(rdr.getCur());
104
105 return true;
106 }
107 };
108
109 bool ID3_FrameImpl::Parse(ID3_Reader& reader)
110 {
111 io::ExitTrigger et(reader);
112 ID3D_NOTICE( "ID3_FrameImpl::Parse(): reader.getBeg() = " << reader.getBeg() );
113 ID3D_NOTICE( "ID3_FrameImpl::Parse(): reader.getCur() = " << reader.getCur() );
114 ID3D_NOTICE( "ID3_FrameImpl::Parse(): reader.getEnd() = " << reader.getEnd() );
115 ID3_Reader::pos_type beg = reader.getCur();
116
117 if (!_hdr.Parse(reader) || reader.getCur() == beg)
118 {
119 ID3D_WARNING( "ID3_FrameImpl::Parse(): no header to parse" );
120 return false;
121 }
122 ID3D_NOTICE( "ID3_FrameImpl::Parse(): after hdr, getCur() = " << reader.getCur() );
123 ID3D_NOTICE( "ID3_FrameImpl::Parse(): found frame! id = " << _hdr.GetTextID() );
124
125 // data is the part of the frame buffer that appears after the header
126 const size_t dataSize = _hdr.GetDataSize();
127 ID3D_NOTICE( "ID3_FrameImpl::Parse(): dataSize = " << dataSize );
128 if (reader.getEnd() < beg + dataSize)
129 {
130 ID3D_WARNING( "ID3_FrameImpl::Parse(): not enough data to parse frame" );
131 return false;
132 }
133 io::WindowedReader wr(reader, dataSize);
134 ID3D_NOTICE( "ID3_FrameImpl::Parse(): window getBeg() = " << wr.getBeg() );
135 ID3D_NOTICE( "ID3_FrameImpl::Parse(): window getCur() = " << wr.getCur() );
136 ID3D_NOTICE( "ID3_FrameImpl::Parse(): window getEnd() = " << wr.getEnd() );
137
138 unsigned long origSize = 0;
139 if (_hdr.GetCompression())
140 {
141 origSize = io::readBENumber(reader, sizeof(uint32));
142 ID3D_NOTICE( "ID3_FrameImpl::Parse(): frame is compressed, origSize = " << origSize );
143 }
144
145 if (_hdr.GetEncryption())
146 {
147 char ch = wr.readChar();
148 this->SetEncryptionID(ch);
149 ID3D_NOTICE( "ID3_FrameImpl::Parse(): frame is encrypted, encryption_id = " << (int) ch );
150 }
151
152 if (_hdr.GetGrouping())
153 {
154 char ch = wr.readChar();
155 this->SetGroupingID(ch);
156 ID3D_NOTICE( "ID3_FrameImpl::Parse(): frame is encrypted, grouping_id = " << (int) ch );
157 }
158
159 // set the type of frame based on the parsed header
160 this->_ClearFields();
161 this->_InitFields();
162
163 bool success = false;
164 // expand out the data if it's compressed
165 if (!_hdr.GetCompression())
166 {
167 success = parseFields(wr, *this);
168 }
169 else
170 {
171 io::CompressedReader csr(wr, origSize);
172 success = parseFields(csr, *this);
173 }
174 et.setExitPos(wr.getCur());
175
176 _changed = false;
177 return true;
178 }
179
ID3_Reader::getBeg
virtual pos_type getBeg()
Return the beginning position in the reader.
Definition: reader.h:48
ID3_FrameImpl::NumFields
size_t NumFields() const
Definition: frame_impl.cpp:167
ID3_FrameImpl::iterator
Fields::iterator iterator
Definition: frame_impl.h:46
ID3_FrameImpl
Definition: frame_impl.h:41
ID3_Reader::getCur
virtual pos_type getCur()=0
Return the current position in the reader.
ID3TE_ASCII
Definition: globals.h:145
ID3_Field::SetEncoding
virtual bool SetEncoding(ID3_TextEnc enc)=0
ID3_FrameImpl::begin
iterator begin()
Definition: frame_impl.h:116
ID3_Field::GetID
virtual ID3_FieldID GetID() const =0
ID3_Field::InScope
virtual bool InScope(ID3_V2Spec spec) const =0
ID3_Reader
Definition: reader.h:33
ID3_V2Spec
ID3_V2Spec
Definition: globals.h:161
ID3_TextEnc
ID3_TextEnc
Enumeration of the types of text encodings: ascii or unicode.
Definition: globals.h:137
ID3_Reader::getEnd
virtual pos_type getEnd()
Return the ending position in the reader.
Definition: reader.h:51
frame_impl.h
ID3FN_TEXTENC
Text encoding (unicode or ASCII)
Definition: globals.h:200
ID3_FrameImpl::Parse
bool Parse(ID3_Reader &)
Definition: frame_parse.cpp:109
NULL
#define NULL
Definition: globals.h:743
ID3_Reader::atEnd
virtual bool atEnd()
Definition: reader.h:125
ID3_Field
The representative class of an ID3v2 field.
Definition: field.h:36
ID3_Reader::pos_type
uint32 pos_type
Definition: reader.h:38
ID3_FrameImpl::end
iterator end()
Definition: frame_impl.h:117
ID3_FrameImpl::GetSpec
ID3_V2Spec GetSpec() const
Definition: frame_impl.cpp:145
ID3_Field::Parse
virtual bool Parse(ID3_Reader &)=0
ID3_Field::Get
virtual uint32 Get() const =0
Returns the value of the integer field.