corregido el formateador de error para que no escriba la seccion Causes en caso de que no tenga ninguna
parent
f340c61f2b
commit
acb1ffc10b
@ -0,0 +1,58 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name string.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 slices
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type Strings []string
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func MakeStrings(size, capacity int) Strings {
|
||||||
|
return make(Strings, size, capacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Strings) Reset() Strings {
|
||||||
|
if s != nil {
|
||||||
|
return s[:0]
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Strings) Has(value string) bool {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, k := range s {
|
||||||
|
if k == value {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Strings) Append(value string) Strings {
|
||||||
|
return append(s, value)
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
* Project $PROJECT_NAME
|
||||||
|
* Active Thing (activething.com) git.activething.com/go
|
||||||
|
*
|
||||||
|
* File name $FILE_NAME
|
||||||
|
* Created by ${USER}
|
||||||
|
* Modified ${DAY}/${MONTH}/${YEAR}
|
||||||
|
*
|
||||||
|
* Copyright ${YEAR} 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 bits
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
G = struct {
|
||||||
|
|
||||||
|
ErrUnsupportedFlagType Err
|
||||||
|
}{
|
||||||
|
|
||||||
|
ErrUnsupportedFlagType : Err{errs.ErrCode ("unsupported-bit-flag-type") },
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name bflag_16.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 15/02/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 bits
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/bits"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type BFlags16 uint16
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFlags16) Has ( flag BFlags16) bool {
|
||||||
|
return f&flag != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFlags16) Add ( flag BFlags16) BFlags16 {
|
||||||
|
return f|flag }
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFlags16) AddWithMask ( flag BFlags16, mask BFlags16) BFlags16 {
|
||||||
|
return (f&mask) | flag }
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFlags16) Del ( flag BFlags16) BFlags16 {
|
||||||
|
return f&^flag }
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFlags16) Invert () BFlags16 {
|
||||||
|
return ^f }
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFlags16) Count() int {
|
||||||
|
return bits.OnesCount16(uint16(f)) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFlags16) Extract() []BFlags16 {
|
||||||
|
if f == 0 {
|
||||||
|
return []BFlags16{}
|
||||||
|
}
|
||||||
|
l := make([]BFlags16,0,16)
|
||||||
|
c := BFlags16(1)
|
||||||
|
for i:=1; i<= 7; i++ {
|
||||||
|
if c&f == c {
|
||||||
|
l = append(l,c)
|
||||||
|
}
|
||||||
|
c <<= 1
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFlags16) FlagsToNames (namer func(flags BFlags16) string) []string {
|
||||||
|
if f == 0 {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
l := make([]string,0,16)
|
||||||
|
c := BFlags16(1)
|
||||||
|
for i:=1; i<= 7; i++ {
|
||||||
|
if c&f == c {
|
||||||
|
l = append(l,namer(c))
|
||||||
|
}
|
||||||
|
c <<= 1
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFlags16) NamesToFlags (names []string, flagger func(name string) BFlags16) BFlags16 {
|
||||||
|
for _,s := range names {
|
||||||
|
f|=flagger(s)
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name err_bits.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 20/04/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 bits
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Err struct { errs.ErrCode }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,106 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name bflag.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 15/02/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 bits
|
||||||
|
|
||||||
|
import (
|
||||||
|
"atypes"
|
||||||
|
"encoding/binary"
|
||||||
|
"math/bits"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func Has [T atypes.UnsignedAll](source T, flag T) bool {
|
||||||
|
return source&flag != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func Add [T atypes.UnsignedAll](source T, flag T) T {
|
||||||
|
return source|flag }
|
||||||
|
|
||||||
|
|
||||||
|
func AddWithMask [T atypes.UnsignedAll](source T, flag T, mask T) T {
|
||||||
|
return (source&mask) | flag }
|
||||||
|
|
||||||
|
|
||||||
|
func Del [T atypes.UnsignedAll](source T, flag T) T {
|
||||||
|
return source&^flag }
|
||||||
|
|
||||||
|
|
||||||
|
func Invert [T atypes.UnsignedAll](source T) T {
|
||||||
|
return ^source }
|
||||||
|
|
||||||
|
|
||||||
|
func Count[T atypes.UnsignedAll](source T) int {
|
||||||
|
switch binary.Size(source) {
|
||||||
|
case 1 : return bits.OnesCount8 (uint8(source))
|
||||||
|
case 2 : return bits.OnesCount16(uint16(source))
|
||||||
|
case 4 : return bits.OnesCount32(uint32(source))
|
||||||
|
case 8 : return bits.OnesCount64(uint64(source))
|
||||||
|
default:
|
||||||
|
panic(G.ErrUnsupportedFlagType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func Extract[T atypes.UnsignedAll](source T) []T {
|
||||||
|
if source == 0 {
|
||||||
|
return []T{}
|
||||||
|
}
|
||||||
|
l := make([]T,0,16)
|
||||||
|
c := T(1)
|
||||||
|
for i:=1; i<= 7; i++ {
|
||||||
|
if c&source == c {
|
||||||
|
l = append(l,c)
|
||||||
|
}
|
||||||
|
c <<= 1
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func FlagsToNames [T atypes.UnsignedAll](source T, namer func(flags T) string) []string {
|
||||||
|
if source == 0 {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
l := make([]string,0,16)
|
||||||
|
c := T(1)
|
||||||
|
for i:=1; i<= 7; i++ {
|
||||||
|
if c&source == c {
|
||||||
|
l = append(l,namer(c))
|
||||||
|
}
|
||||||
|
c <<= 1
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func NamesToFlags [T atypes.UnsignedAll](names []string, flagger func(name string) T) T {
|
||||||
|
var f T
|
||||||
|
for _,s := range names {
|
||||||
|
f|=flagger(s)
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
module bits
|
||||||
|
|
||||||
|
go 1.22
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name err_btes.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 20/04/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 bfers
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Err struct { errs.ErrCode }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name gogo.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 19/02/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 bfields
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
const(
|
||||||
|
|
||||||
|
notFound = -1
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
G = struct {
|
||||||
|
ErrInvalidName Err
|
||||||
|
ErrDuplicated Err
|
||||||
|
ErrFixed Err
|
||||||
|
ErrReadOnly Err
|
||||||
|
|
||||||
|
}{
|
||||||
|
ErrInvalidName: Err{ errs.ErrCode("invalid-name")},
|
||||||
|
ErrDuplicated : Err{ errs.ErrCode("duplicated-field")},
|
||||||
|
ErrFixed : Err{ errs.ErrCode("bfields-fixed")},
|
||||||
|
ErrReadOnly : Err{ errs.ErrCode("bfields-read-only")},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name bfields_att.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 19/02/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 bfields
|
||||||
|
|
||||||
|
|
||||||
|
const(
|
||||||
|
|
||||||
|
AttReadOnly Att = 1 << iota
|
||||||
|
AttFixed
|
||||||
|
AttMultiple
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
|
||||||
|
Att uint8
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (a Att) IsReadOnly() bool {
|
||||||
|
return a&AttReadOnly != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (a Att) IsFixed() bool {
|
||||||
|
return a&AttFixed != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (a Att) IsMultiple() bool {
|
||||||
|
return a&AttMultiple != 0 }
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name bfield.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 19/02/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 bfields
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
BField struct {
|
||||||
|
name []byte
|
||||||
|
value []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func NewBField (name, value []byte) (*BField,error) {
|
||||||
|
if len(name) == 0 {
|
||||||
|
return nil,G.ErrInvalidName
|
||||||
|
}
|
||||||
|
return &BField {
|
||||||
|
name: append(make([]byte,0,len(name)),name...),
|
||||||
|
value: append(make([]byte,0,len(value)),value...),
|
||||||
|
},nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (f BField) Name () []byte {
|
||||||
|
return f.name }
|
||||||
|
|
||||||
|
|
||||||
|
func (f BField) Value() []byte {
|
||||||
|
return f.value }
|
||||||
|
|
||||||
|
|
||||||
|
func (f BField) String () string {
|
||||||
|
r := make([]byte,len(f.name)+len(f.value)+1)
|
||||||
|
copy(r,f.name)
|
||||||
|
r[len(f.name)]=':'
|
||||||
|
copy(r[len(f.name)+1:],f.value)
|
||||||
|
return string(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (f *BField) SetValue(val []byte) {
|
||||||
|
ln := len(val)
|
||||||
|
cp := cap(f.value)
|
||||||
|
if ln <= cp {
|
||||||
|
copy(f.value, val)
|
||||||
|
f.value = f.value[:ln]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
nv := make([]byte, ln)
|
||||||
|
copy(f.value, nv)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f *BField) SetByte(val byte) {
|
||||||
|
f.value = append(f.value[:0], val) }
|
||||||
|
|
||||||
|
|
||||||
|
func (f *BField) SetBool(val bool) {
|
||||||
|
f.value = strconv.AppendBool(f.value[:0], val) }
|
||||||
|
|
||||||
|
|
||||||
|
func (f *BField) SetRune(val rune) {
|
||||||
|
f.value = strconv.AppendQuoteRune(f.value[:0], val) }
|
||||||
|
|
||||||
|
|
||||||
|
func (f *BField) SetString(val string) {
|
||||||
|
f.SetValue([]byte(val)) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (f *BField) SetInt(val int64, bse int) {
|
||||||
|
f.value = strconv.AppendInt(f.value[:0], val, bse) }
|
||||||
|
|
||||||
|
|
||||||
|
func (f *BField) SetUInt(val uint64, bse int) {
|
||||||
|
f.value = strconv.AppendUint(f.value[:0], val, bse) }
|
||||||
|
|
||||||
|
|
||||||
|
func (f *BField) SetFloat(val float64, fmt byte, prc, sze int) {
|
||||||
|
f.value = strconv.AppendFloat(f.value[:0], val, fmt, prc, sze) }
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,197 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name bfield_list.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 19/02/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 bfields
|
||||||
|
|
||||||
|
import (
|
||||||
|
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
BFields struct {
|
||||||
|
Att
|
||||||
|
fields []BField
|
||||||
|
}
|
||||||
|
|
||||||
|
BFieldsFnc func (bfls *BFields) error
|
||||||
|
|
||||||
|
BFieldsWalkFnc func(index int, field *BField) bool
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func NewBFields (options ...BFieldsFnc) (*BFields,error) {
|
||||||
|
fs := &BFields{}
|
||||||
|
for _,o := range options {
|
||||||
|
if er := o(fs); er != nil {
|
||||||
|
return nil,er
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if fs.IsReadOnly() {
|
||||||
|
//todo
|
||||||
|
}
|
||||||
|
return fs,nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFields) Get(nme []byte) *BField {
|
||||||
|
if ix := findField(f.fields, 0, nme); ix != notFound {
|
||||||
|
f.get(ix)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFields) get(index int) *BField {
|
||||||
|
if f.IsReadOnly() {
|
||||||
|
vl := f.fields[index]
|
||||||
|
return &vl
|
||||||
|
}
|
||||||
|
return &f.fields[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f *BFields) Add(nme, val []byte) error {
|
||||||
|
if f.IsFixed() {
|
||||||
|
return G.ErrFixed
|
||||||
|
}
|
||||||
|
if ix := findField(f.fields, 0, nme); ix != notFound {
|
||||||
|
if !f.IsMultiple() {
|
||||||
|
return G.ErrDuplicated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fl, er := NewBField(nme, val)
|
||||||
|
if er != nil {
|
||||||
|
return er
|
||||||
|
}
|
||||||
|
f.fields = append(f.fields, *fl)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *BFields) Del(nme []byte) error {
|
||||||
|
if f.IsFixed() {
|
||||||
|
return G.ErrFixed
|
||||||
|
}
|
||||||
|
if f.IsReadOnly() {
|
||||||
|
return G.ErrReadOnly
|
||||||
|
}
|
||||||
|
fm := 0
|
||||||
|
ix := -1
|
||||||
|
ln := len(f.fields)
|
||||||
|
for {
|
||||||
|
if ix = findField(f.fields, fm, nme); ix == notFound {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
f.fields[ix] = f.fields[ln-1]
|
||||||
|
f.fields = f.fields[:ln-1]
|
||||||
|
ln -= 1
|
||||||
|
if !f.IsMultiple() || ix == ln-1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fm = ix
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *BFields) Upsert(nme, val []byte) error {
|
||||||
|
if len(nme) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if f.IsReadOnly() {
|
||||||
|
return G.ErrReadOnly
|
||||||
|
}
|
||||||
|
if ix := findField(f.fields, 0, nme); ix != -1 {
|
||||||
|
f.fields[ix].SetValue(val)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if f.IsFixed() {
|
||||||
|
return G.ErrFixed
|
||||||
|
}
|
||||||
|
fl, er := NewBField(nme, val)
|
||||||
|
if er != nil {
|
||||||
|
return er
|
||||||
|
}
|
||||||
|
f.fields = append(f.fields, *fl)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFields) Len() int {
|
||||||
|
return len(f.fields) }
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFields) Has(nme []byte) bool {
|
||||||
|
return findField(f.fields, 0, nme) != notFound }
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFields) Count(nme []byte) int {
|
||||||
|
rs := 0
|
||||||
|
for _, fl := range f.fields {
|
||||||
|
if bytes.Equal(fl.name, nme) {
|
||||||
|
rs++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rs
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f BFields) Walk(walker BFieldsWalkFnc) {
|
||||||
|
for ln, ix := len(f.fields), 0; ix < ln; ix++ {
|
||||||
|
if !walker(ix, f.get(ix)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func findField(list []BField, from int, name []byte) int {
|
||||||
|
for ln, ix := len(list), from; ix < ln; ix++ {
|
||||||
|
if bytes.Equal(list[ix].name, name) {
|
||||||
|
return ix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return notFound
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func WithField(nme, val []byte) BFieldsFnc {
|
||||||
|
return func(f *BFields) error { return f.Add(nme, val) }}
|
||||||
|
|
||||||
|
|
||||||
|
func WithAtts(atts Att) BFieldsFnc {
|
||||||
|
return func(f *BFields) error {
|
||||||
|
f.Att = atts
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name err.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 20/04/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 bfields
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Err struct { errs.ErrCode }
|
||||||
|
|
||||||
|
)
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name gogo.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 16/02/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 crypts
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
G = struct {
|
||||||
|
ErrNotImplemented Err
|
||||||
|
}{
|
||||||
|
ErrNotImplemented: Err { errs.ErrCode("crypter-not-implemented")} ,
|
||||||
|
}
|
||||||
|
)
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name crypter.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 16/02/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 crypts
|
||||||
|
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Crypter interface {
|
||||||
|
Encrypter
|
||||||
|
Decrypter
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name decrypter.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 16/02/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 crypts
|
||||||
|
|
||||||
|
import "rsts"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Decrypter interface {
|
||||||
|
Decrypt (data []byte) rsts.Bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DecrypterNop struct {}
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (_ DecrypterNop) Decrypt (_ []byte) rsts.Bytes {
|
||||||
|
return rsts.MakeBytesError(G.ErrNotImplemented) }
|
||||||
|
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name encrypter.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 16/02/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 crypts
|
||||||
|
|
||||||
|
import (
|
||||||
|
|
||||||
|
"rsts"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
|
||||||
|
Encrypter interface {
|
||||||
|
Encrypt (data []byte) rsts.Bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EncrypterNop struct {}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func (_ EncrypterNop) Encrypt (_ []byte) rsts.Bytes {
|
||||||
|
return rsts.MakeBytesError(G.ErrNotImplemented) }
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name err.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 20/04/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 crypts
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
type Err struct { errs.ErrCode }
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
module crypts
|
||||||
|
|
||||||
|
|
||||||
|
go 1.20
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// 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 packs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errs"
|
||||||
|
"syncs"
|
||||||
|
)
|
||||||
|
|
||||||
|
const(
|
||||||
|
|
||||||
|
TagKey = "pack"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
caseMask = ^byte(0x20) // Mask to ignore case in ASCII.
|
||||||
|
kelvin = '\u212a'
|
||||||
|
smallLongEss = '\u017f'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
G = struct {
|
||||||
|
|
||||||
|
ErrInvalidState Err
|
||||||
|
ErrInvalidNode Err
|
||||||
|
ErrInvalidKey Err
|
||||||
|
ErrDuplicatedKey Err
|
||||||
|
ErrKeyRequired Err
|
||||||
|
ErrValueRequired Err
|
||||||
|
ErrInvalidList Err
|
||||||
|
ErrRedundantPack Err
|
||||||
|
ErrInvalidValue Err
|
||||||
|
ErrUnsupportedType Err
|
||||||
|
}{
|
||||||
|
ErrInvalidState : Err{errs.ErrCode("invalid-state")},
|
||||||
|
ErrInvalidNode : Err{errs.ErrCode("invalid-node")},
|
||||||
|
ErrInvalidKey : Err{errs.ErrCode("invalid-key")},
|
||||||
|
ErrDuplicatedKey : Err{errs.ErrCode("duplicated-key")},
|
||||||
|
ErrKeyRequired : Err{errs.ErrCode("key-required")},
|
||||||
|
ErrValueRequired : Err{errs.ErrCode("value-required")},
|
||||||
|
ErrInvalidList : Err{errs.ErrCode("invalid-list")},
|
||||||
|
ErrRedundantPack : Err{errs.ErrCode("redundant-pack")},
|
||||||
|
ErrInvalidValue : Err{errs.ErrCode("invalid-value")},
|
||||||
|
ErrUnsupportedType: Err{errs.ErrCode("unsupported-type")},
|
||||||
|
}
|
||||||
|
|
||||||
|
g = struct {
|
||||||
|
poolsSem uint32
|
||||||
|
statePool *syncs.Pool[State]
|
||||||
|
} {}
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name packabler.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 24/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 (
|
||||||
|
|
||||||
|
Builder interface {
|
||||||
|
|
||||||
|
Build (packer Packer) error
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BuildFnc func (packer Packer) error
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (f BuildFnc) Build (packer Packer) error {
|
||||||
|
return f(packer) }
|
||||||
|
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name err.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 20/04/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 "errs"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Err struct { errs.ErrCode }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,241 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name f.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 29/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 (
|
||||||
|
"bits"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
|
||||||
|
FlagOmit Flags = 1 << iota
|
||||||
|
FlagOmitEmpty
|
||||||
|
FlagQuote
|
||||||
|
FlagScapeHTML
|
||||||
|
FlagString
|
||||||
|
FlagEncrypted
|
||||||
|
|
||||||
|
FlagBinary64 Flags = 0b0000100000000000
|
||||||
|
FlagBinary32 Flags = 0b0000010000000000
|
||||||
|
flagMaskBin Flags = 0b0000110000000000
|
||||||
|
|
||||||
|
FlagDateRFC822 Flags = 0b0001000000000000
|
||||||
|
FlagDateUnix Flags = 0b0010000000000000
|
||||||
|
FlagDateANSIC Flags = 0b0100000000000000
|
||||||
|
FlagDateRFC850 Flags = 0b1000000000000000
|
||||||
|
flagMaskDate Flags = 0b1111000000000000
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type Flags bits.BFlags16
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) Omit () bool {
|
||||||
|
return f&FlagOmit != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) OmitEmpty () bool {
|
||||||
|
return f&FlagOmitEmpty != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) Quote () bool {
|
||||||
|
return f&FlagQuote != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) EscapeHTML () bool {
|
||||||
|
return f&FlagScapeHTML != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) String () bool {
|
||||||
|
return f&FlagString != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) Encrypted() bool {
|
||||||
|
return f&FlagEncrypted != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) Binary () bool {
|
||||||
|
return f&(FlagBinary64|FlagBinary32) != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) Bin64 () bool {
|
||||||
|
return f&FlagBinary64 != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) Bin32 () bool {
|
||||||
|
return f&FlagBinary32 != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) SetDate (flagDate Flags) Flags {
|
||||||
|
return (f&flagMaskDate) | flagDate }
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) SetBinary (flagBinary Flags) Flags {
|
||||||
|
return (f&flagMaskBin) | flagBinary }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) Names () string {
|
||||||
|
var ls []string
|
||||||
|
if f&FlagOmit != 0 { ls = append(ls,"omit")}
|
||||||
|
if f&FlagOmitEmpty != 0 { ls = append(ls,"omitempty")}
|
||||||
|
if f&FlagQuote != 0 { ls = append(ls,"quote")}
|
||||||
|
if f&FlagScapeHTML != 0 { ls = append(ls,"html")}
|
||||||
|
if f&FlagString != 0 { ls = append(ls,"string")}
|
||||||
|
|
||||||
|
if f&flagMaskBin != 0 {
|
||||||
|
ls = append(ls,f.binName())
|
||||||
|
}
|
||||||
|
if f&flagMaskDate != 0 {
|
||||||
|
ls = append(ls,f.dateName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ls) > 0 {
|
||||||
|
return strings.Join(ls,",")
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) binName () string {
|
||||||
|
switch f & flagMaskBin {
|
||||||
|
case FlagBinary64 : return "b64"
|
||||||
|
case FlagBinary32 : return "b32"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) dateName() string {
|
||||||
|
switch f & flagMaskDate {
|
||||||
|
case FlagDateUnix : return "unix"
|
||||||
|
case FlagDateRFC822: return "rfc822"
|
||||||
|
case FlagDateANSIC : return "ansic"
|
||||||
|
case FlagDateRFC850: return "rfc8550"
|
||||||
|
default: return "rfc822z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f Flags) DateFormat () string {
|
||||||
|
switch f & flagMaskDate {
|
||||||
|
case FlagDateUnix : return time.UnixDate
|
||||||
|
case FlagDateRFC822: return time.RFC822
|
||||||
|
case FlagDateANSIC : return time.ANSIC
|
||||||
|
case FlagDateRFC850: return time.RFC850
|
||||||
|
default: return time.RFC822Z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func FlagByName (flag string) (f Flags) {
|
||||||
|
switch strings.ToLower(flag) {
|
||||||
|
|
||||||
|
case "-","omit" : return FlagOmit
|
||||||
|
case "o","omitempty": return FlagOmitEmpty
|
||||||
|
case "q","quote" : return FlagQuote
|
||||||
|
case "h","html" : return FlagScapeHTML
|
||||||
|
case "s","string" : return FlagString
|
||||||
|
case "e","encrypted": return FlagEncrypted
|
||||||
|
|
||||||
|
// formato binario
|
||||||
|
case "b64","bin64" : return FlagBinary64
|
||||||
|
case "b32","bin32" : return FlagBinary32
|
||||||
|
|
||||||
|
// formatos de fechas
|
||||||
|
case "unix" : return FlagDateUnix
|
||||||
|
case "rfc822" : return FlagDateRFC822
|
||||||
|
case "ansic" : return FlagDateANSIC
|
||||||
|
case "rfc850" : return FlagDateRFC850
|
||||||
|
case "rfc822z": return 0
|
||||||
|
|
||||||
|
default: return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func FlagsWithNames(flags ... string) Flags {
|
||||||
|
var f Flags
|
||||||
|
for _,n := range flags {
|
||||||
|
f |= FlagByName(n)
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func FlagsWithString(flags string, onOption func(string) Flags) Flags {
|
||||||
|
|
||||||
|
var f Flags
|
||||||
|
if len(flags) == 0 {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
nf := f
|
||||||
|
for flags != "" {
|
||||||
|
var op string
|
||||||
|
op,flags,_ = strings.Cut(flags,",")
|
||||||
|
nf |= onOption(op)
|
||||||
|
}
|
||||||
|
return nf
|
||||||
|
}
|
||||||
|
|
||||||
|
func FlagsFromPackTag (raw reflect.StructTag) (string,Flags,bool) {
|
||||||
|
return FlagsFromTag(raw,TagKey,FlagByName) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func FlagsFromTag(raw reflect.StructTag, tag string, onOption func(string) Flags) (string,Flags,bool) {
|
||||||
|
st,ok := raw.Lookup(tag)
|
||||||
|
if !ok {
|
||||||
|
return "",0,false
|
||||||
|
}
|
||||||
|
nm,op,_ := strings.Cut(st,",")
|
||||||
|
return nm,FlagsWithString(op,onOption),true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func CheckTag(tag string) bool {
|
||||||
|
if tag == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, c := range tag {
|
||||||
|
switch {
|
||||||
|
case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
|
||||||
|
case !unicode.IsLetter(c) && !unicode.IsDigit(c):
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
module packs
|
||||||
|
|
||||||
|
|
||||||
|
go 1.22
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com, flags Flags) 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", flags Flags);
|
||||||
|
// 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 (
|
||||||
|
|
||||||
|
ListPackBuilder interface {
|
||||||
|
|
||||||
|
Error () error
|
||||||
|
|
||||||
|
ItemAny (value any, flags Flags)
|
||||||
|
|
||||||
|
ItemRaw (value []byte, flags Flags)
|
||||||
|
|
||||||
|
ItemBinary (value []byte, flags Flags)
|
||||||
|
ItemString (value string, flags Flags)
|
||||||
|
|
||||||
|
ItemBool (value bool, flags Flags)
|
||||||
|
|
||||||
|
ItemInt8 (value int8, flags Flags)
|
||||||
|
ItemInt16 (value int16, flags Flags)
|
||||||
|
ItemInt32 (value int32, flags Flags)
|
||||||
|
ItemInt64 (value int64, flags Flags)
|
||||||
|
|
||||||
|
ItemUInt8 (value uint8, flags Flags)
|
||||||
|
ItemUInt16 (value uint16, flags Flags)
|
||||||
|
ItemUInt32 (value uint32, flags Flags)
|
||||||
|
ItemUInt64 (value uint64, flags Flags)
|
||||||
|
|
||||||
|
ItemFloat32 (value float32, flags Flags)
|
||||||
|
ItemFloat64 (value float64, flags Flags)
|
||||||
|
|
||||||
|
ItemDate (value time.Time, flags Flags)
|
||||||
|
|
||||||
|
ItemList (builder func(ListPackBuilder, Flags), flags Flags)
|
||||||
|
ItemMap (builder func(MapPackBuilder, Flags), flags Flags)
|
||||||
|
ItemObject(builder func(ObjectPackBuilder,Flags), flags Flags)
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com, flags Flags) 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", flags Flags);
|
||||||
|
// 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 (
|
||||||
|
|
||||||
|
MapPackBuilder interface {
|
||||||
|
|
||||||
|
KeyValueAny (key any, value any, flags Flags)
|
||||||
|
|
||||||
|
KeyValueRaw (key any,value []byte, flags Flags)
|
||||||
|
|
||||||
|
KeyValueBinary(key any, value []byte, flags Flags)
|
||||||
|
KeyValueString(key any, value string, flags Flags)
|
||||||
|
|
||||||
|
KeyValueBool (key any, value bool, flags Flags)
|
||||||
|
|
||||||
|
KeyValueInt8 (key any, value int8 , flags Flags)
|
||||||
|
KeyValueInt16 (key any, value int16, flags Flags)
|
||||||
|
KeyValueInt32 (key any, value int32, flags Flags)
|
||||||
|
KeyValueInt64 (key any, value int64, flags Flags)
|
||||||
|
|
||||||
|
KeyValueUInt8 (key any, value uint8 , flags Flags)
|
||||||
|
KeyValueUInt16 (key any, value uint16, flags Flags)
|
||||||
|
KeyValueUInt32 (key any, value uint32, flags Flags)
|
||||||
|
KeyValueUInt64 (key any, value uint64, flags Flags)
|
||||||
|
|
||||||
|
KeyValueFloat32(key any, value float32, flags Flags)
|
||||||
|
KeyValueFloat64(key any, value float64, flags Flags)
|
||||||
|
|
||||||
|
KeyValueDate (key any, value time.Time, flags Flags)
|
||||||
|
|
||||||
|
KeyValueList (key any, builder func(ListPackBuilder, Flags), flags Flags)
|
||||||
|
KeyValueMap (key any, builder func(MapPackBuilder, Flags), flags Flags)
|
||||||
|
KeyValueObject(key any, builder func(ObjectPackBuilder,Flags), flags Flags)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -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 packs
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
ObjectPackBuilder interface {
|
||||||
|
|
||||||
|
Error () error
|
||||||
|
|
||||||
|
FieldAny (name string, value any, flags Flags)
|
||||||
|
|
||||||
|
FieldRaw (name string, value []byte, flags Flags)
|
||||||
|
|
||||||
|
FieldBinary (name string, value []byte, flags Flags)
|
||||||
|
FieldString (name string, value string, flags Flags)
|
||||||
|
|
||||||
|
FieldBool (name string, value bool, flags Flags)
|
||||||
|
|
||||||
|
FieldInt8 (name string, value int8 , flags Flags)
|
||||||
|
FieldInt16 (name string, value int16, flags Flags)
|
||||||
|
FieldInt32 (name string, value int32, flags Flags)
|
||||||
|
FieldInt64 (name string, value int64, flags Flags)
|
||||||
|
|
||||||
|
FieldUInt8 (name string, value uint8, flags Flags)
|
||||||
|
FieldUInt16 (name string, value uint16, flags Flags)
|
||||||
|
FieldUInt32 (name string, value uint32, flags Flags)
|
||||||
|
FieldUInt64 (name string, value uint64, flags Flags)
|
||||||
|
|
||||||
|
FieldFloat32 (name string, value float32, flags Flags)
|
||||||
|
FieldFloat64 (name string, value float64, flags Flags)
|
||||||
|
|
||||||
|
FieldDate (name string, value time.Time, flags Flags)
|
||||||
|
|
||||||
|
FieldList (name string, builder func(ListPackBuilder, Flags), flags Flags)
|
||||||
|
FieldMap (name string, builder func(MapPackBuilder, Flags), flags Flags)
|
||||||
|
FieldObject(name string, builder func(ObjectPackBuilder,Flags), flags Flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// 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 packs
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Packer interface {
|
||||||
|
|
||||||
|
Pack (value any, flags Flags)
|
||||||
|
|
||||||
|
Packet () []byte
|
||||||
|
Error () error
|
||||||
|
|
||||||
|
Reset ()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -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 packs
|
||||||
|
|
||||||
|
import (
|
||||||
|
|
||||||
|
"bins/bfers"
|
||||||
|
"crypts"
|
||||||
|
"sync/atomic"
|
||||||
|
"syncs"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
|
||||||
|
State struct {
|
||||||
|
/*Embedded*/*bfers.Buffer
|
||||||
|
Temp [64]byte
|
||||||
|
Level int
|
||||||
|
Error error
|
||||||
|
checks map[any]struct{}
|
||||||
|
counts []int
|
||||||
|
Encrypter crypts.Encrypter
|
||||||
|
}
|
||||||
|
|
||||||
|
StateFnc func (st *State)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func NewState(options ...StateFnc) *State {
|
||||||
|
if atomic.CompareAndSwapUint32(&g.poolsSem,0,1) {
|
||||||
|
g.statePool = syncs.NewPool[State](
|
||||||
|
syncs.PoolWithNew[State](func() *State {
|
||||||
|
return &State{
|
||||||
|
Buffer : bfers.NewBuffer(),
|
||||||
|
checks : make(map[any]struct{}),
|
||||||
|
counts : []int{0},
|
||||||
|
Encrypter: crypts.EncrypterNop{},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if len(options) == 0 {
|
||||||
|
return g.statePool.Get()
|
||||||
|
}
|
||||||
|
st := g.statePool.Get()
|
||||||
|
for _,o := range options {
|
||||||
|
o(st)
|
||||||
|
}
|
||||||
|
return st
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func ReleaseState (state *State) {
|
||||||
|
if state == nil {
|
||||||
|
state.Encrypter = crypts.EncrypterNop{}
|
||||||
|
state.Buffer.Reset()
|
||||||
|
state.Error = nil
|
||||||
|
state.counts= append(state.counts[:0],0)
|
||||||
|
if len(state.checks) > 0 {
|
||||||
|
for k,_ := range state.checks {
|
||||||
|
delete(state.checks,k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.Level = 0
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (s *State) CheckCycle (ptr any) (func(),bool) {
|
||||||
|
if _,hs := s.checks[ptr]; hs {
|
||||||
|
s.SetError(G.ErrRedundantPack)
|
||||||
|
return nil,false
|
||||||
|
}
|
||||||
|
s.checks[ptr]=struct{}{}
|
||||||
|
return func(){ delete(s.checks,ptr) },true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (s *State) Open(opener byte) {
|
||||||
|
s.WriteByte(opener)
|
||||||
|
s.Level++
|
||||||
|
s.counts = append(s.counts,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (s *State) Close(closer byte) {
|
||||||
|
s.WriteByte(closer)
|
||||||
|
s.Level--
|
||||||
|
if s.Level < 0 {
|
||||||
|
s.SetError(G.ErrInvalidNode)
|
||||||
|
}
|
||||||
|
s.counts = s.counts[:len(s.counts)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (s *State) Count() int {
|
||||||
|
if s.Error != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return s.counts[s.Level]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (s *State) Inc () {
|
||||||
|
if s.Error == nil {
|
||||||
|
s.counts[s.Level] += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,127 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// 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 (
|
||||||
|
|
||||||
|
"encoding"
|
||||||
|
"encoding/json"
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
"rsts"
|
||||||
|
"sync"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
const (
|
||||||
|
|
||||||
|
jsonTag = "json"
|
||||||
|
|
||||||
|
maxCyclesAfter = 100
|
||||||
|
|
||||||
|
defaultFlags = packs.Flags(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var (
|
||||||
|
g = struct {
|
||||||
|
hex string
|
||||||
|
jsonChars [utf8.RuneSelf]jsonCharAtt
|
||||||
|
|
||||||
|
nullValue []byte
|
||||||
|
zeroValue []byte
|
||||||
|
trueValue []byte
|
||||||
|
falseValue []byte
|
||||||
|
|
||||||
|
floatNaN []byte
|
||||||
|
floatInfPos []byte
|
||||||
|
floatInfNeg []byte
|
||||||
|
|
||||||
|
|
||||||
|
packersCache sync.Map
|
||||||
|
keyersCache sync.Map
|
||||||
|
fieldsCache sync.Map
|
||||||
|
|
||||||
|
jsonMarshalerType reflect.Type
|
||||||
|
textMarshalerType reflect.Type
|
||||||
|
packMarshalerType reflect.Type
|
||||||
|
|
||||||
|
}{
|
||||||
|
|
||||||
|
hex: "0123456789abcdef",
|
||||||
|
jsonChars: initJSONChars(),
|
||||||
|
|
||||||
|
nullValue: []byte{'n', 'u', 'l', 'l'},
|
||||||
|
zeroValue: []byte{'0'},
|
||||||
|
trueValue: []byte{'"','t', 'r', 'u', 'e','"'},
|
||||||
|
falseValue: []byte{'"','f', 'a', 'l', 's', 'e','"'},
|
||||||
|
|
||||||
|
floatNaN: []byte{'"', 'N', 'a', 'N', '"'},
|
||||||
|
floatInfPos: []byte{'"', 'I', 'n', 'f', '"'},
|
||||||
|
floatInfNeg: []byte{'"', '-', 'I', 'n', 'f', '"'},
|
||||||
|
|
||||||
|
|
||||||
|
jsonMarshalerType: reflect.TypeOf((*json.Marshaler)(nil)).Elem(),
|
||||||
|
textMarshalerType: reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem(),
|
||||||
|
packMarshalerType: reflect.TypeOf((*packs.Packer)(nil)).Elem(),
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func Pack (value any, options ... PackerFnc) (res rsts.Bytes) {
|
||||||
|
p := NewPacker(options ...)
|
||||||
|
p.Pack(value,defaultFlags)
|
||||||
|
if p.Error() != nil {
|
||||||
|
res = rsts.MakeBytesError(p.Error())
|
||||||
|
} else {
|
||||||
|
res = rsts.MakeBytesSuccess(p.Packet())
|
||||||
|
}
|
||||||
|
p.Release()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -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,80 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name builder_list.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 06/02/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 (
|
||||||
|
"packs"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Packer) ItemAny (value any, flags packs.Flags) { p.addItem(func(){ p.PackAny(value,flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) ItemRaw (value []byte, flags packs.Flags) { p.addItem(func() { p.PackRaw(value,flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) ItemBinary (value []byte, flags packs.Flags) { p.addItem(func (){ p.PackBinary(value,flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) ItemString (value string, flags packs.Flags) { p.addItem(func (){ p.PackString(value,flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) ItemBool (value bool, flags packs.Flags) { p.addItem(func (){ p.PackBool(value,flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) ItemInt8 (value int8 , flags packs.Flags) { p.addItem(func (){ packInt(p.state,int64(value),flags) }) }
|
||||||
|
func (p *Packer) ItemInt16 (value int16, flags packs.Flags) { p.addItem(func (){ packInt(p.state,int64(value),flags) }) }
|
||||||
|
func (p *Packer) ItemInt32 (value int32, flags packs.Flags) { p.addItem(func (){ packInt(p.state,int64(value),flags) }) }
|
||||||
|
func (p *Packer) ItemInt64 (value int64, flags packs.Flags) { p.addItem(func (){ packInt(p.state,value,flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) ItemUInt8 (value uint8 , flags packs.Flags){ p.addItem(func (){ packUInt(p.state,uint64(value),flags) }) }
|
||||||
|
func (p *Packer) ItemUInt16 (value uint16, flags packs.Flags){ p.addItem(func (){ packUInt(p.state,uint64(value),flags) }) }
|
||||||
|
func (p *Packer) ItemUInt32 (value uint32, flags packs.Flags){ p.addItem(func (){ packUInt(p.state,uint64(value),flags) }) }
|
||||||
|
func (p *Packer) ItemUInt64 (value uint64, flags packs.Flags){ p.addItem(func (){ packUInt(p.state,uint64(value),flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) ItemFloat32 (value float32, flags packs.Flags){ p.addItem(func (){ packFloatString(p.state,float64(value),flags,32)})}
|
||||||
|
func (p *Packer) ItemFloat64 (value float64, flags packs.Flags){ p.addItem(func (){ packFloatString(p.state,value,flags,64) })}
|
||||||
|
|
||||||
|
func (p *Packer) ItemDate (value time.Time, flags packs.Flags) { p.addItem(func(){ packDate(p.state,value,flags); p.state.Inc() })}
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) ItemList (builder func(packs.ListPackBuilder, packs.Flags), flags packs.Flags) {
|
||||||
|
p.addItem(func(){ p.PackList(builder,flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) ItemMap (builder func(packs.MapPackBuilder, packs.Flags), flags packs.Flags) {
|
||||||
|
p.addItem(func(){ p.PackMap(builder,flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) ItemObject(builder func(packs.ObjectPackBuilder, packs.Flags), flags packs.Flags) {
|
||||||
|
p.addItem(func(){ p.PackObject(builder,flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) addItem (caller func()) {
|
||||||
|
if p.state.Count() > 0 {
|
||||||
|
p.state.WriteByte(',')
|
||||||
|
}
|
||||||
|
caller()
|
||||||
|
if p.state != nil {
|
||||||
|
p.state.Inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name builderMap.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 06/02/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 (
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueAny (key any, value any, flags packs.Flags) {
|
||||||
|
p.addKeyValue(key, func(){ p.PackAny(value,flags)}) }
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueRaw (key any,value []byte, flags packs.Flags) {
|
||||||
|
p.addKeyValue(key, func(){ p.PackRaw(value,flags)}) }
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueBinary (key any, value []byte, flags packs.Flags) {
|
||||||
|
p.addKeyValue(key, func(){ p.PackBinary(value,flags)}) }
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueString (key any, value string, flags packs.Flags) {
|
||||||
|
p.addKeyValue(key, func(){ p.PackString(value,flags)}) }
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueBool (key any, value bool, flags packs.Flags) {
|
||||||
|
p.addKeyValue(key, func(){ p.PackBool(value,flags)}) }
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueInt8 (key any, value int8 , flags packs.Flags) { p.addKeyValue(key, func(){ p.PackInt64(int64(value),flags)}) }
|
||||||
|
func (p *Packer) KeyValueInt16 (key any, value int16, flags packs.Flags) { p.addKeyValue(key, func(){ p.PackInt64(int64(value),flags)}) }
|
||||||
|
func (p *Packer) KeyValueInt32 (key any, value int32, flags packs.Flags) { p.addKeyValue(key, func(){ p.PackInt64(int64(value),flags)}) }
|
||||||
|
func (p *Packer) KeyValueInt64 (key any, value int64, flags packs.Flags) { p.addKeyValue(key, func(){ p.PackInt64(value,flags)}) }
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueUInt8 (key any, value uint8 , flags packs.Flags) { p.addKeyValue(key, func(){ p.PackUInt64(uint64(value),flags)}) }
|
||||||
|
func (p *Packer) KeyValueUInt16 (key any, value uint16, flags packs.Flags) { p.addKeyValue(key, func(){ p.PackUInt64(uint64(value),flags)}) }
|
||||||
|
func (p *Packer) KeyValueUInt32 (key any, value uint32, flags packs.Flags) { p.addKeyValue(key, func(){ p.PackUInt64(uint64(value),flags)}) }
|
||||||
|
func (p *Packer) KeyValueUInt64 (key any, value uint64, flags packs.Flags) { p.addKeyValue(key, func(){ p.PackUInt64(value,flags)}) }
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueFloat32(key any, value float32, flags packs.Flags){
|
||||||
|
p.addKeyValue(key,func(){ p.PackFloat32(value, flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueFloat64(key any, value float64, flags packs.Flags){
|
||||||
|
p.addKeyValue(key,func(){ p.PackFloat64(value, flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueDate (key any, value time.Time, flags packs.Flags){
|
||||||
|
p.addKeyValue(key,func(){ p.PackDate(value, flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueList (key any, builder func(packs.ListPackBuilder, packs.Flags), flags packs.Flags) {
|
||||||
|
p.addKeyValue(key,func(){ p.PackList(builder, flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueMap (key any, builder func(packs.MapPackBuilder, packs.Flags), flags packs.Flags) {
|
||||||
|
p.addKeyValue(key,func(){ p.PackMap(builder, flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) KeyValueObject (key any, builder func(packs.ObjectPackBuilder,packs.Flags), flags packs.Flags) {
|
||||||
|
p.addKeyValue(key,func(){ p.PackObject(builder, flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) addKeyValue(key any, caller func()) {
|
||||||
|
if p.state.Count() > 0 {
|
||||||
|
p.state.WriteByte(',')
|
||||||
|
}
|
||||||
|
p.packStringifyKey(key)
|
||||||
|
if p.state.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.state.WriteByte(':')
|
||||||
|
caller()
|
||||||
|
p.state.Inc()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) packStringifyKey(key any) {
|
||||||
|
switch v := key.(type) {
|
||||||
|
case string : p.PackString(v,packs.FlagScapeHTML)
|
||||||
|
case float32: p.PackFloat32(v,packs.FlagScapeHTML|packs.FlagQuote)
|
||||||
|
case float64: p.PackFloat64(v,packs.FlagScapeHTML|packs.FlagQuote)
|
||||||
|
default:
|
||||||
|
me := &rMapEntry{
|
||||||
|
v : reflect.ValueOf(key),
|
||||||
|
}
|
||||||
|
fn := stringifyRKey(me.v.Type())
|
||||||
|
if fn == nil {
|
||||||
|
p.state.SetError(packs.G.ErrInvalidKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if er := fn(me,me.v); er != nil {
|
||||||
|
p.state.SetError(er)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.PackString(me.k,me.f)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name builder_object.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 06/02/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 (
|
||||||
|
"packs"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Packer) FieldAny (name string, value any, flags packs.Flags) {
|
||||||
|
p.addField(name, func() { p.PackAny(value, flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) FieldRaw (name string, value []byte, flags packs.Flags){
|
||||||
|
p.addField(name, func() { p.PackRaw(value, flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) FieldBinary (name string, value []byte, flags packs.Flags) {
|
||||||
|
p.addField(name, func() { p.PackBinary(value, flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) FieldString (name string, value string, flags packs.Flags) {
|
||||||
|
p.addField(name, func() { p.PackString(value, flags) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) FieldBool (name string, value bool, flags packs.Flags) {
|
||||||
|
p.addField(name, func() { p.PackBool(value, flags) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) FieldInt8 (name string, value int8 , flags packs.Flags) {
|
||||||
|
p.addField(name, func() { p.PackInt64(int64(value), flags) })}
|
||||||
|
|
||||||
|
func (p *Packer) FieldInt16 (name string, value int16, flags packs.Flags) {
|
||||||
|
p.addField(name, func() { p.PackInt64(int64(value), flags) })}
|
||||||
|
|
||||||
|
func (p *Packer) FieldInt32 (name string, value int32, flags packs.Flags) {
|
||||||
|
p.addField(name, func() { p.PackInt64(int64(value), flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) FieldInt64 (name string, value int64, flags packs.Flags) {
|
||||||
|
p.addField(name, func() { p.PackInt64(value, flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) FieldUInt8 (name string, value uint8, flags packs.Flags) {
|
||||||
|
p.addField(name, func() { p.PackUInt64(uint64(value), flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) FieldUInt16 (name string, value uint16, flags packs.Flags) {
|
||||||
|
p.addField(name,func(){ p.PackUInt64(uint64(value), flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) FieldUInt32 (name string, value uint32, flags packs.Flags) {
|
||||||
|
p.addField(name,func(){ p.PackUInt64(uint64(value), flags) }) }
|
||||||
|
|
||||||
|
func (p *Packer) FieldUInt64 (name string, value uint64, flags packs.Flags) {
|
||||||
|
p.addField(name,func(){ p.PackUInt64(value, flags) }) }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) FieldFloat32(name string, value float32,flags packs.Flags) {
|
||||||
|
p.addField(name,func(){ p.PackFloat32(value, flags) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) FieldFloat64(name string, value float64,flags packs.Flags) {
|
||||||
|
p.addField(name,func(){ p.PackFloat64(value, flags) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) FieldDate (name string, value time.Time,flags packs.Flags) {
|
||||||
|
p.addField(name,func(){ p.PackDate(value, flags) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) FieldList (name string, builder func(packs.ListPackBuilder,packs.Flags), flags packs.Flags) {
|
||||||
|
p.addField(name,func(){ p.PackList(builder, flags) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) FieldMap (name string, builder func(packs.MapPackBuilder, packs.Flags), flags packs.Flags) {
|
||||||
|
p.addField(name,func(){ p.PackMap(builder, flags) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) FieldObject (name string, builder func(packs.ObjectPackBuilder,packs.Flags), flags packs.Flags) {
|
||||||
|
p.addField(name,func(){ p.PackObject(builder, flags) })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) addField(name string, caller func()) {
|
||||||
|
if p.state.Count() > 0 {
|
||||||
|
p.state.WriteByte(',')
|
||||||
|
}
|
||||||
|
packString(p.state,name,packs.FlagScapeHTML)
|
||||||
|
if p.state.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.state.WriteByte(':')
|
||||||
|
caller()
|
||||||
|
if p.state != nil {
|
||||||
|
p.state.Inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,649 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name value_packer.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 06/02/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 (
|
||||||
|
"crypts"
|
||||||
|
"encoding/base32"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"errs"
|
||||||
|
"math"
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
|
||||||
|
Packer struct {
|
||||||
|
state *packs.State
|
||||||
|
dirty bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PackerFnc func (packer *Packer)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func NewPacker (options ... PackerFnc) *Packer {
|
||||||
|
pk := &Packer {
|
||||||
|
state : packs.NewState(),
|
||||||
|
}
|
||||||
|
for _,o := range options {
|
||||||
|
o(pk)
|
||||||
|
}
|
||||||
|
return pk
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) Pack (value any, flags packs.Flags) {
|
||||||
|
if p.state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(p.state.Error))
|
||||||
|
}
|
||||||
|
if p.dirty {
|
||||||
|
panic(packs.G.ErrInvalidState)
|
||||||
|
}
|
||||||
|
p.dirty = true
|
||||||
|
p.PackAny(value,flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) Packet () []byte {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return p.state.Bytes() }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) Error () error {
|
||||||
|
return p.state.Error }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) Reset () {
|
||||||
|
p.state.Reset()
|
||||||
|
p.dirty = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) Release () {
|
||||||
|
p.dirty = false
|
||||||
|
packs.ReleaseState(p.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) PackAny (value any, flags packs.Flags) {
|
||||||
|
if p.state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(p.state.Error))
|
||||||
|
}
|
||||||
|
if value == nil {
|
||||||
|
p.state.W(g.nullValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := value.(type) {
|
||||||
|
case packs.Builder:
|
||||||
|
p.state.SetError(v.Build(p))
|
||||||
|
|
||||||
|
case json.Marshaler:
|
||||||
|
d,e := v.MarshalJSON()
|
||||||
|
if e != nil {
|
||||||
|
p.state.SetError(e)
|
||||||
|
} else {
|
||||||
|
p.state.W(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
case bool : packBool (p.state,v,flags )
|
||||||
|
|
||||||
|
case string : packString(p.state,v,flags )
|
||||||
|
|
||||||
|
case int : packInt(p.state,int64(v),flags)
|
||||||
|
case int8 : packInt(p.state,int64(v),flags)
|
||||||
|
case int16 : packInt(p.state,int64(v),flags)
|
||||||
|
case int32 : packInt(p.state,int64(v),flags)
|
||||||
|
case int64 : packInt(p.state,v,flags )
|
||||||
|
|
||||||
|
case uint : packUInt(p.state,uint64(v),flags)
|
||||||
|
case uint8 : packUInt(p.state,uint64(v),flags)
|
||||||
|
case uint16 : packUInt(p.state,uint64(v),flags)
|
||||||
|
case uint32 : packUInt(p.state,uint64(v),flags)
|
||||||
|
case uint64 : packUInt(p.state,v,flags )
|
||||||
|
|
||||||
|
case float32: packFloatString(p.state,float64(v),flags,32)
|
||||||
|
case float64: packFloatString(p.state,v,flags,64)
|
||||||
|
|
||||||
|
case time.Time: packDate (p.state,v,flags)
|
||||||
|
|
||||||
|
case reflect.Value: rTypePacker(v.Type())(p.state,v,flags)
|
||||||
|
|
||||||
|
case []uint8 :
|
||||||
|
if flags.Binary() {
|
||||||
|
packBinary(p.state,v,flags)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
packListUInt[uint8 ](p.state,v,flags)
|
||||||
|
case []uint : packListUInt [uint ] (p.state,v,flags)
|
||||||
|
case []uint16 : packListUInt [uint16] (p.state,v,flags)
|
||||||
|
case []uint32 : packListUInt [uint32] (p.state,v,flags)
|
||||||
|
case []uint64 : packListUInt [uint64] (p.state,v,flags)
|
||||||
|
case []int : packListInt [int ] (p.state,v,flags)
|
||||||
|
case []int8 : packListInt [int8 ] (p.state,v,flags)
|
||||||
|
case []int16 : packListInt [int16] (p.state,v,flags)
|
||||||
|
case []int32 : packListInt [int32] (p.state,v,flags)
|
||||||
|
case []int64 : packListInt [int64] (p.state,v,flags)
|
||||||
|
case []float32: packListFloat[float32](p.state,v,flags,32)
|
||||||
|
case []float64: packListFloat[float64](p.state,v,flags,64)
|
||||||
|
|
||||||
|
case []bool : packListBool (p.state,v,flags)
|
||||||
|
case []string : packListString(p.state,v,flags)
|
||||||
|
case []time.Time: packListDate(p.state,v,flags)
|
||||||
|
|
||||||
|
default:
|
||||||
|
rv := reflect.ValueOf(value)
|
||||||
|
rTypePacker(rv.Type())(p.state,rv,flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) PackRaw (value []byte, flags packs.Flags) { packRaw(p.state,value,flags) }
|
||||||
|
|
||||||
|
func (p *Packer) PackBinary (value []byte, flags packs.Flags) { packBinary(p.state,value,flags) }
|
||||||
|
func (p *Packer) PackString (value string, flags packs.Flags) { packString (p.state,value,flags) }
|
||||||
|
|
||||||
|
func (p *Packer) PackBool (value bool, flags packs.Flags) { packBool(p.state,value,flags) }
|
||||||
|
|
||||||
|
func (p *Packer) PackInt8 (value int8 , flags packs.Flags) { packInt(p.state,int64(value),flags) }
|
||||||
|
func (p *Packer) PackInt16 (value int16, flags packs.Flags) { packInt(p.state,int64(value),flags) }
|
||||||
|
func (p *Packer) PackInt32 (value int32, flags packs.Flags) { packInt(p.state,int64(value),flags) }
|
||||||
|
func (p *Packer) PackInt64 (value int64, flags packs.Flags) { packInt(p.state,value,flags)}
|
||||||
|
|
||||||
|
func (p *Packer) PackUInt8 (value uint8 , flags packs.Flags) { packUInt(p.state,uint64(value),flags) }
|
||||||
|
func (p *Packer) PackUInt16 (value uint16, flags packs.Flags) { packUInt(p.state,uint64(value),flags) }
|
||||||
|
func (p *Packer) PackUInt32 (value uint32, flags packs.Flags) { packUInt(p.state,uint64(value),flags) }
|
||||||
|
func (p *Packer) PackUInt64 (value uint64, flags packs.Flags) { packUInt(p.state, value,flags) }
|
||||||
|
|
||||||
|
func (p *Packer) PackFloat32 (value float32, flags packs.Flags) { packFloatString(p.state, float64(value), flags, 32) }
|
||||||
|
func (p *Packer) PackFloat64 (value float64, flags packs.Flags) { packFloatString(p.state, value, flags, 64) }
|
||||||
|
|
||||||
|
func (p *Packer) PackDate (value time.Time, flags packs.Flags) { packDate(p.state,value,flags) }
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) PackList (builder func(packs.ListPackBuilder, packs.Flags), flags packs.Flags) {
|
||||||
|
p.packCompound('[',']',builder==nil,func(pk *Packer, fl packs.Flags){ builder(pk,fl) },flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) PackMap (builder func(packs.MapPackBuilder, packs.Flags), flags packs.Flags) {
|
||||||
|
p.packCompound('{','}',builder==nil,func(pk *Packer, fl packs.Flags){ builder(pk,fl) },flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packer) PackObject(builder func(packs.ObjectPackBuilder, packs.Flags), flags packs.Flags) {
|
||||||
|
p.packCompound('{','}',builder==nil,func(pk *Packer, fl packs.Flags){ builder(pk,fl) },flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Packer) packCompound (opener, closer byte, isnil bool, buildFn func(*Packer,packs.Flags), flags packs.Flags) {
|
||||||
|
if p.state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(p.state.Error))
|
||||||
|
}
|
||||||
|
if isnil {
|
||||||
|
p.state.W(g.nullValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dn := false
|
||||||
|
defer func(d *bool) {
|
||||||
|
if !(*d) {
|
||||||
|
p.state.SetError(errs.ToError(recover()))
|
||||||
|
}
|
||||||
|
}(&dn)
|
||||||
|
|
||||||
|
p.state.Open(opener)
|
||||||
|
buildFn(p,flags)
|
||||||
|
if p.state.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.state.Close(closer)
|
||||||
|
dn = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func packRaw (state *packs.State, value []byte, flags packs.Flags) {
|
||||||
|
if state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(state.Error))
|
||||||
|
}
|
||||||
|
if value == nil {
|
||||||
|
state.W(g.nullValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(value) == 0 {
|
||||||
|
state.Write2Byte('"','"')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.WOQ(flags.Quote(),'"',value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func packString (state *packs.State, value string , flags packs.Flags) {
|
||||||
|
if state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(state.Error))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(value) == 0 {
|
||||||
|
state.Write2Byte('"','"')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if flags.Encrypted() {
|
||||||
|
packEncrypted(state, []byte(value), flags|packs.FlagBinary64)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if flags.Binary() {
|
||||||
|
packBinary(state,[]byte(value),flags)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
state.WriteByte('"')
|
||||||
|
start := 0
|
||||||
|
for i := 0; i < len(value); {
|
||||||
|
if b := value[i]; b < utf8.RuneSelf {
|
||||||
|
if !g.jsonChars[b].isHtmlUnsafe() || (!flags.EscapeHTML() && !g.jsonChars[b].isUnsafe()) {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if start < i {
|
||||||
|
state.WriteString(value[start:i])
|
||||||
|
}
|
||||||
|
state.WriteByte('\\')
|
||||||
|
switch b {
|
||||||
|
case '\\', '"': state.WriteByte(b)
|
||||||
|
case '\n': state.WriteByte('n')
|
||||||
|
case '\r': state.WriteByte('r')
|
||||||
|
case '\t': state.WriteByte('t')
|
||||||
|
default:
|
||||||
|
state.WriteString(`u00`)
|
||||||
|
state.Write2Byte(g.hex[b>>4], g.hex[b&0xF])
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c, size := utf8.DecodeRuneInString(value[i:])
|
||||||
|
if c == utf8.RuneError && size == 1 {
|
||||||
|
if start < i {
|
||||||
|
state.WriteString(value[start:i])
|
||||||
|
}
|
||||||
|
state.WriteString(`\ufffd`)
|
||||||
|
i += size
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if c == '\u2028' || c == '\u2029' {
|
||||||
|
if start < i {
|
||||||
|
state.WriteString(value[start:i])
|
||||||
|
}
|
||||||
|
state.WriteString(`\u202`)
|
||||||
|
state.WriteByte(g.hex[c&0xF])
|
||||||
|
i += size
|
||||||
|
start = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i += size
|
||||||
|
}
|
||||||
|
if start < len(value) {
|
||||||
|
state.WriteString(value[start:])
|
||||||
|
}
|
||||||
|
state.WriteByte('"')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func packEncrypted (state *packs.State, value []byte, flags packs.Flags) {
|
||||||
|
r := state.Encrypter.Encrypt(value)
|
||||||
|
if !r.Ok() {
|
||||||
|
state.SetError(r.Fail())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.WriteByte('"')
|
||||||
|
if flags.Bin64() || !flags.Binary() {
|
||||||
|
packBinary64(state, r.Value(), flags)
|
||||||
|
} else {
|
||||||
|
packBinary32(state, r.Value(), flags)
|
||||||
|
}
|
||||||
|
if state.Error == nil {
|
||||||
|
state.WriteByte('"')
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func packBinary (state *packs.State, value []byte , flags packs.Flags) {
|
||||||
|
if state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(state.Error))
|
||||||
|
}
|
||||||
|
|
||||||
|
if value == nil {
|
||||||
|
_,_ = state.Write(g.nullValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(value) == 0 {
|
||||||
|
state.Write2Byte('"','"')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if flags.Encrypted() {
|
||||||
|
packEncrypted(state,value,flags)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.WriteByte('"')
|
||||||
|
if flags.Bin64() {
|
||||||
|
packBinary64(state, value, 0)
|
||||||
|
} else if flags.Bin32() {
|
||||||
|
packBinary32(state, value, 0)
|
||||||
|
} else {
|
||||||
|
state.SetError(packs.G.ErrUnsupportedType)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if state.Error == nil {
|
||||||
|
state.WriteByte('"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func packBinary64 (state *packs.State, value []byte , _ packs.Flags) {
|
||||||
|
ln := base64.StdEncoding.EncodedLen(len(value))
|
||||||
|
if ln <= len(state.Temp) {
|
||||||
|
dst := state.Temp[:ln]
|
||||||
|
base64.StdEncoding.Encode(dst, value)
|
||||||
|
_,_= state.Write(dst)
|
||||||
|
} else if ln <= 1024 {
|
||||||
|
dst := make([]byte, ln)
|
||||||
|
base64.StdEncoding.Encode(dst, value)
|
||||||
|
_,_ = state.Write(dst)
|
||||||
|
} else {
|
||||||
|
ec := base64.NewEncoder(base64.StdEncoding, state)
|
||||||
|
_,_ = ec.Write(value)
|
||||||
|
state.SetError(ec.Close())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func packBinary32 (state *packs.State, value []byte , _ packs.Flags) {
|
||||||
|
ln := base32.StdEncoding.EncodedLen(len(value))
|
||||||
|
if ln <= len(state.Temp) {
|
||||||
|
dst := state.Temp[:ln]
|
||||||
|
base32.StdEncoding.Encode(dst, value)
|
||||||
|
_,_= state.Write(dst)
|
||||||
|
} else if ln <= 1024 {
|
||||||
|
dst := make([]byte, ln)
|
||||||
|
base32.StdEncoding.Encode(dst, value)
|
||||||
|
_,_ = state.Write(dst)
|
||||||
|
} else {
|
||||||
|
ec := base32.NewEncoder(base32.StdEncoding, state)
|
||||||
|
_,_ = ec.Write(value)
|
||||||
|
state.SetError(ec.Close())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func packBool (state *packs.State, value bool , flags packs.Flags) {
|
||||||
|
if state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(state.Error))
|
||||||
|
}
|
||||||
|
if value {
|
||||||
|
state.WOQ(flags.Quote(),'"', g.trueValue)
|
||||||
|
} else {
|
||||||
|
state.WOQ(flags.Quote(),'"', g.falseValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func packInt (state *packs.State, value int64 , flags packs.Flags) {
|
||||||
|
if state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(state.Error))
|
||||||
|
}
|
||||||
|
|
||||||
|
q :=flags.Quote()
|
||||||
|
if q {
|
||||||
|
state.WriteByte('"')
|
||||||
|
}
|
||||||
|
if value == 0 {
|
||||||
|
state.WriteByte('0')
|
||||||
|
} else {
|
||||||
|
state.WriteIntStr(value, 10)
|
||||||
|
}
|
||||||
|
if q {
|
||||||
|
state.WriteByte('"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func packUInt (state *packs.State, value uint64 , flags packs.Flags) {
|
||||||
|
if state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(state.Error))
|
||||||
|
}
|
||||||
|
q :=flags.Quote()
|
||||||
|
if q {
|
||||||
|
state.WriteByte('"')
|
||||||
|
}
|
||||||
|
if value == 0 {
|
||||||
|
state.WriteByte('0')
|
||||||
|
} else {
|
||||||
|
state.WriteUIntStr(value, 10)
|
||||||
|
}
|
||||||
|
if q {
|
||||||
|
state.WriteByte('"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func packFloat (state *packs.State, value float64, flags packs.Flags) {
|
||||||
|
packFloatString(state, value, flags, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func packFloatString (state *packs.State, f float64, flags packs.Flags, bits int) {
|
||||||
|
if state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(state.Error))
|
||||||
|
}
|
||||||
|
|
||||||
|
if math.IsInf(f, 0) || math.IsNaN(f) {
|
||||||
|
state.SetError(packs.G.ErrInvalidValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
abs := math.Abs(f)
|
||||||
|
fm := byte('f')
|
||||||
|
|
||||||
|
if abs != 0 {
|
||||||
|
if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
|
||||||
|
fm = 'e'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bf := state.Temp[:0]
|
||||||
|
bf = strconv.AppendFloat(bf, f, fm, -1, int(bits))
|
||||||
|
if fm == 'e' {
|
||||||
|
// clean up e-09 to e-9
|
||||||
|
n := len(bf)
|
||||||
|
if n >= 4 && bf[n-4] == 'e' && bf[n-3] == '-' && bf[n-2] == '0' {
|
||||||
|
bf[n-2] = bf[n-1]
|
||||||
|
bf = bf[:n-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state.WOQ(flags.Quote(),'"',bf)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func packDate(state *packs.State, value time.Time, flags packs.Flags) {
|
||||||
|
if state.Error != nil {
|
||||||
|
panic(packs.G.ErrInvalidState.WrapWithCause(state.Error))
|
||||||
|
}
|
||||||
|
state.WOQ(true,'"',value.AppendFormat(state.Temp[:0],flags.DateFormat()))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func packListString (state *packs.State, list []string, flags packs.Flags) {
|
||||||
|
if !checkList(state,list == nil, len(list) ==0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.WriteByte('[')
|
||||||
|
for i,v := range list {
|
||||||
|
if i > 0 {
|
||||||
|
state.WriteByte(',')
|
||||||
|
}
|
||||||
|
packString(state,v,flags)
|
||||||
|
if state.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.WriteByte(']')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func packListBool (state *packs.State, list []bool, flags packs.Flags) {
|
||||||
|
if !checkList(state,list == nil, len(list) ==0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.WriteByte('[')
|
||||||
|
for i,v := range list {
|
||||||
|
if i > 0 {
|
||||||
|
state.WriteByte(',')
|
||||||
|
}
|
||||||
|
packBool(state,v,flags)
|
||||||
|
if state.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.WriteByte(']')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func packListInt [T int | int8 | int16 | int32 | int64](state *packs.State, list []T, flags packs.Flags) {
|
||||||
|
if !checkList(state,list == nil, len(list) ==0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.WriteByte('[')
|
||||||
|
for i,v := range list {
|
||||||
|
if i > 0 {
|
||||||
|
state.WriteByte(',')
|
||||||
|
}
|
||||||
|
packInt(state,int64(v),flags)
|
||||||
|
if state.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.WriteByte(']')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func packListUInt [T uint | uint8 | uint16 | uint32 | uint64](state *packs.State, list []T, flags packs.Flags) {
|
||||||
|
if !checkList(state,list == nil, len(list) ==0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.WriteByte('[')
|
||||||
|
for i,v := range list {
|
||||||
|
if i > 0 {
|
||||||
|
state.WriteByte(',')
|
||||||
|
}
|
||||||
|
packUInt(state,uint64(v),flags)
|
||||||
|
if state.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.WriteByte(']')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func packListFloat[T float32 | float64](state *packs.State, list []T, flags packs.Flags, bits int) {
|
||||||
|
if !checkList(state,list == nil, len(list) ==0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.WriteByte('[')
|
||||||
|
for i,v := range list {
|
||||||
|
if i > 0 {
|
||||||
|
state.WriteByte(',')
|
||||||
|
}
|
||||||
|
packFloatString(state,float64(v),flags,bits)
|
||||||
|
if state.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.WriteByte(']')
|
||||||
|
}
|
||||||
|
|
||||||
|
func packListDate (state *packs.State, list []time.Time, flags packs.Flags) {
|
||||||
|
if !checkList(state,list == nil, len(list) ==0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.WriteByte('[')
|
||||||
|
for i,v := range list {
|
||||||
|
if i > 0 {
|
||||||
|
state.WriteByte(',')
|
||||||
|
}
|
||||||
|
packDate(state,v,flags)
|
||||||
|
if state.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.WriteByte(']')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func checkList (state *packs.State, isNull, isEmpty bool) bool {
|
||||||
|
if isNull {
|
||||||
|
state.Write2Byte('"','"')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if isEmpty {
|
||||||
|
state.Write2Byte('[',']')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func WithEncrypter(encrypter crypts.Encrypter) PackerFnc {
|
||||||
|
return func(p *Packer) {
|
||||||
|
if encrypter == nil {
|
||||||
|
encrypter = crypts.EncrypterNop{}
|
||||||
|
}
|
||||||
|
p.state.Encrypter = encrypter
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rpacker.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 05/02/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 (
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rPackerFnc func (state *packs.State, rvalue reflect.Value, flags packs.Flags)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func rTypePacker (rtype reflect.Type) rPackerFnc {
|
||||||
|
if fn,ok := g.packersCache.Load(rtype); ok {
|
||||||
|
return fn.(rPackerFnc)
|
||||||
|
}
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
var fn rPackerFnc
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
fi,ld := g.packersCache.LoadOrStore(rtype, rPackerFnc(func (e *packs.State, v reflect.Value, f packs.Flags) {
|
||||||
|
wg.Wait()
|
||||||
|
fn(e,v,f)
|
||||||
|
}))
|
||||||
|
if ld {
|
||||||
|
return fi.(rPackerFnc)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn = _rTypePacker(rtype)
|
||||||
|
wg.Done()
|
||||||
|
|
||||||
|
g.packersCache.Store(rtype,fn)
|
||||||
|
return fn
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func _rTypePacker(rtype reflect.Type) rPackerFnc {
|
||||||
|
|
||||||
|
switch rtype.Kind() {
|
||||||
|
case reflect.Bool : return func(s *packs.State, v reflect.Value, f packs.Flags) { packBool (s,v.Bool (),f )}
|
||||||
|
case reflect.String : return func(s *packs.State, v reflect.Value, f packs.Flags) { packString(s,v.String(),f )}
|
||||||
|
case reflect.Int,
|
||||||
|
reflect.Int8,
|
||||||
|
reflect.Int16,
|
||||||
|
reflect.Int32,
|
||||||
|
reflect.Int64 : return func(s *packs.State, v reflect.Value, f packs.Flags) { packInt (s,v.Int (),f )}
|
||||||
|
case reflect.Uint,
|
||||||
|
reflect.Uint8,
|
||||||
|
reflect.Uint16,
|
||||||
|
reflect.Uint32,
|
||||||
|
reflect.Uint64 : return func(s *packs.State, v reflect.Value, f packs.Flags) { packUInt (s,v.Uint (),f )}
|
||||||
|
case reflect.Float32: return func(s *packs.State, v reflect.Value, f packs.Flags) { packFloatString(s,v.Float(),f,32) }
|
||||||
|
case reflect.Float64: return func(s *packs.State, v reflect.Value, f packs.Flags) { packFloatString(s,v.Float(),f,64) }
|
||||||
|
|
||||||
|
case reflect.Pointer:
|
||||||
|
return rPointerPacker(rtype)
|
||||||
|
|
||||||
|
case reflect.Interface:
|
||||||
|
return rInterfacePacker
|
||||||
|
|
||||||
|
case reflect.Slice,
|
||||||
|
reflect.Array :
|
||||||
|
return rListPacker(rtype)
|
||||||
|
|
||||||
|
case reflect.Map :
|
||||||
|
return rMapPacker(rtype)
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
return rObjectPacker(rtype)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return unsupportedTypePacker
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func unsupportedTypePacker(state *packs.State, _ reflect.Value, _ packs.Flags) {
|
||||||
|
state.SetError(packs.G.ErrUnsupportedType)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rpacker_interface.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 13/02/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 (
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func rInterfacePacker (s *packs.State, v reflect.Value, f packs.Flags) {
|
||||||
|
if v.IsNil() {
|
||||||
|
s.W(g.nullValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rValuePacker(v.Elem())(s,v,f)
|
||||||
|
}
|
||||||
@ -0,0 +1,166 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rkey.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 05/02/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 (
|
||||||
|
"encoding"
|
||||||
|
"math"
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func stringifyRKey(rt reflect.Type) rMapEntryFnc {
|
||||||
|
fn,ok := g.keyersCache.Load(rt)
|
||||||
|
if !ok {
|
||||||
|
fn, _ = g.keyersCache.LoadOrStore(rt, _stringifyRKey(rt))
|
||||||
|
}
|
||||||
|
return fn.(rMapEntryFnc)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func _stringifyRKey(rt reflect.Type) rMapEntryFnc {
|
||||||
|
|
||||||
|
if rt.Kind() == reflect.String {
|
||||||
|
return func(e *rMapEntry, k reflect.Value) error {
|
||||||
|
e.k = k.String()
|
||||||
|
e.f = packs.FlagScapeHTML
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rt.Implements(g.textMarshalerType) {
|
||||||
|
return func(e *rMapEntry, k reflect.Value) error {
|
||||||
|
if k.Kind() == reflect.Pointer && k.IsNil() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
bf, er := (k.Interface().(encoding.TextMarshaler)).MarshalText()
|
||||||
|
if er == nil {
|
||||||
|
e.k = string(bf)
|
||||||
|
e.f = packs.FlagScapeHTML
|
||||||
|
}
|
||||||
|
return er
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch rt.Kind() {
|
||||||
|
|
||||||
|
case reflect.Int,
|
||||||
|
reflect.Int8,
|
||||||
|
reflect.Int16,
|
||||||
|
reflect.Int32,
|
||||||
|
reflect.Int64:
|
||||||
|
return func(e *rMapEntry, k reflect.Value) error {
|
||||||
|
e.k = strconv.FormatInt(k.Int(), 10)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case reflect.Uint,
|
||||||
|
reflect.Uint8,
|
||||||
|
reflect.Uint16,
|
||||||
|
reflect.Uint32,
|
||||||
|
reflect.Uint64,
|
||||||
|
reflect.Uintptr:
|
||||||
|
return func(e *rMapEntry, k reflect.Value) error {
|
||||||
|
e.k = strconv.FormatUint(k.Uint(), 10)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Interface:
|
||||||
|
return func(e *rMapEntry, k reflect.Value) error {
|
||||||
|
k = k.Elem()
|
||||||
|
|
||||||
|
if k.Type().Kind() == reflect.String {
|
||||||
|
e.k = k.String()
|
||||||
|
e.f = packs.FlagScapeHTML
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if t,h := k.Interface().(encoding.TextMarshaler); h {
|
||||||
|
if k.Type().Kind() == reflect.Pointer && k.IsNil() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
bf, er := t.MarshalText()
|
||||||
|
if er == nil {
|
||||||
|
e.k = string(bf)
|
||||||
|
e.f = packs.FlagScapeHTML
|
||||||
|
}
|
||||||
|
return er
|
||||||
|
}
|
||||||
|
|
||||||
|
switch rt.Kind() {
|
||||||
|
|
||||||
|
case reflect.Int,
|
||||||
|
reflect.Int8,
|
||||||
|
reflect.Int16,
|
||||||
|
reflect.Int32,
|
||||||
|
reflect.Int64:
|
||||||
|
e.k = strconv.FormatInt(k.Int(), 10)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case reflect.Uint,
|
||||||
|
reflect.Uint8,
|
||||||
|
reflect.Uint16,
|
||||||
|
reflect.Uint32,
|
||||||
|
reflect.Uint64,
|
||||||
|
reflect.Uintptr:
|
||||||
|
e.k = strconv.FormatUint(k.Uint(), 10)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return packs.G.ErrInvalidKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func stringifyFloat (buffer []byte, f float64, bits int) []byte {
|
||||||
|
if math.IsInf(f, 0) || math.IsNaN(f) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
abs := math.Abs(f)
|
||||||
|
fmt := byte('f')
|
||||||
|
|
||||||
|
if abs != 0 {
|
||||||
|
if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
|
||||||
|
fmt = 'e'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer = strconv.AppendFloat(buffer[:0], f, fmt, -1, int(bits))
|
||||||
|
if fmt == 'e' {
|
||||||
|
// clean up e-09 to e-9
|
||||||
|
n := len(buffer)
|
||||||
|
if n >= 4 && buffer[n-4] == 'e' && buffer[n-3] == '-' && buffer[n-2] == '0' {
|
||||||
|
buffer[n-2] = buffer[n-1]
|
||||||
|
buffer = buffer[:n-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name packer_list.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 05/02/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 (
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
rList struct {
|
||||||
|
packFn rPackerFnc
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func rListPacker (rtype reflect.Type) rPackerFnc {
|
||||||
|
lp := *newRList(rtype)
|
||||||
|
if rtype.Elem().Kind() != reflect.Uint8 {
|
||||||
|
return lp.pack
|
||||||
|
}
|
||||||
|
if rtype.Kind() == reflect.Slice {
|
||||||
|
return lp.packBinarySlice
|
||||||
|
}
|
||||||
|
return lp.packBinary
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func newRList(rtype reflect.Type) *rList {
|
||||||
|
return &rList{ packFn: rTypePacker(rtype.Elem()) }}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (p rList) packBinary (s *packs.State, v reflect.Value, f packs.Flags) {
|
||||||
|
if f.Binary() {
|
||||||
|
packBinary(s, v.Interface().([]byte), f)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.pack(s,v,f)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (p rList) packBinarySlice (s *packs.State, v reflect.Value, f packs.Flags) {
|
||||||
|
if f.Binary() {
|
||||||
|
packBinary(s, v.Interface().([]byte), f)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.packSlice(s,v,f)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (p rList) packSlice(s *packs.State, v reflect.Value, f packs.Flags) {
|
||||||
|
if v.IsNil() {
|
||||||
|
s.W(g.nullValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Level > maxCyclesAfter {
|
||||||
|
cp := struct {
|
||||||
|
p interface{}
|
||||||
|
l int
|
||||||
|
}{
|
||||||
|
p: v.UnsafePointer(),
|
||||||
|
l: v.Len(),
|
||||||
|
}
|
||||||
|
if fn,ok := s.CheckCycle(cp); ok {
|
||||||
|
defer fn()
|
||||||
|
} else {
|
||||||
|
s.SetError(packs.G.ErrRedundantPack)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.pack(s,v,f)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (p rList) pack (s *packs.State, v reflect.Value, f packs.Flags) {
|
||||||
|
if v.IsNil() {
|
||||||
|
s.W(g.nullValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Len() == 0 {
|
||||||
|
s.Write2Byte('[',']')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Open('[')
|
||||||
|
for i:=0; i<v.Len(); i++ {
|
||||||
|
if i > 0 {
|
||||||
|
s.WriteByte(',')
|
||||||
|
}
|
||||||
|
p.packFn(s,v.Index(i),f)
|
||||||
|
if s.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Close(']')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rpacker_map.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 05/02/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 (
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
rMap struct {
|
||||||
|
keyFn rMapEntryFnc
|
||||||
|
packFn rPackerFnc
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func rMapPacker (rtype reflect.Type) rPackerFnc {
|
||||||
|
return (*newRMap(rtype)).pack
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func newRMap(rtype reflect.Type) *rMap {
|
||||||
|
return &rMap{
|
||||||
|
packFn: rTypePacker (rtype.Elem()),
|
||||||
|
keyFn : stringifyRKey(rtype.Key()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (p *rMap) pack (s *packs.State, v reflect.Value, f packs.Flags) {
|
||||||
|
if p.keyFn == nil {
|
||||||
|
s.SetError(packs.G.ErrInvalidKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsNil() {
|
||||||
|
s.W(g.nullValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v.Len() == 0 {
|
||||||
|
s.Write2Byte('{','}')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Level > maxCyclesAfter {
|
||||||
|
if fn,ok := s.CheckCycle(v.UnsafePointer()); ok {
|
||||||
|
defer fn()
|
||||||
|
} else {
|
||||||
|
s.SetError(packs.G.ErrRedundantPack)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mi := v.MapRange()
|
||||||
|
ls := make(rMapEntryList,v.Len())
|
||||||
|
|
||||||
|
for i:=0; mi.Next(); i++ {
|
||||||
|
ls[i] = rMapEntry{
|
||||||
|
v: mi.Value(),
|
||||||
|
}
|
||||||
|
if er := p.keyFn(&ls[i], mi.Key()); er != nil {
|
||||||
|
s.SetError(er)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(ls)
|
||||||
|
|
||||||
|
s.Open ('{')
|
||||||
|
for i:=0; i<len(ls); i++ {
|
||||||
|
if i>0 {
|
||||||
|
s.WriteByte(',')
|
||||||
|
}
|
||||||
|
packString(s,ls[i].k,ls[i].f)
|
||||||
|
if s.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.WriteByte(':')
|
||||||
|
p.packFn(s,ls[i].v,0)
|
||||||
|
if s.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Close('}')
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rpacker_map_entry.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 05/02/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 (
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
|
||||||
|
rMapEntry struct {
|
||||||
|
f packs.Flags // flags
|
||||||
|
v reflect.Value // value
|
||||||
|
k string // Key
|
||||||
|
}
|
||||||
|
|
||||||
|
rMapEntryFnc func(entry *rMapEntry, rkey reflect.Value) error
|
||||||
|
|
||||||
|
rMapEntryList []rMapEntry
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (e rMapEntryList) Len() int {
|
||||||
|
return len(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e rMapEntryList) Less(i, j int) bool {
|
||||||
|
return e[i].k < e[j].k
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e rMapEntryList) Swap(i, j int) {
|
||||||
|
e[i], e[j] = e[j], e[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,280 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rpacker_object.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 07/02/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 (
|
||||||
|
"bins/bfers"
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
rObject struct {
|
||||||
|
fields rFieldList
|
||||||
|
nameIndex map[string]int
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func rObjectPacker (rtype reflect.Type) rPackerFnc {
|
||||||
|
op,ok := g.fieldsCache.Load(rtype)
|
||||||
|
if !ok {
|
||||||
|
op,_ = g.fieldsCache.LoadOrStore(rtype,*newRObject(rtype))
|
||||||
|
}
|
||||||
|
return func(s *packs.State, value reflect.Value, flags packs.Flags) {
|
||||||
|
op.(rObject).pack(s,value,flags)
|
||||||
|
}
|
||||||
|
//return (op.(rObject)).pack
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func newRObject(rtype reflect.Type) *rObject {
|
||||||
|
cur := rFieldList{}
|
||||||
|
nxt := rFieldList{{ rtype: rtype}}
|
||||||
|
|
||||||
|
var fls rFieldList
|
||||||
|
var cnt, nxCnt map[reflect.Type]int
|
||||||
|
vis := map[reflect.Type]bool{}
|
||||||
|
nms := bfers.NewBuffer()
|
||||||
|
|
||||||
|
for len(nxt) > 0 {
|
||||||
|
cur,nxt = nxt,cur[:0]
|
||||||
|
|
||||||
|
for _,f := range cur {
|
||||||
|
if vis[f.rtype] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
vis[f.rtype]=true
|
||||||
|
|
||||||
|
for i:=0; i<f.rtype.NumField(); i++ {
|
||||||
|
sf := f.rtype.Field(i)
|
||||||
|
if sf.Anonymous {
|
||||||
|
tp := sf.Type
|
||||||
|
if tp.Kind() == reflect.Pointer {
|
||||||
|
tp = tp.Elem()
|
||||||
|
}
|
||||||
|
if !sf.IsExported() && tp.Kind() != reflect.Struct {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if !sf.IsExported() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
nm, fg, has := packs.FlagsFromPackTag(sf.Tag)
|
||||||
|
if !has {
|
||||||
|
nm, fg, has = jsonTags(sf.Tag)
|
||||||
|
}
|
||||||
|
if has {
|
||||||
|
if nm == "-" || fg.Omit() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !packs.CheckTag(nm) {
|
||||||
|
nm = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index:=make([]int,len(f.index)+1)
|
||||||
|
copy(index,f.index)
|
||||||
|
index[len(f.index)] = i
|
||||||
|
|
||||||
|
ft := sf.Type
|
||||||
|
if ft.Name() == "" && ft.Kind() == reflect.Pointer {
|
||||||
|
ft = ft.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
if fg.String() && !fg.Quote() {
|
||||||
|
switch ft.Kind() {
|
||||||
|
case reflect.Bool,
|
||||||
|
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||||
|
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
|
||||||
|
reflect.Float32, reflect.Float64,
|
||||||
|
reflect.String:
|
||||||
|
fg = fg|packs.FlagQuote
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nm != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
|
||||||
|
tged := nm != ""
|
||||||
|
if nm == "" {
|
||||||
|
nm = sf.Name
|
||||||
|
}
|
||||||
|
of := rObjectField {
|
||||||
|
name : nm,
|
||||||
|
isTagged: tged,
|
||||||
|
index : index,
|
||||||
|
rtype : ft,
|
||||||
|
flags : fg,
|
||||||
|
}
|
||||||
|
of.nameB = []byte(of.name)
|
||||||
|
of.foldFn= packs.GetFoldFunc(of.nameB)
|
||||||
|
|
||||||
|
// Build nameEscHTML and nameNonEsc ahead of time.
|
||||||
|
nms.Reset()
|
||||||
|
nms.WriteByte('"')
|
||||||
|
nms.WriteHTML(of.nameB)
|
||||||
|
nms.Write2Byte('"',':')
|
||||||
|
of.nameS = nms.String()
|
||||||
|
of.nameU = `"` + of.name + `":`
|
||||||
|
|
||||||
|
fls = append(fls,of)
|
||||||
|
if cnt[f.rtype] > 1 {
|
||||||
|
fls = append(fls,fls[len(fls)-1])
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
nxCnt[ft]++
|
||||||
|
if nxCnt[ft] == 1 {
|
||||||
|
nxt = append(nxt,rObjectField{ name: ft.Name(), index: index, rtype: ft})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(fls,func(i,j int) bool {
|
||||||
|
ls := fls
|
||||||
|
if ls[i].name != ls[j].name {
|
||||||
|
return ls[i].name < ls[j].name
|
||||||
|
}
|
||||||
|
if len(ls[i].index) != len(ls[j].index) {
|
||||||
|
return len(ls[i].index) < len(ls[j].index)
|
||||||
|
}
|
||||||
|
if ls[i].isTagged != ls[j].isTagged {
|
||||||
|
return ls[i].isTagged
|
||||||
|
}
|
||||||
|
return rFieldIndexList(ls).Less(i, j)
|
||||||
|
})
|
||||||
|
|
||||||
|
out := fls[:0]
|
||||||
|
for ad,i :=0,0; i< len(fls); i += ad {
|
||||||
|
fi := fls[i]
|
||||||
|
nm := fi.name
|
||||||
|
for ad=1; i+ad <len(fls); ad++ {
|
||||||
|
fj := fls[i+ad]
|
||||||
|
if fj.name != nm {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ad == 1 {
|
||||||
|
out = append(out,fi)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
do,ok := fls[i:i+ad].dominant()
|
||||||
|
if ok {
|
||||||
|
out = append(out,do)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fls = out
|
||||||
|
sort.Sort(rFieldIndexList(fls))
|
||||||
|
|
||||||
|
for i:= range fls {
|
||||||
|
f := &fls[i]
|
||||||
|
f.packerFn = rTypePacker(f.typeByIndex(rtype))
|
||||||
|
}
|
||||||
|
nmIdx := make(map[string]int,len(fls))
|
||||||
|
for i,fd := range fls {
|
||||||
|
nmIdx[fd.name]=i
|
||||||
|
}
|
||||||
|
return &rObject{
|
||||||
|
fields: fls,
|
||||||
|
nameIndex: nmIdx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (o rObject) pack (s *packs.State, v reflect.Value, f packs.Flags) {
|
||||||
|
nx := byte('{')
|
||||||
|
FieldLoop:
|
||||||
|
for i:= range o.fields {
|
||||||
|
fd := &o.fields[i]
|
||||||
|
|
||||||
|
fv := v
|
||||||
|
for _,i := range fd.index {
|
||||||
|
if fv.Kind() == reflect.Pointer {
|
||||||
|
if fv.IsNil() {
|
||||||
|
continue FieldLoop
|
||||||
|
}
|
||||||
|
fv = fv.Elem()
|
||||||
|
}
|
||||||
|
fv = fv.Field(i)
|
||||||
|
}
|
||||||
|
if fd.flags.OmitEmpty() && isEmptyValue(v) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s.WriteByte(nx)
|
||||||
|
nx = ','
|
||||||
|
if fd.flags.EscapeHTML() {
|
||||||
|
s.WriteString(fd.nameS)
|
||||||
|
} else {
|
||||||
|
s.WriteString(fd.nameU)
|
||||||
|
}
|
||||||
|
fd.packerFn(s,fv, fd.flags|f)
|
||||||
|
}
|
||||||
|
if nx == '{' {
|
||||||
|
s.Write2Byte('{','}')
|
||||||
|
} else {
|
||||||
|
s.WriteByte('}')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func jsonTags (tag reflect.StructTag) (string,packs.Flags,bool) {
|
||||||
|
return packs.FlagsFromTag(tag,jsonTag,func(n string) packs.Flags {
|
||||||
|
switch n {
|
||||||
|
case "omitempty" : return packs.FlagOmitEmpty
|
||||||
|
case "quote" : return packs.FlagQuote
|
||||||
|
default : return 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func isEmptyValue(v reflect.Value) bool {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||||
|
return v.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !v.Bool()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return v.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return v.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return v.Float() == 0
|
||||||
|
case reflect.Interface, reflect.Pointer:
|
||||||
|
return v.IsNil()
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rpacker_field.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 07/02/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 (
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
rObjectField struct {
|
||||||
|
name string
|
||||||
|
nameB []byte
|
||||||
|
nameU string // Unscaped name
|
||||||
|
nameS string // Escaped HTML name
|
||||||
|
|
||||||
|
isTagged bool
|
||||||
|
index []int
|
||||||
|
rtype reflect.Type
|
||||||
|
flags packs.Flags
|
||||||
|
|
||||||
|
foldFn packs.FoldFnc
|
||||||
|
packerFn rPackerFnc
|
||||||
|
}
|
||||||
|
|
||||||
|
rFieldList []rObjectField
|
||||||
|
|
||||||
|
rFieldIndexList []rObjectField
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func (f rObjectField) typeByIndex(rtype reflect.Type) reflect.Type {
|
||||||
|
for _,i := range f.index {
|
||||||
|
if rtype.Kind() == reflect.Pointer {
|
||||||
|
rtype = rtype.Elem()
|
||||||
|
}
|
||||||
|
rtype = rtype.Field(i).Type
|
||||||
|
}
|
||||||
|
return rtype
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (l rFieldList) dominant () (rObjectField,bool) {
|
||||||
|
if len(l) > 1 && len(l[0].index) == len(l[1].index) && l[0].isTagged == l[1].isTagged {
|
||||||
|
return rObjectField{},false
|
||||||
|
}
|
||||||
|
return l[0],true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (x rFieldIndexList) Len() int { return len(x) }
|
||||||
|
|
||||||
|
func (x rFieldIndexList) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
|
func (x rFieldIndexList) Less(i, j int) bool {
|
||||||
|
for k, xik := range x[i].index {
|
||||||
|
if k >= len(x[j].index) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if xik != x[j].index[k] {
|
||||||
|
return xik < x[j].index[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len(x[i].index) < len(x[j].index)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rpacker_pointer.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 09/02/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 (
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
rPointer struct {
|
||||||
|
elemPackFn rPackerFnc
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
func rPointerPacker (rtype reflect.Type) rPackerFnc {
|
||||||
|
return (*newRPointer(rtype)).pack
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func newRPointer (rtype reflect.Type) *rPointer {
|
||||||
|
return &rPointer { elemPackFn: rTypePacker(rtype.Elem()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (p rPointer) pack (s *packs.State, v reflect.Value, f packs.Flags) {
|
||||||
|
if v.IsNil() {
|
||||||
|
s.W(g.nullValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Level++
|
||||||
|
if s.Level > maxCyclesAfter {
|
||||||
|
if fn,ok := s.CheckCycle(v.Interface()); ok {
|
||||||
|
defer fn()
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.elemPackFn(s,v.Elem(),f)
|
||||||
|
s.Level--
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rpacker_value.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 13/02/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 (
|
||||||
|
"packs"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func rValuePacker (rvalue reflect.Value) rPackerFnc {
|
||||||
|
if !rvalue.IsValid() {
|
||||||
|
return invalidValuePacker
|
||||||
|
}
|
||||||
|
return rTypePacker(rvalue.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func invalidValuePacker(state *packs.State, _ reflect.Value, _ packs.Flags) {
|
||||||
|
state.SetError(packs.G.ErrInvalidValue)
|
||||||
|
}
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name value_packer.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 05/02/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 (
|
||||||
|
|
||||||
|
ValuePacker interface {
|
||||||
|
|
||||||
|
PackAny (value any, flags Flags)
|
||||||
|
|
||||||
|
PackRaw (value []byte, flags Flags)
|
||||||
|
PackBinary (value []byte, flags Flags)
|
||||||
|
PackString (value string, flags Flags)
|
||||||
|
|
||||||
|
PackBool (value bool, flags Flags)
|
||||||
|
|
||||||
|
PackInt8 (value int8, flags Flags)
|
||||||
|
PackInt16 (value int16, flags Flags)
|
||||||
|
PackInt32 (value int32, flags Flags)
|
||||||
|
PackInt64 (value int64, flags Flags)
|
||||||
|
|
||||||
|
PackUInt8 (value uint8 , flags Flags)
|
||||||
|
PackUInt16 (value uint16, flags Flags)
|
||||||
|
PackUInt32 (value uint32, flags Flags)
|
||||||
|
PackUInt64 (value uint64, flags Flags)
|
||||||
|
|
||||||
|
PackFloat32 (value float32, flags Flags)
|
||||||
|
PackFloat64 (value float64, flags Flags)
|
||||||
|
|
||||||
|
PackDate (value time.Time, flags Flags)
|
||||||
|
|
||||||
|
PackList (flags Flags, builder func(ListPackBuilder, Flags))
|
||||||
|
PackMap (flags Flags, builder func(MapPackBuilder, Flags))
|
||||||
|
PackObject(flags Flags, builder func(ObjectPackBuilder,Flags))
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
module rets
|
|
||||||
|
|
||||||
go 1.22
|
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
module rsts
|
||||||
|
|
||||||
|
go 1.22
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name err_timer.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 20/04/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 timers
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Err struct { errs.ErrCode }
|
||||||
|
|
||||||
|
)
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name gogo.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 21/02/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 times
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
const(
|
||||||
|
|
||||||
|
secondsDay = 24 * 60 * 60
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
G = struct {
|
||||||
|
|
||||||
|
ErrInvalidDateRange Err
|
||||||
|
}{
|
||||||
|
|
||||||
|
ErrInvalidDateRange : Err{ errs.ErrCode ("invalid-date-range")},
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func IsYearLeap (year int) bool {
|
||||||
|
return year%4 == 0 && (year%100 != 0 || year%400 == 0) }
|
||||||
|
|
||||||
|
|
||||||
|
func DaysInYear (year int) int {
|
||||||
|
if IsYearLeap(year) {
|
||||||
|
return 366 }
|
||||||
|
return 365
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func DaysIn (year, month int) int {
|
||||||
|
if month <= 0 || month > 12 {
|
||||||
|
return 0 }
|
||||||
|
d := [12]int{ 31,28,31,30,31,30,31,30,31,30,31 }
|
||||||
|
if month == 2 && IsYearLeap(year) {
|
||||||
|
return 29 }
|
||||||
|
return d[month]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func DayOfWeek (year, month, day int) int {
|
||||||
|
if month < 3 {
|
||||||
|
month += 12
|
||||||
|
year--
|
||||||
|
}
|
||||||
|
J := year / 100
|
||||||
|
K := year % 100
|
||||||
|
h := (day + (13*(month+1))/5 + K + K/4 + J/4 + 5*J) % 7
|
||||||
|
if h <= 1 {
|
||||||
|
return h+6
|
||||||
|
}
|
||||||
|
return h-1
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name gogo.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 21/02/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 bdates
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
const(
|
||||||
|
|
||||||
|
minBYear int = 1900
|
||||||
|
maxBYear int = 2155
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
|
||||||
|
G = struct {
|
||||||
|
ErrInvalidDay Err
|
||||||
|
ErrInvalidMonth Err
|
||||||
|
ErrInvalidYear Err
|
||||||
|
}{
|
||||||
|
ErrInvalidDay : Err{errs.ErrCode("invalid-day")},
|
||||||
|
ErrInvalidMonth : Err{errs.ErrCode("invalid-month")},
|
||||||
|
ErrInvalidYear : Err{errs.ErrCode("invalid-year")},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func checkDayNumber (day int) bool {
|
||||||
|
return day >=1 && day <=7 }
|
||||||
|
|
||||||
|
|
||||||
|
func checkMonthNumber(month int) bool {
|
||||||
|
return month >=1 && month <=12 }
|
||||||
|
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name bmonth.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 21/02/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 bdates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
BMonth uint32
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,125 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name bweek.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 21/02/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 bdates
|
||||||
|
|
||||||
|
import "math/bits"
|
||||||
|
|
||||||
|
const(
|
||||||
|
|
||||||
|
BWeekDaysMon BWeekDays = 1 << iota
|
||||||
|
BWeekDaysTue
|
||||||
|
BWeekDaysWed
|
||||||
|
BWeekDaysThu
|
||||||
|
BWeekDaysFri
|
||||||
|
BWeekDaysSat
|
||||||
|
BWeekDaysSun
|
||||||
|
|
||||||
|
_BWeekFlag
|
||||||
|
|
||||||
|
BWeekDaysAll = 0x1111111
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
// BWeekDays
|
||||||
|
// Type: uint8
|
||||||
|
// Desc: Representa una lista de los dias de la semana
|
||||||
|
// a través de un byte
|
||||||
|
BWeekDays uint8
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func (w BWeekDays) GetFlag() bool {
|
||||||
|
return w&_BWeekFlag==_BWeekFlag }
|
||||||
|
|
||||||
|
|
||||||
|
func (w BWeekDays) SetFlag(val bool) BWeekDays {
|
||||||
|
if val {
|
||||||
|
return w|_BWeekFlag
|
||||||
|
}
|
||||||
|
return w&^_BWeekFlag
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (w BWeekDays) SetDay (num int, val bool) BWeekDays {
|
||||||
|
if num < 0 || num > 7 {
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
if val {
|
||||||
|
w |= 1 << num-1
|
||||||
|
} else {
|
||||||
|
w &^= 1 << num-1
|
||||||
|
}
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (w BWeekDays) GetDay (num int) bool {
|
||||||
|
if num < 0 || num > 7 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c := BWeekDays(1 << num-1)
|
||||||
|
return (w&c)==c
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (w BWeekDays) Invert () BWeekDays {
|
||||||
|
return ^w }
|
||||||
|
|
||||||
|
|
||||||
|
func (w BWeekDays) Count () int {
|
||||||
|
return bits.OnesCount8(uint8(w)) }
|
||||||
|
|
||||||
|
|
||||||
|
func (w BWeekDays) List () []int {
|
||||||
|
c := BWeekDays(1)
|
||||||
|
r := make([]int,0,7)
|
||||||
|
for i:=1; i<=7; i++ {
|
||||||
|
if c&w == c {
|
||||||
|
r = append(r,i)
|
||||||
|
}
|
||||||
|
c <<=1
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (w BWeekDays) ToSlice () []bool {
|
||||||
|
c := BWeekDays(1)
|
||||||
|
r := make([]bool,7)
|
||||||
|
for i:=0; i<7; i++ {
|
||||||
|
r[i]=c&w == c
|
||||||
|
c <<=1
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (w BWeekDays) Common (dst BWeekDays) BWeekDays { return w & dst }
|
||||||
@ -0,0 +1,128 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name byear.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 21/02/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 bdates
|
||||||
|
|
||||||
|
import "times"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
BYear struct {
|
||||||
|
atts BYearAtt
|
||||||
|
first byte
|
||||||
|
year byte
|
||||||
|
months [12]BMonth
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func NewBYear (year int) *BYear {
|
||||||
|
if year < minBYear || year > maxBYear {
|
||||||
|
panic(G.ErrInvalidYear)
|
||||||
|
}
|
||||||
|
at := BYearAtt(BYearAttSet)
|
||||||
|
if times.IsYearLeap(year) {
|
||||||
|
at|=BYearAttLeap
|
||||||
|
}
|
||||||
|
return &BYear {
|
||||||
|
atts : at,
|
||||||
|
first: byte(times.DayOfWeek(year,1,1)),
|
||||||
|
year : byte(year-1900),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (y *BYear) Atts () BYearAtt {
|
||||||
|
return y.atts }
|
||||||
|
|
||||||
|
func (y *BYear) First () int {
|
||||||
|
return int(y.first) }
|
||||||
|
|
||||||
|
func (y *BYear) Year () int {
|
||||||
|
return minBYear + int(y.year) }
|
||||||
|
|
||||||
|
|
||||||
|
func (y *BYear) Clear (month ...int) {
|
||||||
|
if len(month) == 0 {
|
||||||
|
for i := 0; i < 12; i++ {
|
||||||
|
y.months[i] = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _,i := range month {
|
||||||
|
if !checkMonthNumber(i){
|
||||||
|
panic(G.ErrInvalidMonth)
|
||||||
|
}
|
||||||
|
y.months[i]=0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (y *BYear) GetDay (month, day int) bool {
|
||||||
|
if !checkMonthNumber(month) {
|
||||||
|
panic(G.ErrInvalidMonth )
|
||||||
|
}
|
||||||
|
if day < 1 || day > y.daysInMonth(month) {
|
||||||
|
panic(G.ErrInvalidDay)
|
||||||
|
}
|
||||||
|
return (uint32(1 << day) & uint32(y.months[month])) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (y *BYear) SetDay (month, day int, active bool) {
|
||||||
|
if !checkMonthNumber(month) {
|
||||||
|
panic(G.ErrInvalidMonth )
|
||||||
|
}
|
||||||
|
if day < 1 || day > y.daysInMonth(month) {
|
||||||
|
panic(G.ErrInvalidDay)
|
||||||
|
}
|
||||||
|
month-=1
|
||||||
|
if active {
|
||||||
|
y.months[month] = y.months[month] | BMonth(1 << day)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
y.months[month] = y.months[month] &^ BMonth(1 << day)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (y *BYear) GetMonth (month int) BMonth {
|
||||||
|
if !checkMonthNumber(month) {
|
||||||
|
panic(G.ErrInvalidMonth)
|
||||||
|
}
|
||||||
|
return y.months[month-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (y BYear) daysInMonth (month int) int {
|
||||||
|
d := [12]int{ 31,28,31,30,31,30,31,30,31,30,31 }
|
||||||
|
if month == 2 && y.Atts().IsLeap() {
|
||||||
|
return 29
|
||||||
|
}
|
||||||
|
return d[month-1]
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name byear_att.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 21/02/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 bdates
|
||||||
|
|
||||||
|
|
||||||
|
const(
|
||||||
|
|
||||||
|
BYearAttSet BYearAtt = iota << 1
|
||||||
|
BYearAttLeap
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type BYearAtt byte
|
||||||
|
|
||||||
|
|
||||||
|
func (a BYearAtt) IsSet () bool {
|
||||||
|
return a&BYearAttSet != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (a BYearAtt) IsLeap () bool {
|
||||||
|
return a&BYearAttLeap != 0 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name err_bdates.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 20/04/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 bdates
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Err struct { errs.ErrCode }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name days.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 21/02/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 times
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
DateDays int32
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (d DateDays) AddDate(years, months, days int) DateDays {
|
||||||
|
return TimeToDays(d.ToTime().AddDate(years,months,days)) }
|
||||||
|
|
||||||
|
|
||||||
|
func (d DateDays) ToTime() time.Time {
|
||||||
|
return DaysToTime(d) }
|
||||||
|
|
||||||
|
func (d DateDays) Before (days DateDays) bool {
|
||||||
|
return d < days }
|
||||||
|
|
||||||
|
func (d DateDays) After (days DateDays) bool {
|
||||||
|
return d > days }
|
||||||
|
|
||||||
|
func (d DateDays) Compare(days DateDays) int {
|
||||||
|
if d < days {
|
||||||
|
return -1 }
|
||||||
|
if d == days {
|
||||||
|
return 0 }
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d DateDays) Min (days DateDays) DateDays {
|
||||||
|
if d > days {
|
||||||
|
return days
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d DateDays) Max (days DateDays) DateDays {
|
||||||
|
if d < days {
|
||||||
|
return days
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func TimeToDays (time time.Time) DateDays {
|
||||||
|
_,x := time.Zone()
|
||||||
|
s := time.Unix() + int64(x)
|
||||||
|
if s >= 0 {
|
||||||
|
return DateDays(s/ secondsDay) }
|
||||||
|
return -DateDays((secondsDay -1 -s)/ secondsDay)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func DaysToTime(days DateDays) time.Time {
|
||||||
|
return time.Unix(int64(days) *secondsDay,0).UTC() }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA.
|
||||||
|
"LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS.
|
||||||
|
|
||||||
|
SIDDHARTA
|
||||||
|
- HERMANN HESSE -
|
||||||
|
|
||||||
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
*/
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name date_days_range.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 21/02/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 times
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
DateDaysRange struct {
|
||||||
|
Start DateDays
|
||||||
|
End DateDays
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DateDaysRangeFnc func(daysRange *DateDaysRange)
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewDateRange (options ...DateDaysRangeFnc) *DateDaysRange {
|
||||||
|
dr := &DateDaysRange{}
|
||||||
|
for _,o := range options {
|
||||||
|
o(dr)
|
||||||
|
}
|
||||||
|
return dr
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (r DateDaysRange) IsZero () bool {
|
||||||
|
return r.End-r.Start <= 0 }
|
||||||
|
|
||||||
|
|
||||||
|
func (r DateDaysRange) Size () DateDays {
|
||||||
|
return DateDays(r.End -r.Start) }
|
||||||
|
|
||||||
|
|
||||||
|
func (r DateDaysRange) Contains (days DateDays) bool {
|
||||||
|
if r.IsZero() {
|
||||||
|
return false }
|
||||||
|
return r.Start < days && r.End > days
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (r DateDaysRange) ContainsRange (drange DateDaysRange) bool {
|
||||||
|
if r.IsZero() {
|
||||||
|
return false }
|
||||||
|
return r.Start > drange.Start && r.End < drange.End
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (r DateDaysRange) IsRangeOverlap (drange DateDaysRange) bool {
|
||||||
|
if r.IsZero() {
|
||||||
|
return false }
|
||||||
|
if r.Start == drange.Start || r.Start == drange.End || r.End == drange.End {
|
||||||
|
return true }
|
||||||
|
if r.Start > drange.Start {
|
||||||
|
return drange.End < r.End
|
||||||
|
}
|
||||||
|
return r.End > drange.Start
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA.
|
||||||
|
"LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS.
|
||||||
|
|
||||||
|
SIDDHARTA
|
||||||
|
- HERMANN HESSE -
|
||||||
|
|
||||||
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
*/
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rkey.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 05/02/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 times
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
|
||||||
|
DurationFormatter interface {
|
||||||
|
|
||||||
|
FormatDuration (dur time.Duration, dst []byte) []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FormatDurationFnc func (dur time.Duration, dst []byte) []byte
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func (f FormatDurationFnc) FormatDuration (dur time.Duration, dst []byte) []byte {
|
||||||
|
return f(dur,dst) }
|
||||||
|
|
||||||
|
|
||||||
|
func WrapDurationFormatterQuoted (dfm DurationFormatter, qte byte) DurationFormatter {
|
||||||
|
return FormatDurationFnc(func(tme time.Duration, dst []byte) []byte {
|
||||||
|
dst = append(dst, qte)
|
||||||
|
dst = dfm.FormatDuration(tme, dst)
|
||||||
|
return append(dst, qte)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func DurationMillis (dur time.Duration, dst []byte) []byte {
|
||||||
|
return strconv.AppendFloat(dst, float64(dur)/float64(time.Millisecond), 'f', -1, 64) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func DurationNanos(dur time.Duration, dst []byte) []byte {
|
||||||
|
return strconv.AppendInt(dst, int64(dur), 10) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func DurationSecs(dur time.Duration, dst []byte) []byte {
|
||||||
|
return strconv.AppendFloat(dst, float64(dur)/float64(time.Second), 'f', -1, 64) }
|
||||||
|
|
||||||
|
/*
|
||||||
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA.
|
||||||
|
"LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS.
|
||||||
|
|
||||||
|
SIDDHARTA
|
||||||
|
- HERMANN HESSE -
|
||||||
|
|
||||||
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
*/
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name err.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 20/04/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 times
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
Err struct { errs.ErrCode }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
module times
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
go 1.20
|
||||||
@ -0,0 +1,145 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project atila
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name rkey.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 05/02/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 times
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
|
||||||
|
TimeFormatter interface {
|
||||||
|
|
||||||
|
FormatTime (tme time.Time, dst []byte) []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FormatTimeFnc func (tme time.Time, dst []byte) []byte
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func (f FormatTimeFnc) FormatTime (tme time.Time, dst []byte) []byte {
|
||||||
|
return f(tme,dst) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func WrapTimeFormatterQuoted (tmf TimeFormatter, qte byte) TimeFormatter {
|
||||||
|
return FormatTimeFnc(func(tme time.Time, dst []byte) []byte {
|
||||||
|
dst = append(dst, qte)
|
||||||
|
dst = tmf.FormatTime(tme, dst)
|
||||||
|
return append(dst, qte)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func TimeRFC3339Nano(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.RFC3339Nano) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeANSIC(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.ANSIC) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeUnixDate(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.UnixDate) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeRubyDate(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.RubyDate) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeRFC822(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.RFC822) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeRFC822Z(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.RFC822Z) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeRFC850(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.RFC850) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeRFC1123(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.RFC1123) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeRFC1123Z(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.RFC1123Z) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeRFC3339(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.RFC3339) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeKitchen(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.Kitchen) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeISO8601(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, "2006-01-02T15:04:05.000Z0700") }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func TimeEpoch(tme time.Time, dst []byte) []byte {
|
||||||
|
return strconv.AppendFloat(dst, float64(tme.UnixNano())/float64(time.Second), 'f', -1, 64) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeEpochMillis(tme time.Time, dst []byte) []byte {
|
||||||
|
return strconv.AppendFloat(dst, float64(tme.UnixNano())/float64(time.Millisecond), 'f', -1, 64) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeStamp(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.Stamp) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeStampMilli(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.StampMilli) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeStampMicro(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.StampMicro) }
|
||||||
|
|
||||||
|
|
||||||
|
func TimeStampNano(tme time.Time, dst []byte) []byte {
|
||||||
|
return tme.AppendFormat(dst, time.StampNano) }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA.
|
||||||
|
"LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS.
|
||||||
|
|
||||||
|
SIDDHARTA
|
||||||
|
- HERMANN HESSE -
|
||||||
|
|
||||||
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
*/
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name err.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 20/04/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 vals
|
||||||
|
|
||||||
|
import "errs"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type Err struct { errs.ErrCode }
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in new issue