id3lib 3.8.3
|
00001 // $Id: tag.cpp,v 1.55 2003/03/02 13:35:58 t1mpy Exp $ 00002 00003 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags 00004 // Copyright 1999, 2000 Scott Thomas Haug 00005 // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) 00006 00007 // This library is free software; you can redistribute it and/or modify it 00008 // under the terms of the GNU Library General Public License as published by 00009 // the Free Software Foundation; either version 2 of the License, or (at your 00010 // option) any later version. 00011 // 00012 // This library is distributed in the hope that it will be useful, but WITHOUT 00013 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00015 // License for more details. 00016 // 00017 // You should have received a copy of the GNU Library General Public License 00018 // along with this library; if not, write to the Free Software Foundation, 00019 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00020 00021 // The id3lib authors encourage improvements and optimisations to be sent to 00022 // the id3lib coordinator. Please see the README file for details on where to 00023 // send such submissions. See the AUTHORS file for a list of people who have 00024 // contributed to id3lib. See the ChangeLog file for a list of changes to 00025 // id3lib. These files are distributed with id3lib at 00026 // http://download.sourceforge.net/id3lib/ 00027 00028 //#include "readers.h" 00029 #include "writers.h" 00030 #include "tag_impl.h" //has <stdio.h> "tag.h" "header_tag.h" "frame.h" "field.h" "spec.h" "id3lib_strings.h" "utils.h" 00031 00032 using namespace dami; 00033 00289 ID3_Tag::ID3_Tag(const char *name) 00290 : _impl(new ID3_TagImpl(name)) 00291 { 00292 } 00293 00298 ID3_Tag::ID3_Tag(const ID3_Tag &tag) 00299 : _impl(new ID3_TagImpl(tag)) 00300 { 00301 } 00302 00303 ID3_Tag::~ID3_Tag() 00304 { 00305 delete _impl; 00306 } 00307 00314 void ID3_Tag::Clear() 00315 { 00316 _impl->Clear(); 00317 } 00318 00319 00343 bool ID3_Tag::HasChanged() const 00344 { 00345 return _impl->HasChanged(); 00346 } 00347 00378 size_t ID3_Tag::Size() const 00379 { 00380 return _impl->Size(); 00381 } 00382 00400 bool ID3_Tag::SetUnsync(bool b) 00401 { 00402 return _impl->SetUnsync(b); 00403 } 00404 00405 00419 bool ID3_Tag::SetExtendedHeader(bool ext) 00420 { 00421 return _impl->SetExtended(ext); 00422 } 00423 00453 bool ID3_Tag::SetPadding(bool pad) 00454 { 00455 return _impl->SetPadding(pad); 00456 } 00457 00458 bool ID3_Tag::SetExperimental(bool exp) 00459 { 00460 return _impl->SetExperimental(exp); 00461 } 00462 00463 bool ID3_Tag::GetUnsync() const 00464 { 00465 return _impl->GetUnsync(); 00466 } 00467 00468 bool ID3_Tag::GetExtendedHeader() const 00469 { 00470 return _impl->GetExtended(); 00471 } 00472 00473 bool ID3_Tag::GetExperimental() const 00474 { 00475 return _impl->GetExperimental(); 00476 } 00477 00478 void ID3_Tag::AddFrame(const ID3_Frame& frame) 00479 { 00480 _impl->AddFrame(frame); 00481 } 00482 00502 void ID3_Tag::AddFrame(const ID3_Frame* frame) 00503 { 00504 _impl->AddFrame(frame); 00505 } 00506 00521 bool ID3_Tag::AttachFrame(ID3_Frame *frame) 00522 { 00523 return _impl->AttachFrame(frame); 00524 } 00525 00526 00547 ID3_Frame* ID3_Tag::RemoveFrame(const ID3_Frame *frame) 00548 { 00549 return _impl->RemoveFrame(frame); 00550 } 00551 00552 bool ID3_Tag::Parse(ID3_Reader& reader) 00553 { 00554 return id3::v2::parse(*_impl, reader); 00555 } 00556 00557 size_t ID3_Tag::Parse(const uchar* buffer, size_t bytes) 00558 { 00559 ID3_MemoryReader mr(buffer, bytes); 00560 ID3_Reader::pos_type beg = mr.getCur(); 00561 id3::v2::parse(*_impl, mr); 00562 return mr.getEnd() - beg; 00563 } 00564 00604 size_t ID3_Tag::Parse(const uchar header[ID3_TAGHEADERSIZE], const uchar *buffer) 00605 { 00606 size_t size = ID3_Tag::IsV2Tag(header); 00607 if (0 == size) 00608 { 00609 return 0; 00610 } 00611 BString buf; 00612 buf.reserve(ID3_TagHeader::SIZE + size); 00613 buf.append(reinterpret_cast<const BString::value_type *>(header), 00614 ID3_TagHeader::SIZE); 00615 buf.append(reinterpret_cast<const BString::value_type *>(buffer), size); 00616 return this->Parse(buf.data(), buf.size()); 00617 } 00618 00647 size_t ID3_Tag::Render(uchar* buffer, ID3_TagType tt) const 00648 { 00649 ID3_MemoryWriter mw(buffer, static_cast<unsigned int>(-1)); 00650 return this->Render(mw, tt); 00651 } 00652 00653 size_t ID3_Tag::Render(ID3_Writer& writer, ID3_TagType tt) const 00654 { 00655 ID3_Writer::pos_type beg = writer.getCur(); 00656 if (ID3TT_ID3V2 & tt) 00657 { 00658 id3::v2::render(writer, *this); 00659 } 00660 else if (ID3TT_ID3V1 & tt) 00661 { 00662 id3::v1::render(writer, *this); 00663 } 00664 return writer.getCur() - beg; 00665 } 00666 00667 00704 size_t ID3_Tag::Link(const char *fileInfo, flags_t flags) 00705 { 00706 return _impl->Link(fileInfo, flags); 00707 } 00708 00712 size_t ID3_Tag::Link(ID3_Reader &reader, flags_t flags) 00713 { 00714 return _impl->Link(reader, flags); 00715 } 00716 00717 flags_t ID3_Tag::Update(flags_t flags) 00718 { 00719 return _impl->Update(flags); 00720 } 00721 00727 const Mp3_Headerinfo* ID3_Tag::GetMp3HeaderInfo() const 00728 { 00729 return _impl->GetMp3HeaderInfo(); 00730 } 00731 00738 flags_t ID3_Tag::Strip(flags_t flags) 00739 { 00740 return _impl->Strip(flags); 00741 } 00742 00743 size_t ID3_Tag::GetPrependedBytes() const 00744 { 00745 return _impl->GetPrependedBytes(); 00746 } 00747 00748 size_t ID3_Tag::GetAppendedBytes() const 00749 { 00750 return _impl->GetAppendedBytes(); 00751 } 00752 00753 size_t ID3_Tag::GetFileSize() const 00754 { 00755 return _impl->GetFileSize(); 00756 } 00757 00758 const char* ID3_Tag::GetFileName() const 00759 { 00760 //fix because GetFileName need to return a pointer which keeps to be valid 00761 String fn = _impl->GetFileName(); 00762 if (fn.size()) 00763 { 00764 memset((char *)_tmp_filename, 0, ID3_PATH_LENGTH); 00765 memmove((char *)_tmp_filename, fn.c_str(), fn.size()); 00766 return _tmp_filename; //_impl->GetFileName().c_str(); 00767 } 00768 else 00769 return NULL; 00770 } 00771 00773 00836 ID3_Frame* ID3_Tag::Find(ID3_FrameID id) const 00837 { 00838 return _impl->Find(id); 00839 } 00840 00842 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, uint32 data) const 00843 { 00844 return _impl->Find(id, fld, data); 00845 } 00846 00848 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const char* data) const 00849 { 00850 String str(data); 00851 return _impl->Find(id, fld, str); 00852 } 00853 00855 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const unicode_t* data) const 00856 { 00857 WString str = toWString(data, ucslen(data)); 00858 return _impl->Find(id, fld, str); 00859 } 00860 00868 size_t ID3_Tag::NumFrames() const 00869 { 00870 return _impl->NumFrames(); 00871 } 00872 00887 /* 00888 ID3_Frame* ID3_Tag::GetFrameNum(size_t num) const 00889 { 00890 const size_t numFrames = this->NumFrames(); 00891 if (num >= numFrames) 00892 { 00893 return NULL; 00894 } 00895 00896 ID3_Frame* frame = NULL; 00897 size_t curNum = 0; 00898 // search from the cursor to the end 00899 for (ID3_TagImpl::const_iterator cur = _impl->begin(); cur != _impl->end(); ++cur) 00900 { 00901 if (curNum++ == num) 00902 { 00903 frame = *cur; 00904 break; 00905 } 00906 } 00907 00908 return frame; 00909 } 00910 */ 00911 00920 /* 00921 ID3_Frame* ID3_Tag::operator[](size_t index) const 00922 { 00923 return this->GetFrameNum(index); 00924 } 00925 */ 00926 00927 ID3_Tag& ID3_Tag::operator=( const ID3_Tag &rTag ) 00928 { 00929 if (this != &rTag) 00930 { 00931 *_impl = rTag; 00932 } 00933 return *this; 00934 } 00935 00936 bool ID3_Tag::HasTagType(ID3_TagType tt) const 00937 { 00938 return _impl->HasTagType(tt); 00939 } 00940 00941 ID3_V2Spec ID3_Tag::GetSpec() const 00942 { 00943 return _impl->GetSpec(); 00944 } 00945 00946 bool ID3_Tag::SetSpec(ID3_V2Spec spec) 00947 { 00948 return _impl->SetSpec(spec); 00949 } 00950 00955 size_t ID3_Tag::IsV2Tag(const uchar* const data) 00956 { 00957 ID3_MemoryReader mr(data, ID3_TagHeader::SIZE); 00958 return ID3_TagImpl::IsV2Tag(mr); 00959 } 00960 00961 size_t ID3_Tag::IsV2Tag(ID3_Reader& reader) 00962 { 00963 return ID3_TagImpl::IsV2Tag(reader); 00964 } 00965 00967 void ID3_Tag::AddNewFrame(ID3_Frame* f) 00968 { 00969 _impl->AttachFrame(f); 00970 } 00971 00988 void ID3_Tag::AddFrames(const ID3_Frame *frames, size_t numFrames) 00989 { 00990 for (int i = numFrames - 1; i >= 0; i--) 00991 { 00992 this->AddFrame(frames[i]); 00993 } 00994 } 00995 00996 size_t ID3_Tag::Link(const char *fileInfo, bool parseID3v1, bool parseLyrics3) 00997 { 00998 return _impl->Link(fileInfo, parseID3v1, parseLyrics3); 00999 } 01000 01001 void ID3_Tag::SetCompression(bool b) 01002 { 01003 ; 01004 } 01005 01006 bool ID3_Tag::HasLyrics() const 01007 { 01008 return this->HasTagType(ID3TT_LYRICS); 01009 } 01010 bool ID3_Tag::HasV2Tag() const 01011 { 01012 return this->HasTagType(ID3TT_ID3V2); 01013 } 01014 bool ID3_Tag::HasV1Tag() const 01015 { 01016 return this->HasTagType(ID3TT_ID3V1); 01017 } 01018 01038 ID3_Tag& ID3_Tag::operator<<(const ID3_Frame& frame) 01039 { 01040 this->AddFrame(frame); 01041 return *this; 01042 } 01043 01044 01045 ID3_Tag& ID3_Tag::operator<<(const ID3_Frame* frame) 01046 { 01047 if (frame) 01048 { 01049 this->AddFrame(frame); 01050 } 01051 return *this; 01052 } 01053 01054 int32 ID3_IsTagHeader(const uchar data[ID3_TAGHEADERSIZE]) 01055 { 01056 size_t size = ID3_Tag::IsV2Tag(data); 01057 01058 if (!size) 01059 { 01060 return -1; 01061 } 01062 01063 return size - ID3_TagHeader::SIZE; 01064 } 01065 01066 01067 namespace 01068 { 01069 class IteratorImpl : public ID3_Tag::Iterator 01070 { 01071 ID3_TagImpl::iterator _cur; 01072 ID3_TagImpl::iterator _end; 01073 public: 01074 IteratorImpl(ID3_TagImpl& tag) 01075 : _cur(tag.begin()), _end(tag.end()) 01076 { 01077 } 01078 01079 ID3_Frame* GetNext() 01080 { 01081 ID3_Frame* next = NULL; 01082 while (next == NULL && _cur != _end) 01083 { 01084 next = *_cur; 01085 ++_cur; 01086 } 01087 return next; 01088 } 01089 }; 01090 01091 01092 class ConstIteratorImpl : public ID3_Tag::ConstIterator 01093 { 01094 ID3_TagImpl::const_iterator _cur; 01095 ID3_TagImpl::const_iterator _end; 01096 public: 01097 ConstIteratorImpl(ID3_TagImpl& tag) 01098 : _cur(tag.begin()), _end(tag.end()) 01099 { 01100 } 01101 const ID3_Frame* GetNext() 01102 { 01103 ID3_Frame* next = NULL; 01104 while (next == NULL && _cur != _end) 01105 { 01106 next = *_cur; 01107 ++_cur; 01108 } 01109 return next; 01110 } 01111 }; 01112 } 01113 01114 ID3_Tag::Iterator* 01115 ID3_Tag::CreateIterator() 01116 { 01117 return new IteratorImpl(*_impl); 01118 } 01119 01120 ID3_Tag::ConstIterator* 01121 ID3_Tag::CreateIterator() const 01122 { 01123 return new ConstIteratorImpl(*_impl); 01124 } 01125