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

src/tag_impl.cpp

Go to the documentation of this file.
00001 // $Id: tag_impl.cpp,v 1.13 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 // 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 #if defined HAVE_SYS_PARAM_H 00029 #include <sys/param.h> 00030 #endif 00031 00032 #include "tag_impl.h" //has <stdio.h> "tag.h" "header_tag.h" "frame.h" "field.h" "spec.h" "id3lib_strings.h" "utils.h" 00033 //#include "io_helpers.h" 00034 #include "io_strings.h" 00035 00036 using namespace dami; 00037 00038 size_t ID3_TagImpl::IsV2Tag(ID3_Reader& reader) 00039 { 00040 io::ExitTrigger et(reader); 00041 size_t tagSize = 0; 00042 String id = io::readText(reader, ID3_TagHeader::ID_SIZE); 00043 String ver = io::readText(reader, 2); 00044 char flags = reader.readChar(); 00045 String size = io::readText(reader, 4); 00046 00047 if (id == ID3_TagHeader::ID && 00048 (uchar) ver [0] < 0xFF && (uchar) ver [1] < 0xFF && 00049 (uchar) size[0] < 0x80 && (uchar) size[1] < 0x80 && 00050 (uchar) size[2] < 0x80 && (uchar) size[3] < 0x80) 00051 { 00052 io::StringReader sr(size); 00053 tagSize = io::readUInt28(sr) + ID3_TagHeader::SIZE; 00054 } 00055 else if (id != ID3_TagHeader::ID) 00056 { 00057 // clog << "*** IsV2Tag: Not an id3v2 tag header" << endl; 00058 } 00059 else if ((uchar)ver[0] >= 0xFF) 00060 { 00061 // clog << "*** IsV2Tag: Major offset" << endl; 00062 } 00063 else if ((uchar)ver[1] >= 0xFF) 00064 { 00065 // clog << "*** ISV2Tag: Minor offset" << endl; 00066 } 00067 else if ((uchar)size[0] >= 0x80) 00068 { 00069 // clog << "*** ISV2Tag: 1st size offset" << endl; 00070 } 00071 else if ((uchar)size[1] >= 0x80) 00072 { 00073 // clog << "*** ISV2Tag: 2nd size offset" << endl; 00074 } 00075 else if ((uchar)size[2] >= 0x80) 00076 { 00077 // clog << "*** ISV2Tag: 3rd size offset" << endl; 00078 } 00079 else if ((uchar)size[3] >= 0x80) 00080 { 00081 // clog << "*** ISV2Tag: 4th size offset" << endl; 00082 } 00083 else 00084 { 00085 // clog << "*** shouldn't get here!" << endl; 00086 } 00087 00088 return tagSize; 00089 } 00090 00091 ID3_TagImpl::ID3_TagImpl(const char *name) 00092 : _frames(), 00093 _cursor(_frames.begin()), 00094 _file_name(), 00095 _file_size(0), 00096 _prepended_bytes(0), 00097 _appended_bytes(0), 00098 _is_file_writable(false), 00099 _mp3_info(NULL) // need to do this before this->Clear() 00100 { 00101 this->Clear(); 00102 if (name) 00103 { 00104 this->Link(name); 00105 } 00106 } 00107 00108 ID3_TagImpl::ID3_TagImpl(const ID3_Tag &tag) 00109 : _frames(), 00110 _cursor(_frames.begin()), 00111 _file_name(), 00112 _file_size(0), 00113 _prepended_bytes(0), 00114 _appended_bytes(0), 00115 _is_file_writable(false), 00116 _mp3_info(NULL) // need to do this before this->Clear() 00117 { 00118 *this = tag; 00119 } 00120 00121 ID3_TagImpl::~ID3_TagImpl() 00122 { 00123 this->Clear(); 00124 } 00125 00126 void ID3_TagImpl::Clear() 00127 { 00128 for (iterator cur = _frames.begin(); cur != _frames.end(); ++cur) 00129 { 00130 if (*cur) 00131 { 00132 delete *cur; 00133 *cur = NULL; 00134 } 00135 } 00136 _frames.clear(); 00137 _cursor = _frames.begin(); 00138 _is_padded = true; 00139 00140 _hdr.Clear(); 00141 _hdr.SetSpec(ID3V2_LATEST); 00142 00143 _tags_to_parse.clear(); 00144 if (_mp3_info) 00145 delete _mp3_info; // Also deletes _mp3_header 00146 00147 _mp3_info = NULL; 00148 00149 _changed = true; 00150 } 00151 00152 00153 void ID3_TagImpl::AddFrame(const ID3_Frame& frame) 00154 { 00155 this->AddFrame(&frame); 00156 } 00157 00158 void ID3_TagImpl::AddFrame(const ID3_Frame* frame) 00159 { 00160 if (frame) 00161 { 00162 ID3_Frame* frm = new ID3_Frame(*frame); 00163 this->AttachFrame(frm); 00164 } 00165 } 00166 00167 bool ID3_TagImpl::AttachFrame(ID3_Frame *frame) 00168 { 00169 00170 if (NULL == frame) 00171 { 00172 // log this 00173 return false; 00174 //ID3_THROW(ID3E_NoData); 00175 } 00176 00177 _frames.push_back(frame); 00178 _cursor = _frames.begin(); 00179 00180 _changed = true; 00181 return true; 00182 } 00183 00184 00185 ID3_Frame* ID3_TagImpl::RemoveFrame(const ID3_Frame *frame) 00186 { 00187 ID3_Frame *frm = NULL; 00188 00189 iterator fi = Find(frame); 00190 if (fi != _frames.end()) 00191 { 00192 frm = *fi; 00193 _frames.erase(fi); 00194 _cursor = _frames.begin(); 00195 _changed = true; 00196 } 00197 00198 return frm; 00199 } 00200 00201 00202 bool ID3_TagImpl::HasChanged() const 00203 { 00204 bool changed = _changed; 00205 00206 if (! changed) 00207 { 00208 for (const_iterator fi = _frames.begin(); fi != _frames.end(); ++fi) 00209 { 00210 if (*fi) 00211 { 00212 changed = (*fi)->HasChanged(); 00213 } 00214 00215 if (changed) 00216 { 00217 break; 00218 } 00219 } 00220 } 00221 00222 return changed; 00223 } 00224 00225 bool ID3_TagImpl::SetSpec(ID3_V2Spec spec) 00226 { 00227 bool changed = _hdr.SetSpec(spec); 00228 _changed = _changed || changed; 00229 return changed; 00230 } 00231 00232 ID3_V2Spec ID3_TagImpl::GetSpec() const 00233 { 00234 return _hdr.GetSpec(); 00235 } 00236 00237 bool ID3_TagImpl::SetUnsync(bool b) 00238 { 00239 bool changed = _hdr.SetUnsync(b); 00240 _changed = changed || _changed; 00241 return changed; 00242 } 00243 00244 bool ID3_TagImpl::SetExtended(bool ext) 00245 { 00246 bool changed = _hdr.SetExtended(ext); 00247 _changed = changed || _changed; 00248 return changed; 00249 } 00250 00251 bool ID3_TagImpl::SetExperimental(bool exp) 00252 { 00253 bool changed = _hdr.SetExperimental(exp); 00254 _changed = changed || _changed; 00255 return changed; 00256 } 00257 00258 bool ID3_TagImpl::GetUnsync() const 00259 { 00260 return _hdr.GetUnsync(); 00261 } 00262 00263 bool ID3_TagImpl::GetExtended() const 00264 { 00265 return _hdr.GetExtended(); 00266 } 00267 00268 bool ID3_TagImpl::GetExperimental() const 00269 { 00270 return _hdr.GetExperimental(); 00271 } 00272 00273 bool ID3_TagImpl::GetFooter() const 00274 { 00275 return _hdr.GetFooter(); 00276 } 00277 00278 size_t ID3_TagImpl::GetExtendedBytes() const 00279 { 00280 if (this->GetExtended()) 00281 if (this->GetSpec() == ID3V2_4_0) 00282 return 6; //minimal ID3v2.4 ext header size 00283 else if (this->GetSpec() == ID3V2_3_0) 00284 return 10; //minimal ID3v2.3 ext header size 00285 else 00286 return 0; //not implemented 00287 else 00288 return 0;; 00289 } 00290 00291 bool ID3_TagImpl::SetPadding(bool pad) 00292 { 00293 bool changed = (_is_padded != pad); 00294 _changed = changed || _changed; 00295 if (changed) 00296 { 00297 _is_padded = pad; 00298 } 00299 00300 return changed; 00301 } 00302 00303 00304 ID3_TagImpl & 00305 ID3_TagImpl::operator=( const ID3_Tag &rTag ) 00306 { 00307 this->Clear(); 00308 00309 this->SetUnsync(rTag.GetUnsync()); 00310 this->SetExtended(rTag.GetExtendedHeader()); 00311 this->SetExperimental(rTag.GetExperimental()); 00312 00313 ID3_Tag::ConstIterator* iter = rTag.CreateIterator(); 00314 const ID3_Frame* frame = NULL; 00315 while (NULL != (frame = iter->GetNext())) 00316 { 00317 this->AttachFrame(new ID3_Frame(*frame)); 00318 } 00319 delete iter; 00320 return *this; 00321 } 00322 00323 size_t ID3_GetDataSize(const ID3_TagImpl& tag) 00324 { 00325 return tag.GetFileSize() - tag.GetPrependedBytes() - tag.GetAppendedBytes(); 00326 } 00327

Generated on Thu Jun 3 16:57:09 2004 for id3lib by doxygen 1.3.7