github.com/grbit/go-json@v0.11.0/internal/encoder/context.go (about)

     1  package encoder
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  	"unsafe"
     7  
     8  	"github.com/grbit/go-json/internal/runtime"
     9  )
    10  
    11  type compileContext struct {
    12  	opcodeIndex       uint32
    13  	ptrIndex          int
    14  	indent            uint32
    15  	escapeKey         bool
    16  	structTypeToCodes map[uintptr]Opcodes
    17  	recursiveCodes    *Opcodes
    18  }
    19  
    20  func (c *compileContext) incIndent() {
    21  	c.indent++
    22  }
    23  
    24  func (c *compileContext) decIndent() {
    25  	c.indent--
    26  }
    27  
    28  func (c *compileContext) incIndex() {
    29  	c.incOpcodeIndex()
    30  	c.incPtrIndex()
    31  }
    32  
    33  func (c *compileContext) decIndex() {
    34  	c.decOpcodeIndex()
    35  	c.decPtrIndex()
    36  }
    37  
    38  func (c *compileContext) incOpcodeIndex() {
    39  	c.opcodeIndex++
    40  }
    41  
    42  func (c *compileContext) decOpcodeIndex() {
    43  	c.opcodeIndex--
    44  }
    45  
    46  func (c *compileContext) incPtrIndex() {
    47  	c.ptrIndex++
    48  }
    49  
    50  func (c *compileContext) decPtrIndex() {
    51  	c.ptrIndex--
    52  }
    53  
    54  const (
    55  	bufSize = 1024
    56  )
    57  
    58  var (
    59  	runtimeContextPool = sync.Pool{
    60  		New: func() interface{} {
    61  			return &RuntimeContext{
    62  				Buf:      make([]byte, 0, bufSize),
    63  				Ptrs:     make([]uintptr, 128),
    64  				KeepRefs: make([]unsafe.Pointer, 0, 8),
    65  				Option:   &Option{},
    66  			}
    67  		},
    68  	}
    69  )
    70  
    71  type RuntimeContext struct {
    72  	Context    context.Context
    73  	Buf        []byte
    74  	MarshalBuf []byte
    75  	Ptrs       []uintptr
    76  	KeepRefs   []unsafe.Pointer
    77  	SeenPtr    []uintptr
    78  	BaseIndent uint32
    79  	Prefix     []byte
    80  	IndentStr  []byte
    81  	Option     *Option
    82  }
    83  
    84  func (c *RuntimeContext) Init(p uintptr, codelen int) {
    85  	if len(c.Ptrs) < codelen {
    86  		c.Ptrs = make([]uintptr, codelen)
    87  	}
    88  	c.Ptrs[0] = p
    89  	c.KeepRefs = c.KeepRefs[:0]
    90  	c.SeenPtr = c.SeenPtr[:0]
    91  	c.BaseIndent = 0
    92  }
    93  
    94  func (c *RuntimeContext) Ptr() uintptr {
    95  	header := (*runtime.SliceHeader)(unsafe.Pointer(&c.Ptrs))
    96  	return uintptr(header.Data)
    97  }
    98  
    99  func TakeRuntimeContext() *RuntimeContext {
   100  	return runtimeContextPool.Get().(*RuntimeContext)
   101  }
   102  
   103  func ReleaseRuntimeContext(ctx *RuntimeContext) {
   104  	runtimeContextPool.Put(ctx)
   105  }