-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstring.go
122 lines (99 loc) · 2.67 KB
/
string.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
/*
Copyright 2023 Alexander Bartolomey ([email protected])
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ipfix
import (
"encoding/json"
"fmt"
"io"
)
type String struct {
value string
length uint16
}
func NewString() DataType {
return &String{}
}
func (s *String) String() string {
return string(s.value)
}
func (*String) Type() string {
return "string"
}
func (t *String) Value() interface{} {
return t.value
}
func (t *String) SetValue(v any) DataType {
b, ok := v.(string)
if !ok {
panic(fmt.Errorf("%T cannot be asserted to %T", v, t.value))
}
t.value = b
t.length = uint16(len(b))
return t
}
func (t *String) Length() uint16 {
// this is t.length, because we use this method in Decode, and need to set the
// length value from outside using the Decorator WithLength, to curry the type,
// in order to support variable-length fields.
return t.length
}
func (*String) DefaultLength() uint16 {
return 0
}
func (t *String) Clone() DataType {
return &String{
value: t.value,
}
}
func (*String) WithLength(length uint16) DataTypeConstructor {
return func() DataType {
return &String{
length: length,
}
}
}
func (t *String) SetLength(length uint16) DataType {
t.length = length
return t
}
func (*String) IsReducedLength() bool {
return false
}
func (t *String) Decode(in io.Reader) (n int, err error) {
b := make([]byte, t.Length())
n, err = in.Read(b)
if err != nil {
return n, fmt.Errorf("failed to read data in %T, %w", t, err)
}
// check if in is a valid utf8 string
// TODO(zoomoid): reactivate this, but this broke a lot of string decoding in prior versions...
// if !utf8.Valid(b) {
// // "Collecting Processes SHOULD detect and ignore such values." (RFC7011#section-6.1)
// logger.V(1).Info("WARN decoded string data type that is not valid UTF-8, ignoring...", "bytes", b)
// return nil
// }
t.value = string(b)
return
}
func (t *String) Encode(w io.Writer) (int, error) {
b := []byte(t.value)
return w.Write(b)
}
func (t *String) MarshalJSON() ([]byte, error) {
return json.Marshal(t.value)
}
func (t *String) UnmarshalJSON(in []byte) error {
return json.Unmarshal(in, &t.value)
}
var _ DataTypeConstructor = NewString
var _ DataType = &String{}