Compute lucene-style scores for our hits.
[beagle.git] / Util / ApeReader.cs
blobe22d289018677e386c03a818a792998ce869754f
1 //
2 // ApeReader.cs : Reads an Ape tag from the given stream
3 //
4 // Author:
5 // Raphaël Slinckx <raf.raf@wol.be>
6 //
7 // Copyright 2004 (C) Raphaël Slinckx (ported from http://entagged.sourceforge.net)
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining a
12 // copy of this software and associated documentation files (the "Software"),
13 // to deal in the Software without restriction, including without limitation
14 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 // and/or sell copies of the Software, and to permit persons to whom the
16 // Software is furnished to do so, subject to the following conditions:
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 // DEALINGS IN THE SOFTWARE.
30 using System;
31 using System.IO;
32 using System.Text;
33 using System.Collections;
35 namespace Beagle.Util.AudioUtil {
37 public class ApeTagReader {
39 private ASCIIEncoding ascii = new ASCIIEncoding ();
40 private UTF8Encoding utf = new UTF8Encoding ();
42 public Tag Read (Stream fs)
44 Tag tag = new Tag ();
46 //Check wether the file contains an APE tag--------------------------------
47 fs.Seek (-32, SeekOrigin.End);
49 byte[] b = new byte[8];
50 fs.Read (b, 0, 8);
52 string tagS = ascii.GetString (b, 0, 8);
53 if (tagS != "APETAGEX"){
54 throw new Exception ("There is no APE Tag in this file");
56 //Parse the tag -)------------------------------------------------
57 //Version
58 b = new byte[4];
59 fs.Read (b, 0, 4);
60 int version = getNumber (b, 0, 3);
61 if (version != 2000) {
62 throw new Exception ("APE Tag other than version 2.0 are not supported");
65 //Size
66 b = new byte[4];
67 fs.Read (b, 0, 4);
68 int tagSize = getNumber (b, 0, 3);
70 //Number of items
71 b = new byte[4];
72 fs.Read (b, 0, 4);
73 int itemNumber = getNumber (b, 0, 3);
75 //Tag Flags
76 b = new byte[4];
77 fs.Read (b, 0, 4);
78 //TODO handle these
80 fs.Seek (-tagSize, SeekOrigin.End);
82 for (int i = 0; i < itemNumber; i++) {
83 //Content length
84 b = new byte[4];
85 fs.Read (b, 0, 4);
86 int contentLength = getNumber (b, 0, 3);
88 //Item flags
89 b = new byte[4];
90 fs.Read (b, 0, 4);
91 //TODO handle these
92 bool binary = ((b[0]&0x06) >> 1) == 1;
94 int j = 0;
95 while (fs.ReadByte () != 0)
96 j++;
97 fs.Seek (-j-1, SeekOrigin.Current);
98 int fieldSize = j;
100 //Read Item key
101 b = new byte[fieldSize];
102 fs.Read (b, 0, fieldSize);
103 fs.ReadByte ();
104 string field = ascii.GetString (b, 0, fieldSize);
106 //Read Item content
107 b = new byte[contentLength];
108 fs.Read (b, 0, contentLength);
109 string content;
110 if (!binary)
111 content = utf.GetString (b, 0, contentLength);
112 else
113 content = ascii.GetString (b, 0, contentLength);
115 if (field.ToLower () == "title")
116 tag.Title = content;
117 else if (field.ToLower () == "artist")
118 tag.Artist = content;
119 else if (field.ToLower () == "album")
120 tag.Album = content;
121 else if (field.ToLower () == "year")
122 tag.Year = content;
123 else if (field.ToLower () == "comment") {
124 tag.Comment = content;
125 } else if (field.ToLower () == "track")
126 tag.Track = content;
127 else if (field.ToLower () == "genre")
128 tag.Genre = content;
131 return tag;
134 //Computes a (end-start) bytes long number
135 private int getNumber (byte[] b, int start, int end)
137 int number = 0;
138 for (int i = 0; i< (end-start+1); i++) {
139 number += ((b[start+i]&0xFF) << i*8);
142 return number;