The order of these follows the class-codes in BER. Maybe this should have been a hash.
# File lib/net/ber/ber_parser.rb, line 35
35: def read_ber syntax=nil
36: # TODO: clean this up so it works properly with partial
37: # packets coming from streams that don't block when
38: # we ask for more data (like StringIOs). At it is,
39: # this can throw TypeErrors and other nasties.
40:
41: id = getbyte or return nil # don't trash this value, we'll use it later
42:
43: n = getbyte
44: lengthlength,contentlength = if n <= 127
45: [1,n]
46: else
47: # Replaced the inject because it profiles hot.
48: # j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
49: j = 0
50: read( n & 127 ).each_byte {|n1| j = (j << 8) + n1}
51: [1 + (n & 127), j]
52: end
53:
54: newobj = read contentlength
55:
56: # This exceptionally clever and clear bit of code is verrrry slow.
57: objtype = (syntax && syntax[id]) || BuiltinSyntax[id]
58:
59: # == is expensive so sort this if/else so the common cases are at the top.
60: obj = if objtype == :string
61: #(newobj || "").dup
62: s = BerIdentifiedString.new( newobj || "" )
63: s.ber_identifier = id
64: s
65: elsif objtype == :integer
66: j = 0
67: newobj.each_byte {|b| j = (j << 8) + b}
68: j
69: elsif objtype == :oid
70: # cf X.690 pgh 8.19 for an explanation of this algorithm.
71: # Potentially not good enough. We may need a BerIdentifiedOid
72: # as a subclass of BerIdentifiedArray, to get the ber identifier
73: # and also a to_s method that produces the familiar dotted notation.
74: oid = newobj.unpack("w*")
75: f = oid.shift
76: g = if f < 40
77: [0, f]
78: elsif f < 80
79: [1, f-40]
80: else
81: [2, f-80] # f-80 can easily be > 80. What a weird optimization.
82: end
83: oid.unshift g.last
84: oid.unshift g.first
85: oid
86: elsif objtype == :array
87: #seq = []
88: seq = BerIdentifiedArray.new
89: seq.ber_identifier = id
90: sio = StringIO.new( newobj || "" )
91: # Interpret the subobject, but note how the loop
92: # is built: nil ends the loop, but false (a valid
93: # BER value) does not!
94: while (e = sio.read_ber(syntax)) != nil
95: seq << e
96: end
97: seq
98: elsif objtype == :boolean
99: newobj != "\0000"
100: elsif objtype == :null
101: n = BerIdentifiedNull.new
102: n.ber_identifier = id
103: n
104: else
105: raise BerError.new( "unsupported object type: id=#{id}" )
106: end
107:
108: obj
109: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.