File: integer.rb

package info (click to toggle)
ruby-packable 1.3.14-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 204 kB
  • sloc: ruby: 609; makefile: 4
file content (47 lines) | stat: -rw-r--r-- 1,581 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
          extend ClassMethods
          packers do |p|
            p.set :merge_all      , :bytes=>4, :signed=>true, :endian=>:big
            p.set :default        , :long
            p.set :long           , {}
            p.set :short          , :bytes=>2
            p.set :char           , :bytes=>1, :signed=>false
            p.set :byte           , :bytes=>1
            p.set :unsigned_long  , :bytes=>4, :signed=>false
            p.set :unsigned_short , :bytes=>2, :signed=>false
          end
        end
      end

      def write_packed(io, options)
        val = self
        chars = (0...options[:bytes]).collect do
          byte = val & 0xFF
          val >>= 8
          byte.chr
        end
        chars.reverse! unless NEEDS_REVERSAL[options[:endian]]
        io << chars.join
      end

      module ClassMethods #:nodoc:
        def unpack_string(s,options)
          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))
          r
        end
      end

    end
  end
end