summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-03 23:03:42 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-03 23:03:42 -0700
commitce71b0c309db42f8b56054c202bc43808715f7e0 (patch)
tree515d9b5a21fa0a3fab722323dc947329464de061
parent00afd9f3d5f60f409022a569e455da0987186ecf (diff)
parent86d682017d9c83959a27a68d875e55bc41f1ea6f (diff)
Merge branch 'lukeshu/fix'
-rw-r--r--methods_test.go22
-rw-r--r--reencode.go19
-rw-r--r--roundtrip_test.go54
-rw-r--r--testdata/roundtrip/scandevices.json14
4 files changed, 96 insertions, 13 deletions
diff --git a/methods_test.go b/methods_test.go
index f5d5a9a..64af28c 100644
--- a/methods_test.go
+++ b/methods_test.go
@@ -30,6 +30,10 @@ type SumRun struct {
Sums ShortSum
}
+func (run SumRun) Size() int64 {
+ return int64(len(run.Sums)/(2*run.ChecksumSize)) * (4 * 1024)
+}
+
type SumRunWithGaps struct {
Addr int64
Size int64
@@ -47,13 +51,19 @@ func (sg SumRunWithGaps) EncodeJSON(w io.Writer) error {
return err
}
}
- if run.Addr > cur {
+ switch {
+ case run.Addr < cur:
+ return fmt.Errorf("invalid %T: addr went backwards: %v < %v", sg, run.Addr, cur)
+ case run.Addr > cur:
if _, err := fmt.Fprintf(w, `{"Gap":%d},`, run.Addr-cur); err != nil {
return err
}
- }
- if err := lowmemjson.NewEncoder(w).Encode(run); err != nil {
- return err
+ fallthrough
+ default:
+ if err := lowmemjson.NewEncoder(w).Encode(run); err != nil {
+ return err
+ }
+ cur = run.Addr + run.Size()
}
}
end := sg.Addr + sg.Size
@@ -110,14 +120,14 @@ func TestMethods(t *testing.T) {
{
ChecksumSize: 4,
Addr: 1095761920,
- Sums: "c160817cb5c72bbbe",
+ Sums: "c160817cb5c72bbb",
},
},
}
var buf bytes.Buffer
assert.NoError(t, lowmemjson.NewEncoder(&buf).Encode(in))
assert.Equal(t,
- `{"Addr":13631488,"Size":416033783808,"Runs":[{"Gap":1082130432},{"ChecksumSize":4,"Addr":1095761920,"Sums":"c160817cb5c72bbbe"},{"Gap":416033783808}]}`,
+ `{"Addr":13631488,"Size":416033783808,"Runs":[{"Gap":1082130432},{"ChecksumSize":4,"Addr":1095761920,"Sums":"c160817cb5c72bbb"},{"Gap":414951645184}]}`,
buf.String())
var out SumRunWithGaps
assert.NoError(t, lowmemjson.NewDecoder(&buf).Decode(&out))
diff --git a/reencode.go b/reencode.go
index eae80db..b135fb8 100644
--- a/reencode.go
+++ b/reencode.go
@@ -99,13 +99,14 @@ type ReEncoder struct {
inputPos int64
// state: .handleRune
- lastNonSpace internal.RuneType
- wasNumber bool
- curIndent int
- uhex [4]byte // "\uABCD"-encoded characters in strings
- fracZeros int64
- expZero bool
- specu *speculation
+ lastNonSpace internal.RuneType
+ lastNonSpaceNonEOF internal.RuneType
+ wasNumber bool
+ curIndent int
+ uhex [4]byte // "\uABCD"-encoded characters in strings
+ fracZeros int64
+ expZero bool
+ specu *speculation
// state: .pushBarrier and .popBarrier
stackInputPos []int64
@@ -295,6 +296,7 @@ func (enc *ReEncoder) popWriteBarrier() {
enc.par.PopBarrier()
enc.inputPos += enc.stackInputPos[len(enc.stackInputPos)-1]
enc.stackInputPos = enc.stackInputPos[:len(enc.stackInputPos)-1]
+ enc.lastNonSpace = enc.lastNonSpaceNonEOF
}
// internal ////////////////////////////////////////////////////////////////////
@@ -532,6 +534,9 @@ func (enc *ReEncoder) handleRuneMain(c rune, t internal.RuneType) error {
if t != internal.RuneTypeSpace {
enc.lastNonSpace = t
+ if t != internal.RuneTypeEOF {
+ enc.lastNonSpaceNonEOF = t
+ }
}
return err
}
diff --git a/roundtrip_test.go b/roundtrip_test.go
new file mode 100644
index 0000000..71ca6d0
--- /dev/null
+++ b/roundtrip_test.go
@@ -0,0 +1,54 @@
+// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package lowmemjson_test
+
+import (
+ "bytes"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "git.lukeshu.com/go/lowmemjson"
+)
+
+type ScanDevicesResult map[string]ScanOneDeviceResult
+
+type ScanOneDeviceResult struct {
+ FoundExtentCSums []SysExtentCSum
+}
+
+type SysExtentCSum struct {
+ Generation int64
+ Sums SumRun
+}
+
+func TestRoundTrip(t *testing.T) {
+ t.Parallel()
+ dents, err := os.ReadDir(filepath.Join("testdata", "roundtrip"))
+ require.NoError(t, err)
+ for _, dent := range dents {
+ filename := dent.Name()
+ if !strings.HasSuffix(filename, ".json") {
+ continue
+ }
+ t.Run(strings.TrimSuffix(filename, ".json"), func(t *testing.T) {
+ t.Parallel()
+ inBytes, err := os.ReadFile(filepath.Join("testdata", "roundtrip", filename))
+ require.NoError(t, err)
+ var obj ScanDevicesResult
+ require.NoError(t, lowmemjson.NewDecoder(bytes.NewReader(inBytes)).DecodeThenEOF(&obj))
+ var outBytes bytes.Buffer
+ require.NoError(t, lowmemjson.NewEncoder(lowmemjson.NewReEncoder(&outBytes, lowmemjson.ReEncoderConfig{
+ Indent: "\t",
+ ForceTrailingNewlines: true,
+ CompactIfUnder: 16, //nolint:gomnd // This is what looks nice.
+ })).Encode(obj))
+ require.Equal(t, string(inBytes), outBytes.String())
+ })
+ }
+}
diff --git a/testdata/roundtrip/scandevices.json b/testdata/roundtrip/scandevices.json
new file mode 100644
index 0000000..c62f7df
--- /dev/null
+++ b/testdata/roundtrip/scandevices.json
@@ -0,0 +1,14 @@
+{
+ "dev-1234": {
+ "FoundExtentCSums": [
+ {
+ "Generation": 6596005,
+ "Sums": {
+ "ChecksumSize": 4,
+ "Addr": 52626001920,
+ "Sums": "d69e7384e04333e332f32f8ecfd874ea1ea3f66bd54143f826f740b995105d0e8b2d25a21709109c4930e526a68a89e48d3ebdb6f5191bca3e867eba57110e36d885ca46666168ad782b4fe9af483561"
+ }
+ }
+ ]
+ }
+}