packable 1.3.9 → 1.3.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.rdoc +7 -7
- data/lib/packable/extensions/integer.rb +1 -1
- data/lib/packable/extensions/io.rb +9 -10
- data/lib/packable/extensions/proc.rb +2 -2
- data/lib/packable/mixin.rb +7 -7
- data/lib/packable/packers.rb +6 -7
- data/lib/packable/version.rb +1 -1
- data/test/packing_doc_test.rb +13 -19
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3153716400e2f39421e6eba85ceb0d83a665f4efe1088503953b3c90a69c4781
|
4
|
+
data.tar.gz: 736319d061f9bed0306f16a27c3391aa8675645970fd046809c21a238d7cb0a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e626328601bc4f5aa2a7e933b4e3e8bf894bff2afc0a99b37a0efbc7a3b599f7dc5c96de18502ef38bfefb4989e3093518951d80b61c6cc538572afe4a32323
|
7
|
+
data.tar.gz: f6e56d03ffc9b20bb739d478c925852022fd834e365a30c4c6eeacaebd238fdc02811af04451fcbade176af528a5d99f339b45d263b4a6ca0c76631ff4b8c181
|
data/README.rdoc
CHANGED
@@ -48,7 +48,7 @@ Add GitHub to your gem sources (if you haven't already):
|
|
48
48
|
Get the gem:
|
49
49
|
|
50
50
|
sudo gem install marcandre-packable
|
51
|
-
|
51
|
+
|
52
52
|
That's it! Simply <tt>require 'packable'</tt> in your code to use it.
|
53
53
|
|
54
54
|
== Compatibility
|
@@ -131,14 +131,14 @@ The following shortcuts and defaults are built-in the library:
|
|
131
131
|
:byte => :bytes=>1
|
132
132
|
:unsigned_long => :bytes=>4, :signed=>false
|
133
133
|
:unsigned_short => :bytes=>2, :signed=>false
|
134
|
-
|
135
|
-
=== Float
|
134
|
+
|
135
|
+
=== Float
|
136
136
|
:merge_all => :precision => :single, :endian => :big
|
137
137
|
:default => :float
|
138
138
|
:double => :precision => :double
|
139
139
|
:float => {}
|
140
|
-
|
141
|
-
=== String
|
140
|
+
|
141
|
+
=== String
|
142
142
|
:merge_all => :fill => " "
|
143
143
|
|
144
144
|
== Files and StringIO
|
@@ -180,7 +180,7 @@ and unpacking on +read_packed+. For example:
|
|
180
180
|
|
181
181
|
class MyHeader < Struct.new(:signature, :nb_blocks)
|
182
182
|
include Packable
|
183
|
-
|
183
|
+
|
184
184
|
def write_packed(packedio, options)
|
185
185
|
packedio << [signature, {:bytes=>3}] << [nb_blocks, :short]
|
186
186
|
end
|
@@ -238,7 +238,7 @@ A final note to say that packers are inherited in some way. For instance one cou
|
|
238
238
|
io.read(klass)
|
239
239
|
end
|
240
240
|
end
|
241
|
-
|
241
|
+
|
242
242
|
[42, MyHeader.new("Wow", 1)].pack(:with_class, :with_class).unpack(:with_class, :with_class) ===> [42, MyHeader.new("Wow", 1)]
|
243
243
|
|
244
244
|
= License
|
@@ -3,7 +3,7 @@ module Packable
|
|
3
3
|
module Integer #:nodoc:
|
4
4
|
NEEDS_REVERSAL = Hash.new{|h, endian| raise ArgumentError, "Endian #{endian} is not valid. It must be one of #{h.keys.join(', ')}"}.
|
5
5
|
merge!(:little => true, :big => false, :network => false, :native => "*\x00\x00\x00".unpack('L').first == 42).freeze
|
6
|
-
|
6
|
+
|
7
7
|
def self.included(base)
|
8
8
|
base.class_eval do
|
9
9
|
include Packable
|
@@ -9,7 +9,7 @@ module Packable
|
|
9
9
|
base.alias_method_chain :write, :packing
|
10
10
|
base.alias_method_chain :each, :packing
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# Returns the change in io.pos caused by the block.
|
14
14
|
# Has nothing to do with packing, but quite helpful and so simple...
|
15
15
|
def pos_change(&block)
|
@@ -33,11 +33,11 @@ module Packable
|
|
33
33
|
r.stream = self
|
34
34
|
r >> options
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
# Returns (or yields) a modified IO object that will always pack/unpack when writing/reading.
|
38
38
|
def packed
|
39
39
|
packedio = clone
|
40
|
-
packedio.set_encoding("ascii-8bit") if packedio.respond_to? :set_encoding
|
40
|
+
packedio.set_encoding("ascii-8bit") if packedio.respond_to? :set_encoding
|
41
41
|
class << packedio
|
42
42
|
def << (arg)
|
43
43
|
arg = [arg, :default] unless arg.instance_of?(::Array)
|
@@ -53,17 +53,17 @@ module Packable
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def each_with_packing(*options, &block)
|
56
|
-
return each_without_packing(*options, &block) if (Integer === options.first) || (String === options.first)
|
56
|
+
return each_without_packing(*options, &block) if options.empty? || (Integer === options.first) || (String === options.first)
|
57
57
|
return Enumerator.new(self, :each_with_packing, *options) unless block_given?
|
58
58
|
yield read(*options) until eof?
|
59
59
|
end
|
60
60
|
|
61
61
|
def write_with_packing(*arg)
|
62
|
-
(arg.length
|
62
|
+
(arg.length <= 1) ? write_without_packing(*arg) : pack_and_write(*arg)
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
def read_with_packing(*arg)
|
66
|
-
return read_without_packing(*arg) if arg.
|
66
|
+
return read_without_packing(*arg) if arg.empty? || arg.first.nil? || arg.first.is_a?(Numeric)
|
67
67
|
values = Packable::Packers.to_class_option_list(*arg).map do |klass, options, original|
|
68
68
|
if options[:read_packed]
|
69
69
|
options[:read_packed].call(self)
|
@@ -73,7 +73,7 @@ module Packable
|
|
73
73
|
end
|
74
74
|
return values.size > 1 ? values : values.first
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
# returns a string of exactly n bytes, or else raises an EOFError
|
78
78
|
def read_exactly(n)
|
79
79
|
return "" if n.zero?
|
@@ -81,7 +81,7 @@ module Packable
|
|
81
81
|
raise EOFError if s.nil? || s.length < n
|
82
82
|
s
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
def pack_and_write(*arg)
|
86
86
|
original_pos = pos
|
87
87
|
Packable::Packers.to_object_option_list(*arg).each do |obj, options|
|
@@ -94,7 +94,6 @@ module Packable
|
|
94
94
|
pos - original_pos
|
95
95
|
end
|
96
96
|
|
97
|
-
|
98
97
|
end
|
99
98
|
end
|
100
99
|
end
|
data/lib/packable/mixin.rb
CHANGED
@@ -5,7 +5,7 @@ require 'stringio'
|
|
5
5
|
module Packable
|
6
6
|
def self.included(base) #:nodoc:
|
7
7
|
base.class_eval do
|
8
|
-
class << self
|
8
|
+
class << self
|
9
9
|
include PackersClassMethod
|
10
10
|
include ClassMethods
|
11
11
|
end
|
@@ -26,18 +26,18 @@ module Packable
|
|
26
26
|
#
|
27
27
|
def packers
|
28
28
|
yield packers if block_given?
|
29
|
-
Packers.for(self)
|
29
|
+
Packers.for(self)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
module ClassMethods
|
33
|
+
module ClassMethods
|
34
34
|
|
35
35
|
def unpack(s, options = :default)
|
36
36
|
return s.unpack(options).first if options.is_a? String
|
37
37
|
StringIO.new(s).packed.read(self, options)
|
38
38
|
end
|
39
|
-
|
40
|
-
# Default +read_packed+ calls either the instance method <tt>read_packed</tt> or the
|
39
|
+
|
40
|
+
# Default +read_packed+ calls either the instance method <tt>read_packed</tt> or the
|
41
41
|
# class method +unpack_string+. Choose:
|
42
42
|
# * define a class method +read_packed+ that returns the newly read object
|
43
43
|
# * define an instance method +read_packed+ which reads the io into +self+
|
@@ -57,5 +57,5 @@ module Packable
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
end
|
61
|
-
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/packable/packers.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Packable
|
2
|
-
|
2
|
+
|
3
3
|
# Packers for any packable class.
|
4
4
|
class Packers < Hash
|
5
5
|
SPECIAL = [:default, :merge_all].freeze
|
6
|
-
|
6
|
+
|
7
7
|
# Usage:
|
8
8
|
# PackableClass.packers.set :shortcut, :option => value, ...
|
9
9
|
# PackableClass.packers { |p| p.set...; p.set... }
|
@@ -42,7 +42,7 @@ module Packable
|
|
42
42
|
end
|
43
43
|
|
44
44
|
@@packers_for_class = Hash.new{|h, klass| h[klass] = Packers.new(klass)}
|
45
|
-
|
45
|
+
|
46
46
|
# Returns the configuration for the given +klass+.
|
47
47
|
def self.for(klass)
|
48
48
|
@@packers_for_class[klass]
|
@@ -59,7 +59,7 @@ module Packable
|
|
59
59
|
end
|
60
60
|
r
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
def self.to_object_option_list(*arg) #:nodoc:
|
64
64
|
r=[]
|
65
65
|
until arg.empty? do
|
@@ -85,7 +85,6 @@ module Packable
|
|
85
85
|
raise "Couldn't find packing option #{key}"
|
86
86
|
end
|
87
87
|
|
88
|
-
|
89
88
|
end
|
90
89
|
|
91
90
|
# Use to capture the blocks given to read/write
|
@@ -103,5 +102,5 @@ module Packable
|
|
103
102
|
options[:write_packed] = block.unbind
|
104
103
|
end
|
105
104
|
end
|
106
|
-
|
107
|
-
end
|
105
|
+
|
106
|
+
end
|
data/lib/packable/version.rb
CHANGED
data/test/packing_doc_test.rb
CHANGED
@@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
|
2
2
|
# Warning: ugly...
|
3
3
|
class MyHeader < Struct.new(:signature, :nb_blocks)
|
4
4
|
include Packable
|
5
|
-
|
5
|
+
|
6
6
|
def write_packed(packedio, options)
|
7
7
|
packedio << [signature, {:bytes=>3}] << [nb_blocks, :short]
|
8
8
|
end
|
@@ -10,19 +10,17 @@ class MyHeader < Struct.new(:signature, :nb_blocks)
|
|
10
10
|
def read_packed(packedio, options)
|
11
11
|
self.signature, self.nb_blocks = packedio >> [String, {:bytes => 3}] >> :short
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def ohoh
|
15
15
|
:ahah
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
class PackableDocTest < Minitest::Test
|
19
|
+
class PackableDocTest < Minitest::Test
|
21
20
|
def test_doc
|
22
21
|
|
23
22
|
assert_equal [1,2,3], StringIO.new("\000\001\000\002\000\003").each(:short).to_a
|
24
23
|
|
25
|
-
|
26
24
|
String.packers.set :flv_signature, :bytes => 3, :fill => "FLV"
|
27
25
|
|
28
26
|
assert_equal "xFL", "x".pack(:flv_signature)
|
@@ -31,12 +29,12 @@ class PackableDocTest < Minitest::Test
|
|
31
29
|
p.set :merge_all, :fill => "*" # Unless explicitly specified, :fill will now be "*"
|
32
30
|
p.set :default, :bytes => 8 # If no option is given, this will act as default
|
33
31
|
end
|
34
|
-
|
32
|
+
|
35
33
|
assert_equal "ab******", "ab".pack
|
36
34
|
assert_equal "ab**", "ab".pack(:bytes=>4)
|
37
35
|
assert_equal "ab", "ab".pack(:fill => "!")
|
38
36
|
assert_equal "ab!!", "ab".pack(:fill => "!", :bytes => 4)
|
39
|
-
|
37
|
+
|
40
38
|
String.packers do |p|
|
41
39
|
p.set :creator, :bytes => 4
|
42
40
|
p.set :app_type, :creator
|
@@ -44,9 +42,9 @@ class PackableDocTest < Minitest::Test
|
|
44
42
|
p.set :merge_all, :fill => " "
|
45
43
|
p.set :eigth_bytes, :bytes => 8
|
46
44
|
end
|
47
|
-
|
45
|
+
|
48
46
|
assert_equal "hello".pack(:app_type), "hell"
|
49
|
-
|
47
|
+
|
50
48
|
assert_equal [["sig", 1, "hello, w"]]*4,
|
51
49
|
[
|
52
50
|
lambda { |io| io >> :flv_signature >> Integer >> [String, {:bytes => 8}] },
|
@@ -54,8 +52,7 @@ class PackableDocTest < Minitest::Test
|
|
54
52
|
lambda { |io| io.read(:flv_signature, Integer, String, {:bytes => 8}) },
|
55
53
|
lambda { |io| [io.read(:flv_signature), io.read(Integer), io.read(String, {:bytes => 8})] }
|
56
54
|
].map {|proc| proc.call(StringIO.new("sig\000\000\000\001hello, world"))}
|
57
|
-
|
58
|
-
|
55
|
+
|
59
56
|
ex = "xFL\000\000\000BHello "
|
60
57
|
[
|
61
58
|
lambda { |io| io << "x".pack(:flv_signature) << 66.pack << "Hello".pack(:bytes => 8)}, # returns io
|
@@ -68,31 +65,28 @@ class PackableDocTest < Minitest::Test
|
|
68
65
|
ios.rewind
|
69
66
|
assert_equal ex, ios.read, "With #{proc}"
|
70
67
|
end
|
71
|
-
|
68
|
+
|
72
69
|
#insure StringIO class is not affected
|
73
70
|
ios = StringIO.new
|
74
71
|
ios.packed
|
75
72
|
ios << 66
|
76
73
|
ios.rewind
|
77
74
|
assert_equal "66", ios.read
|
78
|
-
|
79
|
-
|
75
|
+
|
80
76
|
String.packers.set :length_encoded do |packer|
|
81
77
|
packer.write { |io| io << length << self }
|
82
78
|
packer.read { |io| io.read(io.read(Integer)) }
|
83
79
|
end
|
84
|
-
|
80
|
+
|
85
81
|
assert_equal "\000\000\000\006hello!", "hello!".pack(:length_encoded)
|
86
82
|
assert_equal ["this", "is", "great!"], ["this", "is", "great!"].pack(*[:length_encoded]*3).unpack(*[:length_encoded]*3)
|
87
|
-
|
83
|
+
|
88
84
|
h = MyHeader.new("FLV", 65)
|
89
85
|
assert_equal "FLV\000A", h.pack
|
90
86
|
h2, = StringIO.new("FLV\000A") >> MyHeader
|
91
87
|
assert_equal h, h2
|
92
88
|
assert_equal h.ohoh, h2.ohoh
|
93
89
|
|
94
|
-
|
95
|
-
|
96
90
|
Object.packers.set :with_class do |packer|
|
97
91
|
packer.write { |io| io << [self.class.name, :length_encoded] << self }
|
98
92
|
packer.read do |io|
|
@@ -103,4 +97,4 @@ class PackableDocTest < Minitest::Test
|
|
103
97
|
ar = [42, MyHeader.new("FLV", 65)]
|
104
98
|
assert_equal ar, ar.pack(:with_class, :with_class).unpack(:with_class, :with_class)
|
105
99
|
end
|
106
|
-
end
|
100
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc-André Lafortune
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backports
|
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
115
|
version: '0'
|
116
116
|
requirements: []
|
117
117
|
rubyforge_project:
|
118
|
-
rubygems_version: 2.
|
118
|
+
rubygems_version: 2.7.7
|
119
119
|
signing_key:
|
120
120
|
specification_version: 4
|
121
121
|
summary: Extensive packing and unpacking capabilities
|