json_pointer_trace.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package jsonutils
  15. import (
  16. "fmt"
  17. "strings"
  18. )
  19. type sJsonPointerNode struct {
  20. pointer *sJSONPointer
  21. inf interface{}
  22. refcnt int
  23. }
  24. func (n *sJsonPointerNode) String() string {
  25. return fmt.Sprintf("<%d>", n.pointer.nodeId)
  26. }
  27. type sJsonPointerTrace struct {
  28. trace []*sJsonPointerNode
  29. }
  30. func newJsonPointerTrace() *sJsonPointerTrace {
  31. return &sJsonPointerTrace{
  32. trace: make([]*sJsonPointerNode, 0, 10),
  33. }
  34. }
  35. func (t *sJsonPointerTrace) push(inf interface{}, ptr *sJSONPointer) *sJsonPointerNode {
  36. node := &sJsonPointerNode{
  37. pointer: ptr,
  38. inf: inf,
  39. refcnt: 1,
  40. }
  41. t.trace = append(t.trace, node)
  42. // log.Debugf("push: %s", t.String())
  43. return node
  44. }
  45. func (t *sJsonPointerTrace) find(inf interface{}) *sJsonPointerNode {
  46. var ret *sJsonPointerNode
  47. for i := range t.trace {
  48. if t.trace[i].inf == inf {
  49. ret = t.trace[i]
  50. }
  51. if ret != nil {
  52. t.trace[i].refcnt++
  53. }
  54. }
  55. return ret
  56. }
  57. func (t *sJsonPointerTrace) pop() {
  58. if len(t.trace) > 0 && t.trace[len(t.trace)-1].refcnt == 1 {
  59. t.trace = t.trace[0 : len(t.trace)-1]
  60. }
  61. // log.Debugf("pop: %s", t.String())
  62. }
  63. func (t *sJsonPointerTrace) String() string {
  64. buf := &strings.Builder{}
  65. for i := range t.trace {
  66. buf.WriteString(t.trace[i].String())
  67. }
  68. return buf.String()
  69. }