Class: BitGirder::Io::BinaryConverter
- Inherits:
-
BitGirderClass
- Object
- BitGirderClass
- BitGirder::Io::BinaryConverter
- Defined in:
- lib/bitgirder/io.rb
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(*argv) ⇒ BinaryConverter
constructor
Set @plat_order as an instance variable instead of as a class constant.
- #read_bigdec(s) ⇒ Object
- #read_bigdec_with_info(s) ⇒ Object
- #read_bignum(s) ⇒ Object
- #read_bignum_with_info(s) ⇒ Object
- #read_float32(s) ⇒ Object
- #read_float64(s) ⇒ Object
- #write_bigdec(n) ⇒ Object
- #write_bignum(i) ⇒ Object
- #write_float32(f) ⇒ Object
- #write_float64(d) ⇒ Object
Constructor Details
#initialize(*argv) ⇒ BinaryConverter
Set @plat_order as an instance variable instead of as a class constant. We could theoretically set plat order as a class constant, but don’t for 2 reasons. One is that, in the event there is a bug in our detection, we don’t want to fail any class requiring this file, since some code may never touch the BinaryConverter class anyway. Two is that we can use reflection during testing to simulate a different platform byte ordering on a test-by-test basis, rather than having to change a global constant
513 514 515 516 517 518 |
# File 'lib/bitgirder/io.rb', line 513 def initialize( *argv ) super( *argv ) @plat_order = BinaryConverter.detect_platform_order end |
Class Method Details
.detect_platform_order ⇒ Object
725 726 727 728 729 730 731 732 |
# File 'lib/bitgirder/io.rb', line 725 def self.detect_platform_order case test = [ 1 ].pack( 's' ) when "\x01\x00" then ORDER_LITTLE_ENDIAN when "\x00\x01" then ORDER_BIG_ENDIAN else raise "Undetected byte order: #{test.inspect}" end end |
Instance Method Details
#read_bigdec(s) ⇒ Object
721 722 723 |
# File 'lib/bitgirder/io.rb', line 721 def read_bigdec( s ) read_bigdec_with_info( s )[ 0 ] end |
#read_bigdec_with_info(s) ⇒ Object
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 |
# File 'lib/bitgirder/io.rb', line 700 def read_bigdec_with_info( s ) not_nil( s, :s ) unscaled, info1 = read_bignum_with_info( s ) unscaled_len = has_key( info1, :total_len ) scale = read_int32( s[ unscaled_len, 4 ] ) info2 = { :total_len => unscaled_len + 4, :unscaled_len => unscaled_len, :scale_len => 4 } num_str = unscaled.to_s( 10 ) + "e" + ( scale ).to_s [ BigDecimal.new( num_str ), info2 ] end |
#read_bignum(s) ⇒ Object
648 649 650 |
# File 'lib/bitgirder/io.rb', line 648 def read_bignum( s ) read_bignum_with_info( s )[ 0 ] end |
#read_bignum_with_info(s) ⇒ Object
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 |
# File 'lib/bitgirder/io.rb', line 653 def read_bignum_with_info( s ) not_nil( s, :s ) if ( len = s.size ) < 4 raise "Input does not have a size (input len: #{len})" elsif len == 4 raise "Input has no integer data (input len: #{len})" end sz = read_int32( s[ 0, 4 ] ) rem = [ len - 4, len - sz ].min if ( rem = s.size - 4 ) < sz raise "Input specifies size #{sz} but actually is only of " \ "length #{rem}" end info = { :total_len => 4 + sz, :hdr_len => 4, :num_len => sz } [ inflate_bignum( s[ 4, sz ] ), info ] end |
#read_float32(s) ⇒ Object
608 609 610 |
# File 'lib/bitgirder/io.rb', line 608 def read_float32( s ) impl_read_float( s, :s, false ) end |
#read_float64(s) ⇒ Object
613 614 615 |
# File 'lib/bitgirder/io.rb', line 613 def read_float64( s ) impl_read_float( s, :s, true ) end |
#write_bigdec(n) ⇒ Object
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 |
# File 'lib/bitgirder/io.rb', line 681 def write_bigdec( n ) not_nil( n, :n ) raise "Not a BigDecimal" unless n.is_a?( BigDecimal ) sign, unscaled, base, exp = n.split raise "Unexpected base: #{base}" unless base == 10 raise "NaN not supported" if sign == 0 if ( unscaled_i = unscaled.to_i ) == 0 write_bignum( 0 ) + write_int32( 0 ) else # sci_exp is the exponent we'd get using scientific notation sci_exp = -unscaled.size + exp write_bignum( unscaled_i * sign ) + write_int32( sci_exp ) end end |
#write_bignum(i) ⇒ Object
618 619 620 621 622 623 624 625 626 627 628 629 |
# File 'lib/bitgirder/io.rb', line 618 def write_bignum( i ) not_nil( i, :i ) arr = Io.int_to_byte_array( i ) arr.reverse! if @order == ORDER_BIG_ENDIAN res = write_int32( arr.size ) arr.each { |b| res << b.chr } res end |
#write_float32(f) ⇒ Object
589 590 591 |
# File 'lib/bitgirder/io.rb', line 589 def write_float32( f ) impl_write_float( f, :f, false ) end |
#write_float64(d) ⇒ Object
594 595 596 |
# File 'lib/bitgirder/io.rb', line 594 def write_float64( d ) impl_write_float( d, :d, true ) end |