Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

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 Thu Jun 3 16:57:09 2004 for id3lib by doxygen 1.3.7