redefiniendo el builder

packs2
DEV 3 years ago
parent cbbc5e0200
commit 51dc2ab480

@ -10,5 +10,6 @@ use (
./core/opts ./core/opts
./core/syncs ./core/syncs
./packs ./packs
./packets
) )

@ -0,0 +1,7 @@
module activething.com/go/gogo/packets
go 1.20

@ -0,0 +1,64 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name gogo.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 packets
import (
"activething.com/go/gogo/core/errs"
"activething.com/go/gogo/core/syncs"
)
var (
G = struct {
poolsSem uint32
statePool *syncs.Pool[State]
nodePool *syncs.Pool[Node]
ErrInvalidNode errs.ErrCode
ErrInvalidElement errs.ErrCode
ErrInvalidKey errs.ErrCode
ErrDuplicatedKey errs.ErrCode
ErrKeyRequired errs.ErrCode
ErrValueRequired errs.ErrCode
ErrInvalidList errs.ErrCode
ErrRedundantPack errs.ErrCode
ErrInvalidValue 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"),
ErrInvalidValue : errs.ErrCode("packs:invalid-value"),
}
)

@ -0,0 +1,64 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name list_Itemer.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 packets
import "time"
type (
ListPacker interface {
Item (value any)
ItemRaw (value []byte)
ItemBinary (value []byte)
ItemString (value string)
ItemBool (value bool)
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)
ItemDate (value time.Time)
ItemList (builder func(packer ListPacker))
ItemMap (builder func(packer MapPacker ))
ItemObject(builder func(packer ObjectPacker))
}
)

@ -0,0 +1,65 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name map_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 packets
import "time"
type (
MapPacker interface {
KeyValue (key any, value any)
KeyValueRaw (value []byte)
KeyValueBinary (key any, value []byte)
KeyValueString (key any, value string)
KeyValueBool (key any, value bool)
KeyValueInt8 (key any, value int8)
KeyValueInt16 (key any, value int16)
KeyValueInt32 (key any, value int32)
KeyValueInt64 (key any, value int64)
KeyValueUInt8 (key any, value uint8)
KeyValueUInt16 (key any, value uint16)
KeyValueUInt32 (key any, value uint32)
KeyValueUInt64 (key any, value uint64)
KeyValueFloat32 (key any, value float32)
KeyValueFloat64 (key any, value float64)
KeyValueDate (key any, value time.Time)
KeyValueList (builder func(packer ListPacker))
KeyValueMap (builder func(packer MapPacker ))
KeyValueObject(builder func(packer ObjectPacker))
}
)

@ -0,0 +1,61 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name packer_node.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 packets
import "activething.com/go/gogo/core/slices"
type (
Node struct {
Parent *Node
Start int
Count int
Level int
Kind NodeKind
keys slices.String
}
)
func (n *Node) Init(parent *Node, kind NodeKind, start int) *Node {
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 *Node) Reset() *Node {
n.Parent = nil
n.keys = n.keys[:0]
return n
}

@ -0,0 +1,40 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name node_kind.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 packets
const (
NodeKindValue NodeKind = iota
NodeKindList
NodeKindMap
NodeKindObject
)
type NodeKind uint8

@ -0,0 +1,66 @@
// ------------------------------------------------------------------------
// 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 packets
import "time"
type (
ObjectPacker interface {
Field (key any, value any)
FieldRaw (value []byte)
FieldBinary (key any, value []byte)
FieldString (key any, value string)
FieldBool (key any, value bool)
FieldInt8 (key any, value int8)
FieldInt16 (key any, value int16)
FieldInt32 (key any, value int32)
FieldInt64 (key any, value int64)
FieldUInt8 (key any, value uint8)
FieldUInt16 (key any, value uint16)
FieldUInt32 (key any, value uint32)
FieldUInt64 (key any, value uint64)
FieldFloat32 (key any, value float32)
FieldFloat64 (key any, value float64)
FieldDate (key any, value time.Time)
FieldList (builder func(packer ListPacker))
FieldMap (builder func(packer MapPacker ))
FieldObject(builder func(packer ObjectPacker))
}
)

@ -0,0 +1,63 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name 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 packets
import "time"
type (
Packer interface {
Pack (value any)
PackRaw (value []byte)
PackBinary (value []byte)
PackString (value string)
PackBool (value bool)
PackInt8 (value int8)
PackInt16 (value int16)
PackInt32 (value int32)
PackInt64 (value int64)
PackUInt8 (value uint8)
PackUInt16 (value uint16)
PackUInt32 (value uint32)
PackUInt64 (value uint64)
PackFloat32 (value float32)
PackFloat64 (value float64)
PackDate (value time.Time)
PackList (builder func(packer Packer))
PackMap (builder func(packer MapPacker ))
PackObject(builder func(packer ObjectPacker))
}
)

@ -0,0 +1,153 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name packer_state.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 packets
import (
"activething.com/go/gogo/core/bins"
"activething.com/go/gogo/core/slices"
"activething.com/go/gogo/core/syncs"
"sync/atomic"
)
type (
State struct {
/*Embedded*/*bins.Buffer
Node *Node
Temp [64]byte
Seen map[any]struct{}
Error error
}
)
func NewState() *State {
if atomic.CompareAndSwapUint32(&G.poolsSem,0,1) {
G.nodePool = syncs.NewPool[Node](
syncs.PoolWithNew[Node](func()*Node {
return &Node{
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
}

@ -0,0 +1,78 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name gogo.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 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
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{'[', ']'},
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
}

@ -0,0 +1,41 @@
// ------------------------------------------------------------------------
// 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
}

@ -0,0 +1,59 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name list_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 pjson
import (
"activething.com/go/gogo/packets"
"time"
)
func (p *Packer) Item (value any) { p.addSep().Pack(value) }
func (p *Packer) ItemRaw (value []byte) { p.addSep().PackRaw(value) }
func (p *Packer) ItemBinary (value []byte) { p.addSep().PackBinary(value) }
func (p *Packer) ItemString (value string) { p.addSep().PackString(value) }
func (p *Packer) ItemBool (value bool) { p.addSep().PackBool(value) }
func (p *Packer) ItemInt8 (value int8) { p.addSep().PackInt64(int64(value)) }
func (p *Packer) ItemInt16 (value int16) { p.addSep().PackInt64(int64(value)) }
func (p *Packer) ItemInt32 (value int32) { p.addSep().PackInt64(int64(value)) }
func (p *Packer) ItemInt64 (value int64) { p.addSep().PackInt64(value) }
func (p *Packer) ItemUInt8 (value uint8) { p.addSep().PackUInt64(uint64(value)) }
func (p *Packer) ItemUInt16 (value uint16) { p.addSep().PackUInt64(uint64(value)) }
func (p *Packer) ItemUInt32 (value uint32) { p.addSep().PackUInt64(uint64(value)) }
func (p *Packer) ItemUInt64 (value uint64) { p.addSep().PackUInt64(value) }
func (p *Packer) ItemFloat32 (value float32) { p.addSep().PackFloat64(float64(value))}
func (p *Packer) ItemFloat64 (value float64) { p.addSep().PackFloat64(value) }
func (p *Packer) ItemDate (value time.Time) { p.addSep().PackDate(value) }
func (p *Packer) ItemList (builder func(packer packets.ListPacker)) { p.addSep().ItemList (builder) }
func (p *Packer) ItemMap (builder func(packer packets.MapPacker )) { p.addSep().ItemMap (builder) }
func (p *Packer) ItemObject(builder func(packer packets.ObjectPacker)) { p.addSep().ItemObject(builder) }

@ -0,0 +1,63 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name map_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 pjson
import (
"activething.com/go/gogo/packets"
"time"
)
func (p *Packer) KeyValue ( key any, value any) {}
func (p *Packer) KeyValueRaw (value []byte) {}
func (p *Packer) KeyValueBinary ( key any, value []byte) {}
func (p *Packer) KeyValueString ( key any, value string) {}
func (p *Packer) KeyValueBool ( key any, value bool) {}
func (p *Packer) KeyValueRune ( key any, value rune) {}
func (p *Packer) KeyValueInt8 ( key any, value int8) {}
func (p *Packer) KeyValueInt16 ( key any, value int16) {}
func (p *Packer) KeyValueInt32 ( key any, value int32) {}
func (p *Packer) KeyValueInt64 ( key any, value int64) {}
func (p *Packer) KeyValueUInt8 ( key any, value uint8) {}
func (p *Packer) KeyValueUInt16 ( key any, value uint16) {}
func (p *Packer) KeyValueUInt32 ( key any, value uint32) {}
func (p *Packer) KeyValueUInt64 ( key any, value uint64) {}
func (p *Packer) KeyValueFloat32 ( key any, value float32) {}
func (p *Packer) KeyValueFloat64 ( key any, value float64) {}
func (p *Packer) KeyValueDate ( key any, value time.Time) {}
func (p *Packer) KeyValueList (builder func(packer packets.ListPacker)) {}
func (p *Packer) KeyValueMap (builder func(packer packets.MapPacker )) {}
func (p *Packer) KeyValueObject(builder func(packer packets.ObjectPacker)) {}

@ -0,0 +1,61 @@
// ------------------------------------------------------------------------
// 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 pjson
import (
"activething.com/go/gogo/packets"
"time"
)
func (p *Packer) Field ( key any, value any) {}
func (p *Packer) FieldRaw (value []byte) {}
func (p *Packer) FieldBinary ( key any, value []byte) {}
func (p *Packer) FieldString ( key any, value string) {}
func (p *Packer) FieldBool ( key any, value bool) {}
func (p *Packer) FieldRune ( key any, value rune) {}
func (p *Packer) FieldInt8 ( key any, value int8) {}
func (p *Packer) FieldInt16 ( key any, value int16) {}
func (p *Packer) FieldInt32 ( key any, value int32) {}
func (p *Packer) FieldInt64 ( key any, value int64) {}
func (p *Packer) FieldUInt8 ( key any, value uint8) {}
func (p *Packer) FieldUInt16 ( key any, value uint16) {}
func (p *Packer) FieldUInt32 ( key any, value uint32) {}
func (p *Packer) FieldUInt64 ( key any, value uint64) {}
func (p *Packer) FieldFloat32 ( key any, value float32) {}
func (p *Packer) FieldFloat64 ( key any, value float64) {}
func (p *Packer) FieldDate ( key any, value time.Time) {}
func (p *Packer) FieldList (builder func(packer packets.ListPacker)) {}
func (p *Packer) FieldMap (builder func(packer packets.MapPacker )) {}
func (p *Packer) FieldObject(builder func(packer packets.ObjectPacker)) {}

@ -0,0 +1,33 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name options.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 pjson
type (
Options struct {
Flags /*embedded*/
dateLayout string
}
)

@ -0,0 +1,61 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name flags.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 pjson
const (
JSONFlagQuote Flags = 1 << iota
JSONFlagEscapeHTML
JSONFlagIgnoreKeys
JSONFlagQuoteNumbers
JSONFlagIgnoreDefaults
)
type Flags uint8
func (o Flags) Quote() bool {
return o&JSONFlagQuote != 0
}
func (o Flags) QuoteNumbers() bool {
return o&JSONFlagQuoteNumbers != 0
}
func (o Flags) EscapeHTML() bool {
return o&JSONFlagEscapeHTML != 0
}
func (o Flags) IgnoreKeys() bool {
return o&JSONFlagIgnoreKeys != 0
}
func (o Flags) IgnoreDefaults() bool {
return o&JSONFlagIgnoreDefaults != 0
}

@ -0,0 +1,332 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name 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 pjson
import (
"activething.com/go/gogo/core/bins"
"activething.com/go/gogo/core/errs"
"activething.com/go/gogo/packets"
"encoding/base64"
"math"
"strconv"
"time"
"unicode/utf8"
)
type (
Packer struct {
options Options
state *packets.State
}
)
func (p *Packer) Pack (value any) {
if !p.state.SetValue() {
panic(p.state.Error)
}
}
func (p *Packer) PackRaw (value []byte) {
if !p.state.SetValue() {
panic(p.state.Error)
}
if value == nil {
p.state.Write(G.nullValue)
return
}
p.state.Write(value)
}
func (p *Packer) PackBinary (value []byte) {
if !p.state.SetValue() {
panic(p.state.Error)
}
if value == nil {
p.state.Write(G.nullValue)
return
}
if len(value) == 0 {
p.state.Write2Byte('"','"')
return
}
p.state.WriteByte('"')
ln := base64.StdEncoding.EncodedLen(len(value))
if ln <= len(p.state.Temp) {
dst := p.state.Temp[: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 *Packer) PackString (value string) {
if !p.state.SetValue() {
panic(p.state.Error)
}
if len(value) == 0 {
p.state.Write2Byte('"','"')
} else {
p.string(value,p.options.EscapeHTML())
}
}
func (p *Packer) PackBool (value bool) {
if !p.state.SetValue() {
panic(p.state.Error)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
}
if value {
p.state.Write(G.trueValue)
} else {
p.state.Write(G.falseValue)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
}
}
func (p *Packer) PackInt8 (value int8) {}
func (p *Packer) PackInt16 (value int16) {}
func (p *Packer) PackInt32 (value int32) {}
func (p *Packer) PackInt64 (value int64) {
if !p.state.SetValue() {
panic(p.state.Error)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
}
if value == 0 {
p.state.WriteByte('0')
} else {
p.state.WriteIntStr(value, 10)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
}
}
func (p *Packer) PackUInt8 (value uint8) {}
func (p *Packer) PackUInt16 (value uint16) {}
func (p *Packer) PackUInt32 (value uint32) {}
func (p *Packer) PackUInt64 (value uint64) {
if !p.state.SetValue() {
panic(p.state.Error)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
}
if value == 0 {
p.state.WriteByte('0')
} else {
p.state.WriteUIntStr(value, 10)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
}
}
func (p *Packer) PackFloat32 (value float32) {}
func (p *Packer) PackFloat64 (value float64) {
if !p.state.SetValue() {
panic(p.state.Error)
}
if math.IsInf(value,0) || math.IsNaN(value) {
p.state.SetError(packets.G.ErrInvalidValue)
return
}
if p.options.QuoteNumbers() {
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:
fm := byte('f')
if ab := math.Abs(value); ab != 0 {
if ab < 1e-6 || ab >= 1e21 {
fm = 'e'
}
}
b := p.state.Temp[:0]
b = strconv.AppendFloat(b, value, fm, -1, 64)
if fm == 'e' {
// clean up e-09 to e-9
n := len(b)
if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
b[n-2] = b[n-1]
b = b[:n-1]
}
}
p.state.Write(b)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
}
}
func (p *Packer) PackDate (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.options.dateLayout)
}))
p.state.WriteByte('"')
}
func (p *Packer) PackList (builder func(packer packets.ListPacker)) {
p.packCompound(packets.NodeKindList,'[',']',func(pk *Packer) { builder (pk) })
}
func (p *Packer) PackMap (builder func(packer packets.MapPacker )) {
p.packCompound(packets.NodeKindMap,'{','}',func(pk *Packer) { builder (pk) })
}
func (p *Packer) PackObject(builder func(packer packets.ObjectPacker)) {
p.packCompound(packets.NodeKindObject,'{','}',func(pk *Packer) { builder (pk) })
}
func (p *Packer) packCompound(kind packets.NodeKind, opening, closing byte, buildFnc func(*Packer)) {
if !p.state.SetValue() {
panic(p.state.Error)
}
dn := false
defer func(d *bool) {
if !(*d) {
p.state.SetError(errs.ToError(recover()))
}
}(&dn)
if p.state.Open(kind) {
p.addSep()
p.state.WriteByte(opening)
buildFnc(p)
if p.state.Error == nil {
if p.state.Close() {
p.state.WriteByte(closing)
}
}
}
dn = true
}
func (p *Packer) 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 *Packer) addSep () *Packer {
if p.state.Node.Count > 0 {
p.state.WriteByte(',')
}
return p
}
Loading…
Cancel
Save

Powered by TurnKey Linux.