// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later package lowmemjson import ( "git.lukeshu.com/go/lowmemjson/internal/jsonparse" ) type reEncodeCompactNum struct { out reEncoderModule // state fracFirst bool fracZeros int64 expZero bool } var _ reEncoderModule = (*reEncodeCompactNum)(nil) func (enc *reEncodeCompactNum) PopWriteBarrier() { enc.out.PopWriteBarrier() } func (enc *reEncodeCompactNum) HandleRune(c rune, t jsonparse.RuneType, escape BackslashEscapeMode, stackSize int) error { // trim trailing '0's from the fraction-part, but don't remove all digits switch t { case jsonparse.RuneTypeNumberFracDot: enc.fracFirst = true enc.fracZeros = 0 case jsonparse.RuneTypeNumberFracDig: if c == '0' && !enc.fracFirst { enc.fracZeros++ return nil } else { for ; enc.fracZeros > 0; enc.fracZeros-- { if err := enc.out.HandleRune('0', jsonparse.RuneTypeNumberFracDig, escape, stackSize); err != nil { return err } } } enc.fracFirst = false } // trim leading '0's from the exponent-part, but don't remove all digits switch t { case jsonparse.RuneTypeNumberExpE, jsonparse.RuneTypeNumberExpSign: enc.expZero = true case jsonparse.RuneTypeNumberExpDig: if c == '0' && enc.expZero { return nil } enc.expZero = false default: if enc.expZero { if err := enc.out.HandleRune('0', jsonparse.RuneTypeNumberFracDig, escape, stackSize); err != nil { return err } enc.expZero = false } } return enc.out.HandleRune(c, t, escape, stackSize) }