|
| 1 | +module Net::BER::Extensions::Array |
| 2 | + ## |
| 3 | + # Converts an Array to a BER sequence. All values in the Array are |
| 4 | + # expected to be in BER format prior to calling this method. |
| 5 | + def to_ber(id = 0) |
| 6 | + # The universal sequence tag 0x30 is composed of the base tag value |
| 7 | + # (0x10) and the constructed flag (0x20). |
| 8 | + to_ber_seq_internal(0x30 + id) |
| 9 | + end |
| 10 | + alias_method :to_ber_sequence, :to_ber |
| 11 | + |
| 12 | + ## |
| 13 | + # Converts an Array to a BER set. All values in the Array are expected to |
| 14 | + # be in BER format prior to calling this method. |
| 15 | + def to_ber_set(id = 0) |
| 16 | + # The universal set tag 0x31 is composed of the base tag value (0x11) |
| 17 | + # and the constructed flag (0x20). |
| 18 | + to_ber_seq_internal(0x31 + id) |
| 19 | + end |
| 20 | + |
| 21 | + ## |
| 22 | + # Converts an Array to an application-specific sequence, assigned a tag |
| 23 | + # value that is meaningful to the particular protocol being used. All |
| 24 | + # values in the Array are expected to be in BER format pr prior to calling |
| 25 | + # this method. |
| 26 | + #-- |
| 27 | + # Implementor's note 20100320(AZ): RFC 4511 (the LDAPv3 protocol) as well |
| 28 | + # as earlier RFCs 1777 and 2559 seem to indicate that LDAP only has |
| 29 | + # application constructed sequences (0x60). However, ldapsearch sends some |
| 30 | + # context-specific constructed sequences (0xA0); other clients may do the |
| 31 | + # same. This behaviour appears to violate the RFCs. In real-world |
| 32 | + # practice, we may need to change calls of #to_ber_appsequence to |
| 33 | + # #to_ber_contextspecific for full LDAP server compatibility. |
| 34 | + # |
| 35 | + # This note probably belongs elsewhere. |
| 36 | + #++ |
| 37 | + def to_ber_appsequence(id = 0) |
| 38 | + # The application sequence tag always starts from the application flag |
| 39 | + # (0x40) and the constructed flag (0x20). |
| 40 | + to_ber_seq_internal(0x60 + id) |
| 41 | + end |
| 42 | + |
| 43 | + ## |
| 44 | + # Converts an Array to a context-specific sequence, assigned a tag value |
| 45 | + # that is meaningful to the particular context of the particular protocol |
| 46 | + # being used. All values in the Array are expected to be in BER format |
| 47 | + # prior to calling this method. |
| 48 | + def to_ber_contextspecific(id = 0) |
| 49 | + # The application sequence tag always starts from the context flag |
| 50 | + # (0x80) and the constructed flag (0x20). |
| 51 | + to_ber_seq_internal(0xa0 + id) |
| 52 | + end |
| 53 | + |
| 54 | + ## |
| 55 | + # The internal sequence packing routine. All values in the Array are |
| 56 | + # expected to be in BER format prior to calling this method. |
| 57 | + def to_ber_seq_internal(code) |
| 58 | + s = self.join |
| 59 | + [code].pack('C') + s.length.to_ber_length_encoding + s |
| 60 | + end |
| 61 | + private :to_ber_seq_internal |
| 62 | + |
| 63 | + ## |
| 64 | + # SNMP Object Identifiers (OID) are special arrays |
| 65 | + #-- |
| 66 | + # 20100320 AZ: I do not think that this method should be in BER, since |
| 67 | + # this appears to be SNMP-specific. This should probably be subsumed by a |
| 68 | + # proper SNMP OID object. |
| 69 | + #++ |
| 70 | + def to_ber_oid |
| 71 | + ary = self.dup |
| 72 | + first = ary.shift |
| 73 | + raise Net::BER::BerError, "Invalid OID" unless [0, 1, 2].include?(first) |
| 74 | + first = first * 40 + ary.shift |
| 75 | + ary.unshift first |
| 76 | + oid = ary.pack("w*") |
| 77 | + [6, oid.length].pack("CC") + oid |
| 78 | + end |
| 79 | +end |
0 commit comments