packable 1.3.8 → 1.3.14

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
- SHA1:
3
- metadata.gz: 9ff119e7cc22b81b365a6b56bfea0f5361cd4171
4
- data.tar.gz: 76cff9e8574909266778c4164035e54e41319439
2
+ SHA256:
3
+ metadata.gz: 010ee6e2262aa7ea8e3bccde2fa58a80afd1ba4356678c0456a638091cc50f97
4
+ data.tar.gz: 357c44f3a0252815976df5c4ac2260dabe87fb4d907546d1d8380fb37f714ae5
5
5
  SHA512:
6
- metadata.gz: 771b79907fda443f469cdbadcdc05f1740c1c0666bb55ed6cec5589d9061df758a0a4b4c7f0929adb0375422172bddd61eb2b2a11cf5654c361d67b2011ea103
7
- data.tar.gz: 1cd0a39beeb41566bc721d25ff64abe2fa7401bb0e39544893f81e3da3b91dcc4ff0e2a9c306521fd1dec6ef631e416a06fbd2cbabe35fb0cf7800ffbc9355d7
6
+ metadata.gz: 34a8168ef33d77d73dfd27156db34a95e0787900611d5c88878c07953239d80a5e4ec57002057f044ca2fcfa3879295de67206f50e730395c264f84d0cbdcacd
7
+ data.tar.gz: 8619bf57c88279a4d5a852b6a3a7810495881665da8e160ffb7bbcd7b3fc7920e18ade6f50641d19ae341be5fd65447608f06260bc9f7543231a6e7f336d9289
@@ -1,7 +1,7 @@
1
- *Note*: SciRuby are taking over maintenance for this library: https://github.com/SciRuby/packable
2
-
3
1
  = Packable Library - Intro
4
2
 
3
+ *NOTE:* This library monkeypatches core classes and wa designed for Ruby 1.8 & 1.9. A redesign using refinements would be much better. Minimal support is provided.
4
+
5
5
  If you need to do read and write binary data, there is of course <tt>Array::pack</tt> and <tt>String::unpack</tt>.
6
6
  The packable library makes (un)packing nicer, smarter and more powerful.
7
7
  In case you are wondering why on earth someone would want to do serious (un)packing when YAML & XML are built-in:
@@ -26,6 +26,7 @@ The method +each+ also accepts packing options:
26
26
  StringIO.new("\000\001\000\002\000\003").each(:short).to_a ===> [1,2,3]
27
27
  === Custom classes
28
28
  It's easy to make you own classes (un)packable. All the previous goodies are thus available:
29
+
29
30
  File.open("great_flick.flv") do |f|
30
31
  head = f.read(FLV::Header)
31
32
  f.each(FLV::Tag) do |tag|
@@ -48,7 +49,7 @@ Add GitHub to your gem sources (if you haven't already):
48
49
  Get the gem:
49
50
 
50
51
  sudo gem install marcandre-packable
51
-
52
+
52
53
  That's it! Simply <tt>require 'packable'</tt> in your code to use it.
53
54
 
54
55
  == Compatibility
@@ -97,7 +98,7 @@ When unpacking, it is necessary to specify the class in addition to any option,
97
98
 
98
99
  It's easy to add shortcuts for easier (un)packing:
99
100
 
100
- String.packers.set :flv_signature, :bytes => 3, :fill => "FLV"
101
+ String.packers.set :flv_signature, :bytes => 3, :fill => "FLV"
101
102
 
102
103
  "x".pack(:flv_signature) ===> "xFL"
103
104
 
@@ -131,14 +132,14 @@ The following shortcuts and defaults are built-in the library:
131
132
  :byte => :bytes=>1
132
133
  :unsigned_long => :bytes=>4, :signed=>false
133
134
  :unsigned_short => :bytes=>2, :signed=>false
134
-
135
- === Float
135
+
136
+ === Float
136
137
  :merge_all => :precision => :single, :endian => :big
137
138
  :default => :float
138
139
  :double => :precision => :double
139
140
  :float => {}
140
-
141
- === String
141
+
142
+ === String
142
143
  :merge_all => :fill => " "
143
144
 
144
145
  == Files and StringIO
@@ -180,7 +181,7 @@ and unpacking on +read_packed+. For example:
180
181
 
181
182
  class MyHeader < Struct.new(:signature, :nb_blocks)
182
183
  include Packable
183
-
184
+
184
185
  def write_packed(packedio, options)
185
186
  packedio << [signature, {:bytes=>3}] << [nb_blocks, :short]
186
187
  end
@@ -238,7 +239,7 @@ A final note to say that packers are inherited in some way. For instance one cou
238
239
  io.read(klass)
239
240
  end
240
241
  end
241
-
242
+
242
243
  [42, MyHeader.new("Wow", 1)].pack(:with_class, :with_class).unpack(:with_class, :with_class) ===> [42, MyHeader.new("Wow", 1)]
243
244
 
244
245
  = License
@@ -1,5 +1,6 @@
1
1
  require "packable/version"
2
- require 'backports'
2
+ require 'backports/tools/alias_method_chain'
3
+ require 'backports/rails/module'
3
4
  require_relative 'packable/packers'
4
5
  require_relative 'packable/mixin'
5
6
  [Object, Array, String, Integer, Float, IO, Proc].each do |klass|
@@ -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,26 @@ module Packable
9
9
  base.alias_method_chain :write, :packing
10
10
  base.alias_method_chain :each, :packing
11
11
  end
12
-
12
+
13
+ # Methods supported by seekable streams.
14
+ SEEKABLE_API = %i[pos pos= seek rewind].freeze
15
+
16
+ # Check whether can seek without errors.
17
+ def seekable?
18
+ if !defined?(@seekable)
19
+ @seekable =
20
+ # The IO class throws an exception at runtime if we try to change
21
+ # position on a non-regular file.
22
+ if respond_to?(:stat)
23
+ stat.file?
24
+ else
25
+ # Duck-type the rest of this.
26
+ SEEKABLE_API.all? { |m| respond_to?(m) }
27
+ end
28
+ end
29
+ @seekable
30
+ end
31
+
13
32
  # Returns the change in io.pos caused by the block.
14
33
  # Has nothing to do with packing, but quite helpful and so simple...
15
34
  def pos_change(&block)
@@ -33,11 +52,11 @@ module Packable
33
52
  r.stream = self
34
53
  r >> options
35
54
  end
36
-
55
+
37
56
  # Returns (or yields) a modified IO object that will always pack/unpack when writing/reading.
38
57
  def packed
39
58
  packedio = clone
40
- packedio.set_encoding("ascii-8bit") if packedio.respond_to? :set_encoding
59
+ packedio.set_encoding("ascii-8bit") if packedio.respond_to? :set_encoding
41
60
  class << packedio
42
61
  def << (arg)
43
62
  arg = [arg, :default] unless arg.instance_of?(::Array)
@@ -53,17 +72,17 @@ module Packable
53
72
  end
54
73
 
55
74
  def each_with_packing(*options, &block)
56
- return each_without_packing(*options, &block) if (Integer === options.first) || (String === options.first)
75
+ return each_without_packing(*options, &block) if options.empty? || (Integer === options.first) || (String === options.first) || !seekable?
57
76
  return Enumerator.new(self, :each_with_packing, *options) unless block_given?
58
77
  yield read(*options) until eof?
59
78
  end
60
79
 
61
80
  def write_with_packing(*arg)
62
- (arg.length == 1) ? write_without_packing(*arg) : pack_and_write(*arg)
81
+ (arg.length <= 1 || !seekable?) ? write_without_packing(*arg) : pack_and_write(*arg)
63
82
  end
64
-
83
+
65
84
  def read_with_packing(*arg)
66
- return read_without_packing(*arg) if arg.length == 0 || arg.first.nil? || arg.first.is_a?(Numeric)
85
+ return read_without_packing(*arg) if arg.empty? || arg.first.nil? || arg.first.is_a?(Numeric) || !seekable?
67
86
  values = Packable::Packers.to_class_option_list(*arg).map do |klass, options, original|
68
87
  if options[:read_packed]
69
88
  options[:read_packed].call(self)
@@ -73,7 +92,7 @@ module Packable
73
92
  end
74
93
  return values.size > 1 ? values : values.first
75
94
  end
76
-
95
+
77
96
  # returns a string of exactly n bytes, or else raises an EOFError
78
97
  def read_exactly(n)
79
98
  return "" if n.zero?
@@ -81,7 +100,7 @@ module Packable
81
100
  raise EOFError if s.nil? || s.length < n
82
101
  s
83
102
  end
84
-
103
+
85
104
  def pack_and_write(*arg)
86
105
  original_pos = pos
87
106
  Packable::Packers.to_object_option_list(*arg).each do |obj, options|
@@ -94,7 +113,6 @@ module Packable
94
113
  pos - original_pos
95
114
  end
96
115
 
97
-
98
116
  end
99
117
  end
100
118
  end
@@ -6,11 +6,11 @@ module Packable
6
6
  Object.send(:define_method, :__temp_bound_method, &self)
7
7
  Object.instance_method(:__temp_bound_method)
8
8
  end
9
-
9
+
10
10
  # Shortcut for <tt>unbind.bind(to)</tt>
11
11
  def bind(to)
12
12
  unbind.bind(to)
13
13
  end
14
14
  end
15
15
  end
16
- end
16
+ end
@@ -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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Packable
2
- VERSION = "1.3.8"
2
+ VERSION = "1.3.14"
3
3
  end
@@ -6,6 +6,7 @@ require 'packable/version'
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "packable"
8
8
  gem.version = Packable::VERSION
9
+ gem.homepage = "https://github.com/marcandre/packable"
9
10
  gem.authors = ["Marc-André Lafortune"]
10
11
  gem.email = ["github@marc-andre.ca"]
11
12
  gem.description = %q{If you need to do read and write binary data, there is of course <Array::pack and String::unpack\n The packable library makes (un)packing nicer, smarter and more powerful.\n}
@@ -16,6 +17,7 @@ Gem::Specification.new do |gem|
16
17
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
19
  gem.require_paths = ["lib"]
20
+ gem.required_ruby_version = '>= 1.8.7'
19
21
  gem.add_runtime_dependency 'backports'
20
22
  gem.add_development_dependency 'minitest'
21
23
  gem.add_development_dependency 'shoulda'
@@ -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.8
4
+ version: 1.3.14
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: 2016-02-22 00:00:00.000000000 Z
11
+ date: 2020-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backports
@@ -107,15 +107,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: 1.8.7
111
111
  required_rubygems_version: !ruby/object:Gem::Requirement
112
112
  requirements:
113
113
  - - ">="
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
117
- rubyforge_project:
118
- rubygems_version: 2.2.2
117
+ rubygems_version: 3.1.2
119
118
  signing_key:
120
119
  specification_version: 4
121
120
  summary: Extensive packing and unpacking capabilities
@@ -123,4 +122,3 @@ test_files:
123
122
  - test/packing_doc_test.rb
124
123
  - test/packing_test.rb
125
124
  - test/test_helper.rb
126
- has_rdoc: