This repository has been archived by the owner on May 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nanf.go
167 lines (148 loc) · 4.22 KB
/
nanf.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package objectid
/*
nanf.go deals with NameAndNumberForm syntax and viability
*/
/*
NameAndNumberForm contains either an identifier with a parenthesis-enclosed
decimal value, or a decimal value alone. An ordered sequence of instances of
this type comprise an instance of ASN1Notation.
*/
type NameAndNumberForm struct {
identifier string
primaryIdentifier NumberForm
parsed bool
}
/*
IsZero returns a boolean valu indicative of whether
the receiver is considered nil.
*/
func (nanf NameAndNumberForm) IsZero() bool {
return !nanf.parsed
}
/*
Identifier returns the string-based nameForm
value assigned to the receiver instance.
*/
func (nanf NameAndNumberForm) Identifier() string {
return nanf.identifier
}
/*
NumberForm returns the underlying NumberForm
value assigned to the receiver instance.
*/
func (nanf NameAndNumberForm) NumberForm() NumberForm {
return nanf.primaryIdentifier
}
/*
String is a stringer method that returns the properly
formatted NameAndNumberForm string value.
*/
func (nanf NameAndNumberForm) String() (val string) {
n := nanf.primaryIdentifier.String()
if len(nanf.identifier) == 0 {
return n
}
return sprintf("%s(%s)", nanf.identifier, n)
}
/*
Equal returns a boolean value indicative of whether instance
n of NameAndNumberForm matches the receiver.
*/
func (nanf NameAndNumberForm) Equal(n any) (is bool) {
switch tv := n.(type) {
case NameAndNumberForm:
is = nanf.identifier == tv.identifier &&
nanf.primaryIdentifier.Equal(tv.primaryIdentifier)
case *NameAndNumberForm:
is = nanf.identifier == tv.identifier &&
nanf.primaryIdentifier.Equal(tv.primaryIdentifier)
}
return
}
/*
parseNaNFstr returns an instance of *NameAndNumberForm alongside an error.
*/
func parseNaNFstr(x string) (nanf *NameAndNumberForm, err error) {
// Don't waste time on bogus values.
if len(x) == 0 {
err = errorf("No content for parseNaNFstr to read")
return
} else if x[len(x)-1] != ')' {
err = errorf("No closing parenthesis for parseNaNFstr to read")
return
}
// index the rune for '(', indicating the
// identifier (nameForm) has ended, and the
// numberForm is beginning.
idx := indexRune(x, '(')
if idx == -1 {
err = errorf("No opening parenthesis for parseNaNFstr to read")
return
}
// select the numerical characters,
// or bail out ...
err = errorf("Bad numberForm: value must fall within 0 and ^uint128")
if n := x[idx+1 : len(x)-1]; isNumber(n) {
// Parse/verify what appears to be the
// identifier string value.
var identifier string = x[:idx]
err = errorf("Invalid identifier [%s]; syntax must conform to: LOWER *[ [-] +[ UPPER / LOWER / DIGIT ] ]", identifier)
if isIdentifier(identifier) {
// parse the string numberForm value into
// an instance of NumberForm, or bail out.
var prid NumberForm
if prid, err = NewNumberForm(n); err == nil {
// Prepare to return valid information.
nanf = new(NameAndNumberForm)
nanf.parsed = true
nanf.primaryIdentifier = prid
nanf.identifier = x[:idx]
}
}
}
return
}
/*
NewNameAndNumberForm returns an instance of *NameAndNumberForm
alongside an error. Valid input forms are:
• nameAndNumberForm (e.g.: "enterprise(1)"), or ...
• numberForm (e.g.: 1)
NumberForm components CANNOT be negative and CANNOT overflow
NumberForm (uint128). Permitted input types are string, uint64
and (non-negative) int.
*/
func NewNameAndNumberForm(x any) (nanf *NameAndNumberForm, err error) {
err = errorf("%T must conform to: identifier LPAREN numberForm RPAREN", nanf)
switch tv := x.(type) {
case string:
if !isNumber(tv) {
nanf, err = parseNaNFstr(tv)
} else {
var a NumberForm
if a, err = NewNumberForm(tv); err == nil {
nanf = &NameAndNumberForm{primaryIdentifier: a}
}
}
case NumberForm:
nanf = new(NameAndNumberForm)
nanf.primaryIdentifier = tv
err = nil
case uint64:
nanf = new(NameAndNumberForm)
u, _ := NewNumberForm(tv) // skip error checking, we know it won't overflow.
nanf.primaryIdentifier = u
err = nil
case int:
if tv >= 0 {
nanf, err = NewNameAndNumberForm(uint64(tv))
}
default:
err = errorf("Unsupported NameAndNumberForm input type '%T'", tv)
}
// mark this instance as complete,
// assuming no errors were found.
if err == nil {
nanf.parsed = true
}
return
}