src/helpers.cpp

Go to the documentation of this file.
00001 // $Id: helpers.cpp,v 1.12 2002/09/21 17:23:32 t1mpy Exp $
00002 
00003 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
00004 // Copyright 1999, 2000  Scott Thomas Haug
00005 
00006 // Lots of hacking added to this file by Scott Wheeler (scott@slackorama.net)
00007 // 11/02/2001
00008 
00009 // This library is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU Library General Public License as published by
00011 // the Free Software Foundation; either version 2 of the License, or (at your
00012 // option) any later version.
00013 //
00014 // This library is distributed in the hope that it will be useful, but WITHOUT
00015 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00017 // License for more details.
00018 //
00019 // You should have received a copy of the GNU Library General Public License
00020 // along with this library; if not, write to the Free Software Foundation,
00021 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00022 
00023 // The id3lib authors encourage improvements and optimisations to be sent to
00024 // the id3lib coordinator.  Please see the README file for details on where to
00025 // send such submissions.  See the AUTHORS file for a list of people who have
00026 // contributed to id3lib.  See the ChangeLog file for a list of changes to
00027 // id3lib.  These files are distributed with id3lib at
00028 // http://download.sourceforge.net/id3lib/
00029 
00030 #if defined HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033 
00034 
00035 
00036 #include <ctype.h>
00037 
00038 #include "helpers.h"
00039 #include "tag_impl.h" //has <stdio.h> "tag.h" "header_tag.h" "frame.h" "field.h" "spec.h" "id3lib_strings.h" "utils.h"
00040 
00041 using namespace dami;
00042 
00043 String id3::v2::getString(const ID3_Frame* frame, ID3_FieldID fldName)
00044 {
00045   if (!frame)
00046   {
00047     return "";
00048   }
00049   ID3_Field* fp = frame->GetField(fldName);
00050   if (!fp)
00051   {
00052     return "";
00053   }
00054   ID3_TextEnc enc = fp->GetEncoding();
00055   fp->SetEncoding(ID3TE_ASCII);
00056 
00057   String text(fp->GetRawText(), fp->Size());
00058 
00059   fp->SetEncoding(enc);
00060   return text;
00061 }
00062 
00063 String id3::v2::getStringAtIndex(const ID3_Frame* frame, ID3_FieldID fldName,
00064                                  size_t nIndex)
00065 {
00066   if (!frame)
00067   {
00068     return "";
00069   }
00070   String text;
00071   ID3_Field* fp = frame->GetField(fldName);
00072   if (fp && fp->GetNumTextItems() < nIndex)
00073   {
00074     ID3_TextEnc enc = fp->GetEncoding();
00075     fp->SetEncoding(ID3TE_ASCII);
00076 
00077     text = fp->GetRawTextItem(nIndex);
00078 
00079     fp->SetEncoding(enc);
00080   }
00081   return text;
00082 }
00083 
00084 size_t id3::v2::removeFrames(ID3_TagImpl& tag, ID3_FrameID id)
00085 {
00086   size_t numRemoved = 0;
00087   ID3_Frame* frame = NULL;
00088 
00089   while ((frame = tag.Find(id)) != NULL)
00090   {
00091     frame = tag.RemoveFrame(frame);
00092     delete frame;
00093     numRemoved++;
00094   }
00095 
00096   return numRemoved;
00097 }
00098 
00099 String id3::v2::getFrameText(const ID3_TagImpl& tag, ID3_FrameID id)
00100 {
00101   ID3_Frame* frame = tag.Find(id);
00102   return getString(frame, ID3FN_TEXT);
00103 }
00104 
00105 ID3_Frame* id3::v2::setFrameText(ID3_TagImpl& tag, ID3_FrameID id, String text)
00106 {
00107   ID3_Frame* frame = tag.Find(id);
00108   if (!frame)
00109   {
00110     frame = new ID3_Frame(id);
00111     if(!tag.AttachFrame(frame)) return NULL;
00112   }
00113   frame->GetField(ID3FN_TEXT)->Set(text.c_str());
00114 
00115   return frame;
00116 }
00117 
00119 
00120 ID3_Frame* id3::v2::hasArtist(const ID3_TagImpl& tag)
00121 {
00122   ID3_Frame* fp = NULL;
00123   (fp = tag.Find(ID3FID_LEADARTIST)) ||
00124   (fp = tag.Find(ID3FID_BAND))       ||
00125   (fp = tag.Find(ID3FID_CONDUCTOR))  ||
00126   (fp = tag.Find(ID3FID_COMPOSER));
00127   return fp;
00128 }
00129 
00130 String id3::v2::getArtist(const ID3_TagImpl& tag)
00131 {
00132   ID3_Frame* frame = hasArtist(tag);
00133   return getString(frame, ID3FN_TEXT);
00134 }
00135 
00136 ID3_Frame* id3::v2::setArtist(ID3_TagImpl& tag, String text)
00137 {
00138   removeArtists(tag);
00139   return setFrameText(tag, ID3FID_LEADARTIST, text);
00140 }
00141 
00142 size_t id3::v2::removeArtists(ID3_TagImpl& tag)
00143 {
00144   size_t numRemoved = 0;
00145   ID3_Frame* frame = NULL;
00146 
00147   while ((frame = hasArtist(tag)) != NULL)
00148   {
00149     frame = tag.RemoveFrame(frame);
00150     delete frame;
00151     numRemoved++;
00152   }
00153 
00154   return numRemoved;
00155 }
00156 
00158 
00159 ID3_Frame* id3::v2::hasAlbum(const ID3_TagImpl& tag)
00160 {
00161   ID3_Frame* frame = tag.Find(ID3FID_ALBUM);
00162   return(frame);
00163 }
00164 
00165 String id3::v2::getAlbum(const ID3_TagImpl& tag)
00166 {
00167   return getFrameText(tag, ID3FID_ALBUM);
00168 }
00169 
00170 ID3_Frame* id3::v2::setAlbum(ID3_TagImpl& tag, String text)
00171 {
00172   return setFrameText(tag, ID3FID_ALBUM, text);
00173 }
00174 
00175 size_t id3::v2::removeAlbums(ID3_TagImpl& tag)
00176 {
00177   return removeFrames(tag, ID3FID_ALBUM);
00178 }
00179 
00181 
00182 ID3_Frame* id3::v2::hasTitle(const ID3_TagImpl& tag)
00183 {
00184   ID3_Frame* frame = tag.Find(ID3FID_TITLE);
00185   return(frame);
00186 }
00187 
00188 String id3::v2::getTitle(const ID3_TagImpl& tag)
00189 {
00190   return getFrameText(tag, ID3FID_TITLE);
00191 }
00192 
00193 ID3_Frame* id3::v2::setTitle(ID3_TagImpl& tag, String text)
00194 {
00195   return setFrameText(tag, ID3FID_TITLE, text);
00196 }
00197 
00198 size_t id3::v2::removeTitles(ID3_TagImpl& tag)
00199 {
00200   return removeFrames(tag, ID3FID_TITLE);
00201 }
00202 
00204 
00205 ID3_Frame* id3::v2::hasYear(const ID3_TagImpl& tag)
00206 {
00207   ID3_Frame* frame = tag.Find(ID3FID_YEAR);
00208   return(frame);
00209 }
00210 
00211 String id3::v2::getYear(const ID3_TagImpl& tag)
00212 {
00213   return getFrameText(tag, ID3FID_YEAR);
00214 }
00215 
00216 ID3_Frame* id3::v2::setYear(ID3_TagImpl& tag, String text)
00217 {
00218   return setFrameText(tag, ID3FID_YEAR, text);
00219 }
00220 
00221 size_t id3::v2::removeYears(ID3_TagImpl& tag)
00222 {
00223   return removeFrames(tag, ID3FID_YEAR);
00224 }
00225 
00227 
00228 ID3_Frame* id3::v2::hasV1Comment(const ID3_TagImpl& tag)
00229 {
00230   ID3_Frame* frame = NULL;
00231   (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, STR_V1_COMMENT_DESC)) ||
00232   (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, ""                 )) ||
00233   (frame = tag.Find(ID3FID_COMMENT));
00234   return(frame);
00235 }
00236 
00237 ID3_Frame* id3::v2::hasComment(const ID3_TagImpl& tag)
00238 {
00239   ID3_Frame* frame = tag.Find(ID3FID_COMMENT);
00240   return(frame);
00241 }
00242 
00243 String id3::v2::getV1Comment(const ID3_TagImpl& tag)
00244 {
00245   ID3_Frame* frame;
00246   (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, STR_V1_COMMENT_DESC)) ||
00247   (frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, ""                 )) ||
00248   (frame = tag.Find(ID3FID_COMMENT));
00249   return getString(frame, ID3FN_TEXT);
00250 }
00251 
00252 String id3::v2::getComment(const ID3_TagImpl& tag, String desc)
00253 {
00254   ID3_Frame* frame = tag.Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, desc.c_str());
00255   return getString(frame, ID3FN_TEXT);
00256 }
00257 
00258 ID3_Frame* id3::v2::setComment(ID3_TagImpl& tag, String text, String desc,
00259                                String lang)
00260 {
00261   ID3D_NOTICE( "id3::v2::setComment: trying to find frame with description = " << desc );
00262   ID3_Frame* frame = NULL;
00263   // See if there is already a comment with this description
00264   for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter)
00265   {
00266     frame = *iter;
00267     if (frame == NULL)
00268     {
00269       continue;
00270     }
00271     if (frame->GetID() == ID3FID_COMMENT)
00272     {
00273       String tmpDesc = getString(frame, ID3FN_DESCRIPTION);
00274       if (tmpDesc == desc)
00275       {
00276         ID3D_NOTICE( "id3::v2::setComment: found frame with description = " << desc );
00277         break;
00278       }
00279     }
00280     frame = NULL;
00281   }
00282   if (frame == NULL)
00283   {
00284     ID3D_NOTICE( "id3::v2::setComment: creating new comment frame" );
00285     frame = new ID3_Frame(ID3FID_COMMENT);
00286     if(!tag.AttachFrame(frame)) return NULL;
00287   }
00288   if (!frame)
00289   {
00290     ID3D_WARNING( "id3::v2::setComment: ack! no frame" );
00291   }
00292   else
00293   {
00294     frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str());
00295     frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str());
00296     frame->GetField(ID3FN_TEXT)->Set(text.c_str());
00297   }
00298 
00299   return frame;
00300 }
00301 
00302 // Remove all comments from the tag
00303 size_t id3::v2::removeAllComments(ID3_TagImpl& tag)
00304 {
00305   return removeFrames(tag, ID3FID_COMMENT);
00306 }
00307 
00308 // Remove all comments from the tag with the given description
00309 size_t id3::v2::removeComments(ID3_TagImpl& tag, String desc)
00310 {
00311   size_t numRemoved = 0;
00312 
00313   for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter)
00314   {
00315     ID3_Frame* frame = *iter;
00316     if (frame == NULL)
00317     {
00318       continue;
00319     }
00320     if (frame->GetID() == ID3FID_COMMENT)
00321     {
00322       // See if the description we have matches the description of the
00323       // current comment.  If so, remove the comment
00324       String tmpDesc = getString(frame, ID3FN_DESCRIPTION);
00325       if (tmpDesc == desc)
00326       {
00327         frame = tag.RemoveFrame(frame);
00328         delete frame;
00329         numRemoved++;
00330       }
00331     }
00332   }
00333 
00334   return numRemoved;
00335 }
00336 
00338 
00339 ID3_Frame* id3::v2::hasTrack(const ID3_TagImpl& tag)
00340 {
00341   ID3_Frame* frame = tag.Find(ID3FID_TRACKNUM);
00342   return(frame);
00343 }
00344 
00345 String id3::v2::getTrack(const ID3_TagImpl& tag)
00346 {
00347   return getFrameText(tag, ID3FID_TRACKNUM);
00348 }
00349 
00350 size_t id3::v2::getTrackNum(const ID3_TagImpl& tag)
00351 {
00352   String sTrack = getTrack(tag);
00353   return ::atoi(sTrack.c_str());
00354 }
00355 
00356 ID3_Frame* id3::v2::setTrack(ID3_TagImpl& tag, uchar trk, uchar ttl)
00357 {
00358   ID3_Frame* frame = NULL;
00359   String track = toString((size_t)trk);
00360   if (ttl > 0)
00361   {
00362     track += "/";
00363     track += toString((size_t)ttl);
00364   }
00365   setFrameText(tag, ID3FID_TRACKNUM, track);
00366 
00367   return frame;
00368 }
00369 
00370 size_t id3::v2::removeTracks(ID3_TagImpl& tag)
00371 {
00372   return removeFrames(tag, ID3FID_TRACKNUM);
00373 }
00374 
00376 
00377 ID3_Frame* id3::v2::hasGenre(const ID3_TagImpl& tag)
00378 {
00379   ID3_Frame* frame = tag.Find(ID3FID_CONTENTTYPE);
00380   return(frame);
00381 }
00382 
00383 String id3::v2::getGenre(const ID3_TagImpl& tag)
00384 {
00385   return getFrameText(tag, ID3FID_CONTENTTYPE);
00386 }
00387 
00388 size_t id3::v2::getGenreNum(const ID3_TagImpl& tag)
00389 {
00390   String sGenre = getGenre(tag);
00391   size_t ulGenre = 0xFF;
00392   size_t size = sGenre.size();
00393 
00394   // If the genre string begins with "(ddd)", where "ddd" is a number, then
00395   // "ddd" is the genre number---get it
00396   size_t i = 0;
00397   if (i < size && size && sGenre[i] == '(')
00398   {
00399     ++i;
00400     while (i < size && isdigit(sGenre[i]))
00401     {
00402       ++i;
00403     }
00404     if (i < size && sGenre[i] == ')')
00405     {
00406       // if the genre number is greater than 255, its invalid.
00407       ulGenre = min(0xFF, atoi(&sGenre[1]));
00408     }
00409   }
00410 
00411   return ulGenre;
00412 }
00413 
00414 ID3_Frame* id3::v2::setGenre(ID3_TagImpl& tag, size_t genre)
00415 {
00416   String sGenre = "(";
00417   sGenre += toString(genre) + ")";
00418   return setFrameText(tag, ID3FID_CONTENTTYPE, sGenre);
00419 }
00420 
00421 size_t id3::v2::removeGenres(ID3_TagImpl& tag)
00422 {
00423   return removeFrames(tag, ID3FID_CONTENTTYPE);
00424 }
00425 
00427 
00428 ID3_Frame* id3::v2::hasLyrics(const ID3_TagImpl& tag)
00429 {
00430   ID3_Frame* frame = tag.Find(ID3FID_UNSYNCEDLYRICS);
00431   return(frame);
00432 }
00433 
00434 String id3::v2::getLyrics(const ID3_TagImpl& tag)
00435 {
00436   return getFrameText(tag, ID3FID_UNSYNCEDLYRICS);
00437 }
00438 
00439 ID3_Frame* id3::v2::setLyrics(ID3_TagImpl& tag, String text, String desc,
00440                               String lang)
00441 {
00442   ID3_Frame* frame = NULL;
00443   // See if there is already a comment with this description
00444   for (ID3_TagImpl::iterator iter = tag.begin(); iter != tag.end(); ++iter)
00445   {
00446     frame = *iter;
00447     if (frame == NULL)
00448     {
00449       continue;
00450     }
00451     if (frame->GetID() == ID3FID_COMMENT)
00452     {
00453       String tmpDesc = getString(frame, ID3FN_DESCRIPTION);
00454       if (tmpDesc == desc)
00455       {
00456         break;
00457       }
00458     }
00459     frame = NULL;
00460   }
00461   if (frame == NULL)
00462   {
00463     frame = new ID3_Frame(ID3FID_UNSYNCEDLYRICS);
00464     if(!tag.AttachFrame(frame)) return NULL;
00465   }
00466   frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str());
00467   frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str());
00468   frame->GetField(ID3FN_TEXT)->Set(text.c_str());
00469 
00470   return frame;
00471 }
00472 
00473 size_t id3::v2::removeLyrics(ID3_TagImpl& tag)
00474 {
00475   return removeFrames(tag, ID3FID_UNSYNCEDLYRICS);
00476 }
00477 
00478 String id3::v2::getLyricist(const ID3_TagImpl& tag)
00479 {
00480   return getFrameText(tag, ID3FID_LYRICIST);
00481 }
00482 
00483 ID3_Frame* id3::v2::setLyricist(ID3_TagImpl& tag, String text)
00484 {
00485   return setFrameText(tag, ID3FID_LYRICIST, text);
00486 }
00487 
00488 size_t id3::v2::removeLyricists(ID3_TagImpl& tag)
00489 {
00490   return removeFrames(tag, ID3FID_LYRICIST);
00491 }
00492 
00494 
00495 ID3_Frame* id3::v2::hasSyncLyrics(const ID3_TagImpl& tag, String lang, String desc)
00496 {
00497   ID3_Frame* frame=NULL;
00498   (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang)) ||
00499   (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc));
00500   return(frame);
00501 }
00502 
00503 ID3_Frame* id3::v2::setSyncLyrics(ID3_TagImpl& tag, BString data,
00504                                   ID3_TimeStampFormat format, String desc,
00505                                   String lang, ID3_ContentType type)
00506 {
00507   ID3_Frame* frame = NULL;
00508 
00509   // check if a SYLT frame of this language or descriptor already exists
00510   (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang)) ||
00511   (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc));
00512 
00513   if (!frame)
00514   {
00515     frame = new ID3_Frame(ID3FID_SYNCEDLYRICS);
00516     if(!tag.AttachFrame(frame)) return NULL;
00517   }
00518   frame->GetField(ID3FN_LANGUAGE)->Set(lang.c_str());
00519   frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str());
00520   frame->GetField(ID3FN_TIMESTAMPFORMAT)->Set(format);
00521   frame->GetField(ID3FN_CONTENTTYPE)->Set(type);
00522   frame->GetField(ID3FN_DATA)->Set(data.data(), data.size());
00523 
00524   return frame;
00525 }
00526 
00527 BString id3::v2::getSyncLyrics(const ID3_TagImpl& tag, String lang, String desc)
00528 {
00529   // check if a SYLT frame of this language or descriptor exists
00530   ID3_Frame* frame = NULL;
00531   (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang)) ||
00532   (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc)) ||
00533   (frame = tag.Find(ID3FID_SYNCEDLYRICS));
00534 
00535   // get the lyrics size
00536   ID3_Field* fld = frame->GetField(ID3FN_DATA);
00537   return BString(reinterpret_cast<const BString::value_type *>(fld->GetRawBinary()), fld->Size());
00538 }
00539 

Generated on Mon Aug 20 17:48:46 2007 for id3lib by  doxygen 1.5.2