module Net::BER::BERParser
This module is for mixing into IO
and IO-like objects.
Constants
- BuiltinSyntax
- TagClasses
The order of these follows the class-codes in
BER
. Maybe this should have been a hash.
Public Instance Methods
read_ber(syntax=nil)
click to toggle source
read_ber
TODO: clean this up so it works properly with partial packets coming from streams that don’t block when we ask for more data (like StringIOs). At it is, this can throw TypeErrors and other nasties.
# File lib/net/ber.rb, line 70 def read_ber syntax=nil return nil if eof? id = getc # don't trash this value, we'll use it later tag = id & 31 tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" ) tagclass = TagClasses[ id >> 6 ] encoding = (id & 0x20 != 0) ? :constructed : :primitive n = getc lengthlength,contentlength = if n <= 127 [1,n] else j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc} [1 + (n & 127), j] end newobj = read contentlength objtype = nil [syntax, BuiltinSyntax].each {|syn| if syn && (ot = syn[tagclass]) && (ot = ot[encoding]) && ot[tag] objtype = ot[tag] break end } obj = case objtype when :boolean newobj != "\000" when :string (newobj || "").dup when :integer j = 0 newobj.each_byte {|b| j = (j << 8) + b} j when :array seq = [] sio = StringIO.new( newobj || "" ) # Interpret the subobject, but note how the loop # is built: nil ends the loop, but false (a valid # BER value) does not! while (e = sio.read_ber(syntax)) != nil seq << e end seq else raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" ) end # Add the identifier bits into the object if it's a String or an Array. # We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway. obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end" obj end