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.