File: base.rb

package info (click to toggle)
ruby-beefcake 1.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 196 kB
  • sloc: ruby: 1,655; makefile: 4
file content (111 lines) | stat: -rw-r--r-- 2,077 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
module Beefcake

  class Buffer

    MinUint32 =  0
    MaxUint32 =  (1 << 32)-1
    MinInt32  = -(1 << 31)
    MaxInt32  =  (1 << 31)-1

    MinUint64 =  0
    MaxUint64 =  (1 << 64)-1
    MinInt64  = -(1 << 63)
    MaxInt64  =  (1 << 63)-1

    WIRES = {
      :int32    => 0,
      :uint32   => 0,
      :sint32   => 0,
      :int64    => 0,
      :uint64   => 0,
      :sint64   => 0,
      :bool     => 0,
      :fixed64  => 1,
      :sfixed64 => 1,
      :double   => 1,
      :string   => 2,
      :bytes    => 2,
      :fixed32  => 5,
      :sfixed32 => 5,
      :float    => 5,
    }

    def self.wire_for(type)
      wire = WIRES[type]

      if wire
        wire
      elsif Class === type && encodable?(type)
        2
      elsif Module === type
        0
      else
        raise UnknownType, type
      end
    end

    def self.encodable?(type)
      return false if ! type.is_a?(Class)
      type.public_method_defined?(:encode)
    end

    attr_reader :buf

    alias :to_s   :buf
    alias :to_str :buf

    class OutOfRangeError < StandardError
      def initialize(n)
        super("Value of of range: %d" % [n])
      end
    end

    class BufferOverflowError < StandardError
      def initialize(s)
        super("Too many bytes read for %s" % [s])
      end
    end

    class UnknownType < StandardError
      def initialize(s)
        super("Unknown type '%s'" % [s])
      end
    end

    def initialize(buf="")
      self.buf = buf
    end

    def buf=(new_buf)
      @buf = new_buf.force_encoding('BINARY')
      @cursor = 0
    end

    def length
      remain = buf.slice(@cursor..-1)
      remain.bytesize
    end

    def <<(bytes)
      bytes = bytes.force_encoding('BINARY') if bytes.respond_to? :force_encoding
      buf << bytes
    end

    def read(n)
      case n
      when Class
        n.decode(read_string)
      when Symbol
        __send__("read_#{n}")
      when Module
        read_uint64
      else
        read_slice = buf.byteslice(@cursor, n)
        @cursor += n
        return read_slice
      end
    end

  end

end