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

src/tag_impl.cpp

Go to the documentation of this file.
00001 // $Id: tag_impl.cpp,v 1.8 2000/10/29 01:37:29 eldamitri Exp $
00002 
00003 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
00004 // Copyright 1999, 2000  Scott Thomas Haug
00005 
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Library General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or (at your
00009 // option) any later version.
00010 //
00011 // This library is distributed in the hope that it will be useful, but WITHOUT
00012 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014 // License for more details.
00015 //
00016 // You should have received a copy of the GNU Library General Public License
00017 // along with this library; if not, write to the Free Software Foundation,
00018 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00019 
00020 // The id3lib authors encourage improvements and optimisations to be sent to
00021 // the id3lib coordinator.  Please see the README file for details on where to
00022 // send such submissions.  See the AUTHORS file for a list of people who have
00023 // contributed to id3lib.  See the ChangeLog file for a list of changes to
00024 // id3lib.  These files are distributed with id3lib at
00025 // http://download.sourceforge.net/id3lib/
00026 
00027 #if defined HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030 
00031 
00032 
00033 #if defined HAVE_SYS_PARAM_H
00034 #include <sys/param.h>
00035 #endif
00036 
00037 #include <string.h>
00038 
00039 #include "tag_impl.h"
00040 #include "utils.h"
00041 #include "io_helpers.h"
00042 #include "io_strings.h"
00043 
00044 using namespace dami;
00045 
00046 size_t ID3_TagImpl::IsV2Tag(ID3_Reader& reader)
00047 {
00048   io::ExitTrigger et(reader);
00049   size_t tagSize = 0;
00050   String id = io::readText(reader, ID3_TagHeader::ID_SIZE);
00051   String ver = io::readText(reader, 2);
00052   char flags = reader.readChar();
00053   String size = io::readText(reader, 4);
00054   
00055   if (id == ID3_TagHeader::ID &&
00056       (uchar) ver [0] < 0xFF   &&      (uchar) ver [1] < 0xFF   &&
00057       (uchar) size[0] < 0x80   &&      (uchar) size[1] < 0x80   &&
00058       (uchar) size[2] < 0x80   &&      (uchar) size[3] < 0x80)
00059   {
00060     io::StringReader sr(size);
00061     tagSize = io::readUInt28(sr) + ID3_TagHeader::SIZE;
00062   }
00063   else if (id != ID3_TagHeader::ID)
00064   {
00065     // clog << "*** IsV2Tag: Not an id3v2 tag header" << endl;
00066   }
00067   else if ((uchar)ver[0] >= 0xFF)
00068   {
00069     // clog << "*** IsV2Tag: Major offset" << endl;
00070   }
00071   else if ((uchar)ver[1] >= 0xFF)
00072   {
00073     // clog << "*** ISV2Tag: Minor offset" << endl;
00074   }
00075   else if ((uchar)size[0] >= 0x80)
00076   {
00077     // clog << "*** ISV2Tag: 1st size offset" << endl;
00078   }
00079   else if ((uchar)size[1] >= 0x80)
00080   {
00081     // clog << "*** ISV2Tag: 2nd size offset" << endl;
00082   }
00083   else if ((uchar)size[2] >= 0x80)
00084   {
00085     // clog << "*** ISV2Tag: 3rd size offset" << endl;
00086   }
00087   else if ((uchar)size[3] >= 0x80)
00088   {
00089     // clog << "*** ISV2Tag: 4th size offset" << endl;
00090   }
00091   else
00092   {
00093     // clog << "*** shouldn't get here!" << endl;
00094   }
00095   
00096   return tagSize;
00097 }
00098 
00099 ID3_TagImpl::ID3_TagImpl(const char *name)
00100   : _frames(),
00101     _cursor(_frames.begin()),
00102     _file_name(),
00103     _file_size(0),
00104     _prepended_bytes(0),
00105     _appended_bytes(0),
00106     _is_file_writable(false)
00107 {
00108   this->Clear();
00109   if (name)
00110   {
00111     this->Link(name);
00112   }
00113 }
00114 
00115 ID3_TagImpl::ID3_TagImpl(const ID3_Tag &tag)
00116   : _frames(),
00117     _cursor(_frames.begin()),
00118     _file_name(),
00119     _file_size(0),
00120     _prepended_bytes(0),
00121     _appended_bytes(0),
00122     _is_file_writable(false)
00123 {
00124   *this = tag;
00125 }
00126 
00127 ID3_TagImpl::~ID3_TagImpl()
00128 {
00129   this->Clear();
00130 }
00131 
00132 void ID3_TagImpl::Clear()
00133 {
00134   for (iterator cur = _frames.begin(); cur != _frames.end(); ++cur)
00135   {
00136     if (*cur)
00137     {
00138       delete *cur;
00139       *cur = NULL;
00140     }
00141   }
00142   _frames.clear();
00143   _cursor = _frames.begin();
00144   _is_padded = true;
00145   
00146   _hdr.Clear();
00147   _hdr.SetSpec(ID3V2_LATEST);
00148   
00149   _tags_to_parse.clear();
00150 
00151   _changed = true;
00152 }
00153 
00154 
00155 void ID3_TagImpl::AddFrame(const ID3_Frame& frame)
00156 {
00157   this->AddFrame(&frame);
00158 }
00159 
00160 void ID3_TagImpl::AddFrame(const ID3_Frame* frame)
00161 {
00162   if (frame)
00163   {
00164     ID3_Frame* frm = new ID3_Frame(*frame);
00165     this->AttachFrame(frm);
00166   }
00167 }
00168 
00169 void ID3_TagImpl::AttachFrame(ID3_Frame *frame)
00170 {
00171   
00172   if (NULL == frame)
00173   {
00174     // log this
00175     return;
00176     //ID3_THROW(ID3E_NoData);
00177   }
00178 
00179   _frames.push_back(frame);
00180   _cursor = _frames.begin();
00181   
00182   _changed = true;
00183 }
00184 
00185 
00186 ID3_Frame* ID3_TagImpl::RemoveFrame(const ID3_Frame *frame)
00187 {
00188   ID3_Frame *frm = NULL;
00189   
00190   iterator fi = Find(frame);
00191   if (fi != _frames.end())
00192   {
00193     frm = *fi;
00194     _frames.erase(fi);
00195     _cursor = _frames.begin();
00196     _changed = true;
00197   }
00198     
00199   return frm;
00200 }
00201 
00202 
00203 bool ID3_TagImpl::HasChanged() const
00204 {
00205   bool changed = _changed;
00206   
00207   if (! changed)
00208   {
00209     for (const_iterator fi = _frames.begin(); fi != _frames.end(); ++fi)
00210     {
00211       if (*fi)
00212       {
00213         changed = (*fi)->HasChanged();
00214       }
00215         
00216       if (changed)
00217       {
00218         break;
00219       }
00220     }
00221   }
00222   
00223   return changed;
00224 }
00225 
00226 bool ID3_TagImpl::SetSpec(ID3_V2Spec spec)
00227 {
00228   bool changed = _hdr.SetSpec(spec);
00229   _changed = _changed || changed;
00230   return changed;
00231 }
00232 
00233 ID3_V2Spec ID3_TagImpl::GetSpec() const
00234 {
00235   return _hdr.GetSpec();
00236 }
00237 
00238 bool ID3_TagImpl::SetUnsync(bool b)
00239 {
00240   bool changed = _hdr.SetUnsync(b);
00241   _changed = changed || _changed;
00242   return changed;
00243 }
00244 
00245 bool ID3_TagImpl::SetExtended(bool ext)
00246 {
00247   bool changed = _hdr.SetExtended(ext);
00248   _changed = changed || _changed;
00249   return changed;
00250 }
00251 
00252 bool ID3_TagImpl::SetExperimental(bool exp)
00253 {
00254   bool changed = _hdr.SetExperimental(exp);
00255   _changed = changed || _changed;
00256   return changed;
00257 }
00258 
00259 bool ID3_TagImpl::GetUnsync() const
00260 {
00261   return _hdr.GetUnsync();
00262 }
00263 
00264 bool ID3_TagImpl::GetExtended() const
00265 {
00266   return _hdr.GetExtended();
00267 }
00268 
00269 bool ID3_TagImpl::GetExperimental() const
00270 {
00271   return _hdr.GetExperimental();
00272 }
00273 
00274 bool ID3_TagImpl::SetPadding(bool pad)
00275 {
00276   bool changed = (_is_padded != pad);
00277   _changed = changed || _changed;
00278   if (changed)
00279   {
00280     _is_padded = pad;
00281   }
00282   
00283   return changed;
00284 }
00285 
00286 
00287 ID3_TagImpl &
00288 ID3_TagImpl::operator=( const ID3_Tag &rTag )
00289 {
00290   this->Clear();
00291 
00292   this->SetUnsync(rTag.GetUnsync());
00293   this->SetExtended(rTag.GetExtendedHeader());
00294   this->SetExperimental(rTag.GetExperimental());
00295 
00296   ID3_Tag::ConstIterator* iter = rTag.CreateIterator();
00297   const ID3_Frame* frame = NULL;
00298   while (NULL != (frame = iter->GetNext()))
00299   {
00300     this->AttachFrame(new ID3_Frame(*frame));
00301   }
00302   delete iter;
00303   return *this;
00304 }
00305 
00306 size_t ID3_GetDataSize(const ID3_TagImpl& tag)
00307 {
00308   return tag.GetFileSize() - tag.GetPrependedBytes() - tag.GetAppendedBytes();
00309 }
00310 

Generated at Sat Sep 8 15:51:10 2001 for id3lib by doxygen1.2.8 written by Dimitri van Heesch, © 1997-2001