id3 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/CHANGES +12 -0
  2. data/README +0 -5
  3. data/docs/index.html +12 -5
  4. data/lib/id3.rb +111 -16
  5. metadata +3 -2
data/CHANGES ADDED
@@ -0,0 +1,12 @@
1
+ = id3 changes
2
+
3
+ === 0.4.1 (2008-08-16)
4
+
5
+ * Included patch provided by Sergey Udaltsov for UTF-8 and UTF-16 encodings, and new parser routines
6
+
7
+ === 0.4.0 (2008-08-16)
8
+
9
+ * Made previous version 0.4 available as a Ruby Gem , otherwise identical to 0.4
10
+
11
+
12
+
data/README CHANGED
@@ -7,11 +7,6 @@ Home Page: http://www.unixgods.org/~tilo/Ruby/ID3
7
7
 
8
8
  License: http://www.unixgods.org/~tilo/artistic-license.html
9
9
 
10
- MD5 Sums:
11
-
12
- 400ccf29d29da1d203f38657a18fca3e id3-0.4.0.gem
13
- 0ce2f2e3a2e57aba92ce72ec300ffa76 id3-0.4.0.tar.gz
14
-
15
10
 
16
11
  NOTE:
17
12
 
@@ -114,16 +114,23 @@ without problems.&nbsp;&nbsp; <br>
114
114
 
115
115
 
116
116
 
117
- <h3>Download</h3>
117
+ <h3>Downloads</h3>
118
118
 
119
119
 
120
120
  <br>
121
121
  <table border=1>
122
- <tr><th>Version</th><th>gem</th><th>tar.gz</th></tr>
122
+ <tr><th>Version</th><th>gem</th><th>tar.gz</th><th>Changes</th></tr>
123
123
  <tr>
124
- <td>0.4</td>
125
- <td><A HREF=../../id3-0.4.0.gem>id3-0.4.0.gem</A></td>
126
- <td><A HREF=../../id3-0.4.0.tar.gz>id3-0.4.0.tar.gz</A></td>
124
+ <th>0.4.1</th>
125
+ <td><A HREF=../../id3-0.4.1.gem>id3-0.4.1.gem</A></td>
126
+ <td><A HREF=../../id3-0.4.1.tar.gz>id3-0.4.1.tar.gz</A></td>
127
+ <td>Included patch provided by Sergey Udaltsov for UTF-8 and UTF-16 encodings, and new parser routines</td>
128
+ </tr>
129
+ <tr>
130
+ <th>0.4.0</th>
131
+ <td><A HREF=../../id3-0.4.0.gem>id3-0.4.0.gem</A></td>
132
+ <td><A HREF=../../id3-0.4.0.tar.gz>id3-0.4.0.tar.gz</A></td>
133
+ <td>identical to previous 0.4 version, but now also available as a ruby gem</td>
127
134
  </tr>
128
135
  </table>
129
136
 
data/lib/id3.rb CHANGED
@@ -2,10 +2,16 @@
2
2
  # id3.rb Ruby Module for handling the following ID3-tag versions:
3
3
  # ID3v1.0 , ID3v1.1, ID3v2.2.0, ID3v2.3.0, ID3v2.4.0
4
4
  #
5
- # Copyright (C) 2002,2003,2004 by Tilo Sloboda <tilo@unixgods.org>
5
+ # Copyright (C) 2002..2008 by Tilo Sloboda <tilo@unixgods.org>
6
6
  #
7
7
  # created: 12 Oct 2002
8
- # updated: Time-stamp: <Mon 27-Dec-2004 22:23:49 Tilo Sloboda>
8
+ # updated: Time-stamp: <Sat 16-Aug-2008 11:20:33 Tilo Sloboda>
9
+ #
10
+ # Version: 0.4.1
11
+ #
12
+ # Changes:
13
+ # 0.4.1 thanks to Sergey Udaltsov for the UTF-8 UTF-16 patch
14
+ # and parser routines!
9
15
  #
10
16
  # Docs: http://www.id3.org/id3v2-00.txt
11
17
  # http://www.id3.org/id3v2.3.0.txt
@@ -77,6 +83,7 @@
77
83
  # ==============================================================================
78
84
 
79
85
  require "md5"
86
+ require "iconv"
80
87
 
81
88
  require 'hexdump' # load hexdump method to extend class String
82
89
  require 'invert_hash' # new invert method for old Hash
@@ -276,6 +283,90 @@ module ID3
276
283
  VARS = 0
277
284
  PACKING = 1
278
285
 
286
+ BE16BOM = "\xFE\xFF"
287
+ LE16BOM = "\xFF\xFE"
288
+
289
+ def ID3.parse_string_rest(encoding, string)
290
+ case encoding
291
+ when 0
292
+ # ISO8859-1
293
+ return Iconv.iconv("ISO8859-1", "UTF-8", string);
294
+ when 1
295
+ # utf-16
296
+ bom = string[0..1]
297
+ data = string[2..string.length-1]
298
+ srcenc = bom == LE16BOM ? "UTF-16LE" : bom == BE16BOM ? "UTF-16BE" : "??"
299
+ return Iconv.iconv("UTF-8", srcenc, data);
300
+ when 2
301
+ # utf-16BE
302
+ return
303
+ Iconv.iconv("UTF-16BE", "UTF-8", data);
304
+ when 3
305
+ return string
306
+ else
307
+ raise 'Unknown encoding #{encoding}'
308
+ end
309
+ end
310
+
311
+ def ID3.parse_string_zeroend(encoding, string)
312
+ strend = encoding == 0 || encoding == 3 ? "\x00" : "\x00\x00";
313
+
314
+ endidx = string.index(strend)
315
+ if endidx.nil?
316
+ return parse_string_rest(encoding, string), string.length;
317
+ elsif endidx == 0
318
+ return "", strend.length;
319
+ else
320
+ return parse_string_rest(encoding, string[0..endidx-1]), endidx + strend.length;
321
+ end
322
+ end
323
+
324
+ def ID3.parse_a(data)
325
+ return [data]
326
+ end
327
+
328
+ def ID3.parse_Z(data)
329
+ rest = parse_string_rest(data)
330
+ return first, rest
331
+ end
332
+
333
+ def ID3.parse_CZ(data)
334
+ encoding = data[0]
335
+ rest = parse_string_rest(encoding, data[1..data.length-1])
336
+ return encoding, rest
337
+ end
338
+
339
+ def ID3.parse_CZZ(data)
340
+ encoding = data[0]
341
+ second,length = parse_string_zeroend(encoding, data[1..data.length-1])
342
+ rest = parse_string_rest(encoding, data[1 + length..data.length-1])
343
+ return encoding, second, rest
344
+ end
345
+
346
+ def ID3.parse_CZCZa(data)
347
+ encoding = data[0]
348
+ second,length = parse_string_zeroend(encoding, data[1..data.length-1])
349
+ third = data[length + 1]
350
+ fourth,nexpart2 = parse_string_zeroend(encoding, data[2 + length..data.length-1])
351
+ rest = data[2 + length + length2..data.length-1]
352
+ return encoding, second, third, fourth, rest
353
+ end
354
+
355
+ def ID3.parse_Ca3ZZ(data)
356
+ encoding = data[0]
357
+ second = data[1..3]
358
+ third,length = parse_string_zeroend(encoding,data[4..data.length-1])
359
+ rest = parse_string_rest(encoding, data[4 + length..data.length-1])
360
+ return encoding, second, third, rest
361
+ end
362
+
363
+ PARSER_CZ = lambda { |data| parse_CZ(data) }
364
+ PARSER_CZZ = lambda { |data| parse_CZZ(data) }
365
+ PARSER_Z = lambda { |data| parse_Z(data) }
366
+ PARSER_a = lambda { |data| parse_a(data) }
367
+ PARSER_CZCZa = lambda { |data| parse_CZCZa(data) }
368
+ PARSER_Ca3ZZ = lambda { |data| parse_Ca3ZZ(data) }
369
+
279
370
  # not sure if it's Z* or A*
280
371
  # A* does not append a \0 when writing!
281
372
 
@@ -283,21 +374,21 @@ module ID3
283
374
  # seems like i have no version 2.4.x ID3-tags!! If you have some, send them my way!
284
375
 
285
376
  FRAME_PARSER = {
286
- "TEXT" => [ %w(encoding text) , 'CZ*' ] ,
287
- "USERTEXT" => [ %w(encoding description value) , 'CZ*Z*' ] ,
377
+ "TEXT" => [ %w(encoding text) , PARSER_CZ ] ,
378
+ "USERTEXT" => [ %w(encoding description value) , PARSER_CZZ ] ,
288
379
 
289
- "PICTURE" => [ %w(encoding mimeType pictType description picture) , 'CZ*CZ*a*' ] ,
380
+ "PICTURE" => [ %w(encoding mimeType pictType description picture) , PARSER_CZCZa ] ,
290
381
 
291
- "WEB" => [ "url" , 'Z*' ] ,
292
- "WWWUSER" => [ %w(encoding description url) , 'CZ*Z*' ] ,
382
+ "WEB" => [ "url" , PARSER_Z ] ,
383
+ "WWWUSER" => [ %w(encoding description url) , PARSER_CZZ ] ,
293
384
 
294
- "LTEXT" => [ %w(encoding language text) , 'CZ*Z*' ] ,
295
- "UNSYNCEDLYRICS" => [ %w(encoding language content text) , 'Ca3Z*Z*' ] ,
296
- "COMMENT" => [ %w(encoding language short long) , 'Ca3Z*Z*' ] ,
297
- "BINARY" => [ "binary" , 'a*' ] ,
298
- "UNPARSED" => [ "raw" , 'a*' ] # how would we do value checking for this?
385
+ "LTEXT" => [ %w(encoding language text) , PARSER_CZZ ] ,
386
+ "UNSYNCEDLYRICS" => [ %w(encoding language content text) , PARSER_Ca3ZZ ] ,
387
+ "COMMENT" => [ %w(encoding language short long) , PARSER_Ca3ZZ ] ,
388
+ "BINARY" => [ "binary" , PARSER_a ] ,
389
+ "UNPARSED" => [ "raw" , PARSER_a ] # how would we do value checking for this?
299
390
  }
300
-
391
+
301
392
  # ----------------------------------------------------------------------------
302
393
  # MODULE VARIABLES
303
394
  # ----------------------------------------------------------------------------
@@ -964,7 +1055,7 @@ module ID3
964
1055
  framename = header[0..3]
965
1056
  size = (header[4]*256**3)+(header[5]*256**2)+(header[6]*256)+header[7]
966
1057
  flags= header[8..9]
967
- # printf "frame: %s , size: %d, flags: %s\n", framename , size, flags
1058
+ # printf "frame (at %x, frameheader %d): %s , size: %d, flags: %x %x\n", x, frameHeaderSize, framename , size, flags[0], flags[1]
968
1059
 
969
1060
  else
970
1061
  # we can't parse higher versions
@@ -1090,7 +1181,11 @@ module ID3
1090
1181
  end
1091
1182
  EOB
1092
1183
 
1093
- @rawflags = flags.to_i # preserve the raw flags (for debugging only)
1184
+ @rawflags = flags[0].to_i << 8 | flags[1] # preserve the raw flags (for debugging only)
1185
+
1186
+ if (@rawflags & (FRAME_HEADER_FLAGS["2.4.0"]["Unsynchronisation"])) != 0
1187
+ @rawdata = @rawdata.gsub("\xFF\x00","\xFF")
1188
+ end
1094
1189
 
1095
1190
  if (flags.to_i & FRAME_HEADER_FLAG_MASK[@version] != 0)
1096
1191
  # in this case we need to skip parsing the frame... and skip to the next one...
@@ -1128,7 +1223,7 @@ module ID3
1128
1223
  vars2 = vars
1129
1224
  end
1130
1225
 
1131
- values = self.rawdata.unpack(packing)
1226
+ values = packing.call(self.rawdata)
1132
1227
  vars.each { |key|
1133
1228
  self[key] = values.shift
1134
1229
  }
metadata CHANGED
@@ -3,9 +3,9 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: id3
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.4.0
6
+ version: 0.4.1
7
7
  date: 2008-08-16 00:00:00 -07:00
8
- summary: id3-0.4.0 - ID3 tag library for Ruby http://www.unixgods.org/~tilo/Ruby/ID3
8
+ summary: id3-0.4.1 - ID3 tag library for Ruby http://www.unixgods.org/~tilo/Ruby/ID3
9
9
  require_paths:
10
10
  - lib
11
11
  email: tools@unixgods.org
@@ -58,6 +58,7 @@ files:
58
58
  - LICENSE.html
59
59
  - index.html
60
60
  - README
61
+ - CHANGES
61
62
  test_files: []
62
63
 
63
64
  rdoc_options: