1
1
# -*- ruby encoding: utf-8 -*-
2
2
##
3
- # Ber extensions to the Fixnum class.
4
- module Net ::BER ::Extensions ::Fixnum
3
+ # BER extensions to the Integer class, affecting Fixnum and Bignum objects .
4
+ module Net ::BER ::Extensions ::Integer
5
5
##
6
- # Converts the fixnum to BER format.
6
+ # Converts the Integer to BER format.
7
7
def to_ber
8
8
"\002 #{ to_ber_internal } "
9
9
end
10
10
11
11
##
12
- # Converts the fixnum to BER enumerated format.
12
+ # Converts the Integer to BER enumerated format.
13
13
def to_ber_enumerated
14
14
"\012 #{ to_ber_internal } "
15
15
end
16
16
17
17
##
18
- # Converts the fixnum to BER length encodining format.
18
+ # Converts the Integer to BER length encoding format.
19
19
def to_ber_length_encoding
20
20
if self <= 127
21
21
[ self ] . pack ( 'C' )
@@ -33,34 +33,34 @@ def to_ber_application(tag)
33
33
end
34
34
35
35
##
36
- # Used to BER-encode the length and content bytes of a Fixnum . Callers
36
+ # Used to BER-encode the length and content bytes of an Integer . Callers
37
37
# must prepend the tag byte for the contained value.
38
38
def to_ber_internal
39
- # CAUTION: Bit twiddling ahead. You might want to shield your eyes or
40
- # something.
39
+ # Compute the byte length, accounting for negative values requiring two's
40
+ # complement.
41
+ size = 1
42
+ size += 1 until ( ( ( self < 0 ) ? ~self : self ) >> ( size * 8 ) ) . zero?
41
43
42
- # Looks for the first byte in the fixnum that is not all zeroes. It does
43
- # this by masking one byte after another, checking the result for bits
44
- # that are left on.
45
- size = Net :: BER :: MAX_FIXNUM_SIZE
46
- while size > 1
47
- break if ( self & ( 0xff << ( size - 1 ) * 8 ) ) > 0
48
- size - = 1
44
+ # Padding for positive, negative values. See section 8.5 of ITU-T X.690:
45
+ # http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
46
+
47
+ # For positive integers, if most significant bit in an octet is set to one,
48
+ # pad the result (otherwise it's decoded as a negative value).
49
+ if self > 0 && ( self & ( 0x80 << ( size - 1 ) * 8 ) ) > 0
50
+ size + = 1
49
51
end
50
52
51
- # for positive integers, if most significant bit in an octet is set to one,
52
- # pad the result (otherwise it's decoded as a negative value)
53
- # See section 8.5 of ITU-T X.690:
54
- # http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
55
- if self > 0 && ( self & ( 0b10000000 << ( size - 1 ) * 8 ) ) > 0
53
+ # And for negative integers, pad if the most significant bit in the octet
54
+ # is not set to one (othwerise, it's decoded as positive value).
55
+ if self < 0 && ( self & ( 0x80 << ( size - 1 ) * 8 ) ) == 0
56
56
size += 1
57
57
end
58
58
59
- # Store the size of the fixnum in the result
59
+ # Store the size of the Integer in the result
60
60
result = [ size ]
61
61
62
62
# Appends bytes to result, starting with higher orders first. Extraction
63
- # of bytes is done by right shifting the original fixnum by an amount
63
+ # of bytes is done by right shifting the original Integer by an amount
64
64
# and then masking that with 0xff.
65
65
while size > 0
66
66
# right shift size - 1 bytes, mask with 0xff
0 commit comments