bindata 0.8.1 → 0.9.0
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.
- data/ChangeLog +11 -2
- data/README +55 -19
- data/TODO +4 -0
- data/examples/gzip.rb +3 -3
- data/lib/bindata.rb +8 -1
- data/lib/bindata/array.rb +58 -26
- data/lib/bindata/base.rb +133 -83
- data/lib/bindata/choice.rb +142 -61
- data/lib/bindata/float.rb +4 -0
- data/lib/bindata/int.rb +14 -0
- data/lib/bindata/lazy.rb +19 -2
- data/lib/bindata/multi_value.rb +144 -0
- data/lib/bindata/registry.rb +13 -8
- data/lib/bindata/rest.rb +41 -0
- data/lib/bindata/sanitize.rb +36 -0
- data/lib/bindata/single.rb +31 -6
- data/lib/bindata/single_value.rb +203 -0
- data/lib/bindata/string.rb +57 -32
- data/lib/bindata/stringz.rb +15 -0
- data/lib/bindata/struct.rb +189 -204
- data/spec/array_spec.rb +66 -42
- data/spec/base_spec.rb +202 -80
- data/spec/choice_spec.rb +172 -51
- data/spec/int_spec.rb +5 -5
- data/spec/lazy_spec.rb +26 -23
- data/spec/multi_value_spec.rb +250 -0
- data/spec/registry_spec.rb +8 -8
- data/spec/rest_spec.rb +30 -0
- data/spec/sanitize_spec.rb +108 -0
- data/spec/single_spec.rb +63 -49
- data/spec/single_value_spec.rb +131 -0
- data/spec/string_spec.rb +47 -47
- data/spec/stringz_spec.rb +29 -29
- data/spec/struct_spec.rb +112 -198
- metadata +58 -57
data/lib/bindata/registry.rb
CHANGED
|
@@ -9,24 +9,29 @@ module BinData
|
|
|
9
9
|
@registry = {}
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
# Convert camelCase +name+ to underscore style.
|
|
13
|
+
def underscore_name(name)
|
|
14
|
+
name.to_s.sub(/.*::/, "").
|
|
15
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
|
16
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
|
17
|
+
tr("-", "_").
|
|
18
|
+
downcase
|
|
19
|
+
end
|
|
20
|
+
|
|
12
21
|
# Registers the mapping of +name+ to +klass+. +name+ is converted
|
|
13
22
|
# from camelCase to underscore style.
|
|
14
23
|
# Returns the converted name
|
|
15
24
|
def register(name, klass)
|
|
16
25
|
# convert camelCase name to underscore style
|
|
17
|
-
|
|
18
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
|
19
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
|
20
|
-
tr("-", "_").
|
|
21
|
-
downcase
|
|
26
|
+
name = underscore_name(name)
|
|
22
27
|
|
|
23
28
|
# warn if replacing an existing class
|
|
24
|
-
if $VERBOSE and (existing = @registry[
|
|
29
|
+
if $VERBOSE and (existing = @registry[name])
|
|
25
30
|
warn "warning: replacing registered class #{existing} with #{klass}"
|
|
26
31
|
end
|
|
27
32
|
|
|
28
|
-
@registry[
|
|
29
|
-
|
|
33
|
+
@registry[name] = klass
|
|
34
|
+
name.dup
|
|
30
35
|
end
|
|
31
36
|
|
|
32
37
|
# Returns the class matching a previously registered +name+.
|
data/lib/bindata/rest.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require "bindata/single"
|
|
2
|
+
|
|
3
|
+
module BinData
|
|
4
|
+
# Rest will consume the input stream from the current position to the end of
|
|
5
|
+
# the stream. This will mainly be useful for debugging and developing.
|
|
6
|
+
#
|
|
7
|
+
# require 'bindata'
|
|
8
|
+
#
|
|
9
|
+
# class A < BinData::MultiValue
|
|
10
|
+
# string :a, :read_length => 5
|
|
11
|
+
# rest :rest
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
# obj = A.read("abcdefghij")
|
|
15
|
+
# obj.a #=> "abcde"
|
|
16
|
+
# obj.rest #=" "fghij"
|
|
17
|
+
#
|
|
18
|
+
class Rest < Single
|
|
19
|
+
|
|
20
|
+
# Register this class
|
|
21
|
+
register(self.name, self)
|
|
22
|
+
|
|
23
|
+
#---------------
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
# Return the string representation that +val+ will take when written.
|
|
27
|
+
def val_to_str(val)
|
|
28
|
+
val
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Read a number of bytes from +io+ and return the value they represent.
|
|
32
|
+
def read_val(io)
|
|
33
|
+
io.read
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Returns an empty string as default.
|
|
37
|
+
def sensible_default
|
|
38
|
+
""
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'forwardable'
|
|
2
|
+
|
|
3
|
+
module BinData
|
|
4
|
+
# A BinData object accepts arbitrary parameters. This class ensures that
|
|
5
|
+
# the parameters have been sanitized, and categorizes them according to
|
|
6
|
+
# whether they are BinData::Base.accepted_parameters or are extra.
|
|
7
|
+
class SanitizedParameters
|
|
8
|
+
extend Forwardable
|
|
9
|
+
|
|
10
|
+
# Sanitize the given parameters.
|
|
11
|
+
def initialize(klass, params, *args)
|
|
12
|
+
params ||= {}
|
|
13
|
+
@hash = klass.sanitize_parameters(params, *args)
|
|
14
|
+
@accepted_parameters = {}
|
|
15
|
+
@extra_parameters = {}
|
|
16
|
+
|
|
17
|
+
# partition parameters into known and extra parameters
|
|
18
|
+
@hash.each do |k,v|
|
|
19
|
+
k = k.to_sym
|
|
20
|
+
if v.nil?
|
|
21
|
+
raise ArgumentError, "parameter :#{k} has nil value in #{klass}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if klass.accepted_parameters.include?(k)
|
|
25
|
+
@accepted_parameters[k] = v
|
|
26
|
+
else
|
|
27
|
+
@extra_parameters[k] = v
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
attr_reader :accepted_parameters, :extra_parameters
|
|
33
|
+
|
|
34
|
+
def_delegators :@hash, :[], :has_key?, :include?, :keys
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/bindata/single.rb
CHANGED
|
@@ -6,6 +6,26 @@ module BinData
|
|
|
6
6
|
# as integer, float or string. Only one value can be contained by this
|
|
7
7
|
# object. This value can be read from or written to an IO stream.
|
|
8
8
|
#
|
|
9
|
+
# require 'bindata'
|
|
10
|
+
#
|
|
11
|
+
# obj = BinData::Uint8.new(:initial_value => 42)
|
|
12
|
+
# obj.value #=> 42
|
|
13
|
+
# obj.value = 5
|
|
14
|
+
# obj.value #=> 5
|
|
15
|
+
# obj.clear
|
|
16
|
+
# obj.value #=> 42
|
|
17
|
+
#
|
|
18
|
+
# obj = BinData::Uint8.new(:value => 42)
|
|
19
|
+
# obj.value #=> 42
|
|
20
|
+
# obj.value = 5
|
|
21
|
+
# obj.value #=> 42
|
|
22
|
+
#
|
|
23
|
+
# obj = BinData::Uint8.new(:check_value => 3)
|
|
24
|
+
# obj.read("\005") #=> BinData::ValidityError: value is '5' but expected '3'
|
|
25
|
+
#
|
|
26
|
+
# obj = BinData::Uint8.new(:check_value => lambda { value < 5 })
|
|
27
|
+
# obj.read("\007") #=> BinData::ValidityError: value not as expected
|
|
28
|
+
#
|
|
9
29
|
# == Parameters
|
|
10
30
|
#
|
|
11
31
|
# Parameters may be provided at initialisation to control the behaviour of
|
|
@@ -28,15 +48,15 @@ module BinData
|
|
|
28
48
|
class Single < Base
|
|
29
49
|
# These are the parameters used by this class.
|
|
30
50
|
optional_parameters :initial_value, :value, :check_value
|
|
51
|
+
mutually_exclusive_parameters :initial_value, :value
|
|
31
52
|
|
|
32
|
-
#
|
|
33
|
-
def self.
|
|
34
|
-
|
|
53
|
+
# Single objects don't contain fields so this returns an empty list.
|
|
54
|
+
def self.all_possible_field_names(sanitized_params)
|
|
55
|
+
[]
|
|
35
56
|
end
|
|
36
57
|
|
|
37
58
|
def initialize(params = {}, env = nil)
|
|
38
59
|
super(params, env)
|
|
39
|
-
ensure_mutual_exclusion(:initial_value, :value)
|
|
40
60
|
clear
|
|
41
61
|
end
|
|
42
62
|
|
|
@@ -90,6 +110,11 @@ module BinData
|
|
|
90
110
|
value
|
|
91
111
|
end
|
|
92
112
|
|
|
113
|
+
# Single objects are single_values
|
|
114
|
+
def single_value?
|
|
115
|
+
true
|
|
116
|
+
end
|
|
117
|
+
|
|
93
118
|
# Single objects don't contain fields so this returns an empty list.
|
|
94
119
|
def field_names
|
|
95
120
|
[]
|
|
@@ -149,7 +174,7 @@ module BinData
|
|
|
149
174
|
str
|
|
150
175
|
end
|
|
151
176
|
|
|
152
|
-
|
|
177
|
+
###########################################################################
|
|
153
178
|
# To be implemented by subclasses
|
|
154
179
|
|
|
155
180
|
# Return the string representation that +val+ will take when written.
|
|
@@ -168,6 +193,6 @@ module BinData
|
|
|
168
193
|
end
|
|
169
194
|
|
|
170
195
|
# To be implemented by subclasses
|
|
171
|
-
|
|
196
|
+
###########################################################################
|
|
172
197
|
end
|
|
173
198
|
end
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
require 'bindata/single'
|
|
2
|
+
require 'bindata/struct'
|
|
3
|
+
|
|
4
|
+
module BinData
|
|
5
|
+
# A SingleValue is a declarative way to define a new BinData data type.
|
|
6
|
+
# The data type must contain a single value only. For new data types
|
|
7
|
+
# that contain multiple values see BinData::MultiValue.
|
|
8
|
+
#
|
|
9
|
+
# To define a new data type, set fields as if for MultiValue and add a
|
|
10
|
+
# #get and #set method to extract / convert the data between the fields
|
|
11
|
+
# and the #value of the object.
|
|
12
|
+
#
|
|
13
|
+
# require 'bindata'
|
|
14
|
+
#
|
|
15
|
+
# class PascalString < BinData::SingleValue
|
|
16
|
+
# uint8 :len, :value => lambda { data.length }
|
|
17
|
+
# string :data, :read_length => :len
|
|
18
|
+
#
|
|
19
|
+
# def get
|
|
20
|
+
# self.data
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# def set(v)
|
|
24
|
+
# self.data = v
|
|
25
|
+
# end
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# ps = PascalString.new(:initial_value => "hello")
|
|
29
|
+
# ps.to_s #=> "\005hello"
|
|
30
|
+
# ps.read("\003abcde")
|
|
31
|
+
# ps.value #=> "abc"
|
|
32
|
+
#
|
|
33
|
+
# # Unsigned 24 bit big endian integer
|
|
34
|
+
# class Uint24be < BinData::SingleValue
|
|
35
|
+
# uint8 :byte1
|
|
36
|
+
# uint8 :byte2
|
|
37
|
+
# uint8 :byte3
|
|
38
|
+
#
|
|
39
|
+
# def get
|
|
40
|
+
# (self.byte1 << 16) | (self.byte2 << 8) | self.byte3
|
|
41
|
+
# end
|
|
42
|
+
#
|
|
43
|
+
# def set(v)
|
|
44
|
+
# v = 0 if v < 0
|
|
45
|
+
# v = 0xffffff if v > 0xffffff
|
|
46
|
+
#
|
|
47
|
+
# self.byte1 = (v >> 16) & 0xff
|
|
48
|
+
# self.byte2 = (v >> 8) & 0xff
|
|
49
|
+
# self.byte3 = v & 0xff
|
|
50
|
+
# end
|
|
51
|
+
# end
|
|
52
|
+
#
|
|
53
|
+
# u24 = Uint24be.new
|
|
54
|
+
# u24.read("\x12\x34\x56")
|
|
55
|
+
# "0x%x" % u24.value #=> 0x123456
|
|
56
|
+
#
|
|
57
|
+
# == Parameters
|
|
58
|
+
#
|
|
59
|
+
# SingleValue objects accept all the parameters that BinData::Single do.
|
|
60
|
+
#
|
|
61
|
+
class SingleValue < Single
|
|
62
|
+
|
|
63
|
+
class << self
|
|
64
|
+
|
|
65
|
+
# Register the names of all subclasses of this class.
|
|
66
|
+
def inherited(subclass) #:nodoc:
|
|
67
|
+
register(subclass.name, subclass)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Returns or sets the endianess of numerics used in this stucture.
|
|
71
|
+
# Endianess is applied to the fields of this structure.
|
|
72
|
+
# Valid values are :little and :big.
|
|
73
|
+
def endian(endian = nil)
|
|
74
|
+
@endian ||= nil
|
|
75
|
+
if [:little, :big].include?(endian)
|
|
76
|
+
@endian = endian
|
|
77
|
+
elsif endian != nil
|
|
78
|
+
raise ArgumentError, "unknown value for endian '#{endian}'"
|
|
79
|
+
end
|
|
80
|
+
@endian
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Returns all stored fields. Should only be called by
|
|
84
|
+
# #sanitize_parameters
|
|
85
|
+
def fields
|
|
86
|
+
@fields || []
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Used to define fields for the internal structure.
|
|
90
|
+
def method_missing(symbol, *args)
|
|
91
|
+
name, params = args
|
|
92
|
+
|
|
93
|
+
type = symbol
|
|
94
|
+
name = (name.nil? or name == "") ? nil : name.to_s
|
|
95
|
+
params ||= {}
|
|
96
|
+
|
|
97
|
+
# note that fields are stored in an instance variable not a class var
|
|
98
|
+
@fields ||= []
|
|
99
|
+
|
|
100
|
+
# check that type is known
|
|
101
|
+
if lookup(type, endian).nil?
|
|
102
|
+
raise TypeError, "unknown type '#{type}' for #{self}", caller
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# check that name is okay
|
|
106
|
+
if name != nil
|
|
107
|
+
# check for duplicate names
|
|
108
|
+
@fields.each do |t, n, p|
|
|
109
|
+
if n == name
|
|
110
|
+
raise SyntaxError, "duplicate field '#{name}' in #{self}", caller
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# check that name doesn't shadow an existing method
|
|
115
|
+
if self.instance_methods.include?(name)
|
|
116
|
+
raise NameError.new("", name),
|
|
117
|
+
"field '#{name}' shadows an existing method", caller
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# remember this field. These fields will be recalled upon creating
|
|
122
|
+
# an instance of this class
|
|
123
|
+
@fields.push([type, name, params])
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Returns a sanitized +params+ that is of the form expected
|
|
127
|
+
# by #initialize.
|
|
128
|
+
def sanitize_parameters(params, endian = nil)
|
|
129
|
+
params = params.dup
|
|
130
|
+
|
|
131
|
+
# possibly override endian
|
|
132
|
+
endian = self.endian || endian
|
|
133
|
+
|
|
134
|
+
hash = {}
|
|
135
|
+
hash[:fields] = self.fields
|
|
136
|
+
|
|
137
|
+
unless endian.nil?
|
|
138
|
+
hash[:endian] = endian
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
params[:struct_params] = hash
|
|
142
|
+
|
|
143
|
+
super(params, endian)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# These are the parameters used by this class.
|
|
148
|
+
mandatory_parameter :struct_params
|
|
149
|
+
|
|
150
|
+
def initialize(params = {}, env = nil)
|
|
151
|
+
super(params, env)
|
|
152
|
+
|
|
153
|
+
@struct = BinData::Struct.new(param(:struct_params), create_env)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Forward method calls to the internal struct.
|
|
157
|
+
def method_missing(symbol, *args, &block)
|
|
158
|
+
if @struct.respond_to?(symbol)
|
|
159
|
+
@struct.__send__(symbol, *args, &block)
|
|
160
|
+
else
|
|
161
|
+
super
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
#---------------
|
|
166
|
+
private
|
|
167
|
+
|
|
168
|
+
# Retrieve a sensible default from the internal struct.
|
|
169
|
+
def sensible_default
|
|
170
|
+
get
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Read data into the fields of the internal struct then return the value.
|
|
174
|
+
def read_val(io)
|
|
175
|
+
@struct.read(io)
|
|
176
|
+
get
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Sets +val+ into the fields of the internal struct then returns the
|
|
180
|
+
# string representation.
|
|
181
|
+
def val_to_str(val)
|
|
182
|
+
set(val)
|
|
183
|
+
@struct.to_s
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
###########################################################################
|
|
187
|
+
# To be implemented by subclasses
|
|
188
|
+
|
|
189
|
+
# Extracts the value for this data object from the fields of the
|
|
190
|
+
# internal struct.
|
|
191
|
+
def get
|
|
192
|
+
raise NotImplementedError
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Sets the fields of the internal struct to represent +v+.
|
|
196
|
+
def set(v)
|
|
197
|
+
raise NotImplementedError
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# To be implemented by subclasses
|
|
201
|
+
###########################################################################
|
|
202
|
+
end
|
|
203
|
+
end
|
data/lib/bindata/string.rb
CHANGED
|
@@ -4,6 +4,32 @@ module BinData
|
|
|
4
4
|
# A String is a sequence of bytes. This is the same as strings in Ruby.
|
|
5
5
|
# The issue of character encoding is ignored by this class.
|
|
6
6
|
#
|
|
7
|
+
# require 'bindata'
|
|
8
|
+
#
|
|
9
|
+
# data = "abcdefghij"
|
|
10
|
+
#
|
|
11
|
+
# obj = BinData::String.new(:read_length => 5)
|
|
12
|
+
# obj.read(data)
|
|
13
|
+
# obj.value #=> "abcde"
|
|
14
|
+
#
|
|
15
|
+
# obj = BinData::String.new(:length => 6)
|
|
16
|
+
# obj.read(data)
|
|
17
|
+
# obj.value #=> "abcdef"
|
|
18
|
+
# obj.value = "abcdefghij"
|
|
19
|
+
# obj.value #=> "abcdef"
|
|
20
|
+
# obj.value = "abcd"
|
|
21
|
+
# obj.value #=> "abcd\000\000"
|
|
22
|
+
#
|
|
23
|
+
# obj = BinData::String.new(:length => 6, :trim_value => true)
|
|
24
|
+
# obj.value = "abcd"
|
|
25
|
+
# obj.value #=> "abcd"
|
|
26
|
+
# obj.to_s #=> "abcd\000\000"
|
|
27
|
+
#
|
|
28
|
+
# obj = BinData::String.new(:length => 6, :pad_char => 'A')
|
|
29
|
+
# obj.value = "abcd"
|
|
30
|
+
# obj.value #=> "abcdAA"
|
|
31
|
+
# obj.to_s #=> "abcdAA"
|
|
32
|
+
#
|
|
7
33
|
# == Parameters
|
|
8
34
|
#
|
|
9
35
|
# String objects accept all the params that BinData::Single
|
|
@@ -20,20 +46,41 @@ module BinData
|
|
|
20
46
|
# from the end of the string. The value will
|
|
21
47
|
# not be trimmed when writing.
|
|
22
48
|
class String < Single
|
|
49
|
+
|
|
50
|
+
# Register this class
|
|
51
|
+
register(self.name, self)
|
|
52
|
+
|
|
23
53
|
# These are the parameters used by this class.
|
|
24
|
-
mandatory_parameters :pad_char
|
|
25
54
|
optional_parameters :read_length, :length, :trim_value
|
|
55
|
+
default_parameters :pad_char => "\0"
|
|
56
|
+
mutually_exclusive_parameters :read_length, :length
|
|
57
|
+
mutually_exclusive_parameters :length, :value
|
|
58
|
+
|
|
59
|
+
class << self
|
|
60
|
+
|
|
61
|
+
# Returns a sanitized +params+ that is of the form expected
|
|
62
|
+
# by #initialize.
|
|
63
|
+
def sanitize_parameters(params, *args)
|
|
64
|
+
params = params.dup
|
|
26
65
|
|
|
27
|
-
|
|
28
|
-
|
|
66
|
+
# warn about deprecated param - remove before releasing 1.0
|
|
67
|
+
if params[:initial_length]
|
|
68
|
+
warn ":initial_length is deprecated. Replacing with :read_length"
|
|
69
|
+
params[:read_length] = params.delete(:initial_length)
|
|
70
|
+
end
|
|
29
71
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
72
|
+
# set :pad_char to be a single length character string
|
|
73
|
+
if params.has_key?(:pad_char)
|
|
74
|
+
ch = params[:pad_char]
|
|
75
|
+
ch = ch.respond_to?(:chr) ? ch.chr : ch.to_s
|
|
76
|
+
if ch.length > 1
|
|
77
|
+
raise ArgumentError, ":pad_char must not contain more than 1 char"
|
|
78
|
+
end
|
|
79
|
+
params[:pad_char] = ch
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
super(params, *args)
|
|
83
|
+
end
|
|
37
84
|
end
|
|
38
85
|
|
|
39
86
|
# Overrides value to return the value padded to the desired length or
|
|
@@ -67,27 +114,5 @@ module BinData
|
|
|
67
114
|
def sensible_default
|
|
68
115
|
""
|
|
69
116
|
end
|
|
70
|
-
|
|
71
|
-
# Returns a hash of cleaned +params+. Cleaning means that param
|
|
72
|
-
# values are converted to a desired format.
|
|
73
|
-
def cleaned_params(params)
|
|
74
|
-
new_params = params.dup
|
|
75
|
-
|
|
76
|
-
# warn about deprecated param - remove before releasing 1.0
|
|
77
|
-
if params[:initial_length]
|
|
78
|
-
warn ":initial_length is deprecated. Replacing with :read_length"
|
|
79
|
-
new_params[:read_length] = params[:initial_length]
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# set :pad_char to be a single length character string
|
|
83
|
-
ch = new_params[:pad_char] || 0
|
|
84
|
-
ch = ch.respond_to?(:chr) ? ch.chr : ch.to_s
|
|
85
|
-
if ch.length > 1
|
|
86
|
-
raise ArgumentError, ":pad_char must not contain more than 1 char"
|
|
87
|
-
end
|
|
88
|
-
new_params[:pad_char] = ch
|
|
89
|
-
|
|
90
|
-
new_params
|
|
91
|
-
end
|
|
92
117
|
end
|
|
93
118
|
end
|