summaryrefslogtreecommitdiff
path: root/reencode.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-07 12:18:29 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-07 14:05:26 -0700
commit2b9473f5e8816eeea76b2fdada184532be00d3a2 (patch)
tree387757b00f02521d1b3824a0e92f7778dbd32440 /reencode.go
parenteab38672b2467810592b61fe5b0067086d3cbd2c (diff)
internal: Split in to sub-packages
Diffstat (limited to 'reencode.go')
-rw-r--r--reencode.go95
1 files changed, 48 insertions, 47 deletions
diff --git a/reencode.go b/reencode.go
index 3e9cf37..232d91d 100644
--- a/reencode.go
+++ b/reencode.go
@@ -10,7 +10,8 @@ import (
"io"
"unicode/utf8"
- "git.lukeshu.com/go/lowmemjson/internal"
+ "git.lukeshu.com/go/lowmemjson/internal/fastio"
+ "git.lukeshu.com/go/lowmemjson/internal/jsonparse"
)
// A ReEncoderConfig controls how a ReEncoder should behave.
@@ -71,7 +72,7 @@ type ReEncoderConfig struct {
func NewReEncoder(out io.Writer, cfg ReEncoderConfig) *ReEncoder {
return &ReEncoder{
ReEncoderConfig: cfg,
- out: internal.NewAllWriter(out),
+ out: fastio.NewAllWriter(out),
specu: new(speculation),
}
}
@@ -86,7 +87,7 @@ func NewReEncoder(out io.Writer, cfg ReEncoderConfig) *ReEncoder {
// The memory use of a ReEncoder is O(CompactIfUnder+depth).
type ReEncoder struct {
ReEncoderConfig
- out internal.AllWriter
+ out fastio.AllWriter
// state: .Write's and .WriteString's utf8-decoding buffer
buf [utf8.UTFMax]byte
@@ -94,13 +95,13 @@ type ReEncoder struct {
// state: .WriteRune
err error
- par internal.Parser
+ par jsonparse.Parser
written int
inputPos int64
// state: .handleRune
- lastNonSpace internal.RuneType
- lastNonSpaceNonEOF internal.RuneType
+ lastNonSpace jsonparse.RuneType
+ lastNonSpaceNonEOF jsonparse.RuneType
wasNumber bool
curIndent int
uhex [4]byte // "\uABCD"-encoded characters in strings
@@ -135,15 +136,15 @@ func (specu *speculation) Reset() {
type inputTuple struct {
c rune
- t internal.RuneType
+ t jsonparse.RuneType
stackSize int
}
// public API //////////////////////////////////////////////////////////////////
var (
- _ internal.AllWriter = (*ReEncoder)(nil)
- _ io.Closer = (*ReEncoder)(nil)
+ _ fastio.AllWriter = (*ReEncoder)(nil)
+ _ io.Closer = (*ReEncoder)(nil)
)
// Write implements io.Writer; it does what you'd expect.
@@ -208,7 +209,7 @@ func (enc *ReEncoder) WriteString(p string) (int, error) {
// WriteByte implements io.ByteWriter; it does what you'd expect.
func (enc *ReEncoder) WriteByte(b byte) error {
- return internal.WriteByte(enc, b)
+ return fastio.WriteByte(enc, b)
}
// Close implements io.Closer; it does what you'd expect, mostly.
@@ -230,7 +231,7 @@ func (enc *ReEncoder) Close() error {
return enc.err
}
if len(enc.barriers) == 0 {
- if err := enc.handleRune(0, internal.RuneTypeError, enc.stackSize()); err != nil {
+ if err := enc.handleRune(0, jsonparse.RuneTypeError, enc.stackSize()); err != nil {
enc.err = &ReEncodeSyntaxError{
Err: err,
Offset: enc.inputPos,
@@ -274,7 +275,7 @@ rehandle:
return enc.written, enc.err
}
enc.err = enc.handleRune(c, t, enc.stackSize())
- if enc.err == nil && t == internal.RuneTypeEOF {
+ if enc.err == nil && t == jsonparse.RuneTypeEOF {
if enc.AllowMultipleValues && len(enc.barriers) == 0 {
enc.par.Reset()
goto rehandle
@@ -319,7 +320,7 @@ func (enc *ReEncoder) stackSize() int {
return sz
}
-func (enc *ReEncoder) handleRune(c rune, t internal.RuneType, stackSize int) error {
+func (enc *ReEncoder) handleRune(c rune, t jsonparse.RuneType, stackSize int) error {
if enc.CompactIfUnder == 0 || enc.Compact || enc.Indent == "" {
return enc.handleRuneNoSpeculation(c, t)
}
@@ -327,7 +328,7 @@ func (enc *ReEncoder) handleRune(c rune, t internal.RuneType, stackSize int) err
// main
if !enc.specu.speculating { // not speculating
switch t {
- case internal.RuneTypeObjectBeg, internal.RuneTypeArrayBeg: // start speculating
+ case jsonparse.RuneTypeObjectBeg, jsonparse.RuneTypeArrayBeg: // start speculating
if err, _ := enc.handleRunePre(c, t); err != nil {
return err
}
@@ -385,7 +386,7 @@ func (enc *ReEncoder) handleRune(c rune, t internal.RuneType, stackSize int) err
return nil
}
-func (enc *ReEncoder) handleRuneNoSpeculation(c rune, t internal.RuneType) error {
+func (enc *ReEncoder) handleRuneNoSpeculation(c rune, t jsonparse.RuneType) error {
err, shouldHandle := enc.handleRunePre(c, t)
if err != nil {
return err
@@ -398,9 +399,9 @@ func (enc *ReEncoder) handleRuneNoSpeculation(c rune, t internal.RuneType) error
// handleRunePre handles buffered things that need to happen before
// the new rune itself is handled.
-func (enc *ReEncoder) handleRunePre(c rune, t internal.RuneType) (error, bool) {
+func (enc *ReEncoder) handleRunePre(c rune, t jsonparse.RuneType) (error, bool) {
// emit newlines between top-level values
- if enc.lastNonSpace == internal.RuneTypeEOF {
+ if enc.lastNonSpace == jsonparse.RuneTypeEOF {
switch {
case enc.wasNumber && t.IsNumber():
if err := enc.emitByte('\n'); err != nil {
@@ -415,10 +416,10 @@ func (enc *ReEncoder) handleRunePre(c rune, t internal.RuneType) (error, bool) {
// shorten numbers
switch t { // trim trailing '0's from the fraction-part, but don't remove all digits
- case internal.RuneTypeNumberFracDot:
+ case jsonparse.RuneTypeNumberFracDot:
enc.fracZeros = 0
- case internal.RuneTypeNumberFracDig:
- if c == '0' && enc.lastNonSpace == internal.RuneTypeNumberFracDig {
+ case jsonparse.RuneTypeNumberFracDig:
+ if c == '0' && enc.lastNonSpace == jsonparse.RuneTypeNumberFracDig {
enc.fracZeros++
return nil, false
}
@@ -432,9 +433,9 @@ func (enc *ReEncoder) handleRunePre(c rune, t internal.RuneType) (error, bool) {
}
}
switch t { // trim leading '0's from the exponent-part, but don't remove all digits
- case internal.RuneTypeNumberExpE, internal.RuneTypeNumberExpSign:
+ case jsonparse.RuneTypeNumberExpE, jsonparse.RuneTypeNumberExpSign:
enc.expZero = true
- case internal.RuneTypeNumberExpDig:
+ case jsonparse.RuneTypeNumberExpDig:
if c == '0' && enc.expZero {
return nil, false
}
@@ -451,18 +452,18 @@ func (enc *ReEncoder) handleRunePre(c rune, t internal.RuneType) (error, bool) {
// whitespace
switch {
case enc.Compact:
- if t == internal.RuneTypeSpace {
+ if t == jsonparse.RuneTypeSpace {
return nil, false
}
case enc.Indent != "":
switch t {
- case internal.RuneTypeSpace:
+ case jsonparse.RuneTypeSpace:
// let us manage whitespace, don't pass it through
return nil, false
- case internal.RuneTypeObjectEnd, internal.RuneTypeArrayEnd:
+ case jsonparse.RuneTypeObjectEnd, jsonparse.RuneTypeArrayEnd:
enc.curIndent--
switch enc.lastNonSpace {
- case internal.RuneTypeObjectBeg, internal.RuneTypeArrayBeg:
+ case jsonparse.RuneTypeObjectBeg, jsonparse.RuneTypeArrayBeg:
// collapse
default:
if err := enc.emitNlIndent(); err != nil {
@@ -471,17 +472,17 @@ func (enc *ReEncoder) handleRunePre(c rune, t internal.RuneType) (error, bool) {
}
default:
switch enc.lastNonSpace {
- case internal.RuneTypeObjectBeg, internal.RuneTypeObjectComma, internal.RuneTypeArrayBeg, internal.RuneTypeArrayComma:
+ case jsonparse.RuneTypeObjectBeg, jsonparse.RuneTypeObjectComma, jsonparse.RuneTypeArrayBeg, jsonparse.RuneTypeArrayComma:
if err := enc.emitNlIndent(); err != nil {
return err, false
}
- case internal.RuneTypeObjectColon:
+ case jsonparse.RuneTypeObjectColon:
if err := enc.emitByte(' '); err != nil {
return err, false
}
}
switch t {
- case internal.RuneTypeObjectBeg, internal.RuneTypeArrayBeg:
+ case jsonparse.RuneTypeObjectBeg, jsonparse.RuneTypeArrayBeg:
enc.curIndent++
}
}
@@ -491,15 +492,15 @@ func (enc *ReEncoder) handleRunePre(c rune, t internal.RuneType) (error, bool) {
}
// handleRuneMain handles the new rune itself, not buffered things.
-func (enc *ReEncoder) handleRuneMain(c rune, t internal.RuneType) error {
+func (enc *ReEncoder) handleRuneMain(c rune, t jsonparse.RuneType) error {
var err error
switch t {
- case internal.RuneTypeStringChar:
+ case jsonparse.RuneTypeStringChar:
err = enc.emit(writeStringChar(enc.out, c, BackslashEscapeNone, enc.BackslashEscape))
- case internal.RuneTypeStringEsc, internal.RuneTypeStringEscU:
+ case jsonparse.RuneTypeStringEsc, jsonparse.RuneTypeStringEscU:
// do nothing
- case internal.RuneTypeStringEsc1:
+ case jsonparse.RuneTypeStringEsc1:
switch c {
case '"':
err = enc.emit(writeStringChar(enc.out, '"', BackslashEscapeShort, enc.BackslashEscape))
@@ -520,14 +521,14 @@ func (enc *ReEncoder) handleRuneMain(c rune, t internal.RuneType) error {
default:
panic("should not happen")
}
- case internal.RuneTypeStringEscUA:
- enc.uhex[0], _ = internal.HexToInt(c)
- case internal.RuneTypeStringEscUB:
- enc.uhex[1], _ = internal.HexToInt(c)
- case internal.RuneTypeStringEscUC:
- enc.uhex[2], _ = internal.HexToInt(c)
- case internal.RuneTypeStringEscUD:
- enc.uhex[3], _ = internal.HexToInt(c)
+ case jsonparse.RuneTypeStringEscUA:
+ enc.uhex[0], _ = jsonparse.HexToInt(c)
+ case jsonparse.RuneTypeStringEscUB:
+ enc.uhex[1], _ = jsonparse.HexToInt(c)
+ case jsonparse.RuneTypeStringEscUC:
+ enc.uhex[2], _ = jsonparse.HexToInt(c)
+ case jsonparse.RuneTypeStringEscUD:
+ enc.uhex[3], _ = jsonparse.HexToInt(c)
c := 0 |
rune(enc.uhex[0])<<12 |
rune(enc.uhex[1])<<8 |
@@ -535,24 +536,24 @@ func (enc *ReEncoder) handleRuneMain(c rune, t internal.RuneType) error {
rune(enc.uhex[3])<<0
err = enc.emit(writeStringChar(enc.out, c, BackslashEscapeUnicode, enc.BackslashEscape))
- case internal.RuneTypeError: // EOF explicitly stated by .Close()
+ case jsonparse.RuneTypeError: // EOF explicitly stated by .Close()
fallthrough
- case internal.RuneTypeEOF: // EOF implied by the start of the next top-level value
+ case jsonparse.RuneTypeEOF: // EOF implied by the start of the next top-level value
enc.wasNumber = enc.lastNonSpace.IsNumber()
switch {
case enc.ForceTrailingNewlines && len(enc.barriers) == 0:
- t = internal.RuneTypeError // enc.lastNonSpace : an NL isn't needed (we already printed one)
+ t = jsonparse.RuneTypeError // enc.lastNonSpace : an NL isn't needed (we already printed one)
err = enc.emitByte('\n')
default:
- t = internal.RuneTypeEOF // enc.lastNonSpace : an NL *might* be needed
+ t = jsonparse.RuneTypeEOF // enc.lastNonSpace : an NL *might* be needed
}
default:
err = enc.emitByte(byte(c))
}
- if t != internal.RuneTypeSpace {
+ if t != jsonparse.RuneTypeSpace {
enc.lastNonSpace = t
- if t != internal.RuneTypeEOF {
+ if t != jsonparse.RuneTypeEOF {
enc.lastNonSpaceNonEOF = t
}
}