Skip to content

Commit

Permalink
increased compatibility with ID3v2.4
Browse files Browse the repository at this point in the history
  • Loading branch information
joaomoreno committed May 15, 2011
1 parent 7a10ba8 commit 285f4f1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 14 deletions.
4 changes: 2 additions & 2 deletions lib/buffer.coffee
@@ -1,12 +1,12 @@

Buffer.prototype.toInt = (start, length, bom, bits) ->
power = if bits then Math.pow(2, bits) else Math.pow(2, 8)

matchingBits = power - 1
sum = 0
factor = 1
indexes = if bom is 'little' then [start..start + length - 1] else [start + length - 1..start]
for i in indexes
sum += this[i] * factor
sum += (this[i] & matchingBits) * factor
factor *= power
sum

Expand Down
46 changes: 34 additions & 12 deletions lib/id3.coffee
Expand Up @@ -48,7 +48,7 @@ class ID3Parser
tagClass = @tagClass
io.readExactlyToBuffer fd, 0, 10, (err, buffer) ->
tag = { header: parseHeader.apply(self, [buffer]) }
io.readExactlyToBuffer fd, tag.header.length, tag.header.size, (err, buffer) ->
io.readExactlyToBuffer fd, tag.header.length, tag.header.size + 10, (err, buffer) ->
if err then return callback err
try
tag.frames = parseFrames.apply(self, [tag, buffer, 10])
Expand Down Expand Up @@ -78,23 +78,16 @@ class ID3Parser

parseFrameSize: (buffer, start) -> buffer.toInt start + 3, 3

parseFrame: (tag, buffer, start) ->
parseFrame: (buffer, start) ->
return unless start < buffer.length and buffer[start]
frame =
id: @parseFrameId buffer, start
size: @parseFrameSize buffer, start
if frame.id[0] is 'T'
start += @frameHeaderSize
frame.encoding = if buffer[start] == 0 then 'iso-8859-1' else 'utf16'
buffer = buffer[start + 1 .. start + frame.size - 1]
decoding = if frame.encoding is 'utf16' then 'utf16' else 'utf8'
frame.content = buffer.toString(decoding)
frame
id: @parseFrameId buffer, start
size: @parseFrameSize buffer, start

parseFrames: (tag, buffer, start) ->
frames = {}
start = start || 0
while frame = @parseFrame tag, buffer, start
while frame = @parseFrame buffer, start
frames[frame.id] = frame
start += frame.size + @frameHeaderSize
tag.padding = buffer.length - start
Expand Down Expand Up @@ -149,6 +142,19 @@ class ID3v2Parser extends ID3Parser
parseHeaderFlags: (header, buffer) ->
super header, buffer

parseFrame: (buffer, start) ->
return unless start < buffer.length and buffer[start]
frame =
id: @parseFrameId buffer, start
size: @parseFrameSize buffer, start
if frame?.id[0] is 'T'
start += @frameHeaderSize
frame.encoding = if buffer[start] == 0 then 'iso-8859-1' else 'utf16'
buffer = buffer[start + 1 .. start + frame.size - 1]
decoding = if frame.encoding is 'utf16' then 'utf16' else 'utf8'
frame.content = buffer.toString(decoding)
frame

# ### ID3v3 ###

class ID3v3Tag extends ID3Tag
Expand Down Expand Up @@ -228,3 +234,19 @@ class ID3v4Parser extends ID3v3Parser
parseFrameSize: (buffer, start) ->
buffer.toInt start + 4, 4, 'big', 7

parseFrame: (buffer, start) ->
return unless start < buffer.length and buffer[start]
frame =
id: @parseFrameId buffer, start
size: @parseFrameSize buffer, start
if frame?.id[0] is 'T'
start += @frameHeaderSize
frame.encoding = switch buffer[start]
when 0x00 then 'iso-8859-1'
when 0x01, 0x02 then 'utf16'
when 0x03 then 'utf8'
buffer = buffer[start + 1 .. start + frame.size - 1]
decoding = if frame.encoding is 'utf16' then 'utf16' else 'utf8'
frame.content = buffer.toString(decoding)
frame

0 comments on commit 285f4f1

Please sign in to comment.