diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-01-26 00:07:39 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-01-26 00:08:56 -0700 |
commit | 4148776399cb7ea5e10c74dc465e4e1e682cb399 (patch) | |
tree | daf8a3aa6521d3d56aa986f10c3d23ea1b016f4b /reencode.go | |
parent | e483afa206686ce748ad270140f99fad9d713aad (diff) |
Move the Parser to the internal package
Diffstat (limited to 'reencode.go')
-rw-r--r-- | reencode.go | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/reencode.go b/reencode.go index e7030f8..34c3851 100644 --- a/reencode.go +++ b/reencode.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 @@ -9,6 +9,8 @@ import ( "fmt" "io" "unicode/utf8" + + "git.lukeshu.com/go/lowmemjson/internal" ) type speculation struct { @@ -67,13 +69,13 @@ type ReEncoder struct { // state: .WriteRune err error - par Parser + par internal.Parser written int inputPos int64 // state: .handleRune handleRuneState struct { - lastNonSpace RuneType + lastNonSpace internal.RuneType wasNumber bool curIndent int uhex [4]byte // "\uABCD"-encoded characters in strings @@ -129,7 +131,7 @@ func (enc *ReEncoder) Close() error { } return enc.err } - if err := enc.handleRune(0, RuneTypeError); err != nil { + if err := enc.handleRune(0, internal.RuneTypeError); err != nil { enc.err = &ReEncodeSyntaxError{ Err: err, Offset: enc.inputPos, @@ -163,7 +165,7 @@ rehandle: return enc.written, enc.err } enc.err = enc.handleRune(c, t) - if enc.err == nil && t == RuneTypeEOF { + if enc.err == nil && t == internal.RuneTypeEOF { if enc.AllowMultipleValues { enc.par.Reset() goto rehandle @@ -182,7 +184,7 @@ rehandle: // internal //////////////////////////////////////////////////////////////////// -func (enc *ReEncoder) handleRune(c rune, t RuneType) error { +func (enc *ReEncoder) handleRune(c rune, t internal.RuneType) error { if enc.CompactIfUnder == 0 || enc.Compact || enc.Indent == "" { return enc.handleRuneNoSpeculation(c, t) } @@ -190,7 +192,7 @@ func (enc *ReEncoder) handleRune(c rune, t RuneType) error { // main if enc.handleRuneState.specu == nil { // not speculating switch t { - case RuneTypeObjectBeg, RuneTypeArrayBeg: // start speculating + case internal.RuneTypeObjectBeg, internal.RuneTypeArrayBeg: // start speculating if err, _ := enc.handleRunePre(c, t); err != nil { return err } @@ -232,7 +234,7 @@ func (enc *ReEncoder) handleRune(c rune, t RuneType) error { return err } enc.handleRuneState = enc.handleRuneState.specu.indentFmt.handleRuneState - case canCompress && (t == RuneTypeObjectEnd || t == RuneTypeArrayEnd): // stop speculating; use compact + case canCompress && (t == internal.RuneTypeObjectEnd || t == internal.RuneTypeArrayEnd): // stop speculating; use compact if _, err := enc.handleRuneState.specu.compactBuf.WriteTo(enc.Out); err != nil { return err } @@ -245,7 +247,7 @@ func (enc *ReEncoder) handleRune(c rune, t RuneType) error { return nil } -func (enc *ReEncoder) handleRuneNoSpeculation(c rune, t RuneType) error { +func (enc *ReEncoder) handleRuneNoSpeculation(c rune, t internal.RuneType) error { err, shouldHandle := enc.handleRunePre(c, t) if err != nil { return err @@ -258,9 +260,9 @@ func (enc *ReEncoder) handleRuneNoSpeculation(c rune, t RuneType) error { // handle buffered things that need to happen before the new rune // itself is handled. -func (enc *ReEncoder) handleRunePre(c rune, t RuneType) (error, bool) { +func (enc *ReEncoder) handleRunePre(c rune, t internal.RuneType) (error, bool) { // emit newlines between top-level values - if enc.handleRuneState.lastNonSpace == RuneTypeEOF { + if enc.handleRuneState.lastNonSpace == internal.RuneTypeEOF { switch { case enc.handleRuneState.wasNumber && t.IsNumber(): if err := enc.emitByte('\n'); err != nil { @@ -275,10 +277,10 @@ func (enc *ReEncoder) handleRunePre(c rune, t RuneType) (error, bool) { // shorten numbers switch t { // trim trailing '0's from the fraction-part, but don't remove all digits - case RuneTypeNumberFracDot: + case internal.RuneTypeNumberFracDot: enc.handleRuneState.fracZeros = 0 - case RuneTypeNumberFracDig: - if c == '0' && enc.handleRuneState.lastNonSpace == RuneTypeNumberFracDig { + case internal.RuneTypeNumberFracDig: + if c == '0' && enc.handleRuneState.lastNonSpace == internal.RuneTypeNumberFracDig { enc.handleRuneState.fracZeros++ return nil, false } @@ -292,9 +294,9 @@ func (enc *ReEncoder) handleRunePre(c rune, t RuneType) (error, bool) { } } switch t { // trim leading '0's from the exponent-part, but don't remove all digits - case RuneTypeNumberExpE, RuneTypeNumberExpSign: + case internal.RuneTypeNumberExpE, internal.RuneTypeNumberExpSign: enc.handleRuneState.expZero = true - case RuneTypeNumberExpDig: + case internal.RuneTypeNumberExpDig: if c == '0' && enc.handleRuneState.expZero { return nil, false } @@ -311,18 +313,18 @@ func (enc *ReEncoder) handleRunePre(c rune, t RuneType) (error, bool) { // whitespace switch { case enc.Compact: - if t == RuneTypeSpace { + if t == internal.RuneTypeSpace { return nil, false } case enc.Indent != "": switch t { - case RuneTypeSpace: + case internal.RuneTypeSpace: // let us manage whitespace, don't pass it through return nil, false - case RuneTypeObjectEnd, RuneTypeArrayEnd: + case internal.RuneTypeObjectEnd, internal.RuneTypeArrayEnd: enc.handleRuneState.curIndent-- switch enc.handleRuneState.lastNonSpace { - case RuneTypeObjectBeg, RuneTypeArrayBeg: + case internal.RuneTypeObjectBeg, internal.RuneTypeArrayBeg: // collapse default: if err := enc.emitNlIndent(); err != nil { @@ -331,17 +333,17 @@ func (enc *ReEncoder) handleRunePre(c rune, t RuneType) (error, bool) { } default: switch enc.handleRuneState.lastNonSpace { - case RuneTypeObjectBeg, RuneTypeObjectComma, RuneTypeArrayBeg, RuneTypeArrayComma: + case internal.RuneTypeObjectBeg, internal.RuneTypeObjectComma, internal.RuneTypeArrayBeg, internal.RuneTypeArrayComma: if err := enc.emitNlIndent(); err != nil { return err, false } - case RuneTypeObjectColon: + case internal.RuneTypeObjectColon: if err := enc.emitByte(' '); err != nil { return err, false } } switch t { - case RuneTypeObjectBeg, RuneTypeArrayBeg: + case internal.RuneTypeObjectBeg, internal.RuneTypeArrayBeg: enc.handleRuneState.curIndent++ } } @@ -351,20 +353,20 @@ func (enc *ReEncoder) handleRunePre(c rune, t RuneType) (error, bool) { } // handle the new rune itself, not buffered things -func (enc *ReEncoder) handleRuneMain(c rune, t RuneType) error { +func (enc *ReEncoder) handleRuneMain(c rune, t internal.RuneType) error { defer func() { - if t != RuneTypeSpace { + if t != internal.RuneTypeSpace { enc.handleRuneState.lastNonSpace = t } }() switch t { - case RuneTypeStringChar: + case internal.RuneTypeStringChar: return enc.emit(writeStringChar(enc.Out, c, BackslashEscapeNone, enc.BackslashEscape)) - case RuneTypeStringEsc, RuneTypeStringEscU: + case internal.RuneTypeStringEsc, internal.RuneTypeStringEscU: return nil - case RuneTypeStringEsc1: + case internal.RuneTypeStringEsc1: switch c { case '"': return enc.emit(writeStringChar(enc.Out, '"', BackslashEscapeShort, enc.BackslashEscape)) @@ -385,17 +387,17 @@ func (enc *ReEncoder) handleRuneMain(c rune, t RuneType) error { default: panic("should not happen") } - case RuneTypeStringEscUA: - enc.handleRuneState.uhex[0], _ = hex2int(c) + case internal.RuneTypeStringEscUA: + enc.handleRuneState.uhex[0], _ = internal.HexToInt(c) return nil - case RuneTypeStringEscUB: - enc.handleRuneState.uhex[1], _ = hex2int(c) + case internal.RuneTypeStringEscUB: + enc.handleRuneState.uhex[1], _ = internal.HexToInt(c) return nil - case RuneTypeStringEscUC: - enc.handleRuneState.uhex[2], _ = hex2int(c) + case internal.RuneTypeStringEscUC: + enc.handleRuneState.uhex[2], _ = internal.HexToInt(c) return nil - case RuneTypeStringEscUD: - enc.handleRuneState.uhex[3], _ = hex2int(c) + case internal.RuneTypeStringEscUD: + enc.handleRuneState.uhex[3], _ = internal.HexToInt(c) c := 0 | rune(enc.handleRuneState.uhex[0])<<12 | rune(enc.handleRuneState.uhex[1])<<8 | @@ -403,16 +405,16 @@ func (enc *ReEncoder) handleRuneMain(c rune, t RuneType) error { rune(enc.handleRuneState.uhex[3])<<0 return enc.emit(writeStringChar(enc.Out, c, BackslashEscapeUnicode, enc.BackslashEscape)) - case RuneTypeError: // EOF explicitly stated by .Close() + case internal.RuneTypeError: // EOF explicitly stated by .Close() fallthrough - case RuneTypeEOF: // EOF implied by the start of the next top-level value + case internal.RuneTypeEOF: // EOF implied by the start of the next top-level value enc.handleRuneState.wasNumber = enc.handleRuneState.lastNonSpace.IsNumber() switch { case enc.ForceTrailingNewlines: - t = RuneTypeError // enc.handleRuneState.lastNonSpace : an NL isn't needed (we already printed one) + t = internal.RuneTypeError // enc.handleRuneState.lastNonSpace : an NL isn't needed (we already printed one) return enc.emitByte('\n') default: - t = RuneTypeEOF // enc.handleRuneState.lastNonSpace : an NL *might* be needed + t = internal.RuneTypeEOF // enc.handleRuneState.lastNonSpace : an NL *might* be needed return nil } default: |