riffola 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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