summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-01-26 22:31:32 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-01-29 21:01:42 -0700
commitff6dc0bc519886905e758a84e572f5e34d6c03d1 (patch)
tree8906c4b8bb0c7dc468419efc17b872db62a4e068
parentd1b5bc1f05624614f43ef85597f4aa9d7a166d23 (diff)
Move things between files
-rw-r--r--common.go16
-rw-r--r--encode.go23
-rw-r--r--encode_escape.go (renamed from misc.go)108
-rw-r--r--encode_string.go111
-rw-r--r--internal/encode.go (renamed from internal/export_tags.go)4
-rw-r--r--internal/tags.go7
-rw-r--r--ioutil.go31
-rw-r--r--struct.go4
-rw-r--r--test_export.go18
9 files changed, 169 insertions, 153 deletions
diff --git a/common.go b/common.go
new file mode 100644
index 0000000..90156b9
--- /dev/null
+++ b/common.go
@@ -0,0 +1,16 @@
+// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package lowmemjson
+
+import (
+ "encoding/json"
+ "reflect"
+)
+
+var (
+ numberType = reflect.TypeOf(json.Number(""))
+ byteType = reflect.TypeOf(byte(0))
+ byteSliceType = reflect.TypeOf(([]byte)(nil))
+)
diff --git a/encode.go b/encode.go
index 41032e5..fa337ad 100644
--- a/encode.go
+++ b/encode.go
@@ -17,7 +17,6 @@ import (
"sort"
"strconv"
"strings"
- "unicode/utf8"
"unsafe"
)
@@ -426,28 +425,6 @@ func encode(w io.Writer, val reflect.Value, escaper BackslashEscaper, quote bool
}
}
-func encodeStringFromString(w io.Writer, escaper BackslashEscaper, str string) {
- encodeWriteByte(w, '"')
- for _, c := range str {
- if _, err := writeStringChar(w, c, BackslashEscapeNone, escaper); err != nil {
- panic(encodeError{err})
- }
- }
- encodeWriteByte(w, '"')
-}
-
-func encodeStringFromBytes(w io.Writer, escaper BackslashEscaper, str []byte) {
- encodeWriteByte(w, '"')
- for i := 0; i < len(str); {
- c, size := utf8.DecodeRune(str[i:])
- if _, err := writeStringChar(w, c, BackslashEscapeNone, escaper); err != nil {
- panic(encodeError{err})
- }
- i += size
- }
- encodeWriteByte(w, '"')
-}
-
func encodeArray(w io.Writer, val reflect.Value, escaper BackslashEscaper, cycleDepth uint, cycleSeen map[any]struct{}) {
encodeWriteByte(w, '[')
n := val.Len()
diff --git a/misc.go b/encode_escape.go
index fb96b4e..ab0d9c1 100644
--- a/misc.go
+++ b/encode_escape.go
@@ -5,45 +5,9 @@
package lowmemjson
import (
- "encoding/json"
- "io"
- "reflect"
"unicode/utf8"
-
- "git.lukeshu.com/go/lowmemjson/internal"
-)
-
-var (
- numberType = reflect.TypeOf(json.Number(""))
- byteType = reflect.TypeOf(byte(0))
- byteSliceType = reflect.TypeOf(([]byte)(nil))
)
-// generic I/O /////////////////////////////////////////////////////////////////
-
-func writeByte(w io.Writer, c byte) error {
- if br, ok := w.(interface{ WriteByte(byte) error }); ok {
- return br.WriteByte(c)
- }
- var buf [1]byte
- buf[0] = c
- if _, err := w.Write(buf[:]); err != nil {
- return err
- }
- return nil
-}
-
-func writeRune(w io.Writer, c rune) (int, error) {
- if rw, ok := w.(interface{ WriteRune(rune) (int, error) }); ok {
- return rw.WriteRune(c)
- }
- var buf [utf8.UTFMax]byte
- n := utf8.EncodeRune(buf[:], c)
- return w.Write(buf[:n])
-}
-
-// JSON string encoding ////////////////////////////////////////////////////////
-
// BackslashEscapeMode identifies one of the three ways that a
// character may be represented in a JSON string:
//
@@ -137,75 +101,3 @@ func EscapeDefaultNonHTMLSafe(c rune, wasEscaped BackslashEscapeMode) BackslashE
return EscapeJSSafe(c, wasEscaped)
}
}
-
-func writeStringUnicodeEscape(w io.Writer, c rune) (int, error) {
- buf := [6]byte{
- '\\',
- 'u',
- internal.Hex[(c>>12)&0xf],
- internal.Hex[(c>>8)&0xf],
- internal.Hex[(c>>4)&0xf],
- internal.Hex[(c>>0)&0xf],
- }
- return w.Write(buf[:])
-}
-
-func writeStringShortEscape(w io.Writer, c rune) (int, error) {
- var b byte
- switch c {
- case '"', '\\', '/':
- b = byte(c)
- case '\b':
- b = 'b'
- case '\f':
- b = 'f'
- case '\n':
- b = 'n'
- case '\r':
- b = 'r'
- case '\t':
- b = 't'
- default:
- panic("should not happen")
- }
- buf := [2]byte{'\\', b}
- return w.Write(buf[:])
-}
-
-func writeStringChar(w io.Writer, c rune, wasEscaped BackslashEscapeMode, escaper BackslashEscaper) (int, error) {
- if escaper == nil {
- escaper = EscapeDefault
- }
- switch escaper(c, wasEscaped) {
- case BackslashEscapeNone:
- switch {
- case c < 0x0020: // override, gotta escape these
- switch c {
- case '\b', '\f', '\n', '\r', '\t': // short-escape if possible
- return writeStringShortEscape(w, c)
- default:
- return writeStringUnicodeEscape(w, c)
- }
- case c == '"' || c == '\\': // override, gotta escape these
- return writeStringShortEscape(w, c)
- default: // obey
- return writeRune(w, c)
- }
- case BackslashEscapeShort:
- switch c {
- case '"', '\\', '/', '\b', '\f', '\n', '\r', '\t': // obey
- return writeStringShortEscape(w, c)
- default: // override, can't short-escape these
- return writeRune(w, c)
- }
- case BackslashEscapeUnicode:
- switch {
- case c > 0xFFFF: // override, can't escape these (TODO: unless we use UTF-16 surrogates?)
- return writeRune(w, c)
- default: // obey
- return writeStringUnicodeEscape(w, c)
- }
- default:
- panic("escaper returned an invalid escape mode")
- }
-}
diff --git a/encode_string.go b/encode_string.go
new file mode 100644
index 0000000..c5cb442
--- /dev/null
+++ b/encode_string.go
@@ -0,0 +1,111 @@
+// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package lowmemjson
+
+import (
+ "io"
+ "unicode/utf8"
+
+ "git.lukeshu.com/go/lowmemjson/internal"
+)
+
+func writeStringUnicodeEscape(w io.Writer, c rune) (int, error) {
+ buf := [6]byte{
+ '\\',
+ 'u',
+ internal.Hex[(c>>12)&0xf],
+ internal.Hex[(c>>8)&0xf],
+ internal.Hex[(c>>4)&0xf],
+ internal.Hex[(c>>0)&0xf],
+ }
+ return w.Write(buf[:])
+}
+
+func writeStringShortEscape(w io.Writer, c rune) (int, error) {
+ var b byte
+ switch c {
+ case '"', '\\', '/':
+ b = byte(c)
+ case '\b':
+ b = 'b'
+ case '\f':
+ b = 'f'
+ case '\n':
+ b = 'n'
+ case '\r':
+ b = 'r'
+ case '\t':
+ b = 't'
+ default:
+ panic("should not happen")
+ }
+ buf := [2]byte{'\\', b}
+ return w.Write(buf[:])
+}
+
+func writeStringChar(w io.Writer, c rune, wasEscaped BackslashEscapeMode, escaper BackslashEscaper) (int, error) {
+ if escaper == nil {
+ escaper = EscapeDefault
+ }
+ switch escaper(c, wasEscaped) {
+ case BackslashEscapeNone:
+ switch {
+ case c < 0x0020: // override, gotta escape these
+ switch c {
+ case '\b', '\f', '\n', '\r', '\t': // short-escape if possible
+ return writeStringShortEscape(w, c)
+ default:
+ return writeStringUnicodeEscape(w, c)
+ }
+ case c == '"' || c == '\\': // override, gotta escape these
+ return writeStringShortEscape(w, c)
+ default: // obey
+ return writeRune(w, c)
+ }
+ case BackslashEscapeShort:
+ switch c {
+ case '"', '\\', '/', '\b', '\f', '\n', '\r', '\t': // obey
+ return writeStringShortEscape(w, c)
+ default: // override, can't short-escape these
+ return writeRune(w, c)
+ }
+ case BackslashEscapeUnicode:
+ switch {
+ case c > 0xFFFF: // override, can't escape these (TODO: unless we use UTF-16 surrogates?)
+ return writeRune(w, c)
+ default: // obey
+ return writeStringUnicodeEscape(w, c)
+ }
+ default:
+ panic("escaper returned an invalid escape mode")
+ }
+}
+
+func encodeStringFromString(w io.Writer, escaper BackslashEscaper, str string) {
+ encodeWriteByte(w, '"')
+ for _, c := range str {
+ if _, err := writeStringChar(w, c, BackslashEscapeNone, escaper); err != nil {
+ panic(encodeError{err})
+ }
+ }
+ encodeWriteByte(w, '"')
+}
+
+func encodeStringFromBytes(w io.Writer, escaper BackslashEscaper, str []byte) {
+ encodeWriteByte(w, '"')
+ for i := 0; i < len(str); {
+ c, size := utf8.DecodeRune(str[i:])
+ if _, err := writeStringChar(w, c, BackslashEscapeNone, escaper); err != nil {
+ panic(encodeError{err})
+ }
+ i += size
+ }
+ encodeWriteByte(w, '"')
+}
+
+func init() {
+ internal.EncodeStringFromString = func(w io.Writer, s string) { encodeStringFromString(w, nil, s) }
+ internal.EncodeStringFromBytes = func(w io.Writer, s []byte) { encodeStringFromBytes(w, nil, s) }
+}
diff --git a/internal/export_tags.go b/internal/encode.go
index d8cf622..8aae673 100644
--- a/internal/export_tags.go
+++ b/internal/encode.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com>
+// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
//
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -8,8 +8,6 @@ import (
"io"
)
-var ParseTag = parseTag
-
var (
EncodeStringFromBytes func(io.Writer, []byte)
EncodeStringFromString func(io.Writer, string)
diff --git a/internal/tags.go b/internal/tags.go
new file mode 100644
index 0000000..bdf1f72
--- /dev/null
+++ b/internal/tags.go
@@ -0,0 +1,7 @@
+// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package internal
+
+var ParseTag = parseTag
diff --git a/ioutil.go b/ioutil.go
new file mode 100644
index 0000000..a53eac3
--- /dev/null
+++ b/ioutil.go
@@ -0,0 +1,31 @@
+// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package lowmemjson
+
+import (
+ "io"
+ "unicode/utf8"
+)
+
+func writeByte(w io.Writer, c byte) error {
+ if br, ok := w.(interface{ WriteByte(byte) error }); ok {
+ return br.WriteByte(c)
+ }
+ var buf [1]byte
+ buf[0] = c
+ if _, err := w.Write(buf[:]); err != nil {
+ return err
+ }
+ return nil
+}
+
+func writeRune(w io.Writer, c rune) (int, error) {
+ if rw, ok := w.(interface{ WriteRune(rune) (int, error) }); ok {
+ return rw.WriteRune(c)
+ }
+ var buf [utf8.UTFMax]byte
+ n := utf8.EncodeRune(buf[:], c)
+ return w.Write(buf[:n])
+}
diff --git a/struct.go b/struct.go
index 24b2ac0..b7fc287 100644
--- a/struct.go
+++ b/struct.go
@@ -6,6 +6,8 @@ package lowmemjson
import (
"reflect"
+
+ "git.lukeshu.com/go/lowmemjson/internal"
)
type structField struct {
@@ -143,7 +145,7 @@ func indexStructInner(typ reflect.Type, byPos *[]structField, byName map[string]
if tag == "-" {
continue
}
- tagName, opts := parseTag(tag)
+ tagName, opts := internal.ParseTag(tag)
name := tagName
if !isValidTag(name) {
name = ""
diff --git a/test_export.go b/test_export.go
deleted file mode 100644
index 76d29d2..0000000
--- a/test_export.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com>
-//
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-package lowmemjson
-
-import (
- "io"
-
- "git.lukeshu.com/go/lowmemjson/internal"
-)
-
-func init() {
- internal.EncodeStringFromString = func(w io.Writer, s string) { encodeStringFromString(w, nil, s) }
- internal.EncodeStringFromBytes = func(w io.Writer, s []byte) { encodeStringFromBytes(w, nil, s) }
-}
-
-var parseTag = internal.ParseTag