// ------------------------------------------------------------------------ // Project atila // Active Thing (activething.com) git.activething.com/go // // File name builder_state.go // Created by DEV // Modified 16/01/2024 // // Copyright 2024 activething.com // ------------------------------------------------------------------------ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ------------------------------------------------------------------------ package packs import ( "activething.com/go/gogo/core/bins" "sync" "sync/atomic" ) type ( State struct { /*Embedded*/*bins.Buffer Node *Node Error error } ) func AcquireState () *State { if atomic.CompareAndSwapUint32(&G.stateSem,0,1) { G.statePool = &sync.Pool{ New: func() any { return &State { Node : AcquireNode(nil, NodeKindValue, 0), Buffer: bins.NewBuffer(), } }, } } return G.statePool.Get().(*State) } func ReleaseState (state *State) { if state == nil { return } state.Buffer.Reset() state.Node.Reset() state.Error = nil G.statePool.Put(state) } func (s *State) SetError(err error) bool { if s.Error != nil { return true } if err == nil { return false } s.Error = err s.Reset() s.Node.Reset() return true } func (s *State) SetKey(key string) bool { if s.Error != nil { return false } if s.Node.keys.Has(key) { return !s.SetError(G.ErrDuplicatedKey) } s.Node.keys = s.Node.keys.Append(key) return true } func (s *State) SetValue() bool { if s.Error != nil { return false } s.Node.Count++ return true } func (s *State) Open(kind NodeKind) bool { if s.Error != nil { return false } if s.Node.Kind == NodeKindValue { if s.Node.Count > 0 { return !s.SetError(G.ErrInvalidNode) } s.Node.Init(s.Node.Parent, kind, s.Len()) } else { s.Node = AcquireNode(s.Node, kind, s.Len()) } return true } func (s *State) Close() bool { if s.Error != nil { return false } if s.Node.Kind == NodeKindValue { return !s.SetError(G.ErrInvalidNode) } if s.Node.Parent != nil { p := s.Node s.Node = s.Node.Parent ReleaseNode(p.Reset()) } s.Node.Count++ return true }