Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added :endian => :native for Integers and Floats (thanks to Jay Daley)

Raises an exception if :endian is not one of :little, :big, :network or :native
Added some tests for Bignum
  • Loading branch information...
commit eeea3683dee325f60f6dc215b36c4f1e7fce33e6 1 parent 33f47b9
@marcandre authored
View
5 CHANGELOG.rdoc
@@ -1,5 +1,10 @@
= Packable --- History
+== Version 1.3 - April 8, 2009
+Added :endian => :native for Integers and Floats (thanks to Jay Daley)
+Raises an exception if :endian is not one of :little, :big, :network or :native
+Added some tests for Bignum
+
== Version 1.2 - April 2nd, 2009
Compatible with ruby 1.9.1.
The 'jungle_survival_kit' is now in its own 'backports' gem.
View
4 README.rdoc
@@ -73,12 +73,12 @@ These are the options for core types:
=== Integer
[+bytes+] Number of bytes (default is 4) to use.
-[+endian+] Either <tt>:big</tt> (or :network, default) or <tt>:little</tt>.
+[+endian+] Either <tt>:big</tt> (or <tt>:network</tt>, default), <tt>:little</tt> or <tt>:native</tt>.
[+signed+] Either +true+ (default) or +false+. This will make a difference only when unpacking.
=== Float
[+precision+] Either <tt>:single</tt> (default) or <tt>:double</tt>.
-[+endian+] Either <tt>:big</tt> (or :network, default) or <tt>:little</tt>.
+[+endian+] Either <tt>:big</tt> (or <tt>:network</tt>, default), <tt>:little</tt> or <tt>:native</tt>.
=== String
[+bytes+] Total length (default is the full length)
View
5 lib/packable/extensions/float.rb
@@ -19,8 +19,11 @@ def write_packed(io, options)
end
module ClassMethods #:nodoc:
+ ENDIAN_TO_FORMAT = Hash.new{|h, endian| raise ArgumentError, "Endian #{endian} is not valid. It must be one of #{h.keys.join(', ')}"}.
+ merge!(:big => "G", :network => "G", :little => "E", :native => "F").freeze
+
def pack_option_to_format(options)
- format = {:big => "G", :network => "G", :little => "E"}[options[:endian]]
+ format = ENDIAN_TO_FORMAT[options[:endian]]
format.downcase! if options[:precision] == :single
format
end
View
7 lib/packable/extensions/integer.rb
@@ -1,6 +1,9 @@
module Packable
module Extensions #:nodoc:
module Integer #:nodoc:
+ NEEDS_REVERSAL = Hash.new{|h, endian| raise ArgumentError, "Endian #{endian} is not valid. It must be one of #{h.keys.join(', ')}"}.
+ merge!(:little => true, :big => false, :network => false, :native => "*\x00\x00\x00".unpack('L').first == 42).freeze
+
def self.included(base)
base.class_eval do
include Packable
@@ -25,13 +28,13 @@ def write_packed(io, options)
val >>= 8
byte.chr
end
- chars.reverse! unless options[:endian] == :little
+ chars.reverse! unless NEEDS_REVERSAL[options[:endian]]
io << chars.join
end
module ClassMethods #:nodoc:
def unpack_string(s,options)
- s = s.reverse if options[:endian] == :little
+ s = s.reverse if NEEDS_REVERSAL[options[:endian]]
r = 0
s.each_byte {|b| r = (r << 8) + b}
r -= 1 << (8 * options[:bytes]) if options[:signed] && (1 == r >> (8 * options[:bytes] - 1))
View
14 test/packing_test.rb
@@ -47,6 +47,20 @@ def test_integer
assert_equal 258, Integer.unpack("\002\001\000", :bytes => 3, :endian => :little)
assert_equal (1<<24)-1, -1.pack(:bytes => 3).unpack(Integer, :bytes => 3, :signed => false)
assert_equal -1, -1.pack(:bytes => 3).unpack(Integer, :bytes => 3, :signed => true)
+ assert_equal 42, 42.pack('L').unpack(Integer, :bytes => 4, :endian => :native)
+ assert_raise(ArgumentError){ 42.pack(:endian => "Geronimo")}
+ end
+
+ def test_bignum
+ assert_equal 1.pack(:long), ((1 << 69) + 1).pack(:long)
+ assert_equal "*" + ("\000" * 15), (42 << (8*15)).pack(:bytes => 16)
+ assert_equal 42 << (8*15), (42 << (8*15)).pack(:bytes => 16).unpack(Integer, :bytes => 16)
+ assert_equal 42 << (8*15), (42 << (8*15)).pack(:bytes => 16).unpack(Bignum, :bytes => 16)
+ end
+
+ def test_float
+ assert_equal Math::PI.pack(:precision => :double, :endian => :native), Math::PI.pack('F')
+ assert_raise(ArgumentError){ Math::PI.pack(:endian => "Geronimo")}
end
def test_io
Please sign in to comment.
Something went wrong with that request. Please try again.