id3lib 3.8.3

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

tag_parse_v1.cpp
Go to the documentation of this file.
1 // $Id: tag_parse_v1.cpp,v 1.27 2002/07/31 13:45:18 t1mpy Exp $
2
3 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
4 // Copyright 1999, 2000 Scott Thomas Haug
5 // Copyright 2002 Thijmen Klok (thijmen@id3lib.org)
6
7 // This library is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU Library General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or (at your
10 // option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public License
18 // along with this library; if not, write to the Free Software Foundation,
19 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21 // The id3lib authors encourage improvements and optimisations to be sent to
22 // the id3lib coordinator. Please see the README file for details on where to
23 // send such submissions. See the AUTHORS file for a list of people who have
24 // contributed to id3lib. See the ChangeLog file for a list of changes to
25 // id3lib. These files are distributed with id3lib at
26 // http://download.sourceforge.net/id3lib/
27
28 #include "tag_impl.h" //has <stdio.h> "tag.h" "header_tag.h" "frame.h" "field.h" "spec.h" "id3lib_strings.h" "utils.h"
29 #include "helpers.h"
30 #include "id3/io_decorators.h" //has "readers.h" "io_helpers.h" "utils.h"
31 #include "io_strings.h"
32
33 using namespace dami;
34
35 bool id3::v1::parse(ID3_TagImpl& tag, ID3_Reader& reader)
36 {
37 io::ExitTrigger et(reader);
38
39 ID3_Reader::pos_type end = reader.getCur();
40 // posn ourselves at 128 bytes from the current position
41 if (end < reader.getBeg() + ID3_V1_LEN)
42 {
43 ID3D_NOTICE( "id3::v1::parse: not enough bytes to parse, pos = " << end );
44 return false;
45 }
46 reader.setCur(end - ID3_V1_LEN);
47 ID3_Reader::pos_type beg = reader.getCur();
48 //file.seekg(-static_cast<long>(ID3_V1_LEN), ios::cur);
49 if (end != beg + ID3_V1_LEN)
50 {
51 ID3D_WARNING( "id3::v1::parse: failed to reposition " << ID3_V1_LEN <<
52 " bytes" );
53 return false;
54 }
55
56 // read the next 128 bytes in;
57 String field = io::readText(reader, ID3_V1_LEN_ID);
58
59 // check to see if it was a tag
60 if (field != "TAG")
61 {
62 return false;
63 }
64 et.setExitPos(beg);
65
66 // guess so, let's start checking the v2 tag for frames which are the
67 // equivalent of the v1 fields. When we come across a v1 field that has
68 // no current equivalent v2 frame, we create the frame, copy the data
69 // from the v1 frame and attach it to the tag
70
71 // (Scott Wheeler) The above comment was nice in theory, but it wasn't
72 // first checking (before my hacks) to see if there already was v2 data.
73
74 ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
75 String title = io::readTrailingSpaces(reader, ID3_V1_LEN_TITLE);
76 field = id3::v2::getTitle(tag);
77 if (title.size() > 0 && (field.size() == 0 || field == ""))
78 {
79 id3::v2::setTitle(tag, title);
80 }
81 ID3D_NOTICE( "id3::v1::parse: title = \"" << title << "\"" );
82
83 ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
84 String artist = io::readTrailingSpaces(reader, ID3_V1_LEN_ARTIST);
85 field = id3::v2::getArtist(tag);
86 if (artist.size() > 0 && (field.size() == 0 || field == ""))
87 {
88 id3::v2::setArtist(tag, artist);
89 }
90 ID3D_NOTICE( "id3::v1::parse: artist = \"" << artist << "\"" );
91
92 ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
93 String album = io::readTrailingSpaces(reader, ID3_V1_LEN_ALBUM);
94 field = id3::v2::getAlbum(tag);
95 if (album.size() > 0 && (field.size() == 0 || field == ""))
96 {
97 id3::v2::setAlbum(tag, album);
98 }
99 ID3D_NOTICE( "id3::v1::parse: album = \"" << title << "\"" );
100
101 ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
102 String year = io::readTrailingSpaces(reader, ID3_V1_LEN_YEAR);
103 field = id3::v2::getYear(tag);
104 if (year.size() > 0 && (field.size() == 0 || field == ""))
105 {
106 id3::v2::setYear(tag, year);
107 }
108 ID3D_NOTICE( "id3::v1::parse: year = \"" << year << "\"" );
109
110 ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
111 String comment = io::readTrailingSpaces(reader, ID3_V1_LEN_COMMENT-2);
112 // fixes bug for when tracknumber is 0x20
113 BString trackno = io::readBinary(reader, ID3_V1_LEN_COMMENT-28);
114 if (trackno[0] == '\0')
115 {
116 if (trackno[1] != '\0')
117 { //we've got a tracknumber
118 size_t track = trackno[1];
119 field = id3::v2::getTrack(tag);
120 if (field.size() == 0 || field == "00")
121 {
122 id3::v2::setTrack(tag, track, 0);
123 }
124 ID3D_NOTICE( "id3::v1::parse: track = \"" << track << "\"" );
125 ID3D_NOTICE( "id3::v1::parse: comment length = \"" << comment.length() << "\"" );
126 }
127 }
128 else
129 {
130 // trackno[0] != '\0'
131 const int paddingsize = (ID3_V1_LEN_COMMENT-2) - comment.size();
132 const char * padding = " "; //28 spaces
133
134 if (trackno[1] == '\0' || trackno[1] == 0x20 && trackno[0] != 0x20)
135 {
136 // if there used to be spaces they are gone now, we need to rebuild them
137 comment.append(padding, paddingsize);
138 comment.append((const char *)trackno.data(), 1);
139 }
140 else if (trackno[1] != '\0' && trackno[1] != 0x20 && trackno[0] != 0x20)
141 {
142 // if there used to be spaces they are gone now, we need to rebuild them
143 comment.append(padding, paddingsize);
144 comment.append((const char *)trackno.data(), 2);
145 }
146 }
147 ID3D_NOTICE( "id3::v1::parse: comment = \"" << comment << "\"" );
148 if (comment.size() > 0)
149 {
150 id3::v2::setComment(tag, comment, STR_V1_COMMENT_DESC, "XXX");
151 }
152
153 ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
154 // the GENRE field/frame
155 uchar genre = reader.readChar();
156 field = id3::v2::getGenre(tag);
157 if (genre != 0xFF && (field.size() == 0 || field == ""))
158 {
159 id3::v2::setGenre(tag, genre);
160 }
161 ID3D_NOTICE( "id3::v1::parse: genre = \"" << (int) genre << "\"" );
162
163 ID3D_NOTICE("id3::v1::parse: read bytes: " << reader.getCur() - beg);
164 return true;
165 }
166
167
dami::id3::v2::getArtist
ID3_C_EXPORT String getArtist(const ID3_TagImpl &)
Definition: helpers.cpp:130
ID3_Reader::getBeg
virtual pos_type getBeg()
Return the beginning position in the reader.
Definition: reader.h:48
dami::id3::v2::getTitle
ID3_C_EXPORT String getTitle(const ID3_TagImpl &)
Definition: helpers.cpp:188
dami::String
std::basic_string< char > String
Definition: id3lib_strings.h:198
ID3_TagImpl
Definition: tag_impl.h:73
dami::id3::v2::getYear
ID3_C_EXPORT String getYear(const ID3_TagImpl &)
Definition: helpers.cpp:211
ID3_V1_LEN_COMMENT
Definition: globals.h:337
ID3_V1_LEN_ALBUM
Definition: globals.h:335
ID3_V1_LEN_ID
Definition: globals.h:332
ID3_Reader::getCur
virtual pos_type getCur()=0
Return the current position in the reader.
dami::id3::v2::getAlbum
ID3_C_EXPORT String getAlbum(const ID3_TagImpl &)
Definition: helpers.cpp:165
ID3_V1_LEN_ARTIST
Definition: globals.h:334
ID3_Reader::setCur
virtual pos_type setCur(pos_type pos)=0
Set the value of the current position for reading.
dami::id3::v2::setAlbum
ID3_C_EXPORT ID3_Frame * setAlbum(ID3_TagImpl &, String)
Definition: helpers.cpp:170
uchar
unsigned char uchar
Definition: globals.h:114
dami::id3::v2::setTrack
ID3_C_EXPORT ID3_Frame * setTrack(ID3_TagImpl &, uchar ucTrack, uchar ucTotal)
Definition: helpers.cpp:356
dami::id3::v2::setYear
ID3_C_EXPORT ID3_Frame * setYear(ID3_TagImpl &, String)
Definition: helpers.cpp:216
ID3_V1_LEN
Definition: globals.h:331
dami::id3::v1::parse
bool parse(ID3_TagImpl &, ID3_Reader &)
Definition: tag_parse_v1.cpp:35
dami::BString
std::basic_string< unsigned char > BString
Definition: id3lib_strings.h:199
ID3_V1_LEN_TITLE
Definition: globals.h:333
ID3_Reader::readChar
virtual int_type readChar()
Read a single character and advance the internal position.
Definition: reader.h:65
ID3_Reader
Definition: reader.h:33
tag_impl.h
dami::id3::v2::setGenre
ID3_C_EXPORT ID3_Frame * setGenre(ID3_TagImpl &, size_t ucGenre)
Definition: helpers.cpp:414
dami::id3::v2::getTrack
ID3_C_EXPORT String getTrack(const ID3_TagImpl &)
Definition: helpers.cpp:345
ID3_V1_LEN_YEAR
Definition: globals.h:336
STR_V1_COMMENT_DESC
#define STR_V1_COMMENT_DESC
String used for the description field of a comment tag converted from an id3v1 tag to an id3v2 tag...
Definition: globals.h:111
ID3_Reader::pos_type
uint32 pos_type
Definition: reader.h:38
helpers.h
dami::id3::v2::setArtist
ID3_C_EXPORT ID3_Frame * setArtist(ID3_TagImpl &, String)
Definition: helpers.cpp:136
dami::id3::v2::getGenre
ID3_C_EXPORT String getGenre(const ID3_TagImpl &)
Definition: helpers.cpp:383
dami::id3::v2::setComment
ID3_C_EXPORT ID3_Frame * setComment(ID3_TagImpl &, String, String, String)
Definition: helpers.cpp:258
dami::id3::v2::setTitle
ID3_C_EXPORT ID3_Frame * setTitle(ID3_TagImpl &, String)
Definition: helpers.cpp:193