id3lib 3.8.3
|
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