id3lib 3.8.3

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

tag_impl.cpp
Go to the documentation of this file.
1 // $Id: tag_impl.cpp,v 1.13 2002/09/21 17:23:32 t1mpy Exp $
2
3 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
4 // Copyright 1999, 2000 Scott Thomas Haug
5 // Copyright 2002 Thijmen Klok (thijmen@id3lib.org)
6
7 // This library is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU Library General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or (at your
10 // option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public License
18 // along with this library; if not, write to the Free Software Foundation,
19 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21 // The id3lib authors encourage improvements and optimisations to be sent to
22 // the id3lib coordinator. Please see the README file for details on where to
23 // send such submissions. See the AUTHORS file for a list of people who have
24 // contributed to id3lib. See the ChangeLog file for a list of changes to
25 // id3lib. These files are distributed with id3lib at
26 // http://download.sourceforge.net/id3lib/
27
28 #if defined HAVE_SYS_PARAM_H
29 #include <sys/param.h>
30 #endif
31
32 #include "tag_impl.h" //has <stdio.h> "tag.h" "header_tag.h" "frame.h" "field.h" "spec.h" "id3lib_strings.h" "utils.h"
33 //#include "io_helpers.h"
34 #include "io_strings.h"
35
36 using namespace dami;
37
38 size_t ID3_TagImpl::IsV2Tag(ID3_Reader& reader)
39 {
40 io::ExitTrigger et(reader);
41 size_t tagSize = 0;
42 String id = io::readText(reader, ID3_TagHeader::ID_SIZE);
43 String ver = io::readText(reader, 2);
44 char flags = reader.readChar();
45 String size = io::readText(reader, 4);
46
47 if (id == ID3_TagHeader::ID &&
48 (uchar) ver [0] < 0xFF && (uchar) ver [1] < 0xFF &&
49 (uchar) size[0] < 0x80 && (uchar) size[1] < 0x80 &&
50 (uchar) size[2] < 0x80 && (uchar) size[3] < 0x80)
51 {
52 io::StringReader sr(size);
53 tagSize = io::readUInt28(sr) + ID3_TagHeader::SIZE;
54 }
55 else if (id != ID3_TagHeader::ID)
56 {
57 // clog << "*** IsV2Tag: Not an id3v2 tag header" << endl;
58 }
59 else if ((uchar)ver[0] >= 0xFF)
60 {
61 // clog << "*** IsV2Tag: Major offset" << endl;
62 }
63 else if ((uchar)ver[1] >= 0xFF)
64 {
65 // clog << "*** ISV2Tag: Minor offset" << endl;
66 }
67 else if ((uchar)size[0] >= 0x80)
68 {
69 // clog << "*** ISV2Tag: 1st size offset" << endl;
70 }
71 else if ((uchar)size[1] >= 0x80)
72 {
73 // clog << "*** ISV2Tag: 2nd size offset" << endl;
74 }
75 else if ((uchar)size[2] >= 0x80)
76 {
77 // clog << "*** ISV2Tag: 3rd size offset" << endl;
78 }
79 else if ((uchar)size[3] >= 0x80)
80 {
81 // clog << "*** ISV2Tag: 4th size offset" << endl;
82 }
83 else
84 {
85 // clog << "*** shouldn't get here!" << endl;
86 }
87
88 return tagSize;
89 }
90
91 ID3_TagImpl::ID3_TagImpl(const char *name)
92 : _frames(),
93 _cursor(_frames.begin()),
94 _file_name(),
95 _file_size(0),
96 _prepended_bytes(0),
97 _appended_bytes(0),
98 _is_file_writable(false),
99 _mp3_info(NULL) // need to do this before this->Clear()
100 {
101 this->Clear();
102 if (name)
103 {
104 this->Link(name);
105 }
106 }
107
108 ID3_TagImpl::ID3_TagImpl(const ID3_Tag &tag)
109 : _frames(),
110 _cursor(_frames.begin()),
111 _file_name(),
112 _file_size(0),
113 _prepended_bytes(0),
114 _appended_bytes(0),
115 _is_file_writable(false),
116 _mp3_info(NULL) // need to do this before this->Clear()
117 {
118 *this = tag;
119 }
120
121 ID3_TagImpl::~ID3_TagImpl()
122 {
123 this->Clear();
124 }
125
126 void ID3_TagImpl::Clear()
127 {
128 for (iterator cur = _frames.begin(); cur != _frames.end(); ++cur)
129 {
130 if (*cur)
131 {
132 delete *cur;
133 *cur = NULL;
134 }
135 }
136 _frames.clear();
137 _cursor = _frames.begin();
138 _is_padded = true;
139
140 _hdr.Clear();
141 _hdr.SetSpec(ID3V2_LATEST);
142
143 _tags_to_parse.clear();
144 if (_mp3_info)
145 delete _mp3_info; // Also deletes _mp3_header
146
147 _mp3_info = NULL;
148
149 _changed = true;
150 }
151
152
153 void ID3_TagImpl::AddFrame(const ID3_Frame& frame)
154 {
155 this->AddFrame(&frame);
156 }
157
158 void ID3_TagImpl::AddFrame(const ID3_Frame* frame)
159 {
160 if (frame)
161 {
162 ID3_Frame* frm = new ID3_Frame(*frame);
163 this->AttachFrame(frm);
164 }
165 }
166
167 bool ID3_TagImpl::AttachFrame(ID3_Frame *frame)
168 {
169
170 if (NULL == frame)
171 {
172 // log this
173 return false;
174 //ID3_THROW(ID3E_NoData);
175 }
176
177 _frames.push_back(frame);
178 _cursor = _frames.begin();
179
180 _changed = true;
181 return true;
182 }
183
184
185 ID3_Frame* ID3_TagImpl::RemoveFrame(const ID3_Frame *frame)
186 {
187 ID3_Frame *frm = NULL;
188
189 iterator fi = Find(frame);
190 if (fi != _frames.end())
191 {
192 frm = *fi;
193 _frames.erase(fi);
194 _cursor = _frames.begin();
195 _changed = true;
196 }
197
198 return frm;
199 }
200
201
202 bool ID3_TagImpl::HasChanged() const
203 {
204 bool changed = _changed;
205
206 if (! changed)
207 {
208 for (const_iterator fi = _frames.begin(); fi != _frames.end(); ++fi)
209 {
210 if (*fi)
211 {
212 changed = (*fi)->HasChanged();
213 }
214
215 if (changed)
216 {
217 break;
218 }
219 }
220 }
221
222 return changed;
223 }
224
225 bool ID3_TagImpl::SetSpec(ID3_V2Spec spec)
226 {
227 bool changed = _hdr.SetSpec(spec);
228 _changed = _changed || changed;
229 return changed;
230 }
231
232 ID3_V2Spec ID3_TagImpl::GetSpec() const
233 {
234 return _hdr.GetSpec();
235 }
236
237 bool ID3_TagImpl::SetUnsync(bool b)
238 {
239 bool changed = _hdr.SetUnsync(b);
240 _changed = changed || _changed;
241 return changed;
242 }
243
244 bool ID3_TagImpl::SetExtended(bool ext)
245 {
246 bool changed = _hdr.SetExtended(ext);
247 _changed = changed || _changed;
248 return changed;
249 }
250
251 bool ID3_TagImpl::SetExperimental(bool exp)
252 {
253 bool changed = _hdr.SetExperimental(exp);
254 _changed = changed || _changed;
255 return changed;
256 }
257
258 bool ID3_TagImpl::GetUnsync() const
259 {
260 return _hdr.GetUnsync();
261 }
262
263 bool ID3_TagImpl::GetExtended() const
264 {
265 return _hdr.GetExtended();
266 }
267
268 bool ID3_TagImpl::GetExperimental() const
269 {
270 return _hdr.GetExperimental();
271 }
272
273 bool ID3_TagImpl::GetFooter() const
274 {
275 return _hdr.GetFooter();
276 }
277
278 size_t ID3_TagImpl::GetExtendedBytes() const
279 {
280 if (this->GetExtended())
281 if (this->GetSpec() == ID3V2_4_0)
282 return 6; //minimal ID3v2.4 ext header size
283 else if (this->GetSpec() == ID3V2_3_0)
284 return 10; //minimal ID3v2.3 ext header size
285 else
286 return 0; //not implemented
287 else
288 return 0;;
289 }
290
291 bool ID3_TagImpl::SetPadding(bool pad)
292 {
293 bool changed = (_is_padded != pad);
294 _changed = changed || _changed;
295 if (changed)
296 {
297 _is_padded = pad;
298 }
299
300 return changed;
301 }
302
303
304 ID3_TagImpl &
305 ID3_TagImpl::operator=( const ID3_Tag &rTag )
306 {
307 this->Clear();
308
309 this->SetUnsync(rTag.GetUnsync());
310 this->SetExtended(rTag.GetExtendedHeader());
311 this->SetExperimental(rTag.GetExperimental());
312
313 ID3_Tag::ConstIterator* iter = rTag.CreateIterator();
314 const ID3_Frame* frame = NULL;
315 while (NULL != (frame = iter->GetNext()))
316 {
317 this->AttachFrame(new ID3_Frame(*frame));
318 }
319 delete iter;
320 return *this;
321 }
322
323 size_t ID3_GetDataSize(const ID3_TagImpl& tag)
324 {
325 return tag.GetFileSize() - tag.GetPrependedBytes() - tag.GetAppendedBytes();
326 }
327
ID3_TagImpl::GetExtendedBytes
size_t GetExtendedBytes() const
Definition: tag_impl.cpp:278
ID3_TagImpl::GetExtended
bool GetExtended() const
Definition: tag_impl.cpp:263
ID3_TagHeader::ID_SIZE
Definition: header_tag.h:103
ID3_TagHeader::ID
static const char *const ID
Definition: header_tag.h:100
ID3_TagImpl::SetExperimental
bool SetExperimental(bool)
Definition: tag_impl.cpp:251
dami::String
std::basic_string< char > String
Definition: id3lib_strings.h:198
ID3_TagImpl
Definition: tag_impl.h:73
ID3_TagImpl::GetFooter
bool GetFooter() const
Definition: tag_impl.cpp:273
ID3_Tag
The representative class of an id3 tag.
Definition: tag.h:41
ID3_TagImpl::Clear
void Clear()
Definition: tag_impl.cpp:126
ID3_Tag::GetUnsync
bool GetUnsync() const
Definition: tag.cpp:463
ID3_TagImpl::Link
size_t Link(const char *fileInfo, flags_t=(flags_t) ID3TT_ALL)
Definition: tag_file.cpp:131
ID3_TagHeader::SetUnsync
bool SetUnsync(bool b)
Definition: header_tag.h:66
ID3_TagHeader::GetExtended
bool GetExtended() const
Definition: header_tag.h:79
ID3_TagHeader::GetUnsync
bool GetUnsync() const
Definition: header_tag.h:72
ID3_GetDataSize
size_t ID3_GetDataSize(const ID3_TagImpl &tag)
Definition: tag_impl.cpp:323
ID3_TagHeader::GetFooter
bool GetFooter() const
Definition: header_tag.h:93
ID3_TagImpl::AddFrame
void AddFrame(const ID3_Frame &)
Definition: tag_impl.cpp:153
ID3_TagHeader::SIZE
Definition: header_tag.h:108
ID3_TagImpl::GetExperimental
bool GetExperimental() const
Definition: tag_impl.cpp:268
ID3_TagImpl::SetExtended
bool SetExtended(bool)
Definition: tag_impl.cpp:244
ID3_TagImpl::GetPrependedBytes
size_t GetPrependedBytes() const
Definition: tag_impl.h:111
uchar
unsigned char uchar
Definition: globals.h:114
ID3_Header::Clear
virtual bool Clear()
Definition: header.h:73
ID3_TagImpl::Find
ID3_Frame * Find(ID3_FrameID id) const
Definition: tag_find.cpp:61
ID3V2_4_0
Definition: globals.h:167
ID3_TagImpl::~ID3_TagImpl
virtual ~ID3_TagImpl()
Definition: tag_impl.cpp:121
ID3_Tag::GetExtendedHeader
bool GetExtendedHeader() const
Definition: tag.cpp:468
ID3_TagImpl::GetFileSize
size_t GetFileSize() const
Definition: tag_impl.h:113
ID3_TagImpl::SetPadding
bool SetPadding(bool)
Definition: tag_impl.cpp:291
ID3_Flags::clear
bool clear()
Definition: flags.h:46
ID3_Reader::readChar
virtual int_type readChar()
Read a single character and advance the internal position.
Definition: reader.h:65
ID3_Reader
Definition: reader.h:33
ID3_TagImpl::GetUnsync
bool GetUnsync() const
Definition: tag_impl.cpp:258
tag_impl.h
ID3_TagImpl::AttachFrame
bool AttachFrame(ID3_Frame *)
Definition: tag_impl.cpp:167
ID3_Tag::ConstIterator
Definition: tag.h:53
ID3_V2Spec
ID3_V2Spec
Definition: globals.h:161
ID3_Tag::CreateIterator
Iterator * CreateIterator()
Definition: tag.cpp:1115
ID3V2_3_0
Definition: globals.h:166
ID3_Header::GetSpec
ID3_V2Spec GetSpec() const
Definition: header.h:62
ID3_TagImpl::GetSpec
ID3_V2Spec GetSpec() const
Definition: tag_impl.cpp:232
ID3_Frame
The representative class of an id3v2 frame.
Definition: id3lib_frame.h:38
ID3_TagImpl::operator=
ID3_TagImpl & operator=(const ID3_Tag &)
Definition: tag_impl.cpp:305
ID3_TagImpl::const_iterator
Frames::const_iterator const_iterator
Definition: tag_impl.h:78
ID3_TagHeader::SetExperimental
bool SetExperimental(bool b)
Definition: header_tag.h:80
ID3_TagImpl::IsV2Tag
static size_t IsV2Tag(ID3_Reader &)
Definition: tag_impl.cpp:38
ID3_TagHeader::SetSpec
bool SetSpec(ID3_V2Spec)
Definition: header_tag.cpp:39
ID3_TagImpl::RemoveFrame
ID3_Frame * RemoveFrame(const ID3_Frame *)
Definition: tag_impl.cpp:185
ID3_TagImpl::iterator
Frames::iterator iterator
Definition: tag_impl.h:77
ID3_TagHeader::GetExperimental
bool GetExperimental() const
Definition: header_tag.h:86
NULL
#define NULL
Definition: globals.h:743
ID3_TagImpl::GetAppendedBytes
size_t GetAppendedBytes() const
Definition: tag_impl.h:112
ID3_TagImpl::HasChanged
bool HasChanged() const
Definition: tag_impl.cpp:202
ID3_Tag::GetExperimental
bool GetExperimental() const
Definition: tag.cpp:473
ID3_TagHeader::SetExtended
bool SetExtended(bool b)
Definition: header_tag.h:73
ID3_TagImpl::ID3_TagImpl
ID3_TagImpl(const char *name=NULL)
Definition: tag_impl.cpp:91
ID3_TagImpl::SetUnsync
bool SetUnsync(bool)
Definition: tag_impl.cpp:237
ID3_TagImpl::SetSpec
bool SetSpec(ID3_V2Spec)
Definition: tag_impl.cpp:225
ID3V2_LATEST
Definition: globals.h:169