EMMA Coverage Report (generated Tue Mar 14 21:50:42 EST 2006)
[all classes][org.farng.mp3.lyrics3]

COVERAGE SUMMARY FOR SOURCE FILE [Lyrics3v1.java]

nameclass, %method, %block, %line, %
Lyrics3v1.java100% (1/1)72%  (26/36)42%  (232/551)43%  (52.8/123)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Lyrics3v1100% (1/1)72%  (26/36)42%  (232/551)43%  (52.8/123)
Lyrics3v1 (RandomAccessFile): void 0%   (0/1)0%   (0/9)0%   (0/4)
append (AbstractMP3Tag): void 0%   (0/1)0%   (0/30)0%   (0/7)
getIdentifier (): String 0%   (0/1)0%   (0/2)0%   (0/1)
getSize (): int 0%   (0/1)0%   (0/10)0%   (0/1)
isSubsetOf (Object): boolean 0%   (0/1)0%   (0/16)0%   (0/3)
iterator (): Iterator 0%   (0/1)0%   (0/5)0%   (0/1)
overwrite (AbstractMP3Tag): void 0%   (0/1)0%   (0/26)0%   (0/7)
toString (): String 0%   (0/1)0%   (0/25)0%   (0/2)
write (AbstractMP3Tag): void 0%   (0/1)0%   (0/18)0%   (0/6)
write (RandomAccessFile): void 0%   (0/1)0%   (0/104)0%   (0/20)
read (RandomAccessFile): void 100% (1/1)40%  (12/30)43%  (3/7)
seek (RandomAccessFile): boolean 100% (1/1)55%  (53/96)48%  (10/21)
Lyrics3v1 (AbstractMP3Tag): void 100% (1/1)79%  (33/42)82%  (9/11)
equals (Object): boolean 100% (1/1)80%  (16/20)67%  (4/6)
Lyrics3v1 (): void 100% (1/1)100% (6/6)100% (3/3)
Lyrics3v1 (Lyrics3v1): void 100% (1/1)100% (14/14)100% (4/4)
getAlbumTitle (): String 100% (1/1)100% (5/5)100% (1/1)
getAuthorComposer (): String 100% (1/1)100% (5/5)100% (1/1)
getLeadArtist (): String 100% (1/1)100% (5/5)100% (1/1)
getLyric (): String 100% (1/1)100% (3/3)100% (1/1)
getSongComment (): String 100% (1/1)100% (5/5)100% (1/1)
getSongGenre (): String 100% (1/1)100% (5/5)100% (1/1)
getSongLyric (): String 100% (1/1)100% (4/4)100% (1/1)
getSongTitle (): String 100% (1/1)100% (5/5)100% (1/1)
getTrackNumberOnAlbum (): String 100% (1/1)100% (5/5)100% (1/1)
getYearReleased (): String 100% (1/1)100% (5/5)100% (1/1)
setAlbumTitle (String): void 100% (1/1)100% (5/5)100% (1/1)
setAuthorComposer (String): void 100% (1/1)100% (5/5)100% (1/1)
setLeadArtist (String): void 100% (1/1)100% (5/5)100% (1/1)
setLyric (String): void 100% (1/1)100% (6/6)100% (2/2)
setSongComment (String): void 100% (1/1)100% (5/5)100% (1/1)
setSongGenre (String): void 100% (1/1)100% (5/5)100% (1/1)
setSongLyric (String): void 100% (1/1)100% (5/5)100% (2/2)
setSongTitle (String): void 100% (1/1)100% (5/5)100% (1/1)
setTrackNumberOnAlbum (String): void 100% (1/1)100% (5/5)100% (1/1)
setYearReleased (String): void 100% (1/1)100% (5/5)100% (1/1)

1package org.farng.mp3.lyrics3;
2 
3import org.farng.mp3.AbstractMP3Tag;
4import org.farng.mp3.TagNotFoundException;
5import org.farng.mp3.TagOptionSingleton;
6import org.farng.mp3.TagUtility;
7import org.farng.mp3.id3.ID3v1;
8 
9import java.io.IOException;
10import java.io.RandomAccessFile;
11import java.util.Iterator;
12 
13/**
14 * <TABLE border=0> <TBODY> <TR> <TD class=h1>&nbsp;Lyrics3 made easy&nbsp;</TD></TR> </TBODY></TABLE> <BR>&nbsp; <TABLE
15 * border=0> <TBODY> <TR> <TD class=h2>What is Lyrics3?</TD></TR></TBODY></TABLE> <TABLE border=0> <TBODY> <TR
16 * vAlign=top> <TD> <P>When Winamp introduced its plugin capabilities Kuo (Djohan) Shiang-shiang's Lyrics Displayer was
17 * one of the first plugins, and probably the first program that made a connection between MP3 audio and lyrics. The
18 * lyrics displayed by Kuo's Lyrics Displayer were stored in separate text files from which the program got it.</P>
19 * <p/>
20 * <P>Petr Strnad saw the problems in this so he decided to make a lyrics tag, enabling the text to reside inside the
21 * audio file. This is done by creating a chunk of data which begins with "LYRICSBEGIN", ends with "LYRICSEND" and has
22 * the lyrics between these keywords. This data block is then saved in the audio file between the audio and the ID3 tag.
23 * If no ID3 tag is present one must be attached.</P>
24 * <p/>
25 * <P>The following simple rules applies to the lyrics inserted between the keywords:</P>
26 * <p/>
27 * <p/>
28 * <UL> <LI>The keywords "LYRICSBEGIN" and "LYRICSEND" must not be present in the lyrics. <LI>The text is encoded with
29 * ISO-8859-1 character set <LI>A byte in the text must not have the binary value 255. <LI>The maximum length of the
30 * lyrics is 5100 bytes. <LI>Newlines are made with CR+LF sequence.</LI></UL>
31 * <p/>
32 * <P></P></TD> </TR></TBODY></TABLE>
33 *
34 * @author Eric Farng
35 * @version $Revision: 1.5 $
36 */
37public class Lyrics3v1 extends AbstractLyrics3 {
38 
39    private String lyric = "";
40 
41    /**
42     * Creates a new Lyrics3v1 object.
43     */
44    public Lyrics3v1() {
45        super();
46    }
47 
48    /**
49     * Creates a new Lyrics3v1 object.
50     */
51    public Lyrics3v1(final Lyrics3v1 copyObject) {
52        super(copyObject);
53        this.lyric = new String(copyObject.lyric);
54    }
55 
56    /**
57     * Creates a new Lyrics3v1 object.
58     */
59    public Lyrics3v1(final AbstractMP3Tag mp3Tag) {
60        if (mp3Tag != null) {
61            final Lyrics3v2 lyricTag;
62            if (mp3Tag instanceof Lyrics3v1) {
63                throw new UnsupportedOperationException("Copy Constructor not called. Please type cast the argument");
64            } else if (mp3Tag instanceof Lyrics3v2) {
65                lyricTag = (Lyrics3v2) mp3Tag;
66            } else {
67                lyricTag = new Lyrics3v2(mp3Tag);
68            }
69            final FieldBodyLYR lyricField;
70            lyricField = (FieldBodyLYR) lyricTag.getField("LYR").getBody();
71            this.lyric = new String(lyricField.getLyric().trim());
72        }
73    }
74 
75    /**
76     * Creates a new Lyrics3v1 object.
77     */
78    public Lyrics3v1(final RandomAccessFile file) throws TagNotFoundException, java.io.IOException {
79        this.read(file);
80    }
81 
82    public String getIdentifier() {
83        return "Lyrics3v1.00";
84    }
85 
86    public void setLyric(final String lyric) {
87        this.lyric = TagUtility.truncate(lyric, 5100);
88    }
89 
90    public String getLyric() {
91        return this.lyric;
92    }
93 
94    public int getSize() {
95        return "LYRICSBEGIN".length() + this.lyric.length() + "LYRICSEND".length();
96    }
97 
98    public boolean isSubsetOf(final Object object) {
99        if ((object instanceof Lyrics3v1) == false) {
100            return false;
101        }
102        return (((Lyrics3v1) object).lyric.indexOf(this.lyric) >= 0);
103    }
104 
105    public void append(final AbstractMP3Tag tag) {
106        final Lyrics3v1 oldTag = this;
107        final Lyrics3v1 newTag;
108        if (tag != null) {
109            if (tag instanceof Lyrics3v1) {
110                newTag = (Lyrics3v1) tag;
111            } else {
112                newTag = new Lyrics3v1();
113            }
114            this.lyric = oldTag.lyric + "\n" + newTag.lyric;
115        }
116    }
117 
118    public boolean equals(final Object obj) {
119        if ((obj instanceof Lyrics3v1) == false) {
120            return false;
121        }
122        final Lyrics3v1 lyrics3v1 = (Lyrics3v1) obj;
123        if (this.lyric.equals(lyrics3v1.lyric) == false) {
124            return false;
125        }
126        return super.equals(obj);
127    }
128 
129    public Iterator iterator() {
130        // todo Implement this org.farng.mp3.AbstractMP3Tag abstract method
131        throw new java.lang.UnsupportedOperationException("Method iterator() not yet implemented.");
132    }
133 
134    public void overwrite(final AbstractMP3Tag tag) {
135        final Lyrics3v1 oldTag = this;
136        final Lyrics3v1 newTag;
137        if (tag != null) {
138            if (tag instanceof Lyrics3v1) {
139                newTag = (Lyrics3v1) tag;
140            } else {
141                newTag = new Lyrics3v1();
142            }
143            this.lyric = TagOptionSingleton.getInstance().isLyrics3Save() ? newTag.lyric : oldTag.lyric;
144        }
145    }
146 
147    public void read(final RandomAccessFile file) throws TagNotFoundException, IOException {
148        final byte[] buffer = new byte[5100 + 9 + 11];
149        final String lyricBuffer;
150        if (seek(file) == false) {
151            throw new TagNotFoundException("ID3v1 tag not found");
152        }
153        file.read(buffer);
154        lyricBuffer = new String(buffer);
155        this.lyric = lyricBuffer.substring(0, lyricBuffer.indexOf("LYRICSEND"));
156    }
157 
158    public boolean seek(final RandomAccessFile file) throws IOException {
159        final byte[] buffer = new byte[5100 + 9 + 11];
160        String lyricsEnd;
161        final String lyricsStart;
162        long offset;
163 
164        // check right before the ID3 1.0 tag for the lyrics tag
165        file.seek(file.length() - 128 - 9);
166        file.read(buffer, 0, 9);
167        lyricsEnd = new String(buffer, 0, 9);
168        if (lyricsEnd.equals("LYRICSEND")) {
169            offset = file.getFilePointer();
170        } else {
171            // check the end of the file for a lyrics tag incase an ID3
172            // tag wasn't placed after it.
173            file.seek(file.length() - 9);
174            file.read(buffer, 0, 9);
175            lyricsEnd = new String(buffer, 0, 9);
176            if (lyricsEnd.equals("LYRICSEND")) {
177                offset = file.getFilePointer();
178            } else {
179                return false;
180            }
181        }
182 
183        // the tag can at most only be 5100 bytes
184        offset -= (5100 + 9 + 11);
185        file.seek(offset);
186        file.read(buffer);
187        lyricsStart = new String(buffer);
188 
189        // search for the tag
190        final int i = lyricsStart.indexOf("LYRICSBEGIN");
191        if (i == -1) {
192            return false;
193        }
194        file.seek(offset + i + 11);
195        return true;
196    }
197 
198    public String toString() {
199        final String str = getIdentifier() + " " + this.getSize() + "\n";
200        return str + this.lyric;
201    }
202 
203    public void write(final AbstractMP3Tag tag) {
204        final Lyrics3v1 newTag;
205        if (tag != null) {
206            if (tag instanceof Lyrics3v1) {
207                newTag = (Lyrics3v1) tag;
208            } else {
209                newTag = new Lyrics3v1();
210            }
211            this.lyric = newTag.lyric;
212        }
213    }
214 
215    public void write(final RandomAccessFile file) throws IOException {
216        String str;
217        int offset;
218        final byte[] buffer;
219        final ID3v1 id3v1tag;
220        id3v1tag = (new ID3v1()).getID3tag(file);
221        delete(file);
222        file.seek(file.length());
223        buffer = new byte[this.lyric.length() + 11 + 9];
224        str = "LYRICSBEGIN";
225        for (int i = 0; i < str.length(); i++) {
226            buffer[i] = (byte) str.charAt(i);
227        }
228        offset = str.length();
229        str = TagUtility.truncate(this.lyric, 5100);
230        for (int i = 0; i < str.length(); i++) {
231            buffer[i + offset] = (byte) str.charAt(i);
232        }
233        offset += str.length();
234        str = "LYRICSEND";
235        for (int i = 0; i < str.length(); i++) {
236            buffer[i + offset] = (byte) str.charAt(i);
237        }
238        offset += str.length();
239        file.write(buffer, 0, offset);
240        if (id3v1tag != null) {
241            id3v1tag.write(file);
242        }
243    }
244 
245    public String getSongTitle() {
246        throw new UnsupportedOperationException("This tag does not contain that information");
247    }
248 
249    public String getLeadArtist() {
250        throw new UnsupportedOperationException("This tag does not contain that information");
251    }
252 
253    public String getAlbumTitle() {
254        throw new UnsupportedOperationException("This tag does not contain that information");
255    }
256 
257    public String getYearReleased() {
258        throw new UnsupportedOperationException("This tag does not contain that information");
259    }
260 
261    public String getSongComment() {
262        throw new UnsupportedOperationException("This tag does not contain that information");
263    }
264 
265    public String getSongGenre() {
266        throw new UnsupportedOperationException("This tag does not contain that information");
267    }
268 
269    public String getTrackNumberOnAlbum() {
270        throw new UnsupportedOperationException("This tag does not contain that information");
271    }
272 
273    public String getSongLyric() {
274        return getLyric().trim();
275    }
276 
277    public String getAuthorComposer() {
278        throw new UnsupportedOperationException("This tag does not contain that information");
279    }
280 
281    public void setSongTitle(String songTitle) {
282        throw new UnsupportedOperationException("This tag does not contain that information");
283    }
284 
285    public void setLeadArtist(String leadArtist) {
286        throw new UnsupportedOperationException("This tag does not contain that information");
287    }
288 
289    public void setAlbumTitle(String albumTitle) {
290        throw new UnsupportedOperationException("This tag does not contain that information");
291    }
292 
293    public void setYearReleased(String yearReleased) {
294        throw new UnsupportedOperationException("This tag does not contain that information");
295    }
296 
297    public void setSongComment(String songComment) {
298        throw new UnsupportedOperationException("This tag does not contain that information");
299    }
300 
301    public void setSongGenre(String songGenre) {
302        throw new UnsupportedOperationException("This tag does not contain that information");
303    }
304 
305    public void setTrackNumberOnAlbum(String trackNumberOnAlbum) {
306        throw new UnsupportedOperationException("This tag does not contain that information");
307    }
308 
309    public void setSongLyric(String songLyrics) {
310        setLyric(songLyrics.trim());
311    }
312 
313    public void setAuthorComposer(String authorComposer) {
314        throw new UnsupportedOperationException("This tag does not contain that information");
315    }
316}

[all classes][org.farng.mp3.lyrics3]
EMMA 2.0.5312 (C) Vladimir Roubtsov