-
Notifications
You must be signed in to change notification settings - Fork 0
/
ostr.go
137 lines (110 loc) · 2.57 KB
/
ostr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
126
127
128
129
130
131
132
133
134
135
136
137
package dirsyn
/*
OctetString implements [§ 3.3.25 of RFC 4517]:
OctetString = *OCTET
[§ 3.3.25 of RFC 4517]: https://datatracker.ietf.org/doc/html/rfc4517#section-3.3.25
*/
type OctetString []byte
/*
IsZero returns a Boolean value indicative of a nil receiver state.
*/
func (r OctetString) IsZero() bool { return r == nil }
/*
String returns the string representation of the receiver instance.
*/
func (r OctetString) String() string {
return string(r)
}
/*
OctetString returns an instance of [OctetString] alongside an error
following an analysis of x in the context of an Octet String.
*/
func (r RFC4517) OctetString(x any) (OctetString, error) {
return marshalOctetString(x)
}
func octetString(x any) (result Boolean) {
_, err := marshalOctetString(x)
result.Set(err == nil)
return
}
func marshalOctetString(x any) (oct OctetString, err error) {
var raw []byte
if raw, err = assertOctetString(x); err != nil {
return
}
for i := 0; i < len(raw) && err == nil; i++ {
var char rune = rune(raw[i])
if !ucIs(octRange, char) {
err = errorTxt("Incompatible Octet String character: " + string(char))
}
}
if err == nil {
oct = OctetString(raw)
}
return
}
func assertOctetString(in any) (raw []byte, err error) {
switch tv := in.(type) {
case []byte:
raw = tv
case OctetString:
raw = []byte(tv)
case string:
raw = []byte(tv)
default:
err = errorBadType("OctetStringMatch")
}
return
}
/*
octetStringMatch implements [§ 4.2.27 of RFC 4517].
OID: 2.5.13.17.
[§ 4.2.27 of RFC 4517]: https://datatracker.ietf.org/doc/html/rfc4517#section-4.2.27
*/
func octetStringMatch(a, b any) (result Boolean, err error) {
var A, B []byte
if A, err = assertOctetString(a); err != nil {
return
}
if B, err = assertOctetString(b); err != nil {
return
}
var res bool
if res = len(A) == len(B); res {
for i, ch := range B {
if res = A[i] == ch; !res {
break
}
}
}
result.Set(res)
return
}
func octetStringOrderingMatch(a, b any) (result Boolean, err error) {
var str1, str2 []byte
if str1, err = assertOctetString(a); err != nil {
return
}
if str2, err = assertOctetString(b); err != nil {
return
}
mLen := len(str2)
if len(str1) < mLen {
mLen = len(str1)
}
// Compare octet strings from the first octet to the last
for i := 0; i < mLen; i++ {
if str2[i] < str1[i] {
result.Set(true)
return
} else if str2[i] > str1[i] {
result.Set(false)
return
}
}
// If the strings are identical up to the length of the
// shorter string, the shorter string precedes the longer
// string
result.Set(len(str2) < len(str1))
return
}