marcandre-packable 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 1
2
+ :patch: 2
3
3
  :major: 1
4
4
  :minor: 3
@@ -19,9 +19,12 @@ module Packable
19
19
  end
20
20
 
21
21
  module ClassMethods #:nodoc:
22
- ENDIAN_TO_FORMAT = Hash.new{|h, endian| raise ArgumentError, "Endian #{endian} is not valid. It must be one of #{h.keys.join(', ')}"}.
22
+ ENDIAN_TO_FORMAT = Hash.new{|h, endian| raise ArgumentError, "Endian #{endian} is not valid. It must be one of #{h.keys.join(', ')}."}.
23
23
  merge!(:big => "G", :network => "G", :little => "E", :native => "F").freeze
24
-
24
+
25
+ PRECISION = Hash.new{|h, precision| raise ArgumentError, "Precision #{precision} is not valid. It must be one of #{h.keys.join(', ')}."}.
26
+ merge!(:single => 4, :double => 8).freeze
27
+
25
28
  def pack_option_to_format(options)
26
29
  format = ENDIAN_TO_FORMAT[options[:endian]]
27
30
  format.downcase! if options[:precision] == :single
@@ -29,9 +32,8 @@ module Packable
29
32
  end
30
33
 
31
34
  def read_packed(io, options)
32
- io.read({:single => 4, :double => 8}[options[:precision]]) \
33
- .unpack(pack_option_to_format(options)) \
34
- .first
35
+ s = io.read_exactly(PRECISION[options[:precision]])
36
+ s && s.unpack(pack_option_to_format(options)).first
35
37
  end
36
38
  end
37
39
 
@@ -74,6 +74,14 @@ module Packable
74
74
  return values.size > 1 ? values : values.first
75
75
  end
76
76
 
77
+ # returns a string of exactly n bytes, or else raises an EOFError
78
+ def read_exactly(n)
79
+ return "" if n.zero?
80
+ s = read_without_packing(n)
81
+ raise EOFError if s.nil? || s.length < n
82
+ s
83
+ end
84
+
77
85
  def pack_and_write(*arg)
78
86
  original_pos = pos
79
87
  Packable::Packers.to_object_option_list(*arg).each do |obj, options|
@@ -21,6 +21,8 @@ module Packable
21
21
  def unpack_with_long_form(*arg)
22
22
  return unpack_without_long_form(*arg) if arg.first.is_a? String
23
23
  StringIO.new(self).packed.read(*arg)
24
+ rescue EOFError
25
+ nil
24
26
  end
25
27
 
26
28
  module ClassMethods #:nodoc:
@@ -52,8 +52,8 @@ module Packable
52
52
  obj
53
53
  else
54
54
  len = options[:bytes]
55
- s = len ? io.read(len) : io.read
56
- unpack_string(s, options)
55
+ s = len ? io.read_exactly(len) : io.read
56
+ unpack_string(s, options) unless s.nil?
57
57
  end
58
58
  end
59
59
 
data/packable.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{packable}
5
- s.version = "1.3.1"
5
+ s.version = "1.3.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Marc-Andr\303\251 Lafortune"]
9
- s.date = %q{2009-08-19}
9
+ s.date = %q{2009-08-20}
10
10
  s.description = %q{If you need to do read and write binary data, there is of course <Array::pack and String::unpack The packable library makes (un)packing nicer, smarter and more powerful.}
11
11
  s.email = %q{github@marc-andre.ca}
12
12
  s.extra_rdoc_files = [
data/test/packing_test.rb CHANGED
@@ -76,6 +76,24 @@ class TestingPack < Test::Unit::TestCase
76
76
  assert_raise(TypeError) {"".unpack(42, :short)}
77
77
  end
78
78
 
79
+ context "Reading beyond the eof" do
80
+ should "raises an EOFError when reading" do
81
+ ["", "x"].each do |s|
82
+ io = StringIO.new(s)
83
+ assert_raise(EOFError) {io.read(:double)}
84
+ assert_raise(EOFError) {io.read(:short)}
85
+ assert_raise(EOFError) {io.read(String, :bytes => 4)}
86
+ end
87
+ end
88
+
89
+ should "return nil for unpacking" do
90
+ assert_nil "".unpack(:double)
91
+ assert_nil "".unpack(:short)
92
+ assert_nil "x".unpack(:double)
93
+ assert_nil "x".unpack(:short)
94
+ end
95
+ end
96
+
79
97
  context "Filters" do
80
98
  context "for Object" do
81
99
  Object.packers.set :generic_class_writer do |packer|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marcandre-packable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Marc-Andr\xC3\xA9 Lafortune"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-19 00:00:00 -07:00
12
+ date: 2009-08-20 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency