Skip to content

Commit

Permalink
proper content is returned as frame content for basic frame
Browse files Browse the repository at this point in the history
  • Loading branch information
Krists authored and Krists committed Oct 19, 2013
1 parent a81cf13 commit 369d07f
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 167 deletions.
43 changes: 26 additions & 17 deletions lib/id3tag/frames/v2/basic_frame.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,27 @@ def content
end

def unpacked_content
raw_content_io.rewind
offset = 0
offset += DECOMPRESSED_SIZE_BYTE_COUNT if compressed?
offset += GROUP_BYTE_COUNT if grouped?
raw_content_io.seek(offset)
count = additional_info_byte_count
pos = count > 0 ? (count - 1) : 0
raw_content_io.seek(pos)
raw_content_io.read
end

def group_id
if grouped?
raw_content_io.rewind
offset = 0
offset += DECOMPRESSED_SIZE_BYTE_COUNT if compressed?
raw_content_io.seek(offset)
raw_content_io.read(GROUP_BYTE_COUNT).unpack("C").first
pos, count = position_and_count_of_group_id_bytes
if grouped? && pos && count
raw_content_io.seek(pos)
raw_content_io.read(count).unpack("C").first
else
nil
end
end

def decompressed_size
if compressed?
raw_content_io.rewind
raw_content_io.read(DECOMPRESSED_SIZE_BYTE_COUNT).unpack("N").first
pos, count = position_and_count_of_data_length_bytes
if compressed? && pos && count
raw_content_io.seek(pos)
raw_content_io.read(count).unpack("N").first
else
raw_content_io.size
end
Expand Down Expand Up @@ -77,15 +74,27 @@ def data_length_indicator?
frame_flags.data_length_indicator?
end

def inspect
"<#{self.class.name} #{id}: #{inspect_content}>"
end

private

def additional_info_byte_count
frame_flags.additional_info_byte_count
end

def inspect
"<#{self.class.name} #{id}: #{inspect_content}>"
def position_and_count_of_data_length_bytes
frame_flags.position_and_count_of_data_length_bytes
end

private
def position_and_count_of_group_id_bytes
frame_flags.position_and_count_of_group_id_bytes
end

def position_and_count_of_encryption_id_bytes
frame_flags.position_and_count_of_encryption_id_bytes
end

def frame_flags
@frame_flags ||= FrameFlags.new(@flags, @major_version_number)
Expand Down
61 changes: 25 additions & 36 deletions lib/id3tag/frames/v2/frame_flags.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ module ID3Tag
module Frames
module V2
class FrameFlags
EXCLUDE_END_TRUE = true
FLAG_MAP_IN_APPEARANCE_ORDER_BY_VERSION = {
3 => {
:status_flags => [ :preserve_on_tag_alteration, :preserve_on_file_alteration, :read_only, nil, nil, nil, nil, nil ],
Expand Down Expand Up @@ -61,55 +60,45 @@ def data_length_indicator?
end

def additional_info_byte_count
current_additional_info_map.inject(0) do |total, query|
total += query.last if self.send(query.first)
additional_info_flags_in_effect.inject(0) do |total, query|
total += query.last
total
end
end

def range_of_data_length_bytes
if data_length_indicator?
cursor = 0
length = 0
current_additional_info_map.reject { |q| !self.send(q.first) }.map do |q|
cursor += q.last if q.first != :data_length_indicator?
if q.first == :data_length_indicator?
length = q.last
break
end
end
Range.new(cursor,cursor + length, EXCLUDE_END_TRUE)
def position_and_count_of_data_length_bytes
if data_length_indicator? || compressed?
find_position_and_length_for_additional_info(:data_length_indicator?, :compressed?)
end
end

def range_of_group_id
def position_and_count_of_group_id_bytes
if grouped?
cursor = 0
length = 0
current_additional_info_map.reject { |q| !self.send(q.first) }.map do |q|
cursor += q.last if q.first != :grouped?
if q.first == :grouped?
length = q.last
break
end
end
Range.new(cursor, cursor + length, EXCLUDE_END_TRUE)
find_position_and_length_for_additional_info(:grouped?)
end
end

def range_of_encryption_id
def position_and_count_of_encryption_id_bytes
if encrypted?
cursor = 0
length = 0
current_additional_info_map.reject { |q| !self.send(q.first) }.map do |q|
cursor += q.last if q.first != :encrypted?
if q.first == :encrypted?
length = q.last
break
end
find_position_and_length_for_additional_info(:encrypted?)
end
end

def find_position_and_length_for_additional_info(*methods_of_interest)
start_position = 0
target_info_byte_count = nil
additional_info_flags_in_effect.map do |query_method, byte_count|
start_position += (byte_count) unless methods_of_interest.include?(query_method)
if methods_of_interest.include?(query_method)
target_info_byte_count = byte_count
break
end
Range.new(cursor, cursor + length, EXCLUDE_END_TRUE)
end
[start_position, target_info_byte_count]
end

def additional_info_flags_in_effect
current_additional_info_map.reject { |q| !self.send(q.first) }
end

private
Expand Down
84 changes: 0 additions & 84 deletions spec/lib/id3tag/frames/v2/basic_frame_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,88 +22,4 @@
frame.inspect.should eq('<ID3Tag::Frames::V2::BasicFrame foo: bar>')
end
end

context 'when flags are not present. like in version v2.2' do
subject { frame }
let(:major_version_number) { 2 }

its(:preserve_on_tag_alteration?) { should be_true }
its(:preserve_on_file_alteration?) { should be_true }
its(:read_only?) { should be_false }
its(:compressed?) { should be_false }
its(:encrypted?) { should be_false }
its(:grouped?) { should be_false }
end

context "when using v.2.3" do
let(:major_version_number) { 3 }
context "when all frags set to 1" do
let(:flags) { [0b11100000,0b11100000].pack("C2") }
subject { frame }
its(:preserve_on_tag_alteration?) { should be_false }
its(:preserve_on_file_alteration?) { should be_false }
its(:read_only?) { should be_true }
its(:compressed?) { should be_true }
its(:encrypted?) { should be_true }
its(:grouped?) { should be_true }
its(:unsynchronised?) { should be_false }
its(:data_length_indicator?) { should be_false }
end

context "when frags are mixed" do
let(:flags) { [0b10100000,0b01000000].pack("C2") }
subject { frame }
its(:preserve_on_tag_alteration?) { should be_false }
its(:preserve_on_file_alteration?) { should be_true }
its(:read_only?) { should be_true }
its(:compressed?) { should be_false }
its(:encrypted?) { should be_true }
its(:grouped?) { should be_false }
end

context "when frame is compressed" do
let(:flags) { [0b00000000,0b10000000].pack("C2") }
let(:raw_content) { [55].pack("N") + "aaaaa" }
subject { frame }
its(:decompressed_size) { should eq(55) }
end

context "when frame is not compressed" do
let(:flags) { [0b00000000,0b00000000].pack("C2") }
subject { frame }
its(:decompressed_size) { should eq(3) }
end

context "when frame is grouped" do
let(:flags) { [0b00000000,0b00100000].pack("C2") }
let(:raw_content) { [77].pack("C") + "aaaaa" }
subject { frame }
its(:group_id) { should eq(77) }
its(:content) { should eq("aaaaa") }
end

context "when frame is not grouped" do
let(:flags) { [0b00000000,0b00000000].pack("C2") }
let(:raw_content) { "z" }
subject { frame }
its(:group_id) { should eq(nil) }
its(:content) { should eq("z") }
end
end

context "when using v.2.4" do
let(:major_version_number) { 4 }
context "when all frags set to 1" do
let(:flags) { [0b01110000,0b01001111].pack("C2") }
subject { frame }
its(:preserve_on_tag_alteration?) { should be_false }
its(:preserve_on_file_alteration?) { should be_false }
its(:read_only?) { should be_true }
its(:compressed?) { should be_true }
its(:encrypted?) { should be_true }
its(:grouped?) { should be_true }
its(:unsynchronised?) { should be_true }
its(:data_length_indicator?) { should be_true }
end
end
end
54 changes: 27 additions & 27 deletions spec/lib/id3tag/frames/v2/frame_flags_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
its(:unsynchronised?) { should be_false }
its(:data_length_indicator?) { should be_false }
its(:additional_info_byte_count) { should eq 0 }
its(:range_of_data_length_bytes) { should eq nil }
its(:range_of_group_id) { should eq nil }
its(:range_of_encryption_id) { should eq nil }
its(:position_and_count_of_data_length_bytes) { should eq nil }
its(:position_and_count_of_group_id_bytes) { should eq nil }
its(:position_and_count_of_encryption_id_bytes) { should eq nil }
end

context "when major version is 3" do
Expand All @@ -34,9 +34,9 @@
its(:unsynchronised?) { should be_false }
its(:data_length_indicator?) { should be_false }
its(:additional_info_byte_count) { should eq 0 }
its(:range_of_data_length_bytes) { should eq nil }
its(:range_of_group_id) { should eq nil }
its(:range_of_encryption_id) { should eq nil }
its(:position_and_count_of_data_length_bytes) { should eq nil }
its(:position_and_count_of_group_id_bytes) { should eq nil }
its(:position_and_count_of_encryption_id_bytes) { should eq nil }
end

context "when compression is on" do
Expand All @@ -50,9 +50,9 @@
its(:unsynchronised?) { should be_false }
its(:data_length_indicator?) { should be_false }
its(:additional_info_byte_count) { should eq 4 }
its(:range_of_data_length_bytes) { should eq 0...4 }
its(:range_of_group_id) { should eq nil }
its(:range_of_encryption_id) { should eq nil }
its(:position_and_count_of_data_length_bytes) { should eq [0, 4] }
its(:position_and_count_of_group_id_bytes) { should eq nil }
its(:position_and_count_of_encryption_id_bytes) { should eq nil }
end

context "when compression and group id is on" do
Expand All @@ -66,9 +66,9 @@
its(:unsynchronised?) { should be_false }
its(:data_length_indicator?) { should be_false }
its(:additional_info_byte_count) { should eq 5 }
its(:range_of_data_length_bytes) { should eq 0...4 }
its(:range_of_group_id) { should eq 3...4 }
its(:range_of_encryption_id) { should eq nil }
its(:position_and_count_of_data_length_bytes) { should eq [0, 4] }
its(:position_and_count_of_group_id_bytes) { should eq [4, 1] }
its(:position_and_count_of_encryption_id_bytes) { should eq nil }
end

context "when all flags are 1" do
Expand All @@ -82,9 +82,9 @@
its(:unsynchronised?) { should be_false }
its(:data_length_indicator?) { should be_false }
its(:additional_info_byte_count) { should eq 6 }
its(:range_of_data_length_bytes) { should eq 0...4 }
its(:range_of_group_id) { should eq 3...4 }
its(:range_of_encryption_id) { should eq 4...5 }
its(:position_and_count_of_data_length_bytes) { should eq [0, 4] }
its(:position_and_count_of_group_id_bytes) { should eq [5, 1] }
its(:position_and_count_of_encryption_id_bytes) { should eq [4, 1] }
end
end

Expand All @@ -101,9 +101,9 @@
its(:unsynchronised?) { should be_false }
its(:data_length_indicator?) { should be_false }
its(:additional_info_byte_count) { should eq 0 }
its(:range_of_data_length_bytes) { should eq nil }
its(:range_of_group_id) { should eq nil }
its(:range_of_encryption_id) { should eq nil }
its(:position_and_count_of_data_length_bytes) { should eq nil }
its(:position_and_count_of_group_id_bytes) { should eq nil }
its(:position_and_count_of_encryption_id_bytes) { should eq nil }
end

context "when compression is on" do
Expand All @@ -117,9 +117,9 @@
its(:unsynchronised?) { should be_false }
its(:data_length_indicator?) { should be_true }
its(:additional_info_byte_count) { should eq 4 }
its(:range_of_data_length_bytes) { should eq 0...4 }
its(:range_of_group_id) { should eq nil }
its(:range_of_encryption_id) { should eq nil }
its(:position_and_count_of_data_length_bytes) { should eq [0, 4] }
its(:position_and_count_of_group_id_bytes) { should eq nil }
its(:position_and_count_of_encryption_id_bytes) { should eq nil }
end

context "when compression and group id is on" do
Expand All @@ -133,9 +133,9 @@
its(:unsynchronised?) { should be_false }
its(:data_length_indicator?) { should be_true }
its(:additional_info_byte_count) { should eq 5 }
its(:range_of_data_length_bytes) { should eq 1...5 }
its(:range_of_group_id) { should eq 0...1 }
its(:range_of_encryption_id) { should eq nil }
its(:position_and_count_of_data_length_bytes) { should eq [1, 4] }
its(:position_and_count_of_group_id_bytes) { should eq [0, 1] }
its(:position_and_count_of_encryption_id_bytes) { should eq nil }
end

context "when all flags are 1" do
Expand All @@ -149,9 +149,9 @@
its(:unsynchronised?) { should be_true }
its(:data_length_indicator?) { should be_true }
its(:additional_info_byte_count) { should eq 6 }
its(:range_of_data_length_bytes) { should eq 2...6 }
its(:range_of_group_id) { should eq 0...1 }
its(:range_of_encryption_id) { should eq 1...2 }
its(:position_and_count_of_data_length_bytes) { should eq [2, 4] }
its(:position_and_count_of_group_id_bytes) { should eq [0, 1] }
its(:position_and_count_of_encryption_id_bytes) { should eq [1, 1] }
end
end
end
Loading

0 comments on commit 369d07f

Please sign in to comment.