Module: Net::BER::BERParser
Overview
This module is for mixing into IO and IO-like objects.
Constant Summary collapse
- TagClasses =
The order of these follows the class-codes in BER. Maybe this should have been a hash.
[:universal, :application, :context_specific, :private]
- BuiltinSyntax =
{ :universal => { :primitive => { 1 => :boolean, 2 => :integer, 4 => :string, 10 => :integer, }, :constructed => { 16 => :array, 17 => :array } } }
Instance Method Summary collapse
-
#read_ber(syntax = nil) ⇒ Object
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).
Instance Method Details
#read_ber(syntax = nil) ⇒ Object
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.
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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# 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 |