github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/stack.go (about) 1 package jzon 2 3 import ( 4 "sync" 5 ) 6 7 var ( 8 stackPool = sync.Pool{ 9 New: func() interface{} { 10 return &stack{ 11 stack: make([]uint64, 1), 12 } 13 }, 14 } 15 ) 16 17 type stackElement = int8 18 19 const ( 20 stackElementNone stackElement = -1 21 22 stackElementObjectBegin stackElement = 0 // 0b00 23 stackElementObject stackElement = 2 // 0b10 24 25 stackElementArrayBegin stackElement = 1 // 0b01 26 stackElementArray stackElement = 3 // 0b11 27 ) 28 29 type stack struct { 30 stack []uint64 31 depth uint 32 } 33 34 func (s *stack) init() *stack { 35 s.depth = 0 36 return s 37 } 38 39 func (s *stack) initObject() *stack { 40 if len(s.stack) == 0 { 41 s.stack = make([]uint64, 1) 42 } 43 s.stack[0] = 0 44 s.depth = 1 45 return s 46 } 47 48 func (s *stack) initArray() *stack { 49 if len(s.stack) == 0 { 50 s.stack = make([]uint64, 1) 51 } 52 s.stack[0] = 1 53 s.depth = 1 54 return s 55 } 56 57 func (s *stack) top() stackElement { 58 if s.depth == 0 { 59 return stackElementNone 60 } 61 depth := s.depth - 1 62 div := depth >> 6 63 mod := depth & 63 64 return stackElement((s.stack[div] >> mod) & 1) 65 } 66 67 func (s *stack) pop() stackElement { 68 if s.depth == 0 { 69 return stackElementNone 70 } 71 depth := s.depth - 1 72 div := depth >> 6 73 mod := depth & 63 74 s.depth-- 75 // stackElementObjectBegin -> stackElementObject 76 // stackElementArrayBegin -> stackElementArray 77 return stackElement((s.stack[div]>>mod)&1) | 2 78 } 79 80 func (s *stack) pushObject() *stack { 81 div := s.depth >> 6 82 if div == uint(len(s.stack)) { 83 s.stack = append(s.stack, 0) 84 } else { 85 s.stack[div] &= (1 << (s.depth & 63)) - 1 86 } 87 s.depth++ 88 return s 89 } 90 91 func (s *stack) pushArray() *stack { 92 div := s.depth >> 6 93 if div == uint(len(s.stack)) { 94 s.stack = append(s.stack, 1) 95 } else { 96 s.stack[div] |= 1 << (s.depth & 63) 97 } 98 s.depth++ 99 return s 100 }