src/tag_parse_v1.cpp

Go to the documentation of this file.
00001 // $Id: tag_parse_v1.cpp,v 1.27 2002/07/31 13:45:18 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 "tag_impl.h" //has <stdio.h> "tag.h" "header_tag.h" "frame.h" "field.h" "spec.h" "id3lib_strings.h" "utils.h"
00029 #include "helpers.h"
00030 #include "id3/io_decorators.h" //has "readers.h" "io_helpers.h" "utils.h"
00031 #include "io_strings.h"
00032 
00033 using namespace dami;
00034 
00035 bool id3::v1::parse(ID3_TagImpl& tag, ID3_Reader& reader)
00036 {
00037   io::ExitTrigger et(reader);
00038   
00039   ID3_Reader::pos_type end = reader.getCur();
00040   // posn ourselves at 128 bytes from the current position
00041   if (end < reader.getBeg() + ID3_V1_LEN)
00042   {
00043     ID3D_NOTICE( "id3::v1::parse: not enough bytes to parse, pos = " << end );
00044     return false;
00045   }
00046   reader.setCur(end - ID3_V1_LEN);
00047   ID3_Reader::pos_type beg = reader.getCur();
00048   //file.seekg(-static_cast<long>(ID3_V1_LEN), ios::cur);
00049   if (end != beg + ID3_V1_LEN)
00050   {
00051     ID3D_WARNING( "id3::v1::parse: failed to reposition " << ID3_V1_LEN << 
00052                   " bytes" );
00053     return false;
00054   }
00055   
00056   // read the next 128 bytes in;
00057   String field = io::readText(reader, ID3_V1_LEN_ID);
00058   
00059   // check to see if it was a tag
00060   if (field != "TAG")
00061   {
00062     return false;
00063   }
00064   et.setExitPos(beg);
00065   
00066   // guess so, let's start checking the v2 tag for frames which are the
00067   // equivalent of the v1 fields.  When we come across a v1 field that has
00068   // no current equivalent v2 frame, we create the frame, copy the data
00069   // from the v1 frame and attach it to the tag
00070 
00071   // (Scott Wheeler) The above comment was nice in theory, but it wasn't
00072   // first checking (before my hacks) to see if there already was v2 data.
00073 
00074   ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
00075   String title = io::readTrailingSpaces(reader, ID3_V1_LEN_TITLE);
00076   field = id3::v2::getTitle(tag);
00077   if (title.size() > 0 && (field.size() == 0 || field == ""))
00078   {
00079     id3::v2::setTitle(tag, title);
00080   }
00081   ID3D_NOTICE( "id3::v1::parse: title = \"" << title << "\"" );
00082   
00083   ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
00084   String artist = io::readTrailingSpaces(reader, ID3_V1_LEN_ARTIST);
00085   field = id3::v2::getArtist(tag);
00086   if (artist.size() > 0 && (field.size() == 0 || field == ""))
00087   {
00088     id3::v2::setArtist(tag, artist);
00089   }
00090   ID3D_NOTICE( "id3::v1::parse: artist = \"" << artist << "\"" );
00091   
00092   ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
00093   String album = io::readTrailingSpaces(reader, ID3_V1_LEN_ALBUM);
00094   field = id3::v2::getAlbum(tag);
00095   if (album.size() > 0 && (field.size() == 0 || field == ""))
00096   {
00097     id3::v2::setAlbum(tag, album);
00098   }
00099   ID3D_NOTICE( "id3::v1::parse: album = \"" << title << "\"" );
00100   
00101   ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
00102   String year = io::readTrailingSpaces(reader, ID3_V1_LEN_YEAR);
00103   field = id3::v2::getYear(tag);
00104   if (year.size() > 0 && (field.size() == 0 || field == ""))
00105   {
00106     id3::v2::setYear(tag, year);
00107   }
00108   ID3D_NOTICE( "id3::v1::parse: year = \"" << year << "\"" );
00109   
00110   ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
00111   String comment = io::readTrailingSpaces(reader, ID3_V1_LEN_COMMENT-2);
00112   // fixes bug for when tracknumber is 0x20
00113   BString trackno = io::readBinary(reader, ID3_V1_LEN_COMMENT-28);
00114   if (trackno[0] == '\0')
00115   {
00116     if (trackno[1] != '\0')
00117     { //we've got a tracknumber
00118       size_t track = trackno[1];
00119       field = id3::v2::getTrack(tag);
00120       if (field.size() == 0 || field == "00")
00121       {
00122         id3::v2::setTrack(tag, track, 0);
00123       }
00124       ID3D_NOTICE( "id3::v1::parse: track = \"" << track << "\"" );
00125       ID3D_NOTICE( "id3::v1::parse: comment length = \"" << comment.length() << "\"" );
00126     }
00127   }
00128   else
00129   {
00130     // trackno[0] != '\0'
00131     const int paddingsize = (ID3_V1_LEN_COMMENT-2) - comment.size();
00132     const char * padding = "                            "; //28 spaces
00133 
00134     if (trackno[1] == '\0' || trackno[1] == 0x20 && trackno[0] != 0x20)
00135     {
00136       // if there used to be spaces they are gone now, we need to rebuild them
00137       comment.append(padding, paddingsize);
00138       comment.append((const char *)trackno.data(), 1);
00139     }
00140     else if (trackno[1] != '\0' && trackno[1] != 0x20 &&  trackno[0] != 0x20)
00141     {
00142       // if there used to be spaces they are gone now, we need to rebuild them
00143       comment.append(padding, paddingsize);
00144       comment.append((const char *)trackno.data(), 2);
00145     }
00146   }
00147   ID3D_NOTICE( "id3::v1::parse: comment = \"" << comment << "\"" );
00148   if (comment.size() > 0)
00149   {
00150     id3::v2::setComment(tag, comment, STR_V1_COMMENT_DESC, "XXX");
00151   }
00152   
00153   ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
00154   // the GENRE field/frame
00155   uchar genre = reader.readChar();
00156   field = id3::v2::getGenre(tag);
00157   if (genre != 0xFF && (field.size() == 0 || field == ""))
00158   {
00159     id3::v2::setGenre(tag, genre);
00160   }
00161   ID3D_NOTICE( "id3::v1::parse: genre = \"" << (int) genre << "\"" );
00162 
00163   ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
00164   return true;
00165 }
00166 
00167 

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