// ------------------------------------------------------------------------ // 🚀 Project active3 // 🔗 Active Thing (activething.com) git.activething.com/go // // File name builder_state.go // ✍️ Created by DEV // 📅 Modified 04/05/2024 // // 🔒 Copyright 2024 activething.com // // 📜 LICENSE -------------------------------------------------------------- // 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 pstate import ( "apack" "bfrs" "crps" ) type ( State struct { B *bfrs.ABuffer key any field string IsValue bool Level int levels []StateLevel Current *StateLevel Pos int Err error cyclesCheck map[any]struct{} Encrypter crps.Encrypter } StateFnc func(state *State) ) func AcquireState (options ...StateFnc) *State { return (g.statePool.Get()).init(options) } func ReleaseState (state *State) { g.statePool.Put(state.reset()) } func NewState(options ...StateFnc) *State { return (&State{ B : bfrs.NewABuffer(), levels: make([]StateLevel,g.levelsLen), }).init(options) } func (s *State) init (options []StateFnc) *State { for _,o := range options { o(s) } s.levels[0].Ini(ModeValue,0) return s } func (s *State) reset () *State { s.B.Reset() s.key = nil s.field = "" s.IsValue = false s.Level = 0 s.Pos = 0 s.Err = nil s.cyclesCheck = nil s.Encrypter = nil for i := 0; i g.levelsLen { s.levels = append(s.levels, *((&(StateLevel{})).Ini(mode, s.B.Len()))) } else { (&s.levels[s.Level]).Ini(mode, s.B.Len()) } s.Current = &s.levels[s.Level] } func (s *State) Close(mode Mode) { s.Level-- if s.Level < 0 { s.SetError(apack.G.ErrStateInvalidLevel) return } if s.levels[s.Level].Mode != mode { s.SetError(apack.G.ErrInvalidNode) } s.Current = &s.levels[s.Level] } func (s *State) CheckCycle(ptr any) (func(),bool) { if _,hs := s.cyclesCheck[ptr]; hs { s.SetError(apack.G.ErrCircularReference) return nil,false } s.cyclesCheck[ptr]=struct{}{} return func(){ delete(s.cyclesCheck,ptr) }, true } func (s *State) SetError (err error) bool { if err == nil { return false } s.reset() s.Err = err return true }