...
1 package ber
2
3 import (
4 "errors"
5 "fmt"
6 "io"
7 )
8
9 func readIdentifier(reader io.Reader) (Identifier, int, error) {
10 identifier := Identifier{}
11 read := 0
12
13
14 b, err := readByte(reader)
15 if err != nil {
16 if Debug {
17 fmt.Printf("error reading identifier byte: %v\n", err)
18 }
19 return Identifier{}, read, err
20 }
21 read++
22
23 identifier.ClassType = Class(b) & ClassBitmask
24 identifier.TagType = Type(b) & TypeBitmask
25
26 if tag := Tag(b) & TagBitmask; tag != HighTag {
27
28 identifier.Tag = tag
29 return identifier, read, nil
30 }
31
32
33 tagBytes := 0
34 for {
35 b, err := readByte(reader)
36 if err != nil {
37 if Debug {
38 fmt.Printf("error reading high-tag-number tag byte %d: %v\n", tagBytes, err)
39 }
40 return Identifier{}, read, unexpectedEOF(err)
41 }
42 tagBytes++
43 read++
44
45
46 identifier.Tag <<= 7
47 identifier.Tag |= Tag(b) & HighTagValueBitmask
48
49
50 if tagBytes == 1 && identifier.Tag == 0 {
51 return Identifier{}, read, errors.New("invalid first high-tag-number tag byte")
52 }
53
54
55 if tagBytes > 9 {
56 return Identifier{}, read, errors.New("high-tag-number tag overflow")
57 }
58
59
60 if Tag(b)&HighTagContinueBitmask == 0 {
61 break
62 }
63 }
64
65 return identifier, read, nil
66 }
67
68 func encodeIdentifier(identifier Identifier) []byte {
69 b := []byte{0x0}
70 b[0] |= byte(identifier.ClassType)
71 b[0] |= byte(identifier.TagType)
72
73 if identifier.Tag < HighTag {
74
75 b[0] |= byte(identifier.Tag)
76 } else {
77
78 b[0] |= byte(HighTag)
79
80 tag := identifier.Tag
81
82 b = append(b, encodeHighTag(tag)...)
83 }
84 return b
85 }
86
87 func encodeHighTag(tag Tag) []byte {
88
89 b := make([]byte, 0, 4)
90 for tag != 0 {
91
92 t := tag & HighTagValueBitmask
93
94
95 tag >>= 7
96
97
98 if len(b) != 0 {
99 t |= HighTagContinueBitmask
100 }
101
102 b = append(b, byte(t))
103 }
104
105
106
107
108 for i, j := 0, len(b)-1; i < len(b)/2; i++ {
109 b[i], b[j-i] = b[j-i], b[i]
110 }
111 return b
112 }
113
View as plain text