Compare commits
2 Commits
c944b05fa3
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| d73ebd56da | |||
| 79ca748884 |
23
decode.go
23
decode.go
@@ -236,10 +236,11 @@ func (d *decodeState) dictionaryInterface() any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *decodeState) arrayInterface() any {
|
func (d *decodeState) arrayInterface() any {
|
||||||
count := 1
|
commas := 0
|
||||||
depth := 1
|
depth := 1
|
||||||
ts := d.span
|
ts := d.span
|
||||||
data := d.data
|
data := d.data
|
||||||
|
empty := true
|
||||||
|
|
||||||
for ts < len(data) {
|
for ts < len(data) {
|
||||||
f := cgpCharTable[data[ts]]
|
f := cgpCharTable[data[ts]]
|
||||||
@@ -252,20 +253,20 @@ func (d *decodeState) arrayInterface() any {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else if f&isCgpComma != 0 && depth == 1 {
|
} else if f&isCgpComma != 0 && depth == 1 {
|
||||||
count++
|
commas++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if f&isCgpSpace == 0 {
|
||||||
|
empty = false
|
||||||
|
}
|
||||||
ts++
|
ts++
|
||||||
}
|
}
|
||||||
|
|
||||||
// Если мы нашли элементы (или хотя бы один), count должен быть корректным.
|
capacity := 0
|
||||||
// Для пустого массива () count останется 0. Для (1) - тоже 0, надо +1 если не пусто.
|
if !empty {
|
||||||
// Но проще: если мы встретили хотя бы один символ до закрытия, это 1 элемент или больше.
|
capacity = commas + 1
|
||||||
if ts > d.span { // Если между ( и ) что-то было
|
|
||||||
count++
|
|
||||||
}
|
}
|
||||||
|
res := make([]any, 0, capacity)
|
||||||
res := make([]any, 0, count)
|
|
||||||
|
|
||||||
for d.span < d.len {
|
for d.span < d.len {
|
||||||
d.skipSpaces()
|
d.skipSpaces()
|
||||||
@@ -616,11 +617,13 @@ func parseIPSB(v any) net.IP {
|
|||||||
return net.ParseIP(s)
|
return net.ParseIP(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ipsbsaReplacer = strings.NewReplacer("[", "", "]", "")
|
||||||
|
|
||||||
func parseIPSBSA(s string) []net.IP {
|
func parseIPSBSA(s string) []net.IP {
|
||||||
if s == "" {
|
if s == "" {
|
||||||
return []net.IP{}
|
return []net.IP{}
|
||||||
}
|
}
|
||||||
s = strings.NewReplacer("[", "", "]", "").Replace(s)
|
s = ipsbsaReplacer.Replace(s)
|
||||||
parts := strings.Split(s, ",")
|
parts := strings.Split(s, ",")
|
||||||
res := make([]net.IP, 0, len(parts))
|
res := make([]net.IP, 0, len(parts))
|
||||||
for _, p := range parts {
|
for _, p := range parts {
|
||||||
|
|||||||
@@ -156,3 +156,81 @@ func TestDecodeDataBlock(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestArrayCounting проверяет корректность подсчёта элементов в arrayInterface.
|
||||||
|
func TestArrayCounting(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
{"Empty", "()", 0},
|
||||||
|
{"One", "(a)", 1},
|
||||||
|
{"Two", "(a,b)", 2},
|
||||||
|
{"Three", "(a,b,c)", 3},
|
||||||
|
{"Nested", "(a,(b,c),d)", 3},
|
||||||
|
{"NestedDict", "(a,{k=v;},c)", 3},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
var got any
|
||||||
|
if err := Unmarshal([]byte(tt.input), &got); err != nil {
|
||||||
|
t.Fatalf("Unmarshal() error = %v", err)
|
||||||
|
}
|
||||||
|
arr, ok := got.([]any)
|
||||||
|
if !ok {
|
||||||
|
if tt.want == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Fatalf("expected []any, got %T: %v", got, got)
|
||||||
|
}
|
||||||
|
if len(arr) != tt.want {
|
||||||
|
t.Errorf("len=%d, want %d, got %v", len(arr), tt.want, arr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestParseCGPSizeQuotes проверяет нужен ли strings.Trim в parseCGPSize.
|
||||||
|
func TestParseCGPSizeQuotes(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want any
|
||||||
|
}{
|
||||||
|
{"NoQuotes", "10K", int64(10 * 1024)},
|
||||||
|
{"WithQuotes", `"10K"`, int64(10 * 1024)},
|
||||||
|
{"Unlimited", "unlimited", int64(-1)},
|
||||||
|
{"Plain", "1024", int64(1024)},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := parseCGPSize(tt.input)
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("parseCGPSize(%q) = %v (%T), want %v (%T)", tt.input, got, got, tt.want, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestParseIPSBSA проверяет parseIPSBSA.
|
||||||
|
func TestParseIPSBSA(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
{"Empty", "", 0},
|
||||||
|
{"Single", "[192.168.1.1]", 1},
|
||||||
|
{"Multiple", "[192.168.1.1], [10.0.0.1]", 2},
|
||||||
|
{"IPv6", "[::1], [fe80::1]", 2},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := parseIPSBSA(tt.input)
|
||||||
|
if len(got) != tt.want {
|
||||||
|
t.Errorf("parseIPSBSA(%q) = %d IPs, want %d: %v", tt.input, len(got), tt.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
29
types.go
29
types.go
@@ -82,29 +82,20 @@ func (c CGPIP) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writeCGP формирует данные для отправки на сервер CGP напрямую в буфер.
|
// writeCGP формирует данные для отправки на сервер CGP напрямую в буфер.
|
||||||
func (c CGPIP) writeCGP(w encodeWriter) (err error) {
|
func (c CGPIP) writeCGP(w encodeWriter) error {
|
||||||
if c.IsZero() {
|
if c.IsZero() {
|
||||||
_, err = w.WriteString("#NULL#")
|
_, err := w.WriteString("#NULL#")
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = w.WriteString("#I["); err != nil {
|
w.WriteString("#I[")
|
||||||
return
|
w.WriteString(c.IP.String())
|
||||||
}
|
w.WriteByte(']')
|
||||||
if _, err = w.WriteString(c.IP.String()); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = w.WriteByte(']'); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Port > 0 {
|
if c.Port > 0 {
|
||||||
if err = w.WriteByte(':'); err != nil {
|
w.WriteByte(':')
|
||||||
return
|
w.WriteString(strconv.Itoa(c.Port))
|
||||||
}
|
}
|
||||||
if _, err = w.WriteString(strconv.Itoa(c.Port)); err != nil {
|
|
||||||
return
|
return nil
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user