riffola 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2be335b138c805162b56fb07b14d589a1c90f00fa0a6fed6c1cb9dba482151f4
4
- data.tar.gz: c393edd260fc4b43a94feb327449e059a25f46a4189c2b42c1516029619703a8
3
+ metadata.gz: 75947af5b2176ff928adee071dd95929c96c4b85f706e11d37615b5e27e32515
4
+ data.tar.gz: 6cc4db5122b635d032acc00f63bb092ee9584f19d56e75cd29e57ae35bbfb9cc
5
5
  SHA512:
6
- metadata.gz: fc246a663893068f9c96fcdcbe842112a0c160b63f475b98ad357e8c775613f0f279eb413ad7aad135b9644d44570824c9980493390fc4821c8514a5dd9ffb14
7
- data.tar.gz: dd1956dc6c17bffcb1e37e24d33abbb3c79553a600f11a6b26267434f7467bfe283034aad8b63c8f9bf55d3de60d3341500e926febaaf26c171a45fc9314ece1
6
+ metadata.gz: 7d2b2612fb38347063f3907d0c7833fc3cc7d4f949137fe9a674e33e9635e7fb5f4d80e17208944512be053e98834a610fcb50f132d48a6c428d17f39c2e855b
7
+ data.tar.gz: ca68e8a260cc1d305198d62fc3826caba13e8c7b5064a3eb9a48861ea36f108414992d6ea933a449a048090beef7cc0791c2aeba88aa9820243f67a315afa5b8
@@ -1,3 +1,5 @@
1
+ require 'riffola/chunk'
2
+
1
3
  module Riffola
2
4
 
3
5
  # Return a list of Riff chunk objects stored in a file, from a given offset.
@@ -41,200 +43,4 @@ module Riffola
41
43
  chunks
42
44
  end
43
45
 
44
- class Chunk
45
-
46
- # Define default chunk format properties
47
- DEFAULT_CHUNK_FORMAT = {
48
- size_length: 4,
49
- header_size: 0,
50
- data_size_correction: 0
51
- }
52
-
53
- # Constructor
54
- #
55
- # Parameters::
56
- # * *file_name* (String): The file name
57
- # * *offset* (Integer): The offset to read the file from [default: 0]
58
- # * *chunks_format* (Hash<String, Hash<Symbol,Object> >): Format of a given set of chunk names (use '*' for all chunks). For each chunk name, the following can be specified: [default = {}]
59
- # * *size_length* (Integer): Number of bytes encoding the size of the chunk [default: 4]
60
- # * *header_size* (Integer): Size of the chunk's header [default: 0]
61
- # * *data_size_correction* (Integer): Correction to apply to the data size read [default: 0]
62
- # Each property can also be a Proc taking the file handle (positioned at the beginning of the chunk) and returning the real value:
63
- # * Parameters::
64
- # * *file* (IO): The file IO, positioned at the beginning of the chunk (at the name)
65
- # * Result::
66
- # * Object: The corresponding property value
67
- # * *max_size* (Integer): Maximum readable size (starting from the file's offset) to retrieve chunks, or nil to read till the end of the file [default: nil]
68
- # * *parent_chunk* (Chunk or nil): Parent chunk, or nil if none [default: nil]
69
- # * *warnings* (Boolean): Do we activate warnings? [default: true]
70
- # * *debug* (Boolean): Do we activate debugging logs? [default: false]
71
- def initialize(file_name, offset: 0, chunks_format: {}, max_size: nil, parent_chunk: nil, warnings: true, debug: false)
72
- @file_name = file_name
73
- @offset = offset
74
- @chunks_format = chunks_format
75
- # Fill the default format if not present
76
- @chunks_format['*'] = {} unless @chunks_format.key?('*')
77
- DEFAULT_CHUNK_FORMAT.each do |format_property, default_property_value|
78
- @chunks_format['*'][format_property] = default_property_value unless @chunks_format['*'].key?(format_property)
79
- end
80
- @parent_chunk = parent_chunk
81
- @max_size = max_size.nil? ? File.size(@file_name) - @offset : max_size
82
- @warnings = warnings
83
- @debug = debug
84
- # Get chunk format in instance variables named after the property
85
- chunk_name = self.name
86
- DEFAULT_CHUNK_FORMAT.keys.each do |format_property|
87
- property_value = @chunks_format.key?(chunk_name) && @chunks_format[chunk_name].key?(format_property) ? @chunks_format[chunk_name][format_property] : @chunks_format['*'][format_property]
88
- if property_value.is_a?(Proc)
89
- File.open(@file_name) do |file|
90
- file.seek(@offset)
91
- property_value = property_value.call(file)
92
- end
93
- end
94
- instance_variable_set(:"@#{format_property}", property_value)
95
- end
96
- puts "[DEBUG] - Read chunk from #{@file_name}@#{@offset}/#{@max_size}: #{chunk_name} (size length: #{@size_length}, header size: #{@header_size}, data size: #{self.size}/#{@max_size})" if @debug
97
- # puts "[DEBUG] - Chunks format: #{@chunks_format.inspect}" if @debug
98
- end
99
-
100
- # Return the name of this chunk
101
- #
102
- # Result::
103
- # * String: Chunk name
104
- def name
105
- chunk_name = nil
106
- File.open(@file_name) do |file|
107
- file.seek(@offset, IO::SEEK_CUR)
108
- chunk_name = file.read(4)
109
- end
110
- puts "[WARNING] - Doesn't look like a valid chunk name: #{chunk_name}" if @warnings && !chunk_name =~ /^[\w ]{4}$/
111
- chunk_name
112
- end
113
-
114
- # Return the size of this chunk
115
- #
116
- # Result::
117
- # * Integer: Chunk size in bytes
118
- def size
119
- chunk_size = nil
120
- File.open(@file_name) do |file|
121
- file.seek(@offset + 4, IO::SEEK_CUR)
122
- case @size_length
123
- when 4
124
- chunk_size = file.read(@size_length).unpack('L').first
125
- when 2
126
- chunk_size = file.read(@size_length).unpack('S').first
127
- else
128
- raise "Can't decode size field of length #{@size_length}"
129
- end
130
- end
131
- chunk_size + @data_size_correction
132
- end
133
-
134
- # Return the header of this chunk
135
- #
136
- # Result::
137
- # * String: Header
138
- def header
139
- chunk_header = nil
140
- File.open(@file_name) do |file|
141
- file.seek(@offset + 4 + @size_length, IO::SEEK_CUR)
142
- chunk_header = file.read(@header_size)
143
- end
144
- chunk_header
145
- end
146
-
147
- # Return the data of this chunk
148
- #
149
- # Result::
150
- # * String: Data
151
- def data
152
- chunk_data = nil
153
- data_size = self.size
154
- complete_header_size = 4 + @size_length + @header_size
155
- puts "[WARNING] - Data size is #{data_size} but the maximum readable size is #{@max_size} and the headers have #{complete_header_size}" if @warnings && complete_header_size + data_size > @max_size
156
- File.open(@file_name) do |file|
157
- file.seek(@offset + complete_header_size, IO::SEEK_CUR)
158
- chunk_data = file.read(data_size)
159
- end
160
- chunk_data
161
- end
162
-
163
- # Return the parent chunk, or nil if none
164
- #
165
- # Result::
166
- # * Chunk or nil: The parent chunk, or nil if none
167
- def parent_chunk
168
- @parent_chunk
169
- end
170
-
171
- # Return a string representation of this chunk
172
- #
173
- # Result::
174
- # * String: tring representation of this chunk
175
- def to_s
176
- "<Riffola-Chunk #{self.name} (#{@file_name}@#{@offset})>"
177
- end
178
-
179
- # Return the next chunk
180
- #
181
- # Result::
182
- # * Chunk or nil: The next chunk, or nil if none
183
- def next
184
- complete_chunk_size = 4 + @size_length + @header_size + self.size
185
- remaining_size = @max_size - complete_chunk_size
186
- raise "#{self} - Remaining size for next chunk: #{remaining_size}" if remaining_size < 0
187
- remaining_size > 0 ? Chunk.new(@file_name,
188
- offset: @offset + complete_chunk_size,
189
- chunks_format: @chunks_format,
190
- max_size: remaining_size,
191
- parent_chunk: @parent_chunk,
192
- warnings: @warnings,
193
- debug: @debug
194
- ) : nil
195
- end
196
-
197
- # Return this chunk's data as a list of sub-chunks
198
- #
199
- # Parameters::
200
- # * *data_offset* (Integer): The offset to read the sub-chunks from this chunk's data [default: 0]
201
- # * *sub_chunks_format* (Hash<String, Hash<Symbol,Object> >): Chunks format. See Chunk#initialize for details. [default = @chunks_format]
202
- # * *warnings* (Boolean): Do we activate warnings? [default: @warnings]
203
- # * *debug* (Boolean): Do we activate debugging logs? [default: @debug]
204
- # * Proc: Optional code called for each chunk being decoded
205
- # * Parameters::
206
- # * *chunk* (Chunk): Chunk being decoded
207
- # * Result::
208
- # * Boolean: Do we continue decoding chunks?
209
- # Result::
210
- # * Array<Chunk>: List of sub-chunks
211
- def sub_chunks(data_offset: 0, sub_chunk_size_length: @size_length, sub_chunk_header_size: @header_size, sub_chunks_format: @chunks_format, warnings: @warnings, debug: @debug, &callback)
212
- data_size = self.size
213
- data_size > 0 ? Riffola.read(@file_name,
214
- offset: @offset + 4 + @size_length + @header_size + data_offset,
215
- chunks_format: sub_chunks_format,
216
- max_size: data_size - data_offset,
217
- parent_chunk: self,
218
- warnings: @warnings,
219
- debug: @debug,
220
- &callback
221
- ) : []
222
- end
223
-
224
- # Compare Chunks
225
- #
226
- # Parameters::
227
- # * *other* (Object): Other object
228
- # Result::
229
- # * Boolean: Are objects equal?
230
- def ==(other)
231
- other.is_a?(Chunk) &&
232
- other.name == self.name &&
233
- other.size == self.size &&
234
- other.header == self.header &&
235
- other.data == self.data
236
- end
237
-
238
- end
239
-
240
46
  end
@@ -0,0 +1,199 @@
1
+ module Riffola
2
+
3
+ class Chunk
4
+
5
+ # Define default chunk format properties
6
+ DEFAULT_CHUNK_FORMAT = {
7
+ size_length: 4,
8
+ header_size: 0,
9
+ data_size_correction: 0
10
+ }
11
+
12
+ # Constructor
13
+ #
14
+ # Parameters::
15
+ # * *file_name* (String): The file name
16
+ # * *offset* (Integer): The offset to read the file from [default: 0]
17
+ # * *chunks_format* (Hash<String, Hash<Symbol,Object> >): Format of a given set of chunk names (use '*' for all chunks). For each chunk name, the following can be specified: [default = {}]
18
+ # * *size_length* (Integer): Number of bytes encoding the size of the chunk [default: 4]
19
+ # * *header_size* (Integer): Size of the chunk's header [default: 0]
20
+ # * *data_size_correction* (Integer): Correction to apply to the data size read [default: 0]
21
+ # Each property can also be a Proc taking the file handle (positioned at the beginning of the chunk) and returning the real value:
22
+ # * Parameters::
23
+ # * *file* (IO): The file IO, positioned at the beginning of the chunk (at the name)
24
+ # * Result::
25
+ # * Object: The corresponding property value
26
+ # * *max_size* (Integer): Maximum readable size (starting from the file's offset) to retrieve chunks, or nil to read till the end of the file [default: nil]
27
+ # * *parent_chunk* (Chunk or nil): Parent chunk, or nil if none [default: nil]
28
+ # * *warnings* (Boolean): Do we activate warnings? [default: true]
29
+ # * *debug* (Boolean): Do we activate debugging logs? [default: false]
30
+ def initialize(file_name, offset: 0, chunks_format: {}, max_size: nil, parent_chunk: nil, warnings: true, debug: false)
31
+ @file_name = file_name
32
+ @offset = offset
33
+ @chunks_format = chunks_format
34
+ # Fill the default format if not present
35
+ @chunks_format['*'] = {} unless @chunks_format.key?('*')
36
+ DEFAULT_CHUNK_FORMAT.each do |format_property, default_property_value|
37
+ @chunks_format['*'][format_property] = default_property_value unless @chunks_format['*'].key?(format_property)
38
+ end
39
+ @parent_chunk = parent_chunk
40
+ @max_size = max_size.nil? ? File.size(@file_name) - @offset : max_size
41
+ @warnings = warnings
42
+ @debug = debug
43
+ # Get chunk format in instance variables named after the property
44
+ chunk_name = self.name
45
+ DEFAULT_CHUNK_FORMAT.keys.each do |format_property|
46
+ property_value = @chunks_format.key?(chunk_name) && @chunks_format[chunk_name].key?(format_property) ? @chunks_format[chunk_name][format_property] : @chunks_format['*'][format_property]
47
+ if property_value.is_a?(Proc)
48
+ File.open(@file_name) do |file|
49
+ file.seek(@offset)
50
+ property_value = property_value.call(file)
51
+ end
52
+ end
53
+ instance_variable_set(:"@#{format_property}", property_value)
54
+ end
55
+ puts "[DEBUG] - Read chunk from #{@file_name}@#{@offset}/#{@max_size}: #{chunk_name} (size length: #{@size_length}, header size: #{@header_size}, data size: #{self.size}/#{@max_size})" if @debug
56
+ # puts "[DEBUG] - Chunks format: #{@chunks_format.inspect}" if @debug
57
+ end
58
+
59
+ # Return the name of this chunk
60
+ #
61
+ # Result::
62
+ # * String: Chunk name
63
+ def name
64
+ chunk_name = nil
65
+ File.open(@file_name) do |file|
66
+ file.seek(@offset, IO::SEEK_CUR)
67
+ chunk_name = file.read(4)
68
+ end
69
+ puts "[WARNING] - Doesn't look like a valid chunk name: #{chunk_name}" if @warnings && !(chunk_name =~ /^[\w ]{4}$/)
70
+ chunk_name
71
+ end
72
+
73
+ # Return the size of this chunk
74
+ #
75
+ # Result::
76
+ # * Integer: Chunk size in bytes
77
+ def size
78
+ chunk_size = nil
79
+ File.open(@file_name) do |file|
80
+ file.seek(@offset + 4, IO::SEEK_CUR)
81
+ case @size_length
82
+ when 4
83
+ chunk_size = file.read(@size_length).unpack('L').first
84
+ when 2
85
+ chunk_size = file.read(@size_length).unpack('S').first
86
+ else
87
+ raise "Can't decode size field of length #{@size_length}"
88
+ end
89
+ end
90
+ chunk_size + @data_size_correction
91
+ end
92
+
93
+ # Return the header of this chunk
94
+ #
95
+ # Result::
96
+ # * String: Header
97
+ def header
98
+ chunk_header = nil
99
+ File.open(@file_name) do |file|
100
+ file.seek(@offset + 4 + @size_length, IO::SEEK_CUR)
101
+ chunk_header = file.read(@header_size)
102
+ end
103
+ chunk_header
104
+ end
105
+
106
+ # Return the data of this chunk
107
+ #
108
+ # Result::
109
+ # * String: Data
110
+ def data
111
+ chunk_data = nil
112
+ data_size = self.size
113
+ complete_header_size = 4 + @size_length + @header_size
114
+ puts "[WARNING] - Data size is #{data_size} but the maximum readable size is #{@max_size} and the headers have #{complete_header_size}" if @warnings && complete_header_size + data_size > @max_size
115
+ File.open(@file_name) do |file|
116
+ file.seek(@offset + complete_header_size, IO::SEEK_CUR)
117
+ chunk_data = file.read(data_size)
118
+ end
119
+ chunk_data
120
+ end
121
+
122
+ # Return the parent chunk, or nil if none
123
+ #
124
+ # Result::
125
+ # * Chunk or nil: The parent chunk, or nil if none
126
+ def parent_chunk
127
+ @parent_chunk
128
+ end
129
+
130
+ # Return a string representation of this chunk
131
+ #
132
+ # Result::
133
+ # * String: tring representation of this chunk
134
+ def to_s
135
+ "<Riffola-Chunk #{self.name} (#{@file_name}@#{@offset})>"
136
+ end
137
+
138
+ # Return the next chunk
139
+ #
140
+ # Result::
141
+ # * Chunk or nil: The next chunk, or nil if none
142
+ def next
143
+ complete_chunk_size = 4 + @size_length + @header_size + self.size
144
+ remaining_size = @max_size - complete_chunk_size
145
+ raise "#{self} - Remaining size for next chunk: #{remaining_size}" if remaining_size < 0
146
+ remaining_size > 0 ? Chunk.new(@file_name,
147
+ offset: @offset + complete_chunk_size,
148
+ chunks_format: @chunks_format,
149
+ max_size: remaining_size,
150
+ parent_chunk: @parent_chunk,
151
+ warnings: @warnings,
152
+ debug: @debug
153
+ ) : nil
154
+ end
155
+
156
+ # Return this chunk's data as a list of sub-chunks
157
+ #
158
+ # Parameters::
159
+ # * *data_offset* (Integer): The offset to read the sub-chunks from this chunk's data [default: 0]
160
+ # * *sub_chunks_format* (Hash<String, Hash<Symbol,Object> >): Chunks format. See Chunk#initialize for details. [default = @chunks_format]
161
+ # * *warnings* (Boolean): Do we activate warnings? [default: @warnings]
162
+ # * *debug* (Boolean): Do we activate debugging logs? [default: @debug]
163
+ # * Proc: Optional code called for each chunk being decoded
164
+ # * Parameters::
165
+ # * *chunk* (Chunk): Chunk being decoded
166
+ # * Result::
167
+ # * Boolean: Do we continue decoding chunks?
168
+ # Result::
169
+ # * Array<Chunk>: List of sub-chunks
170
+ def sub_chunks(data_offset: 0, sub_chunk_size_length: @size_length, sub_chunk_header_size: @header_size, sub_chunks_format: @chunks_format, warnings: @warnings, debug: @debug, &callback)
171
+ data_size = self.size
172
+ data_size > 0 ? Riffola.read(@file_name,
173
+ offset: @offset + 4 + @size_length + @header_size + data_offset,
174
+ chunks_format: sub_chunks_format,
175
+ max_size: data_size - data_offset,
176
+ parent_chunk: self,
177
+ warnings: @warnings,
178
+ debug: @debug,
179
+ &callback
180
+ ) : []
181
+ end
182
+
183
+ # Compare Chunks
184
+ #
185
+ # Parameters::
186
+ # * *other* (Object): Other object
187
+ # Result::
188
+ # * Boolean: Are objects equal?
189
+ def ==(other)
190
+ other.is_a?(Chunk) &&
191
+ other.name == self.name &&
192
+ other.size == self.size &&
193
+ other.header == self.header &&
194
+ other.data == self.data
195
+ end
196
+
197
+ end
198
+
199
+ end
@@ -1,5 +1,5 @@
1
1
  module Riffola
2
2
 
3
- VERSION = '0.0.1'
3
+ VERSION = '0.0.2'
4
4
 
5
5
  end
File without changes
File without changes
metadata CHANGED
@@ -1,85 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riffola
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muriel Salvan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-11 00:00:00.000000000 Z
11
+ date: 2021-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '3.10'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '3.10'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: hex_string
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '1.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '1.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: byebug
42
+ name: sem_ver_components
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '0.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rubocop
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: ruby-prof
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
54
+ version: '0.0'
83
55
  description: Library reading an extended RIFF format, supporting huge files. RIFF
84
56
  format is composed of a list of chunks, each chunk being an identifier, an encoded
85
57
  data size, an optional header and chunk data itself. Riffola has ways to deal with
@@ -92,6 +64,7 @@ extensions: []
92
64
  extra_rdoc_files: []
93
65
  files:
94
66
  - lib/riffola.rb
67
+ - lib/riffola/chunk.rb
95
68
  - lib/riffola/version.rb
96
69
  - spec/riffola_spec.rb
97
70
  - spec/spec_helper.rb
@@ -114,8 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
87
  - !ruby/object:Gem::Version
115
88
  version: '0'
116
89
  requirements: []
117
- rubyforge_project:
118
- rubygems_version: 2.7.3
90
+ rubygems_version: 3.2.3
119
91
  signing_key:
120
92
  specification_version: 4
121
93
  summary: Riffola - Reading extended RIFF files