# File lib/net/ber.rb, line 70
 70:     def read_ber syntax=nil
 71:       return nil if eof?
 72: 
 73:       id = getc  # don't trash this value, we'll use it later
 74:       tag = id & 31
 75:       tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
 76:       tagclass = TagClasses[ id >> 6 ]
 77:       encoding = (id & 0x20 != 0) ? :constructed : :primitive
 78: 
 79:       n = getc
 80:       lengthlength,contentlength = if n <= 127
 81:         [1,n]
 82:       else
 83:         j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
 84:         [1 + (n & 127), j]
 85:       end
 86: 
 87:       newobj = read contentlength
 88: 
 89:       objtype = nil
 90:       [syntax, BuiltinSyntax].each {|syn|
 91:         if syn && (ot = syn[tagclass]) && (ot = ot[encoding]) && ot[tag]
 92:           objtype = ot[tag]
 93:           break
 94:         end
 95:       }
 96:       
 97:       obj = case objtype
 98:       when :boolean
 99:         newobj != "\000"
100:       when :string
101:         (newobj || "").dup
102:       when :integer
103:         j = 0
104:         newobj.each_byte {|b| j = (j << 8) + b}
105:         j
106:       when :array
107:         seq = []
108:         sio = StringIO.new( newobj || "" )
109:         # Interpret the subobject, but note how the loop
110:         # is built: nil ends the loop, but false (a valid
111:         # BER value) does not!
112:         while (e = sio.read_ber(syntax)) != nil
113:           seq << e
114:         end
115:         seq
116:       else
117:         raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
118:       end
119: 
120:       # Add the identifier bits into the object if it's a String or an Array.
121:       # We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway.
122:       obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end"
123:       obj
124: 
125:     end