parent
9851697694
commit
8c2c4c1a67
@ -1,372 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name builder.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package _pjson
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/bins"
|
||||
"activething.com/go/gogo/core/errs"
|
||||
"activething.com/go/gogo/core/opts"
|
||||
"activething.com/go/gogo/packs"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"math/cmplx"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
Builder struct {
|
||||
options Options
|
||||
encoder *json.Encoder
|
||||
dateLayout string
|
||||
scratch [64]byte
|
||||
state packs.BuilderState
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
func NewBuilder (options ...opts.OptionFnc[Builder]) *Builder {
|
||||
return opts.Apply[Builder](&Builder{
|
||||
state : *packs.NewBuilderState(),
|
||||
dateLayout: time.RFC822Z,
|
||||
options : JSONOptionsQuote | JSONOptionsEscapeHTML,
|
||||
}, options ...)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (p *Builder) Data () []byte {
|
||||
return p.state.Bytes()
|
||||
}
|
||||
|
||||
func (p *Builder) Error() error {
|
||||
return p.state.Error
|
||||
}
|
||||
|
||||
func (p *Builder) SetError (err error) {
|
||||
p.state.SetError(err)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func (p *Builder) Reset() {
|
||||
p.encoder = nil
|
||||
p.state.Reset()
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (p *Builder) Any (value any) {
|
||||
switch value.(type) {
|
||||
case json.Marshaler :
|
||||
p.state.SetError(p.jsonEncoder().Encode(value))
|
||||
|
||||
default:
|
||||
packs.BuildAny(p ,value,func(v any) error { return p.jsonEncoder().Encode(value) })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) Binary (value []byte) {
|
||||
if value == nil {
|
||||
p.state.Write(G.nullValue)
|
||||
return
|
||||
}
|
||||
if len(value) == 0{
|
||||
p.state.Write(G.stringEmpty)
|
||||
return
|
||||
}
|
||||
|
||||
p.state.WriteByte('"')
|
||||
ln := base64.StdEncoding.EncodedLen(len(value))
|
||||
if ln <= len(p.scratch) {
|
||||
dst := p.scratch[:ln]
|
||||
base64.StdEncoding.Encode(dst, value)
|
||||
p.state.Write(dst)
|
||||
} else if ln <= 1024 {
|
||||
dst := make([]byte, ln)
|
||||
base64.StdEncoding.Encode(dst, value)
|
||||
p.state.Write(dst)
|
||||
} else {
|
||||
enc := base64.NewEncoder(base64.StdEncoding, p.state)
|
||||
enc.Write(value)
|
||||
enc.Close()
|
||||
}
|
||||
p.state.WriteByte('"')
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) String(value string) {
|
||||
if !p.state.SetValue() {
|
||||
panic(p.state.Error)
|
||||
}
|
||||
if len(value) == 0 {
|
||||
p.state.Write(G.stringEmpty)
|
||||
} else {
|
||||
p.string(value,p.options.EscapeHTML())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) Bool (value bool) {
|
||||
if !p.state.SetValue() {
|
||||
panic(p.state.Error)
|
||||
}
|
||||
if value {
|
||||
p.state.Write(G.trueValue)
|
||||
} else {
|
||||
p.state.Write(G.falseValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) Rune (value rune) {
|
||||
p.UInt64(uint64(value))
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) UInt(value uint) { p.UInt64(uint64(value)) }
|
||||
func (p *Builder) UInt8(value uint8) { p.UInt64(uint64(value)) }
|
||||
func (p *Builder) UInt16(value uint16) { p.UInt64(uint64(value)) }
|
||||
func (p *Builder) UInt32(value uint32) { p.UInt64(uint64(value)) }
|
||||
func (p *Builder) UInt64(value uint64) {
|
||||
if !p.state.SetValue() {
|
||||
panic(p.state.Error)
|
||||
}
|
||||
if value == 0 {
|
||||
p.state.WriteByte('0')
|
||||
} else {
|
||||
p.state.WriteUIntStr(value, 10)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) Int (value int) { p.Int64(int64(value)) }
|
||||
func (p *Builder) Int8 (value int8) { p.Int64(int64(value)) }
|
||||
func (p *Builder) Int16(value int16) { p.Int64(int64(value)) }
|
||||
func (p *Builder) Int32(value int32) { p.Int64(int64(value)) }
|
||||
func (p *Builder) Int64(value int64) {
|
||||
if !p.state.SetValue() {
|
||||
panic(p.state.Error)
|
||||
}
|
||||
if value == 0 {
|
||||
if p.options.IgnoreDefaults() && p.state.Node.Kind == packs.NodeKindObject {
|
||||
p.state.Truncate(p.state.Len())
|
||||
return
|
||||
}
|
||||
p.state.WriteByte('0')
|
||||
} else {
|
||||
p.state.WriteIntStr(value, 10)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) Float32(value float32) { p.Float64(float64(value)) }
|
||||
|
||||
func (p *Builder) Float64(value float64) {
|
||||
if !p.state.SetValue() {
|
||||
panic(p.state.Error)
|
||||
}
|
||||
if p.options.QuoteFloats() {
|
||||
p.state.WriteByte('"')
|
||||
}
|
||||
switch {
|
||||
case value == 0 : p.state.Write(G.zeroValue)
|
||||
case math.IsNaN(value) : p.state.Write(G.floatNaN)
|
||||
case math.IsInf(value, 1) : p.state.Write(G.floatInfPos)
|
||||
case math.IsInf(value, -1) : p.state.Write(G.floatInfNeg)
|
||||
default:
|
||||
p.state.WriteFloatStr(value, 'f', -1)
|
||||
}
|
||||
if p.options.QuoteFloats() {
|
||||
p.state.WriteByte('"')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (p *Builder) Complex64(value complex64) { p.Complex128(complex128(value)) }
|
||||
func (p *Builder) Complex128(value complex128){
|
||||
if !p.state.SetValue() {
|
||||
panic(p.state.Error)
|
||||
}
|
||||
if p.options.QuoteFloats() {
|
||||
p.state.WriteByte('"')
|
||||
}
|
||||
switch {
|
||||
case value == 0 : p.state.Write(G.zeroValue)
|
||||
case cmplx.IsInf(value): p.state.Write(G.floatInfPos)
|
||||
case cmplx.IsNaN(value): p.state.Write(G.floatNaN)
|
||||
default:
|
||||
r, i := real(value), imag(value)
|
||||
p.state.WriteByte('"')
|
||||
p.state.WriteFloatStr(r, 'f', -1)
|
||||
p.state.WriteByte('+')
|
||||
p.state.WriteFloatStr(i, 'f', -1)
|
||||
p.state.Write2Byte('i', '"')
|
||||
}
|
||||
if p.options.QuoteFloats() {
|
||||
p.state.WriteByte('"')
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) Date (value time.Time) {
|
||||
if !p.state.SetValue() {
|
||||
panic(p.state.Error)
|
||||
}
|
||||
p.state.WriteByte('"')
|
||||
p.state.AppendWith(bins.AppendFnc(func(d []byte) []byte {
|
||||
return value.AppendFormat(d,p.dateLayout)
|
||||
}))
|
||||
p.state.WriteByte('"')
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) List(buildFnc func(builder packs.BuilderList)) {
|
||||
p.packCompound(packs.NodeKindList, '[', ']', func() { buildFnc(p) })
|
||||
}
|
||||
|
||||
func (p *Builder) Map(buildFnc func(builder packs.BuilderMap)) {
|
||||
p.packCompound(packs.NodeKindMap, '{', '}', func() { buildFnc(p) })
|
||||
}
|
||||
|
||||
func (p *Builder) Object(buildFnc func(builder packs.BuilderObject)) {
|
||||
p.packCompound(packs.NodeKindObject, '{', '}', func() { buildFnc(p) })
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) packCompound(kind packs.NodeKind, opening, closing byte, buildFnc func()) {
|
||||
dn := false
|
||||
defer func(d *bool) {
|
||||
if !(*d) {
|
||||
p.state.SetError(errs.ToError(recover()))
|
||||
}
|
||||
}(&dn)
|
||||
if p.open(kind, opening) {
|
||||
buildFnc()
|
||||
p.close(closing)
|
||||
}
|
||||
dn = true
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (p *Builder) string(s string, scapeHTML bool) {
|
||||
p.state.WriteByte('"')
|
||||
start := 0
|
||||
for i := 0; i < len(s); {
|
||||
if b := s[i]; b < utf8.RuneSelf {
|
||||
if !G.jsonChars[b].isHtmlUnsafe() || (!scapeHTML && !G.jsonChars[b].isUnsafe()) {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
if start < i {
|
||||
p.state.WriteString(s[start:i])
|
||||
}
|
||||
p.state.WriteByte('\\')
|
||||
switch b {
|
||||
case '\\', '"': p.state.WriteByte(b)
|
||||
case '\n': p.state.WriteByte('n')
|
||||
case '\r': p.state.WriteByte('r')
|
||||
case '\t': p.state.WriteByte('t')
|
||||
default:
|
||||
p.state.WriteString(`u00`)
|
||||
p.state.Write2Byte(G.hex[b>>4], G.hex[b&0xF])
|
||||
}
|
||||
i++
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
c, size := utf8.DecodeRuneInString(s[i:])
|
||||
if c == utf8.RuneError && size == 1 {
|
||||
if start < i {
|
||||
p.state.WriteString(s[start:i])
|
||||
}
|
||||
p.state.WriteString(`\ufffd`)
|
||||
i += size
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
|
||||
if c == '\u2028' || c == '\u2029' {
|
||||
if start < i {
|
||||
p.state.WriteString(s[start:i])
|
||||
}
|
||||
p.state.WriteString(`\u202`)
|
||||
p.state.WriteByte(G.hex[c&0xF])
|
||||
i += size
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
i += size
|
||||
}
|
||||
if start < len(s) {
|
||||
p.state.WriteString(s[start:])
|
||||
}
|
||||
p.state.WriteByte('"')
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func (p *Builder) throwPanicIfError() {
|
||||
if p.state.Error != nil {
|
||||
panic(p.state.Error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (p *Builder) jsonEncoder () *json.Encoder {
|
||||
if p.encoder == nil {
|
||||
p.encoder = json.NewEncoder(p.state)
|
||||
p.encoder.SetEscapeHTML(p.options.EscapeHTML())
|
||||
}
|
||||
return p.encoder
|
||||
}
|
||||
|
||||
func (p *Builder) open(kind packs.NodeKind, opening byte) bool {
|
||||
if p.state.Open(kind) {
|
||||
p.addSep()
|
||||
p.state.WriteByte(opening)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Builder) close(closing byte) bool {
|
||||
if p.state.Close() {
|
||||
p.state.WriteByte(closing)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name builderList.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package _pjson
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/packs"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (p *Builder) ItemAny (value any) { p.addSep(); p.Any(value) }
|
||||
|
||||
func (p *Builder) ItemBinary (value []byte){ p.addSep(); p.Binary(value) }
|
||||
func (p *Builder) ItemString (value string){ p.addSep(); p.String(value) }
|
||||
|
||||
func (p *Builder) ItemBool (value bool) { p.addSep(); p.Bool(value) }
|
||||
func (p *Builder) ItemRune (value rune) { p.addSep(); p.Rune(value) }
|
||||
|
||||
func (p *Builder) ItemInt8 (value int8) { p.addSep(); p.Int64(int64(value)) }
|
||||
func (p *Builder) ItemInt16 (value int16) { p.addSep(); p.Int64(int64(value)) }
|
||||
func (p *Builder) ItemInt32 (value int32) { p.addSep(); p.Int64(int64(value)) }
|
||||
func (p *Builder) ItemInt64 (value int64) { p.addSep(); p.Int64(value) }
|
||||
|
||||
func (p *Builder) ItemUInt8 (value uint8) { p.addSep(); p.UInt64(uint64(value)) }
|
||||
func (p *Builder) ItemUInt16 (value uint16){ p.addSep(); p.UInt64(uint64(value)) }
|
||||
func (p *Builder) ItemUInt32 (value uint32){ p.addSep(); p.UInt64(uint64(value)) }
|
||||
func (p *Builder) ItemUInt64 (value uint64){ p.addSep(); p.UInt64(value) }
|
||||
|
||||
func (p *Builder) ItemFloat32(value float32){ p.addSep(); p.Float64(float64(value)) }
|
||||
func (p *Builder) ItemFloat64(value float64){ p.addSep(); p.Float64(value) }
|
||||
|
||||
func (p *Builder) ItemComplex64 (value complex64) { p.addSep(); p.Complex128(complex128(value)) }
|
||||
func (p *Builder) ItemComplex128(value complex128) { p.addSep(); p.Complex128(value) }
|
||||
|
||||
func (p *Builder) ItemDate (value time.Time) { p.addSep(); p.Date(value) }
|
||||
|
||||
func (p *Builder) ItemList (builder func(packer packs.BuilderList)) { p.addSep(); p.ItemList(builder) }
|
||||
func (p *Builder) ItemMap (builder func(packer packs.BuilderMap)) { p.addSep(); p.ItemMap(builder) }
|
||||
func (p *Builder) ItemObject(builder func(packer packs.BuilderObject)){ p.addSep(); p.ItemObject(builder) }
|
||||
|
||||
|
||||
@ -1,115 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name BuilderMap.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package _pjson
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/packs"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (p *Builder) ElemAny (key any, value any) {
|
||||
if p.addKey(key) {
|
||||
p.Any(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemBinary (key any, value []byte){
|
||||
if p.addKey(key) {
|
||||
p.Binary(value)
|
||||
}
|
||||
}
|
||||
func (p *Builder) ElemString (key any, value string){
|
||||
if p.addKey(key) {
|
||||
p.String(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemBool (key any, value bool ){
|
||||
if p.addKey(key) {
|
||||
p.Bool(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemRune (key any, value rune ){
|
||||
if p.addKey(key) {
|
||||
p.Rune(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemInt8 (key any, value int8 ){ p.ElemInt64(key, int64(value)) }
|
||||
func (p *Builder) ElemInt16 (key any, value int16 ){ p.ElemInt64(key, int64(value)) }
|
||||
func (p *Builder) ElemInt32 (key any, value int32 ){ p.ElemInt64(key, int64(value)) }
|
||||
func (p *Builder) ElemInt64 (key any, value int64 ){
|
||||
if p.addKey(key) {
|
||||
p.Int64(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemUInt8 (key any, value uint8 ){ p.ElemUInt64(key, uint64(value)) }
|
||||
func (p *Builder) ElemUInt16 (key any, value uint16){ p.ElemUInt64(key, uint64(value)) }
|
||||
func (p *Builder) ElemUInt32 (key any, value uint32){ p.ElemUInt64(key, uint64(value)) }
|
||||
func (p *Builder) ElemUInt64 (key any, value uint64){
|
||||
if p.addKey(key) {
|
||||
p.UInt64(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemFloat32(key any, value float32){ p.ElemFloat64(key, float64(value)) }
|
||||
func (p *Builder) ElemFloat64(key any, value float64){
|
||||
if p.addKey(key) {
|
||||
p.Float64(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemComplex64 (key any, value complex64 ){ p.ElemComplex128(key, complex128(value)) }
|
||||
func (p *Builder) ElemComplex128(key any, value complex128){
|
||||
if p.addKey(key) {
|
||||
p.Complex128(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemDate (key any, value time.Time) {
|
||||
if p.addKey(key) {
|
||||
p.Date(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemList (key any, builder func(packer packs.BuilderList)) {
|
||||
if p.addKey(key) {
|
||||
p.List(builder)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemMap (key any, builder func(packer packs.BuilderMap)) {
|
||||
if p.addKey(key) {
|
||||
p.Map(builder)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) ElemObject(key any, builder func(packer packs.BuilderObject)) {
|
||||
if p.addKey(key) {
|
||||
p.Object(builder)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,143 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name BuilderObject.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package _pjson
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/packs"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (p *Builder) PropAny (name string, value any) {
|
||||
if p.addName(name) {
|
||||
p.Any(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropBinary (name string, value []byte){
|
||||
if p.options.IgnoreDefaults() && len(value) == 0 {
|
||||
return
|
||||
}
|
||||
if p.addName(name) {
|
||||
p.Binary(value)
|
||||
}
|
||||
}
|
||||
func (p *Builder) PropString (name string, value string){
|
||||
if p.options.IgnoreDefaults() && len(value) == 0 {
|
||||
return
|
||||
}
|
||||
if p.addName(name) {
|
||||
p.String(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropBool (name string, value bool ){
|
||||
if p.options.IgnoreDefaults() && !value {
|
||||
return
|
||||
}
|
||||
if p.addName(name) {
|
||||
p.Bool(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropRune (name string, value rune ){
|
||||
if p.options.IgnoreDefaults() && value == 0 {
|
||||
return
|
||||
}
|
||||
if p.addName(name) {
|
||||
p.Rune(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropInt8 (name string, value int8 ){ p.PropInt64(name, int64(value)) }
|
||||
func (p *Builder) PropInt16 (name string, value int16 ){ p.PropInt64(name, int64(value)) }
|
||||
func (p *Builder) PropInt32 (name string, value int32 ){ p.PropInt64(name, int64(value)) }
|
||||
func (p *Builder) PropInt64 (name string, value int64 ){
|
||||
if p.options.IgnoreDefaults() && value == 0 {
|
||||
return
|
||||
}
|
||||
if p.addName(name) {
|
||||
p.Int64(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropUInt8 (name string, value uint8 ){ p.PropUInt64(name, uint64(value)) }
|
||||
func (p *Builder) PropUInt16 (name string, value uint16){ p.PropUInt64(name, uint64(value)) }
|
||||
func (p *Builder) PropUInt32 (name string, value uint32){ p.PropUInt64(name, uint64(value)) }
|
||||
func (p *Builder) PropUInt64 (name string, value uint64){
|
||||
if p.options.IgnoreDefaults() && value == 0 {
|
||||
return
|
||||
}
|
||||
if p.addName(name) {
|
||||
p.UInt64(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropFloat32(name string, value float32){ p.PropFloat64(name, float64(value)) }
|
||||
func (p *Builder) PropFloat64(name string, value float64){
|
||||
if p.options.IgnoreDefaults() && value == 0 {
|
||||
return
|
||||
}
|
||||
if p.addName(name) {
|
||||
p.Float64(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropComplex64 (name string, value complex64 ){ p.PropComplex128(name, complex128(value)) }
|
||||
func (p *Builder) PropComplex128(name string, value complex128){
|
||||
if p.options.IgnoreDefaults() && value == (0+0i) {
|
||||
return
|
||||
}
|
||||
if p.addName(name) {
|
||||
p.Complex128(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropDate (name string, value time.Time) {
|
||||
if p.options.IgnoreDefaults() && value.IsZero() {
|
||||
return
|
||||
}
|
||||
if p.addName(name) {
|
||||
p.Date(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropList (name string, builder func(packer packs.BuilderList)) {
|
||||
if p.addName(name) {
|
||||
p.List(builder)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropMap (name string, builder func(packer packs.BuilderMap)) {
|
||||
if p.addName(name) {
|
||||
p.Map(builder)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Builder) PropObject(name string, builder func(packer packs.BuilderObject)) {
|
||||
if p.addName(name) {
|
||||
p.Object(builder)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
module actiovething.com/go/gogo/packs/pjson
|
||||
|
||||
|
||||
go 1.20
|
||||
@ -1,77 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name gogo.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package _pjson
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
var (
|
||||
G = struct {
|
||||
hex string
|
||||
jsonChars [utf8.RuneSelf]jsonCharAtt
|
||||
|
||||
sep byte
|
||||
nullValue []byte
|
||||
zeroValue []byte
|
||||
trueValue []byte
|
||||
falseValue []byte
|
||||
mapEmpty []byte
|
||||
listEmpty []byte
|
||||
objectEmpty []byte
|
||||
stringEmpty []byte
|
||||
floatNaN []byte
|
||||
floatInfPos []byte
|
||||
floatInfNeg []byte
|
||||
}{
|
||||
|
||||
hex: "0123456789abcdef",
|
||||
jsonChars: initJSONChars(),
|
||||
|
||||
sep: ',',
|
||||
nullValue: []byte{'n', 'u', 'l', 'l'},
|
||||
zeroValue: []byte{'0'},
|
||||
trueValue: []byte{'"','t', 'r', 'u', 'e','"'},
|
||||
falseValue: []byte{'"','f', 'a', 'l', 's', 'e','"'},
|
||||
mapEmpty: []byte{'{', '}'},
|
||||
objectEmpty: []byte{'{', '}'},
|
||||
listEmpty: []byte{'[', ']'},
|
||||
stringEmpty: []byte{'"', '"'},
|
||||
floatNaN: []byte{'"', 'N', 'a', 'N', '"'},
|
||||
floatInfPos: []byte{'"', 'I', 'n', 'f', '"'},
|
||||
floatInfNeg: []byte{'"', '-', 'I', 'n', 'f', '"'},
|
||||
}
|
||||
)
|
||||
|
||||
func initJSONChars() [utf8.RuneSelf]jsonCharAtt {
|
||||
var tb = [utf8.RuneSelf]jsonCharAtt{
|
||||
'"': jsonCharAttAllUnsafe,
|
||||
'&': jsonCharAttHtmlUnsafe,
|
||||
'<': jsonCharAttHtmlUnsafe,
|
||||
'>': jsonCharAttHtmlUnsafe,
|
||||
'\\': jsonCharAttAllUnsafe,
|
||||
}
|
||||
for i := 0; i <= 31; i++ {
|
||||
tb[i] = jsonCharAttAllUnsafe
|
||||
}
|
||||
return tb
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name json_char_atts.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package _pjson
|
||||
|
||||
const (
|
||||
jsonCharAttUnsafe jsonCharAtt = 1 << iota
|
||||
jsonCharAttHtmlUnsafe
|
||||
|
||||
jsonCharAttAllUnsafe = jsonCharAttUnsafe | jsonCharAttHtmlUnsafe
|
||||
)
|
||||
|
||||
type jsonCharAtt uint8
|
||||
|
||||
func (a jsonCharAtt) isUnsafe() bool {
|
||||
return a&jsonCharAttUnsafe != 0
|
||||
}
|
||||
|
||||
func (a jsonCharAtt) isHtmlUnsafe() bool {
|
||||
return a&jsonCharAttHtmlUnsafe != 0
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name new_builder.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package _pjson
|
||||
|
||||
|
||||
|
||||
func (p *Builder) addSep () {
|
||||
if p.state.Node.Count > 0 {
|
||||
p.state.WriteByte(',')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) addKey (key any) bool {
|
||||
p.addSep()
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) addName(name string) bool {
|
||||
p.addSep()
|
||||
p.state.WriteByte('"')
|
||||
p.state.WriteString(name)
|
||||
p.state.WriteByte('"')
|
||||
p.state.WriteByte(':')
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
func (p *Builder) stringifyKey(key any) string {
|
||||
return ""
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name options.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package _pjson
|
||||
|
||||
const (
|
||||
|
||||
JSONOptionsQuote Options = 1 << iota
|
||||
JSONOptionsEscapeHTML
|
||||
JSONOptionsIgnoreKeys
|
||||
JSONOptionsQuoteFloats
|
||||
JSONOptionsIgnoreDefaults
|
||||
|
||||
)
|
||||
|
||||
type Options uint8
|
||||
|
||||
|
||||
|
||||
|
||||
func (o Options) Quoted() bool {
|
||||
return o&JSONOptionsQuote != 0
|
||||
}
|
||||
|
||||
func (o Options) QuoteFloats() bool {
|
||||
return o&JSONOptionsQuoteFloats != 0
|
||||
}
|
||||
|
||||
func (o Options) EscapeHTML() bool {
|
||||
return o&JSONOptionsEscapeHTML != 0
|
||||
}
|
||||
|
||||
func (o Options) IgnoreKeys() bool {
|
||||
return o&JSONOptionsIgnoreKeys != 0
|
||||
}
|
||||
|
||||
func (o Options) IgnoreDefaults() bool {
|
||||
return o&JSONOptionsIgnoreDefaults != 0
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name pack_builder.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
import "time"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
type (
|
||||
|
||||
|
||||
Builder interface {
|
||||
Data () []byte
|
||||
Error () error
|
||||
SetError(err error)
|
||||
|
||||
Any (value any)
|
||||
|
||||
Binary (value []byte)
|
||||
String (value string)
|
||||
|
||||
Bool (value bool)
|
||||
Rune (value rune)
|
||||
|
||||
Int8 (value int8)
|
||||
Int16 (value int16)
|
||||
Int32 (value int32)
|
||||
Int64 (value int64)
|
||||
|
||||
UInt8 (value uint8)
|
||||
UInt16 (value uint16)
|
||||
UInt32 (value uint32)
|
||||
UInt64 (value uint64)
|
||||
|
||||
Float32 (value float32)
|
||||
Float64 (value float64)
|
||||
|
||||
Complex64 (value complex64)
|
||||
Complex128(value complex128)
|
||||
|
||||
Date(value time.Time)
|
||||
|
||||
BuildList (builder func(packer BuilderList))
|
||||
BuildMap (builder func(packer BuilderMap))
|
||||
BuildObject(builder func(packer BuilderObject))
|
||||
}
|
||||
)
|
||||
@ -1,63 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name pack_builder_list.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
import "time"
|
||||
|
||||
type (
|
||||
|
||||
BuilderList interface {
|
||||
|
||||
ItemAny (value any)
|
||||
|
||||
ItemBinary (value []byte)
|
||||
ItemString (value string)
|
||||
|
||||
ItemBool (value bool)
|
||||
ItemRune (value rune)
|
||||
|
||||
ItemInt8 (value int8)
|
||||
ItemInt16 (value int16)
|
||||
ItemInt32 (value int32)
|
||||
ItemInt64 (value int64)
|
||||
|
||||
ItemUInt8 (value uint8)
|
||||
ItemUInt16 (value uint16)
|
||||
ItemUInt32 (value uint32)
|
||||
ItemUInt64 (value uint64)
|
||||
|
||||
ItemFloat32(value float32)
|
||||
ItemFloat64(value float64)
|
||||
|
||||
ItemComplex64 (value complex64)
|
||||
ItemComplex128(value complex128)
|
||||
|
||||
ItemDate (value time.Time)
|
||||
|
||||
ItemList (builder func(packer BuilderList))
|
||||
ItemMap (builder func(packer BuilderMap))
|
||||
ItemObject(builder func(packer BuilderObject))
|
||||
|
||||
}
|
||||
)
|
||||
@ -1,64 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name pack_builder_map.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
import "time"
|
||||
|
||||
type (
|
||||
|
||||
|
||||
BuilderMap interface {
|
||||
|
||||
ElemAny (key any, value any)
|
||||
|
||||
ElemBinary (key any, value []byte)
|
||||
ElemString (key any, value string)
|
||||
|
||||
ElemBool (key any, value bool)
|
||||
ElemRune (key any, value rune)
|
||||
|
||||
ElemInt8 (key any, value int8)
|
||||
ElemInt16 (key any, value int16)
|
||||
ElemInt32 (key any, value int32)
|
||||
ElemInt64 (key any, value int64)
|
||||
|
||||
ElemUInt8 (key any, value uint8)
|
||||
ElemUInt16 (key any, value uint16)
|
||||
ElemUInt32 (key any, value uint32)
|
||||
ElemUInt64 (key any, value uint64)
|
||||
|
||||
ElemFloat32(key any, value float32)
|
||||
ElemFloat64(key any, value float64)
|
||||
|
||||
ElemComplex64 (key any, value complex64)
|
||||
ElemComplex128(key any, value complex128)
|
||||
|
||||
ElemDate(key any, value time.Time)
|
||||
|
||||
ElemList (key any, builder func(packer BuilderList))
|
||||
ElemMap (key any, builder func(packer BuilderMap))
|
||||
ElemObject(key any, builder func(packer BuilderObject))
|
||||
}
|
||||
|
||||
)
|
||||
@ -1,61 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name pack_builder_object.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
import "time"
|
||||
|
||||
type (
|
||||
BuilderObject interface {
|
||||
|
||||
PropAny (name string, value any)
|
||||
|
||||
PropBinary (name string, value []byte)
|
||||
PropString (name string, value string)
|
||||
|
||||
PropBool (name string, value bool)
|
||||
PropRune (name string, value rune)
|
||||
|
||||
PropInt8 (name string, value int8)
|
||||
PropInt16 (name string, value int16)
|
||||
PropInt32 (name string, value int32)
|
||||
PropInt64 (name string, value int64)
|
||||
|
||||
PropUInt8 (name string, value uint8)
|
||||
PropUInt16 (name string, value uint16)
|
||||
PropUInt32 (name string, value uint32)
|
||||
PropUInt64 (name string, value uint64)
|
||||
|
||||
PropFloat32(name string, value float32)
|
||||
PropFloat64(name string, value float64)
|
||||
|
||||
PropComplex64 (name string, value complex64)
|
||||
PropComplex128(name string, value complex128)
|
||||
|
||||
PropDate(name string, value time.Time)
|
||||
|
||||
PropList (name string, builder func(packer BuilderList))
|
||||
PropMap (name string, builder func(packer BuilderMap))
|
||||
PropObject(name string, builder func(packer BuilderObject))
|
||||
}
|
||||
)
|
||||
@ -1,152 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name builder_state.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/bins"
|
||||
"activething.com/go/gogo/core/slices"
|
||||
"activething.com/go/gogo/core/syncs"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
|
||||
const maxCyclesCheckIdle = 100
|
||||
|
||||
type (
|
||||
|
||||
|
||||
State struct {
|
||||
*bins.Buffer/*Embedded*/
|
||||
Node *StateNode
|
||||
Temp [64]byte
|
||||
Seen map[any]struct{}
|
||||
Error error
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
|
||||
func NewState() *State {
|
||||
if atomic.CompareAndSwapUint32(&G.poolsSem,0,1) {
|
||||
G.nodePool = syncs.NewPool[StateNode](
|
||||
syncs.PoolWithNew[StateNode](func()*StateNode{
|
||||
return &StateNode{
|
||||
Kind: NodeKindValue,
|
||||
keys: make(slices.String, 0, 10),
|
||||
}
|
||||
}),
|
||||
)
|
||||
G.statePool = syncs.NewPool[State](
|
||||
syncs.PoolWithNew[State](func() *State {
|
||||
return &State{
|
||||
Node : G.nodePool.Get().Init(nil, NodeKindValue, 0),
|
||||
Buffer: bins.NewBuffer(),
|
||||
Seen: make(map[any]struct{}),
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
return G.statePool.Get()
|
||||
}
|
||||
|
||||
|
||||
func ReleaseState (state *State) {
|
||||
if state == nil {
|
||||
state.Buffer.Reset()
|
||||
state.Node.Reset()
|
||||
state.Error = nil
|
||||
if atomic.LoadUint32(&G.poolsSem) == 1 {
|
||||
G.statePool.Put(state)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func (s *State) SetError(err error) bool {
|
||||
if s.Error != nil {
|
||||
return true
|
||||
}
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
s.Error = err
|
||||
s.Reset()
|
||||
s.Node.Reset()
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *State) SetKey(key string) bool {
|
||||
if s.Error != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if s.Node.keys.Has(key) {
|
||||
return !s.SetError(G.ErrDuplicatedKey)
|
||||
}
|
||||
s.Node.keys = s.Node.keys.Append(key)
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *State) SetValue() bool {
|
||||
if s.Error != nil {
|
||||
return false
|
||||
}
|
||||
s.Node.Count++
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *State) Open(kind NodeKind) bool {
|
||||
if s.Error != nil {
|
||||
return false
|
||||
}
|
||||
if s.Node.Kind == NodeKindValue {
|
||||
if s.Node.Count > 0 {
|
||||
return !s.SetError(G.ErrInvalidNode)
|
||||
}
|
||||
s.Node.Init(s.Node.Parent, kind, s.Len())
|
||||
} else {
|
||||
s.Node = G.nodePool.Get().Init(s.Node, kind, s.Len())
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *State) Close() bool {
|
||||
if s.Error != nil {
|
||||
return false
|
||||
}
|
||||
if s.Node.Kind == NodeKindValue {
|
||||
return !s.SetError(G.ErrInvalidNode)
|
||||
}
|
||||
|
||||
if s.Node.Parent != nil {
|
||||
p := s.Node
|
||||
s.Node = s.Node.Parent
|
||||
G.nodePool.Put(p.Reset())
|
||||
}
|
||||
s.Node.Count++
|
||||
return true
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name builder_node.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/slices"
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
StateNode struct {
|
||||
Parent *StateNode
|
||||
Start int
|
||||
Count int
|
||||
Level int
|
||||
Kind NodeKind
|
||||
keys slices.String
|
||||
}
|
||||
)
|
||||
|
||||
func (n *StateNode) Init(parent *StateNode, kind NodeKind, start int) *StateNode {
|
||||
n.Parent = parent
|
||||
if parent != nil {
|
||||
n.Level = parent.Level + 1
|
||||
} else {
|
||||
n.Level = 0
|
||||
}
|
||||
n.Level = 0
|
||||
n.Count = 0
|
||||
n.Start = start
|
||||
n.Kind = kind
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *StateNode) Reset() *StateNode {
|
||||
n.Parent = nil
|
||||
n.keys = n.keys[:0]
|
||||
return n
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name node_kind.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
const (
|
||||
|
||||
NodeKindValue NodeKind = iota
|
||||
NodeKindList
|
||||
NodeKindMap
|
||||
NodeKindObject
|
||||
)
|
||||
|
||||
type NodeKind uint8
|
||||
|
||||
@ -1,215 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name m.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/errs"
|
||||
"activething.com/go/gogo/core/syncs"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
G = struct {
|
||||
|
||||
poolsSem uint32
|
||||
statePool *syncs.Pool[State]
|
||||
nodePool *syncs.Pool[StateNode]
|
||||
|
||||
ErrInvalidNode errs.ErrCode
|
||||
ErrInvalidElement errs.ErrCode
|
||||
ErrInvalidKey errs.ErrCode
|
||||
ErrDuplicatedKey errs.ErrCode
|
||||
ErrKeyRequired errs.ErrCode
|
||||
ErrValueRequired errs.ErrCode
|
||||
ErrInvalidList errs.ErrCode
|
||||
ErrRedundantPack errs.ErrCode
|
||||
}{
|
||||
ErrInvalidNode : errs.ErrCode("packs.invalid-StateNode"),
|
||||
ErrInvalidElement: errs.ErrCode("packs.invalid-element"),
|
||||
ErrInvalidKey : errs.ErrCode("packs.invalid-key"),
|
||||
ErrDuplicatedKey : errs.ErrCode("packs:duplicated-key"),
|
||||
ErrKeyRequired : errs.ErrCode("packs:key-required"),
|
||||
ErrValueRequired : errs.ErrCode("packs:value-required"),
|
||||
ErrInvalidList : errs.ErrCode("packs:invalid-list"),
|
||||
ErrRedundantPack : errs.ErrCode("packs:redundant-pack"),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func BuildAny(builder Builder, value any, def func(value any) error) {
|
||||
|
||||
switch tp := value.(type) {
|
||||
|
||||
case Packabler: builder.SetError(tp.BuildPack(builder))
|
||||
|
||||
case error : builder.String(tp.Error())
|
||||
|
||||
case string : builder.String(tp)
|
||||
case bool : builder.Bool (tp)
|
||||
|
||||
case int : builder.Int64(int64(tp))
|
||||
case int8 : builder.Int8 (tp)
|
||||
case int16 : builder.Int16(tp)
|
||||
case int32 : builder.Int32(tp)
|
||||
case int64 : builder.Int64(tp)
|
||||
|
||||
case uint : builder.UInt64(uint64(tp))
|
||||
case uint8 : builder.UInt8 (tp)
|
||||
case uint16 : builder.UInt16(tp)
|
||||
case uint32 : builder.UInt32(tp)
|
||||
case uint64 : builder.UInt64(tp)
|
||||
|
||||
case float32: builder.Float32(tp)
|
||||
case float64: builder.Float64(tp)
|
||||
|
||||
case complex64 : builder.Complex64 (tp)
|
||||
case complex128: builder.Complex128(tp)
|
||||
|
||||
case time.Time : builder.Date(tp)
|
||||
case time.Duration: builder.Int64(int64(tp))
|
||||
|
||||
case reflect.Value:
|
||||
switch tp.Kind() {
|
||||
case reflect.Slice,
|
||||
reflect.Array : packList (builder,value)
|
||||
case reflect.Map : packMapReflected (builder,tp)
|
||||
case reflect.Struct: packObjectReflected(builder,tp)
|
||||
default:
|
||||
builder.SetError(def(value))
|
||||
}
|
||||
|
||||
default:
|
||||
rf := reflect.ValueOf(value)
|
||||
switch rf.Kind() {
|
||||
case reflect.Slice,
|
||||
reflect.Array : packList (builder,value)
|
||||
case reflect.Map : packMapReflected (builder,rf)
|
||||
case reflect.Struct: packObjectReflected(builder,rf)
|
||||
}
|
||||
BuildAny(builder,reflect.ValueOf(value),def)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func packListReflected(builder Builder, value reflect.Value) {
|
||||
builder.List(func (p BuilderList) {
|
||||
r := value
|
||||
for i:=0; i<r.Len(); i++ {
|
||||
p.ItemAny(r.Index(i).Interface())
|
||||
if builder.Error() != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func packMapReflected(builder Builder, value reflect.Value) {
|
||||
value.Type().Elem().Key().Kind()
|
||||
builder.Map(func (p BuilderMap) {
|
||||
r := value
|
||||
for _,k := range r.MapKeys() {
|
||||
p.ElemAny(k.Interface(),r.MapIndex(k).Interface())
|
||||
if builder.Error() != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func packObjectReflected(builder Builder, value reflect.Value) {
|
||||
builder.Object(func (p BuilderObject) {
|
||||
r := value
|
||||
t := r.Type()
|
||||
for i:=0; i < r.NumField(); i++ {
|
||||
if t.Field(i).IsExported() {
|
||||
p.PropAny(t.Field(i).Name,r.Field(i).Interface())
|
||||
if builder.Error() != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func _packList[T any ] (builder Builder, values []T, call func(BuilderList,T)) {
|
||||
builder.List(func (p BuilderList) {
|
||||
for _,v := range values {
|
||||
call(p,v)
|
||||
if builder.Error() != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func packList(builder Builder, value any) {
|
||||
switch tp := value.(type) {
|
||||
|
||||
case []string : _packList[string](builder,tp, func (b BuilderList, v string) { b.ItemString(v) })
|
||||
case []bool : _packList[bool ](builder,tp, func (b BuilderList, v bool ) { b.ItemBool (v) })
|
||||
case []int8 : _packList[int8 ](builder,tp, func (b BuilderList, v int8 ) { b.ItemInt8 (v) })
|
||||
case []int16 : _packList[int16 ](builder,tp, func (b BuilderList, v int16 ) { b.ItemInt16 (v) })
|
||||
case []int32 : _packList[int32 ](builder,tp, func (b BuilderList, v int32 ) { b.ItemInt32 (v) })
|
||||
case []int64 : _packList[int64 ](builder,tp, func (b BuilderList, v int64 ) { b.ItemInt64 (v) })
|
||||
case []uint8 : _packList[uint8 ](builder,tp, func (b BuilderList, v uint8 ) { b.ItemUInt8 (v) })
|
||||
case []uint16 : _packList[uint16](builder,tp, func (b BuilderList, v uint16) { b.ItemUInt16(v) })
|
||||
case []uint32 : _packList[uint32](builder,tp, func (b BuilderList, v uint32) { b.ItemUInt32(v) })
|
||||
case []uint64 : _packList[uint64](builder,tp, func (b BuilderList, v uint64) { b.ItemUInt64(v) })
|
||||
|
||||
case []float32 : _packList[float32](builder,tp, func (b BuilderList, v float32) { b.ItemFloat32(v) })
|
||||
case []float64 : _packList[float64](builder,tp, func (b BuilderList, v float64) { b.ItemFloat64(v) })
|
||||
|
||||
case []complex64 : _packList[complex64] (builder,tp, func (b BuilderList, v complex64 ) { b.ItemComplex64 (v) })
|
||||
case []complex128: _packList[complex128](builder,tp, func (b BuilderList, v complex128) { b.ItemComplex128(v) })
|
||||
|
||||
case []time.Time : _packList[time.Time] (builder,tp, func (b BuilderList, v time.Time) { b.ItemDate(v) })
|
||||
|
||||
case []time.Duration: _packList[time.Duration](builder,tp, func (b BuilderList, v time.Duration ) { b.ItemInt64 (int64(v)) })
|
||||
|
||||
case []any: _packList[any](builder,tp,func (b BuilderList, v any ) { b.ItemAny (v) })
|
||||
|
||||
case reflect.Value:
|
||||
if tp.Type().Kind() != reflect.Slice && tp.Type().Kind() != reflect.Array {
|
||||
builder.SetError(G.ErrInvalidList)
|
||||
return
|
||||
}
|
||||
packListReflected(builder,tp)
|
||||
default:
|
||||
packListReflected(builder,reflect.ValueOf(value))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name builder.go
|
||||
// Created by DEV
|
||||
// Modified 21/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/opts"
|
||||
"activething.com/go/gogo/core/syncs"
|
||||
"activething.com/go/gogo/packs"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
const(
|
||||
|
||||
maxDeepUncheck = 100
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
Builder struct {
|
||||
options Options
|
||||
encoder *json.Encoder
|
||||
dateLayout string
|
||||
scratch [64]byte
|
||||
state *__packs.State
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
func NewBuilder(options ...opts.OptionFnc[Builder]) *Builder {
|
||||
if atomic.CompareAndSwapUint32(&G.sentinel,0,1) {
|
||||
G.builderPool = syncs.NewPool[Builder](
|
||||
syncs.PoolWithNew[Builder](func() *Builder {
|
||||
return &Builder{
|
||||
options : jsonOptionsDefaults,
|
||||
state : __packs.NewState(),
|
||||
dateLayout: time.RFC822Z,
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
return opts.Apply(G.builderPool.Get(),options...)
|
||||
}
|
||||
|
||||
|
||||
func releaseBuilder(builder *Builder) {
|
||||
if builder != nil {
|
||||
builder.reset()
|
||||
if atomic.LoadUint32(&G.sentinel) == 1 {
|
||||
G.builderPool.Put(builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (b *Builder) Any (value any) {
|
||||
|
||||
switch value.(type) {
|
||||
default:
|
||||
rv := reflect.ValueOf(value)
|
||||
switch rv.Kind() {
|
||||
|
||||
case reflect.Struct : b.objPacker(rv)
|
||||
case reflect.Map : b.mapPacker(rv)
|
||||
case reflect.Slice : b.listPacker(rv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (b *Builder) BuildMap (builder func(packer __packs.BuilderMap)) {}
|
||||
|
||||
|
||||
func (b *Builder) BuildList(builder func(packer __packs.BuilderList)) {}
|
||||
|
||||
|
||||
func (b *Builder) BuildObject(builder func(packer __packs.BuilderList)) {}
|
||||
|
||||
|
||||
|
||||
func (b *Builder) reset () *Builder {
|
||||
//todo
|
||||
b.options = jsonOptionsDefaults
|
||||
b.encoder = nil
|
||||
b.dateLayout = time.RFC822Z
|
||||
b.state.Reset()
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func stringifyKey(key reflect.Value, ops Options) (string,bool) {
|
||||
|
||||
return "ss",true
|
||||
}
|
||||
@ -1,88 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name gogo.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/core/syncs"
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
G = struct {
|
||||
|
||||
objectCache sync.Map
|
||||
|
||||
sentinel uint32
|
||||
builderPool *syncs.Pool[Builder]
|
||||
|
||||
hex string
|
||||
jsonChars [utf8.RuneSelf]jsonCharAtt
|
||||
|
||||
sep byte
|
||||
nullValue []byte
|
||||
zeroValue []byte
|
||||
trueValue []byte
|
||||
falseValue []byte
|
||||
mapEmpty []byte
|
||||
listEmpty []byte
|
||||
objectEmpty []byte
|
||||
stringEmpty []byte
|
||||
floatNaN []byte
|
||||
floatInfPos []byte
|
||||
floatInfNeg []byte
|
||||
}{
|
||||
|
||||
hex: "0123456789abcdef",
|
||||
jsonChars: initJSONChars(),
|
||||
|
||||
sep: ',',
|
||||
nullValue: []byte{'n', 'u', 'l', 'l'},
|
||||
zeroValue: []byte{'0'},
|
||||
trueValue: []byte{'"','t', 'r', 'u', 'e','"'},
|
||||
falseValue: []byte{'"','f', 'a', 'l', 's', 'e','"'},
|
||||
mapEmpty: []byte{'{', '}'},
|
||||
objectEmpty: []byte{'{', '}'},
|
||||
listEmpty: []byte{'[', ']'},
|
||||
stringEmpty: []byte{'"', '"'},
|
||||
floatNaN: []byte{'"', 'N', 'a', 'N', '"'},
|
||||
floatInfPos: []byte{'"', 'I', 'n', 'f', '"'},
|
||||
floatInfNeg: []byte{'"', '-', 'I', 'n', 'f', '"'},
|
||||
}
|
||||
)
|
||||
|
||||
func initJSONChars() [utf8.RuneSelf]jsonCharAtt {
|
||||
var tb = [utf8.RuneSelf]jsonCharAtt{
|
||||
'"': jsonCharAttAllUnsafe,
|
||||
'&': jsonCharAttHtmlUnsafe,
|
||||
'<': jsonCharAttHtmlUnsafe,
|
||||
'>': jsonCharAttHtmlUnsafe,
|
||||
'\\': jsonCharAttAllUnsafe,
|
||||
}
|
||||
for i := 0; i <= 31; i++ {
|
||||
tb[i] = jsonCharAttAllUnsafe
|
||||
}
|
||||
return tb
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name json_char_atts.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
|
||||
const (
|
||||
jsonCharAttUnsafe jsonCharAtt = 1 << iota
|
||||
jsonCharAttHtmlUnsafe
|
||||
|
||||
jsonCharAttAllUnsafe = jsonCharAttUnsafe | jsonCharAttHtmlUnsafe
|
||||
)
|
||||
|
||||
type jsonCharAtt uint8
|
||||
|
||||
func (a jsonCharAtt) isUnsafe() bool {
|
||||
return a&jsonCharAttUnsafe != 0
|
||||
}
|
||||
|
||||
func (a jsonCharAtt) isHtmlUnsafe() bool {
|
||||
return a&jsonCharAttHtmlUnsafe != 0
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name object_packer.go
|
||||
// Created by DEV
|
||||
// Modified 23/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,66 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name options.go
|
||||
// Created by DEV
|
||||
// Modified 18/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
const (
|
||||
|
||||
JSONOptionsQuote Options = 1 << iota
|
||||
JSONOptionsEscapeHTML
|
||||
JSONOptionsIgnoreKeys
|
||||
JSONOptionsQuoteFloats
|
||||
JSONOptionsIgnoreDefaults
|
||||
JSONOptionsSortMapKeys
|
||||
|
||||
jsonOptionsDefaults = JSONOptionsQuote | JSONOptionsEscapeHTML
|
||||
|
||||
)
|
||||
|
||||
type Options uint8
|
||||
|
||||
|
||||
|
||||
|
||||
func (o Options) Quoted() bool {
|
||||
return o&JSONOptionsQuote != 0
|
||||
}
|
||||
|
||||
func (o Options) QuoteFloats() bool {
|
||||
return o&JSONOptionsQuoteFloats != 0
|
||||
}
|
||||
|
||||
func (o Options) EscapeHTML() bool {
|
||||
return o&JSONOptionsEscapeHTML != 0
|
||||
}
|
||||
|
||||
func (o Options) IgnoreKeys() bool {
|
||||
return o&JSONOptionsIgnoreKeys != 0
|
||||
}
|
||||
|
||||
func (o Options) IgnoreDefaults() bool {
|
||||
return o&JSONOptionsIgnoreDefaults != 0
|
||||
}
|
||||
|
||||
func (o Options) SortMapKeys() bool {
|
||||
return o&JSONOptionsSortMapKeys != 0
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name packer.go
|
||||
// Created by DEV
|
||||
// Modified 22/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
import "activething.com/go/gogo/core/errs"
|
||||
|
||||
type (
|
||||
|
||||
|
||||
JSONPacker struct {}
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
func (p JSONPacker) Pack (value any) (dt []byte, er error) {
|
||||
dn := false
|
||||
bl := NewBuilder()
|
||||
defer func (b *Builder, v *bool, e *error) {
|
||||
releaseBuilder(b)
|
||||
if !(*v) {
|
||||
*e = errs.ToError(recover())
|
||||
}
|
||||
}(bl,&dn,&er)
|
||||
|
||||
bl.Any(value)
|
||||
if bl.state.Error != nil {
|
||||
er = bl.state.Error
|
||||
} else {
|
||||
dt = append([]byte(nil),bl.state.Bytes() ...)
|
||||
}
|
||||
dn = true
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -1,110 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name list_builder.go
|
||||
// Created by DEV
|
||||
// Modified 23/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/packs"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
|
||||
func (b *Builder) listPacker(rv reflect.Value) {
|
||||
if rv.IsNil() {
|
||||
b.state.Write(G.nullValue)
|
||||
return
|
||||
}
|
||||
if rv.Len() == 0 {
|
||||
b.state.Write2Byte('[',']')
|
||||
return
|
||||
}
|
||||
if b.state.Node.Level > maxDeepUncheck {
|
||||
p := struct {
|
||||
ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe
|
||||
len int
|
||||
}{
|
||||
ptr: rv.UnsafePointer(),
|
||||
len: rv.Len(),
|
||||
}
|
||||
if _,ok := b.state.Seen[p]; ok {
|
||||
b.state.SetError(__packs.G.ErrRedundantPack)
|
||||
return
|
||||
}
|
||||
b.state.Seen[p] = struct{}{}
|
||||
defer delete(b.state.Seen,p)
|
||||
}
|
||||
|
||||
switch rv.Type().Elem().Kind() {
|
||||
case reflect.String: b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemString(ev.String()) })
|
||||
case reflect.Bool : b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemBool(ev.Bool()) })
|
||||
case reflect.Int8,
|
||||
reflect.Int16,
|
||||
reflect.Int32,
|
||||
reflect.Int64,
|
||||
reflect.Int : b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemInt64(ev.Int()) })
|
||||
case reflect.Uint8,
|
||||
reflect.Uint16,
|
||||
reflect.Uint32,
|
||||
reflect.Uint64,
|
||||
reflect.Uint : b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemUInt64(ev.Uint()) })
|
||||
case reflect.Float32,
|
||||
reflect.Float64: b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemFloat64(ev.Float()) })
|
||||
case reflect.Complex64,
|
||||
reflect.Complex128: b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemComplex128(ev.Complex()) })
|
||||
|
||||
|
||||
case reflect.Map:
|
||||
b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) })
|
||||
|
||||
case reflect.Struct:
|
||||
if rv.Type() == reflect.TypeOf(time.Time{}) {
|
||||
b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemDate(rv.Interface().(time.Time)) })
|
||||
return
|
||||
}
|
||||
b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) })
|
||||
|
||||
case reflect.Array,
|
||||
reflect.Slice :
|
||||
b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) })
|
||||
|
||||
|
||||
|
||||
default:
|
||||
b._listPacker(rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (b *Builder) _listPacker (list reflect.Value, pack func(lb __packs.BuilderList, ev reflect.Value)) {
|
||||
b.BuildList(func(l __packs.BuilderList) {
|
||||
for i := 0; i < list.Len(); i++ {
|
||||
pack(l, list.Index(i))
|
||||
if b.state.Error != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,87 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name packer_map.go
|
||||
// Created by DEV
|
||||
// Modified 23/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
import (
|
||||
"activething.com/go/gogo/packs"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
func (b *Builder) mapPacker (rv reflect.Value) {
|
||||
if rv.IsNil() {
|
||||
b.state.Write(G.nullValue)
|
||||
return
|
||||
}
|
||||
if rv.Len() == 0 {
|
||||
b.state.Write2Byte('{','}')
|
||||
return
|
||||
}
|
||||
if b.state.Node.Level > maxDeepUncheck {
|
||||
p := rv.UnsafePointer()
|
||||
if _,ok := b.state.Seen[p]; ok {
|
||||
b.state.SetError(__packs.G.ErrRedundantPack)
|
||||
return
|
||||
}
|
||||
b.state.Seen[p] = struct{}{}
|
||||
defer delete(b.state.Seen,p)
|
||||
}
|
||||
|
||||
|
||||
mi := rv.MapRange()
|
||||
if b.options.SortMapKeys() {
|
||||
ls := make([]reflectMapElem, rv.Len())
|
||||
for i := 0; mi.Next(); i++ {
|
||||
ls[i].k = mi.Key()
|
||||
ls[i].v = mi.Value()
|
||||
if !ls[i].stringifyKey(b.options) {
|
||||
b.state.SetError(__packs.G.ErrInvalidKey)
|
||||
return
|
||||
}
|
||||
}
|
||||
if b.options.SortMapKeys() {
|
||||
sort.Slice(ls, func(i, j int) bool { return ls[i].s < ls[j].s })
|
||||
}
|
||||
|
||||
b.Map(func(bm __packs.BuilderMap) {
|
||||
for _, e := range ls {
|
||||
bm.ElemAny(e.s, e.v)
|
||||
if b.state.Error != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
b.Map(func(bm __packs.BuilderMap) {
|
||||
for i:=0; mi.Next(); i++ {
|
||||
bm.ElemAny(mi.Key(),mi.Value())
|
||||
if b.state.Error != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name packer_object.go
|
||||
// Created by DEV
|
||||
// Modified 23/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
import "reflect"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func (b *Builder) objPacker (rv reflect.Value) {
|
||||
if rv.IsNil() {
|
||||
b.state.Write(G.nullValue)
|
||||
return
|
||||
}
|
||||
if rv.Len() == 0 {
|
||||
b.state.Write2Byte('{','}')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name reflect_map_elem.go
|
||||
// Created by DEV
|
||||
// Modified 22/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package jjson
|
||||
|
||||
import "reflect"
|
||||
|
||||
type (
|
||||
|
||||
reflectMapElem struct {
|
||||
k reflect.Value
|
||||
v reflect.Value
|
||||
s string
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
|
||||
func (b *reflectMapElem) stringifyKey(ops Options) (is bool) {
|
||||
b.s,is = stringifyKey(b.k,ops)
|
||||
return
|
||||
}
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name packabler.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
type (
|
||||
|
||||
Packabler interface {
|
||||
BuildPack(builder Builder) error
|
||||
}
|
||||
)
|
||||
@ -1,35 +0,0 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Project atila
|
||||
// Active Thing (activething.com) git.activething.com/go
|
||||
//
|
||||
// File name packer.go
|
||||
// Created by DEV
|
||||
// Modified 16/01/2024
|
||||
//
|
||||
// Copyright 2024 activething.com
|
||||
// ------------------------------------------------------------------------
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
package __packs
|
||||
|
||||
type (
|
||||
|
||||
|
||||
Packer interface {
|
||||
|
||||
Pack(value any) ([]byte, error)
|
||||
|
||||
}
|
||||
|
||||
)
|
||||
@ -1,7 +0,0 @@
|
||||
module activething.com/go/gogo/packets
|
||||
|
||||
|
||||
go 1.20
|
||||
|
||||
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
module activething.com/go/gogo/packs
|
||||
|
||||
|
||||
go 1.20
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in new issue