id3lib  3.8.3
helpers.cpp
Go to the documentation of this file.
1 // $Id: helpers.cpp,v 1.12 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 
6 // Lots of hacking added to this file by Scott Wheeler (scott@slackorama.net)
7 // 11/02/2001
8 
9 // This library is free software; you can redistribute it and/or modify it
10 // under the terms of the GNU Library General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or (at your
12 // option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful, but WITHOUT
15 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
17 // License for more details.
18 //
19 // You should have received a copy of the GNU Library General Public License
20 // along with this library; if not, write to the Free Software Foundation,
21 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23 // The id3lib authors encourage improvements and optimisations to be sent to
24 // the id3lib coordinator. Please see the README file for details on where to
25 // send such submissions. See the AUTHORS file for a list of people who have
26 // contributed to id3lib. See the ChangeLog file for a list of changes to
27 // id3lib. These files are distributed with id3lib at
28 // http://download.sourceforge.net/id3lib/
29 
30 #if defined HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 
35 
36 #include <ctype.h>
37 
38 #include "helpers.h"
39 #include "tag_impl.h" //has <stdio.h> "tag.h" "header_tag.h" "frame.h" "field.h" "spec.h" "id3lib_strings.h" "utils.h"
40 
41 using namespace dami;
42 
43 String id3::v2::getString(const ID3_Frame* frame, ID3_FieldID fldName)
44 {
45  if (!frame)
46  {
47  return "";
48  }
49  ID3_Field* fp = frame->GetField(fldName);
50  if (!fp)
51  {
52  return "";
53  }
54  ID3_TextEnc enc = fp->GetEncoding();
56 
57  String text(fp->GetRawText(), fp->Size());
58 
59  fp->SetEncoding(enc);
60  return text;
61 }
62 
63 String id3::v2::getStringAtIndex(const ID3_Frame* frame, ID3_FieldID fldName,
64  size_t nIndex)
65 {
66  if (!frame)
67  {
68  return "";
69  }
70  String text;
71  ID3_Field* fp = frame->GetField(fldName);
72  if (fp && fp->GetNumTextItems() < nIndex)
73  {
74  ID3_TextEnc enc = fp->GetEncoding();
76 
77  text = fp->GetRawTextItem(nIndex);
78 
79  fp->SetEncoding(enc);
80  }
81  return text;
82 }
83 
85 {
86  size_t numRemoved = 0;
87  ID3_Frame* frame = NULL;
88 
89  while ((frame = tag.Find(id)) != NULL)
90  {
91  frame = tag.RemoveFrame(frame);
92  delete frame;
93  numRemoved++;
94  }
95 
96  return numRemoved;
97 }
98 
100 {
101  ID3_Frame* frame = tag.Find(id);
102  return getString(frame, ID3FN_TEXT);
103 }
104 
106 {
107  ID3_Frame* frame = tag.Find(id);
108  if (!frame)
109  {
110  frame = new ID3_Frame(id);
111  if(!tag.AttachFrame(frame)) return NULL;
112  }
113  frame->GetField(ID3FN_TEXT)->Set(text.c_str());
114 
115  return frame;
116 }
117 
119 
121 {
122  ID3_Frame* fp = NULL;
123  (fp = tag.Find(ID3FID_LEADARTIST)) ||
124  (fp = tag.Find(ID3FID_BAND)) ||
125  (fp = tag.Find(ID3FID_CONDUCTOR)) ||
126  (fp = tag.Find(ID3FID_COMPOSER));
127  return fp;
128 }
129 
130 String id3::v2::getArtist(const ID3_TagImpl& tag)
131 {
132  ID3_Frame* frame = hasArtist(tag);
133  return getString(frame, ID3FN_TEXT);
134 }
135 
137 {
138  removeArtists(tag);
139  return setFrameText(tag, ID3FID_LEADARTIST, text);
140 }
141 
143 {
144  size_t numRemoved = 0;
145  ID3_Frame* frame = NULL;
146 
147  while ((frame = hasArtist(tag)) != NULL)
148  {
149  frame = tag.RemoveFrame(frame);
150  delete frame;
151  numRemoved++;
152  }
153 
154  return numRemoved;
155 }
156 
158 
160 {
161  ID3_Frame* frame = tag.Find(ID3FID_ALBUM);
162  return(frame);
163 }
164 
165 String id3::v2::getAlbum(const ID3_TagImpl& tag)
166 {
167  return getFrameText(tag, ID3FID_ALBUM);
168 }
169 
171 {
172  return setFrameText(tag, ID3FID_ALBUM, text);
173 }
174 
176 {
177  return removeFrames(tag, ID3FID_ALBUM);
178 }
179 
181 
183 {
184  ID3_Frame* frame = tag.Find(ID3FID_TITLE);
185  return(frame);
186 }
187 
188 String id3::v2::getTitle(const ID3_TagImpl& tag)
189 {
190  return getFrameText(tag, ID3FID_TITLE);
191 }
192 
194 {
195  return setFrameText(tag, ID3FID_TITLE, text);
196 }
197 
199 {
200  return removeFrames(tag, ID3FID_TITLE);
201 }
202 
204 
206 {
207  ID3_Frame* frame = tag.Find(ID3FID_YEAR);
208  return(frame);
209 }
210 
211 String id3::v2::getYear(const ID3_TagImpl& tag)
212 {
213  return getFrameText(tag, ID3FID_YEAR);
214 }
215 
217 {
218  return setFrameText(tag, ID3FID_YEAR, text);
219 }
220 
222 {
223  return removeFrames(tag, ID3FID_YEAR);
224 }
225 
227 
229 {
230  ID3_Frame* frame = NULL;
232  (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, "" )) ||
233  (frame = tag.Find(ID3FID_COMMENT));
234  return(frame);
235 }
236 
238 {
239  ID3_Frame* frame = tag.Find(ID3FID_COMMENT);
240  return(frame);
241 }
242 
244 {
245  ID3_Frame* frame;
247  (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, "" )) ||
248  (frame = tag.Find(ID3FID_COMMENT));
249  return getString(frame, ID3FN_TEXT);
250 }
251 
252 String id3::v2::getComment(const ID3_TagImpl& tag, String desc)
253 {
254  ID3_Frame* frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, desc.c_str());
255  return getString(frame, ID3FN_TEXT);
256 }
257 
258 ID3_Frame* id3::v2::setComment(ID3_TagImpl& tag, String text, String desc,
259  String lang)
260 {
261  ID3D_NOTICE( "id3::v2::setComment: trying to find frame with description = " << desc );
262  ID3_Frame* frame = NULL;
263  // See if there is already a comment with this description
264  for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter)
265  {
266  frame = *iter;
267  if (frame == NULL)
268  {
269  continue;
270  }
271  if (frame->GetID() == ID3FID_COMMENT)
272  {
273  String tmpDesc = getString(frame, ID3FN_DESCRIPTION);
274  if (tmpDesc == desc)
275  {
276  ID3D_NOTICE( "id3::v2::setComment: found frame with description = " << desc );
277  break;
278  }
279  }
280  frame = NULL;
281  }
282  if (frame == NULL)
283  {
284  ID3D_NOTICE( "id3::v2::setComment: creating new comment frame" );
285  frame = new ID3_Frame(ID3FID_COMMENT);
286  if(!tag.AttachFrame(frame)) return NULL;
287  }
288  if (!frame)
289  {
290  ID3D_WARNING( "id3::v2::setComment: ack! no frame" );
291  }
292  else
293  {
294  frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str());
295  frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str());
296  frame->GetField(ID3FN_TEXT)->Set(text.c_str());
297  }
298 
299  return frame;
300 }
301 
302 // Remove all comments from the tag
304 {
305  return removeFrames(tag, ID3FID_COMMENT);
306 }
307 
308 // Remove all comments from the tag with the given description
309 size_t id3::v2::removeComments(ID3_TagImpl& tag, String desc)
310 {
311  size_t numRemoved = 0;
312 
313  for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter)
314  {
315  ID3_Frame* frame = *iter;
316  if (frame == NULL)
317  {
318  continue;
319  }
320  if (frame->GetID() == ID3FID_COMMENT)
321  {
322  // See if the description we have matches the description of the
323  // current comment. If so, remove the comment
324  String tmpDesc = getString(frame, ID3FN_DESCRIPTION);
325  if (tmpDesc == desc)
326  {
327  frame = tag.RemoveFrame(frame);
328  delete frame;
329  numRemoved++;
330  }
331  }
332  }
333 
334  return numRemoved;
335 }
336 
338 
340 {
341  ID3_Frame* frame = tag.Find(ID3FID_TRACKNUM);
342  return(frame);
343 }
344 
345 String id3::v2::getTrack(const ID3_TagImpl& tag)
346 {
347  return getFrameText(tag, ID3FID_TRACKNUM);
348 }
349 
351 {
352  String sTrack = getTrack(tag);
353  return ::atoi(sTrack.c_str());
354 }
355 
357 {
358  ID3_Frame* frame = NULL;
359  String track = toString((size_t)trk);
360  if (ttl > 0)
361  {
362  track += "/";
363  track += toString((size_t)ttl);
364  }
365  setFrameText(tag, ID3FID_TRACKNUM, track);
366 
367  return frame;
368 }
369 
371 {
372  return removeFrames(tag, ID3FID_TRACKNUM);
373 }
374 
376 
378 {
379  ID3_Frame* frame = tag.Find(ID3FID_CONTENTTYPE);
380  return(frame);
381 }
382 
383 String id3::v2::getGenre(const ID3_TagImpl& tag)
384 {
385  return getFrameText(tag, ID3FID_CONTENTTYPE);
386 }
387 
389 {
390  String sGenre = getGenre(tag);
391  size_t ulGenre = 0xFF;
392  size_t size = sGenre.size();
393 
394  // If the genre string begins with "(ddd)", where "ddd" is a number, then
395  // "ddd" is the genre number---get it
396  size_t i = 0;
397  if (i < size && size && sGenre[i] == '(')
398  {
399  ++i;
400  while (i < size && isdigit(sGenre[i]))
401  {
402  ++i;
403  }
404  if (i < size && sGenre[i] == ')')
405  {
406  // if the genre number is greater than 255, its invalid.
407  ulGenre = min(0xFF, atoi(&sGenre[1]));
408  }
409  }
410 
411  return ulGenre;
412 }
413 
415 {
416  String sGenre = "(";
417  sGenre += toString(genre) + ")";
418  return setFrameText(tag, ID3FID_CONTENTTYPE, sGenre);
419 }
420 
422 {
423  return removeFrames(tag, ID3FID_CONTENTTYPE);
424 }
425 
427 
429 {
430  ID3_Frame* frame = tag.Find(ID3FID_UNSYNCEDLYRICS);
431  return(frame);
432 }
433 
434 String id3::v2::getLyrics(const ID3_TagImpl& tag)
435 {
436  return getFrameText(tag, ID3FID_UNSYNCEDLYRICS);
437 }
438 
439 ID3_Frame* id3::v2::setLyrics(ID3_TagImpl& tag, String text, String desc,
440  String lang)
441 {
442  ID3_Frame* frame = NULL;
443  // See if there is already a comment with this description
444  for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter)
445  {
446  frame = *iter;
447  if (frame == NULL)
448  {
449  continue;
450  }
451  if (frame->GetID() == ID3FID_COMMENT)
452  {
453  String tmpDesc = getString(frame, ID3FN_DESCRIPTION);
454  if (tmpDesc == desc)
455  {
456  break;
457  }
458  }
459  frame = NULL;
460  }
461  if (frame == NULL)
462  {
463  frame = new ID3_Frame(ID3FID_UNSYNCEDLYRICS);
464  if(!tag.AttachFrame(frame)) return NULL;
465  }
466  frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str());
467  frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str());
468  frame->GetField(ID3FN_TEXT)->Set(text.c_str());
469 
470  return frame;
471 }
472 
474 {
475  return removeFrames(tag, ID3FID_UNSYNCEDLYRICS);
476 }
477 
479 {
480  return getFrameText(tag, ID3FID_LYRICIST);
481 }
482 
484 {
485  return setFrameText(tag, ID3FID_LYRICIST, text);
486 }
487 
489 {
490  return removeFrames(tag, ID3FID_LYRICIST);
491 }
492 
494 
495 ID3_Frame* id3::v2::hasSyncLyrics(const ID3_TagImpl& tag, String lang, String desc)
496 {
497  ID3_Frame* frame=NULL;
498  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang)) ||
499  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc));
500  return(frame);
501 }
502 
504  ID3_TimeStampFormat format, String desc,
505  String lang, ID3_ContentType type)
506 {
507  ID3_Frame* frame = NULL;
508 
509  // check if a SYLT frame of this language or descriptor already exists
510  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang)) ||
511  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc));
512 
513  if (!frame)
514  {
515  frame = new ID3_Frame(ID3FID_SYNCEDLYRICS);
516  if(!tag.AttachFrame(frame)) return NULL;
517  }
518  frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str());
519  frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str());
520  frame->GetField(ID3FN_TIMESTAMPFORMAT)->Set(format);
521  frame->GetField(ID3FN_CONTENTTYPE)->Set(type);
522  frame->GetField(ID3FN_DATA)->Set(data.data(), data.size());
523 
524  return frame;
525 }
526 
527 BString id3::v2::getSyncLyrics(const ID3_TagImpl& tag, String lang, String desc)
528 {
529  // check if a SYLT frame of this language or descriptor exists
530  ID3_Frame* frame = NULL;
531  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang)) ||
532  (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc)) ||
533  (frame = tag.Find(ID3FID_SYNCEDLYRICS));
534 
535  // get the lyrics size
536  ID3_Field* fld = frame->GetField(ID3FN_DATA);
537  return BString(reinterpret_cast<const BString::value_type *>(fld->GetRawBinary()), fld->Size());
538 }
539 
The representative class of an ID3v2 field.
Definition: field.h:37
virtual const char * GetRawText() const =0
virtual size_t Size() const =0
Returns the size of a field.
virtual ID3_TextEnc GetEncoding() const =0
virtual size_t GetNumTextItems() const =0
virtual bool SetEncoding(ID3_TextEnc enc)=0
virtual const char * GetRawTextItem(size_t) const =0
virtual const uchar * GetRawBinary() const =0
The representative class of an id3v2 frame.
ID3_Frame * Find(ID3_FrameID id) const
Definition: tag_find.cpp:61
Frames::iterator iterator
Definition: tag_impl.h:77
iterator begin()
Definition: tag_impl.h:132
ID3_Frame * RemoveFrame(const ID3_Frame *)
Definition: tag_impl.cpp:185
bool AttachFrame(ID3_Frame *)
Definition: tag_impl.cpp:167
iterator end()
Definition: tag_impl.h:133
#define NULL
Definition: globals.h:743
ID3_FieldID
Enumeration of the different types of fields in a frame.
Definition: globals.h:198
@ ID3FN_DESCRIPTION
Description field.
Definition: globals.h:204
@ ID3FN_TIMESTAMPFORMAT
SYLT Timestamp Format.
Definition: globals.h:221
@ ID3FN_LANGUAGE
Language field.
Definition: globals.h:209
@ ID3FN_TEXT
Text field.
Definition: globals.h:201
@ ID3FN_DATA
Data field.
Definition: globals.h:203
@ ID3FN_CONTENTTYPE
SYLT content type.
Definition: globals.h:222
ID3_TextEnc
Enumeration of the types of text encodings: ascii or unicode.
Definition: globals.h:138
@ ID3TE_ASCII
Definition: globals.h:145
ID3_ContentType
Definition: globals.h:382
#define STR_V1_COMMENT_DESC
String used for the description field of a comment tag converted from an id3v1 tag to an id3v2 tag.
Definition: globals.h:111
unsigned char uchar
Definition: globals.h:114
ID3_FrameID
Enumeration of the different types of frames recognized by id3lib.
Definition: globals.h:230
@ ID3FID_LEADARTIST
Lead performer(s)/Soloist(s)
Definition: globals.h:292
@ ID3FID_CONTENTTYPE
Content type.
Definition: globals.h:263
@ ID3FID_COMPOSER
Composer.
Definition: globals.h:262
@ ID3FID_LYRICIST
Lyricist/Text writer.
Definition: globals.h:274
@ ID3FID_BAND
Band/orchestra/accompaniment.
Definition: globals.h:293
@ ID3FID_ALBUM
Album/Movie/Show title.
Definition: globals.h:260
@ ID3FID_COMMENT
Comments.
Definition: globals.h:235
@ ID3FID_CONDUCTOR
Conductor/performer refinement.
Definition: globals.h:294
@ ID3FID_YEAR
Year.
Definition: globals.h:311
@ ID3FID_TRACKNUM
Track number/Position in set.
Definition: globals.h:299
@ ID3FID_UNSYNCEDLYRICS
Unsynchronized lyric/text transcription.
Definition: globals.h:314
@ ID3FID_TITLE
Title/songname/content description.
Definition: globals.h:278
@ ID3FID_SYNCEDLYRICS
Synchronized lyric/text.
Definition: globals.h:258
ID3_TimeStampFormat
Definition: globals.h:418
ID3_C_EXPORT ID3_Frame * hasComment(const ID3_TagImpl &)
Definition: helpers.cpp:237
ID3_C_EXPORT size_t removeAllComments(ID3_TagImpl &)
Definition: helpers.cpp:303
ID3_C_EXPORT String getLyrics(const ID3_TagImpl &)
Definition: helpers.cpp:434
ID3_C_EXPORT String getArtist(const ID3_TagImpl &)
Definition: helpers.cpp:130
ID3_C_EXPORT size_t removeTracks(ID3_TagImpl &)
Definition: helpers.cpp:370
ID3_C_EXPORT size_t getGenreNum(const ID3_TagImpl &)
Definition: helpers.cpp:388
ID3_C_EXPORT String getTitle(const ID3_TagImpl &)
Definition: helpers.cpp:188
ID3_C_EXPORT size_t removeYears(ID3_TagImpl &)
Definition: helpers.cpp:221
ID3_C_EXPORT ID3_Frame * setLyricist(ID3_TagImpl &, String)
Definition: helpers.cpp:483
ID3_C_EXPORT String getString(const ID3_Frame *, ID3_FieldID)
Definition: helpers.cpp:43
ID3_C_EXPORT ID3_Frame * setLyrics(ID3_TagImpl &, String, String, String)
Definition: helpers.cpp:439
ID3_C_EXPORT ID3_Frame * setAlbum(ID3_TagImpl &, String)
Definition: helpers.cpp:170
ID3_C_EXPORT String getAlbum(const ID3_TagImpl &)
Definition: helpers.cpp:165
ID3_C_EXPORT String getV1Comment(const ID3_TagImpl &)
Definition: helpers.cpp:243
ID3_C_EXPORT ID3_Frame * setTitle(ID3_TagImpl &, String)
Definition: helpers.cpp:193
ID3_C_EXPORT ID3_Frame * setArtist(ID3_TagImpl &, String)
Definition: helpers.cpp:136
ID3_C_EXPORT ID3_Frame * setYear(ID3_TagImpl &, String)
Definition: helpers.cpp:216
ID3_C_EXPORT size_t removeTitles(ID3_TagImpl &)
Definition: helpers.cpp:198
ID3_C_EXPORT String getLyricist(const ID3_TagImpl &)
Definition: helpers.cpp:478
ID3_C_EXPORT ID3_Frame * hasArtist(const ID3_TagImpl &)
Definition: helpers.cpp:120
ID3_C_EXPORT String getYear(const ID3_TagImpl &)
Definition: helpers.cpp:211
ID3_C_EXPORT ID3_Frame * hasGenre(const ID3_TagImpl &)
Definition: helpers.cpp:377
ID3_C_EXPORT String getComment(const ID3_TagImpl &, String desc)
Definition: helpers.cpp:252
ID3_C_EXPORT ID3_Frame * setFrameText(ID3_TagImpl &, ID3_FrameID, String)
Definition: helpers.cpp:105
ID3_C_EXPORT ID3_Frame * hasSyncLyrics(const ID3_TagImpl &, String lang, String desc)
Definition: helpers.cpp:495
ID3_C_EXPORT ID3_Frame * setComment(ID3_TagImpl &, String, String, String)
Definition: helpers.cpp:258
ID3_C_EXPORT ID3_Frame * hasV1Comment(const ID3_TagImpl &)
Definition: helpers.cpp:228
ID3_C_EXPORT size_t removeGenres(ID3_TagImpl &)
Definition: helpers.cpp:421
ID3_C_EXPORT ID3_Frame * setTrack(ID3_TagImpl &, uchar ucTrack, uchar ucTotal)
Definition: helpers.cpp:356
ID3_C_EXPORT BString getSyncLyrics(const ID3_TagImpl &tag, String lang, String desc)
Definition: helpers.cpp:527
ID3_C_EXPORT ID3_Frame * hasTrack(const ID3_TagImpl &)
Definition: helpers.cpp:339
ID3_C_EXPORT String getFrameText(const ID3_TagImpl &, ID3_FrameID)
Definition: helpers.cpp:99
ID3_C_EXPORT size_t removeLyricists(ID3_TagImpl &)
Definition: helpers.cpp:488
ID3_C_EXPORT ID3_Frame * hasTitle(const ID3_TagImpl &)
Definition: helpers.cpp:182
ID3_C_EXPORT String getGenre(const ID3_TagImpl &)
Definition: helpers.cpp:383
ID3_C_EXPORT size_t removeFrames(ID3_TagImpl &, ID3_FrameID)
Definition: helpers.cpp:84
ID3_C_EXPORT size_t removeComments(ID3_TagImpl &, String)
Definition: helpers.cpp:309
ID3_C_EXPORT size_t getTrackNum(const ID3_TagImpl &)
Definition: helpers.cpp:350
ID3_C_EXPORT String getTrack(const ID3_TagImpl &)
Definition: helpers.cpp:345
ID3_C_EXPORT ID3_Frame * hasYear(const ID3_TagImpl &)
Definition: helpers.cpp:205
ID3_C_EXPORT ID3_Frame * setGenre(ID3_TagImpl &, size_t ucGenre)
Definition: helpers.cpp:414
ID3_C_EXPORT size_t removeLyrics(ID3_TagImpl &)
Definition: helpers.cpp:473
ID3_C_EXPORT ID3_Frame * hasLyrics(const ID3_TagImpl &)
Definition: helpers.cpp:428
ID3_C_EXPORT String getStringAtIndex(const ID3_Frame *, ID3_FieldID, size_t)
Definition: helpers.cpp:63
ID3_C_EXPORT ID3_Frame * hasAlbum(const ID3_TagImpl &)
Definition: helpers.cpp:159
ID3_C_EXPORT ID3_Frame * setSyncLyrics(ID3_TagImpl &, BString, ID3_TimeStampFormat, String, String, ID3_ContentType)
Definition: helpers.cpp:503
ID3_C_EXPORT size_t removeAlbums(ID3_TagImpl &)
Definition: helpers.cpp:175
ID3_C_EXPORT size_t removeArtists(ID3_TagImpl &)
Definition: helpers.cpp:142
Definition: tag_impl.h:42
const T & min(const T &a, const T &b)
Definition: utils.h:51
String ID3_C_EXPORT toString(uint32 val)
Definition: utils.cpp:365