id3lib 3.8.3
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
34using namespace dami;
35
36namespace
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
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
The representative class of an ID3v2 field.
Definition field.h:37
virtual uint32 Get() const =0
Returns the value of the integer field.
virtual ID3_FieldID GetID() const =0
virtual bool Parse(ID3_Reader &)=0
virtual bool SetEncoding(ID3_TextEnc enc)=0
virtual bool InScope(ID3_V2Spec spec) const =0
bool GetGrouping() const
bool GetEncryption() const
const char * GetTextID() const
bool Parse(ID3_Reader &)
bool GetCompression() const
bool Parse(ID3_Reader &)
bool SetGroupingID(uchar id)
Definition frame_impl.h:106
void _InitFields()
size_t NumFields() const
iterator end()
Definition frame_impl.h:117
ID3_V2Spec GetSpec() const
Fields::iterator iterator
Definition frame_impl.h:46
bool SetEncryptionID(uchar id)
Definition frame_impl.h:97
bool _ClearFields()
iterator begin()
Definition frame_impl.h:116
size_t GetDataSize() const
Definition header.h:71
virtual pos_type getCur()=0
Return the current position in the reader.
virtual bool atEnd()
Definition reader.h:125
virtual pos_type getEnd()
Return the ending position in the reader.
Definition reader.h:51
uint32 pos_type
Definition reader.h:38
virtual pos_type getBeg()
Return the beginning position in the reader.
Definition reader.h:48
#define NULL
Definition globals.h:743
@ ID3FN_TEXTENC
Text encoding (unicode or ASCII)
Definition globals.h:200
ID3_TextEnc
Enumeration of the types of text encodings: ascii or unicode.
Definition globals.h:138
@ ID3TE_ASCII
Definition globals.h:145
ID3_V2Spec
Definition globals.h:162

Generated for id3lib by doxygen 1.10.0