<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>src/tag_parse_musicmatch.cpp Source File</title> <link href="id3lib.css" rel="stylesheet" type="text/css"> </head><body bgcolor="#ffffff"> <!-- Generated by Doxygen 1.2.12 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="namespaces.html">Namespace List</a> <a class="qindex" href="hierarchy.html">Class Hierarchy</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="namespacemembers.html">Namespace Members</a> <a class="qindex" href="functions.html">Compound Members</a> <a class="qindex" href="globals.html">File Members</a> </center> <hr><h1>src/tag_parse_musicmatch.cpp</h1><a href="tag__parse__musicmatch_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 <font class="comment">// $Id: tag_parse_musicmatch.cpp,v 1.17 2001/08/26 23:33:29 dmazzoni Exp $</font> 00002 00003 <font class="comment">// id3lib: a C++ library for creating and manipulating id3v1/v2 tags</font> 00004 <font class="comment">// Copyright 1999, 2000 Scott Thomas Haug</font> 00005 00006 <font class="comment">// This library is free software; you can redistribute it and/or modify it</font> 00007 <font class="comment">// under the terms of the GNU Library General Public License as published by</font> 00008 <font class="comment">// the Free Software Foundation; either version 2 of the License, or (at your</font> 00009 <font class="comment">// option) any later version.</font> 00010 <font class="comment">//</font> 00011 <font class="comment">// This library is distributed in the hope that it will be useful, but WITHOUT</font> 00012 <font class="comment">// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or</font> 00013 <font class="comment">// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public</font> 00014 <font class="comment">// License for more details.</font> 00015 <font class="comment">//</font> 00016 <font class="comment">// You should have received a copy of the GNU Library General Public License</font> 00017 <font class="comment">// along with this library; if not, write to the Free Software Foundation,</font> 00018 <font class="comment">// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.</font> 00019 00020 <font class="comment">// The id3lib authors encourage improvements and optimisations to be sent to</font> 00021 <font class="comment">// the id3lib coordinator. Please see the README file for details on where to</font> 00022 <font class="comment">// send such submissions. See the AUTHORS file for a list of people who have</font> 00023 <font class="comment">// contributed to id3lib. See the ChangeLog file for a list of changes to</font> 00024 <font class="comment">// id3lib. These files are distributed with id3lib at</font> 00025 <font class="comment">// http://download.sourceforge.net/id3lib/</font> 00026 00027 <font class="preprocessor">#if defined HAVE_CONFIG_H</font> 00028 <font class="preprocessor"></font><font class="preprocessor">#include <config.h></font> 00029 <font class="preprocessor">#endif</font> 00030 <font class="preprocessor"></font> 00031 00032 <font class="preprocessor">#include <ctype.h></font> 00033 <font class="preprocessor">#include <stdlib.h></font> 00034 <font class="preprocessor">#include "<a class="code" href="tag__impl_8h.html">tag_impl.h</a>"</font> 00035 <font class="preprocessor">#include "utils.h"</font> 00036 <font class="preprocessor">#include "helpers.h"</font> 00037 <font class="preprocessor">#include "io_decorators.h"</font> 00038 <font class="preprocessor">#include "io_helpers.h"</font> 00039 00040 <font class="keyword">using</font> <font class="keyword">namespace </font>dami; 00041 00042 <font class="keyword">namespace </font> 00043 <font class="keyword"></font>{ 00044 <a class="code" href="sized__types_8h.html#a4">uint32</a> readSeconds(<a class="code" href="class_i_d3___reader.html">ID3_Reader</a>& reader, size_t len) 00045 { 00046 io::ExitTrigger et(reader); 00047 io::WindowedReader wr(reader, len); 00048 <a class="code" href="class_i_d3___reader.html#s2">ID3_Reader::pos_type</a> beg = wr.getCur(); 00049 <a class="code" href="sized__types_8h.html#a4">uint32</a> seconds = 0; 00050 <a class="code" href="sized__types_8h.html#a4">uint32</a> cur = 0; 00051 <font class="keywordflow">while</font> (!wr.atEnd()) 00052 { 00053 <a class="code" href="class_i_d3___reader.html#s1">ID3_Reader::char_type</a> ch = wr.readChar(); 00054 <font class="keywordflow">if</font> (<font class="charliteral">':'</font> == ch) 00055 { 00056 seconds += 60 * cur; 00057 cur = 0; 00058 } 00059 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!isdigit(ch)) 00060 { 00061 <font class="keywordflow">return</font> 0; 00062 } 00063 <font class="keywordflow">else</font> 00064 { 00065 cur = cur * 10 + (ch - <font class="charliteral">'0'</font>); 00066 } 00067 } 00068 et.release(); 00069 <font class="keywordflow">return</font> seconds + cur; 00070 } 00071 00072 <a class="code" href="class_i_d3___frame.html">ID3_Frame</a>* readTextFrame(<a class="code" href="class_i_d3___reader.html">ID3_Reader</a>& reader, <a class="code" href="globals_8h.html#a219">ID3_FrameID</a> id, <font class="keyword">const</font> String desc = <font class="stringliteral">""</font>) 00073 { 00074 <a class="code" href="sized__types_8h.html#a4">uint32</a> size = io::readLENumber(reader, 2); 00075 ID3D_NOTICE( <font class="stringliteral">"readTextFrame: size = "</font> << size ); 00076 <font class="keywordflow">if</font> (size == 0) 00077 { 00078 <font class="keywordflow">return</font> <a class="code" href="globals_8h.html#a24">NULL</a>; 00079 } 00080 00081 String text; 00082 <font class="keywordflow">if</font> (<a class="code" href="globals_8h.html#a219a135">ID3FID_SONGLEN</a> != id) 00083 { 00084 io::LineFeedReader lfr(reader); 00085 text = io::readText(lfr, size); 00086 ID3D_NOTICE( <font class="stringliteral">"readTextFrame: text = "</font> << text ); 00087 } 00088 <font class="keywordflow">else</font> 00089 { 00090 text = toString(readSeconds(reader, size) * 1000); 00091 ID3D_NOTICE( <font class="stringliteral">"readTextFrame: songlen = "</font> << text ); 00092 } 00093 00094 <a class="code" href="class_i_d3___frame.html">ID3_Frame</a>* frame = <font class="keyword">new</font> <a class="code" href="class_i_d3___frame.html">ID3_Frame</a>(id); 00095 <font class="keywordflow">if</font> (frame) 00096 { 00097 <font class="keywordflow">if</font> (frame-><a class="code" href="class_i_d3___frame.html#a15">Contains</a>(<a class="code" href="globals_8h.html#a218a72">ID3FN_TEXT</a>)) 00098 { 00099 frame-><a class="code" href="class_i_d3___frame.html#a6">GetField</a>(ID3FN_TEXT)-><a class="code" href="class_i_d3___field.html#a5">Set</a>(text.c_str()); 00100 } 00101 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (frame-><a class="code" href="class_i_d3___frame.html#a15">Contains</a>(<a class="code" href="globals_8h.html#a218a73">ID3FN_URL</a>)) 00102 { 00103 frame-><a class="code" href="class_i_d3___frame.html#a6">GetField</a>(ID3FN_URL)-><a class="code" href="class_i_d3___field.html#a5">Set</a>(text.c_str()); 00104 } 00105 <font class="keywordflow">if</font> (frame->Contains(<a class="code" href="globals_8h.html#a218a80">ID3FN_LANGUAGE</a>)) 00106 { 00107 frame->GetField(ID3FN_LANGUAGE)->Set(<font class="stringliteral">"XXX"</font>); 00108 } 00109 <font class="keywordflow">if</font> (frame->Contains(<a class="code" href="globals_8h.html#a218a75">ID3FN_DESCRIPTION</a>)) 00110 { 00111 frame->GetField(ID3FN_DESCRIPTION)->Set(desc.c_str()); 00112 } 00113 } 00114 <font class="keywordflow">return</font> frame; 00115 } 00116 }; 00117 00118 <font class="keywordtype">bool</font> mm::parse(<a class="code" href="class_i_d3___tag_impl.html">ID3_TagImpl</a>& tag, <a class="code" href="class_i_d3___reader.html">ID3_Reader</a>& rdr) 00119 { 00120 io::ExitTrigger et(rdr); 00121 <a class="code" href="class_i_d3___reader.html#s2">ID3_Reader::pos_type</a> <a class="code" href="class_i_d3___tag_impl.html#a35">end</a> = rdr.<a class="code" href="class_i_d3___reader.html#a3">getCur</a>(); 00122 <font class="keywordflow">if</font> (<a class="code" href="class_i_d3___tag_impl.html#a35">end</a> < rdr.<a class="code" href="class_i_d3___reader.html#a1">getBeg</a>() + 48) 00123 { 00124 ID3D_NOTICE( <font class="stringliteral">"mm::parse: bailing, not enough bytes to parse, pos = "</font> << <a class="code" href="class_i_d3___tag_impl.html#a35">end</a> ); 00125 <font class="keywordflow">return</font> <font class="keyword">false</font>; 00126 } 00127 00128 rdr.<a class="code" href="class_i_d3___reader.html#a4">setCur</a>(<a class="code" href="class_i_d3___tag_impl.html#a35">end</a> - 48); 00129 String version; 00130 00131 { 00132 <font class="keywordflow">if</font> (io::readText(rdr, 32) != <font class="stringliteral">"Brava Software Inc. "</font>) 00133 { 00134 ID3D_NOTICE( <font class="stringliteral">"mm::parse: bailing, couldn't find footer"</font> ); 00135 <font class="keywordflow">return</font> <font class="keyword">false</font>; 00136 } 00137 00138 version = io::readText(rdr, 4); 00139 <font class="keywordflow">if</font> (version.size() != 4 || 00140 !isdigit(version[0]) || version[1] != <font class="charliteral">'.'</font> || 00141 !isdigit(version[2]) || 00142 !isdigit(version[3])) 00143 { 00144 ID3D_WARNING( <font class="stringliteral">"mm::parse: bailing, nonstandard version = "</font> << version ); 00145 <font class="keywordflow">return</font> <font class="keyword">false</font>; 00146 } 00147 } 00148 00149 <a class="code" href="class_i_d3___reader.html#s2">ID3_Reader::pos_type</a> beg = rdr.<a class="code" href="class_i_d3___reader.html#a4">setCur</a>(<a class="code" href="class_i_d3___tag_impl.html#a35">end</a> - 48); 00150 et.setExitPos(beg); 00151 <font class="keywordflow">if</font> (<a class="code" href="class_i_d3___tag_impl.html#a35">end</a> < 68) 00152 { 00153 ID3D_NOTICE( <font class="stringliteral">"mm::parse: bailing, not enough bytes to parse offsets, pos = "</font> << <a class="code" href="class_i_d3___tag_impl.html#a35">end</a> ); 00154 <font class="keywordflow">return</font> <font class="keyword">false</font>; 00155 } 00156 rdr.<a class="code" href="class_i_d3___reader.html#a4">setCur</a>(<a class="code" href="class_i_d3___tag_impl.html#a35">end</a> - 68); 00157 00158 io::WindowedReader dataWindow(rdr); 00159 dataWindow.setEnd(rdr.<a class="code" href="class_i_d3___reader.html#a3">getCur</a>()); 00160 00161 <a class="code" href="sized__types_8h.html#a4">uint32</a> offsets[5]; 00162 00163 io::WindowedReader offsetWindow(rdr, 20); 00164 <font class="keywordflow">for</font> (size_t i = 0; i < 5; ++i) 00165 { 00166 offsets[i] = io::readLENumber(rdr, <font class="keyword">sizeof</font>(<a class="code" href="sized__types_8h.html#a4">uint32</a>)); 00167 } 00168 00169 size_t metadataSize = 0; 00170 <font class="keywordflow">if</font> (version <= <font class="stringliteral">"3.00"</font>) 00171 { 00172 <font class="comment">// All MusicMatch tags up to and including version 3.0 had metadata </font> 00173 <font class="comment">// sections exactly 7868 bytes in length.</font> 00174 metadataSize = 7868; 00175 } 00176 <font class="keywordflow">else</font> 00177 { 00178 <font class="comment">// MusicMatch tags after version 3.0 had three possible lengths for their</font> 00179 <font class="comment">// metadata sections. We can determine which it was by searching for</font> 00180 <font class="comment">// the version section signature that should precede the metadata section</font> 00181 <font class="comment">// by exactly 256 bytes.</font> 00182 size_t possibleSizes[] = { 8132, 8004, 7936 }; 00183 00184 <font class="keywordflow">for</font> (size_t i = 0; i < <font class="keyword">sizeof</font>(possibleSizes)/<font class="keyword">sizeof</font>(size_t); ++i) 00185 { 00186 dataWindow.setCur(dataWindow.getEnd()); 00187 00188 <font class="comment">// Our offset will be exactly 256 bytes prior to our potential metadata</font> 00189 <font class="comment">// section</font> 00190 size_t offset = possibleSizes[i] + 256; 00191 <font class="keywordflow">if</font> (dataWindow.getCur() < offset) 00192 { 00193 <font class="comment">// if our filesize is less than the offset, then it can't possibly</font> 00194 <font class="comment">// be the correct offset, so try again.</font> 00195 <font class="keywordflow">continue</font>; 00196 } 00197 dataWindow.setCur(dataWindow.getCur() - offset); 00198 00199 <font class="comment">// now read in the signature to see if it's a match</font> 00200 <font class="keywordflow">if</font> (io::readText(dataWindow, 8) == <font class="stringliteral">"18273645"</font>) 00201 { 00202 metadataSize = possibleSizes[i]; 00203 <font class="keywordflow">break</font>; 00204 } 00205 } 00206 } 00207 <font class="keywordflow">if</font> (0 == metadataSize) 00208 { 00209 <font class="comment">// if we didn't establish a size for the metadata, then something is</font> 00210 <font class="comment">// wrong. probably should log this.</font> 00211 ID3D_WARNING( <font class="stringliteral">"mm::parse: bailing, couldn't find meta data signature, end = "</font> << <a class="code" href="class_i_d3___tag_impl.html#a35">end</a> ); 00212 <font class="keywordflow">return</font> <font class="keyword">false</font>; 00213 } 00214 00215 <font class="comment">// parse the offset pointers to determine the actual sizes of all the </font> 00216 <font class="comment">// sections</font> 00217 size_t sectionSizes[5]; 00218 size_t tagSize = metadataSize; 00219 00220 <font class="comment">// we already know the size of the last section</font> 00221 sectionSizes[4] = metadataSize; 00222 00223 size_t lastOffset = 0; 00224 <font class="keywordflow">for</font> (<font class="keywordtype">int</font> i = 0; i < 5; i++) 00225 { 00226 size_t thisOffset = offsets[i]; 00227 <font class="comment">//ASSERT(thisOffset > lastOffset);</font> 00228 <font class="keywordflow">if</font> (i > 0) 00229 { 00230 size_t sectionSize = thisOffset - lastOffset; 00231 sectionSizes[i-1] = sectionSize; 00232 tagSize += sectionSize; 00233 } 00234 lastOffset = thisOffset; 00235 } 00236 00237 <font class="comment">// now check to see that our tag size is reasonable</font> 00238 <font class="keywordflow">if</font> (dataWindow.getEnd() < tagSize) 00239 { 00240 <font class="comment">// Ack! The tag size doesn't jive with the tag's ending position in</font> 00241 <font class="comment">// the file. Bail!</font> 00242 ID3D_WARNING( <font class="stringliteral">"mm::parse: bailing, tag size is too big, tag size = "</font> << tagSize << <font class="stringliteral">", end = "</font> << <a class="code" href="class_i_d3___tag_impl.html#a35">end</a> ); 00243 <font class="keywordflow">return</font> <font class="keyword">false</font>; 00244 } 00245 00246 dataWindow.setBeg(dataWindow.getEnd() - tagSize); 00247 dataWindow.setCur(dataWindow.getBeg()); 00248 00249 <font class="comment">// Now calculate the adjusted offsets</font> 00250 offsets[0] = dataWindow.getBeg(); 00251 <font class="keywordflow">for</font> (size_t i = 0; i < 4; ++i) 00252 { 00253 offsets[i+1] = offsets[i] + sectionSizes[i]; 00254 } 00255 00256 <font class="comment">// now check for a tag header and adjust the tag_beg pointer appropriately</font> 00257 <font class="keywordflow">if</font> (dataWindow.getBeg() >= 256) 00258 { 00259 rdr.<a class="code" href="class_i_d3___reader.html#a4">setCur</a>(dataWindow.getBeg() - 256); 00260 <font class="keywordflow">if</font> (io::readText(rdr, 8) == <font class="stringliteral">"18273645"</font>) 00261 { 00262 et.setExitPos(rdr.<a class="code" href="class_i_d3___reader.html#a3">getCur</a>() - 8); 00263 } 00264 <font class="keywordflow">else</font> 00265 { 00266 et.setExitPos(dataWindow.getBeg()); 00267 } 00268 dataWindow.setCur(dataWindow.getBeg()); 00269 } 00270 00271 <font class="comment">// Now parse the various sections...</font> 00272 00273 <font class="comment">// Parse the image extension at offset 0</font> 00274 dataWindow.setCur(offsets[0]); 00275 String imgExt = io::readTrailingSpaces(dataWindow, 4); 00276 00277 <font class="comment">// Parse the image binary at offset 1</font> 00278 dataWindow.setCur(offsets[1]); 00279 <a class="code" href="sized__types_8h.html#a4">uint32</a> imgSize = io::readLENumber(dataWindow, 4); 00280 <font class="keywordflow">if</font> (imgSize == 0) 00281 { 00282 <font class="comment">// no image binary. don't do anything.</font> 00283 } 00284 <font class="keywordflow">else</font> 00285 { 00286 io::WindowedReader imgWindow(dataWindow, imgSize); 00287 <font class="keywordflow">if</font> (imgWindow.getEnd() < imgWindow.getBeg() + imgSize) 00288 { 00289 <font class="comment">// Ack! The image size given extends beyond the next offset! This is </font> 00290 <font class="comment">// not good... log?</font> 00291 } 00292 <font class="keywordflow">else</font> 00293 { 00294 BString imgData = io::readAllBinary(imgWindow); 00295 <a class="code" href="class_i_d3___frame.html">ID3_Frame</a>* frame = <font class="keyword">new</font> <a class="code" href="class_i_d3___frame.html">ID3_Frame</a>(<a class="code" href="globals_8h.html#a219a97">ID3FID_PICTURE</a>); 00296 <font class="keywordflow">if</font> (frame) 00297 { 00298 String mimetype(<font class="stringliteral">"image/"</font>); 00299 mimetype += imgExt; 00300 frame-><a class="code" href="class_i_d3___frame.html#a6">GetField</a>(ID3FN_MIMETYPE)-><a class="code" href="class_i_d3___field.html#a5">Set</a>(mimetype.c_str()); 00301 frame-><a class="code" href="class_i_d3___frame.html#a6">GetField</a>(ID3FN_IMAGEFORMAT)-><a class="code" href="class_i_d3___field.html#a5">Set</a>(<font class="stringliteral">""</font>); 00302 frame->GetField(ID3FN_PICTURETYPE)->Set(static_cast<unsigned int>(0)); 00303 frame->GetField(ID3FN_DESCRIPTION)->Set(<font class="stringliteral">""</font>); 00304 frame->GetField(ID3FN_DATA)->Set(reinterpret_cast<const uchar*>(imgData.data()), imgData.size()); 00305 tag.AttachFrame(frame); 00306 } 00307 } 00308 } 00309 00310 <font class="comment">//file.seekg(offsets[2]);</font> 00311 <font class="comment">//file.seekg(offsets[3]);</font> 00312 dataWindow.setCur(offsets[4]); 00313 00314 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a131">ID3FID_TITLE</a>)); 00315 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a119">ID3FID_ALBUM</a>)); 00316 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a143">ID3FID_LEADARTIST</a>)); 00317 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a122">ID3FID_CONTENTTYPE</a>)); 00318 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a98">ID3FID_COMMENT</a>, <font class="stringliteral">"MusicMatch_Tempo"</font>)); 00319 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a98">ID3FID_COMMENT</a>, <font class="stringliteral">"MusicMatch_Mood"</font>)); 00320 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a98">ID3FID_COMMENT</a>, <font class="stringliteral">"MusicMatch_Situation"</font>)); 00321 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a98">ID3FID_COMMENT</a>, <font class="stringliteral">"MusicMatch_Preference"</font>)); 00322 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a135">ID3FID_SONGLEN</a>)); 00323 00324 <font class="comment">// The next 12 bytes can be ignored. The first 8 represent the </font> 00325 <font class="comment">// creation date as a 64 bit floating point number. The last 4 are</font> 00326 <font class="comment">// for a play counter.</font> 00327 dataWindow.skipChars(12); 00328 00329 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a98">ID3FID_COMMENT</a>, <font class="stringliteral">"MusicMatch_Path"</font>)); 00330 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a98">ID3FID_COMMENT</a>, <font class="stringliteral">"MusicMatch_Serial"</font>)); 00331 00332 <font class="comment">// 2 bytes for track</font> 00333 <a class="code" href="sized__types_8h.html#a4">uint32</a> trkNum = io::readLENumber(dataWindow, 2); 00334 <font class="keywordflow">if</font> (trkNum > 0) 00335 { 00336 String trkStr = toString(trkNum); 00337 <a class="code" href="class_i_d3___frame.html">ID3_Frame</a>* frame = <font class="keyword">new</font> <a class="code" href="class_i_d3___frame.html">ID3_Frame</a>(<a class="code" href="globals_8h.html#a219a149">ID3FID_TRACKNUM</a>); 00338 <font class="keywordflow">if</font> (frame) 00339 { 00340 frame-><a class="code" href="class_i_d3___frame.html#a6">GetField</a>(ID3FN_TEXT)-><a class="code" href="class_i_d3___field.html#a5">Set</a>(trkStr.c_str()); 00341 tag.AttachFrame(frame); 00342 } 00343 } 00344 00345 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a98">ID3FID_COMMENT</a>, <font class="stringliteral">"MusicMatch_Notes"</font>)); 00346 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a98">ID3FID_COMMENT</a>, <font class="stringliteral">"MusicMatch_Bio"</font>)); 00347 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a160">ID3FID_UNSYNCEDLYRICS</a>)); 00348 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a164">ID3FID_WWWARTIST</a>)); 00349 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a161">ID3FID_WWWCOMMERCIALINFO</a>)); 00350 tag.AttachFrame(readTextFrame(dataWindow, <a class="code" href="globals_8h.html#a219a98">ID3FID_COMMENT</a>, <font class="stringliteral">"MusicMatch_ArtistEmail"</font>)); 00351 00352 <font class="comment">// email?</font> 00353 00354 <font class="keywordflow">return</font> <font class="keyword">true</font>; 00355 } </pre></div><hr><address><small>Generated on Thu Jan 3 07:35:56 2002 for id3lib by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.gif" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.12 written by <a href="mailto:dimitri@stack.nl">Dimitri van Heesch</a>, © 1997-2001</small></address> </body> </html>