gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ptr.go (2073B)


      1 package decoder
      2 
      3 import (
      4 	"fmt"
      5 	"unsafe"
      6 
      7 	"github.com/goccy/go-json/internal/runtime"
      8 )
      9 
     10 type ptrDecoder struct {
     11 	dec        Decoder
     12 	typ        *runtime.Type
     13 	structName string
     14 	fieldName  string
     15 }
     16 
     17 func newPtrDecoder(dec Decoder, typ *runtime.Type, structName, fieldName string) *ptrDecoder {
     18 	return &ptrDecoder{
     19 		dec:        dec,
     20 		typ:        typ,
     21 		structName: structName,
     22 		fieldName:  fieldName,
     23 	}
     24 }
     25 
     26 func (d *ptrDecoder) contentDecoder() Decoder {
     27 	dec, ok := d.dec.(*ptrDecoder)
     28 	if !ok {
     29 		return d.dec
     30 	}
     31 	return dec.contentDecoder()
     32 }
     33 
     34 //nolint:golint
     35 //go:linkname unsafe_New reflect.unsafe_New
     36 func unsafe_New(*runtime.Type) unsafe.Pointer
     37 
     38 func UnsafeNew(t *runtime.Type) unsafe.Pointer {
     39 	return unsafe_New(t)
     40 }
     41 
     42 func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
     43 	if s.skipWhiteSpace() == nul {
     44 		s.read()
     45 	}
     46 	if s.char() == 'n' {
     47 		if err := nullBytes(s); err != nil {
     48 			return err
     49 		}
     50 		*(*unsafe.Pointer)(p) = nil
     51 		return nil
     52 	}
     53 	var newptr unsafe.Pointer
     54 	if *(*unsafe.Pointer)(p) == nil {
     55 		newptr = unsafe_New(d.typ)
     56 		*(*unsafe.Pointer)(p) = newptr
     57 	} else {
     58 		newptr = *(*unsafe.Pointer)(p)
     59 	}
     60 	if err := d.dec.DecodeStream(s, depth, newptr); err != nil {
     61 		return err
     62 	}
     63 	return nil
     64 }
     65 
     66 func (d *ptrDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
     67 	buf := ctx.Buf
     68 	cursor = skipWhiteSpace(buf, cursor)
     69 	if buf[cursor] == 'n' {
     70 		if err := validateNull(buf, cursor); err != nil {
     71 			return 0, err
     72 		}
     73 		if p != nil {
     74 			*(*unsafe.Pointer)(p) = nil
     75 		}
     76 		cursor += 4
     77 		return cursor, nil
     78 	}
     79 	var newptr unsafe.Pointer
     80 	if *(*unsafe.Pointer)(p) == nil {
     81 		newptr = unsafe_New(d.typ)
     82 		*(*unsafe.Pointer)(p) = newptr
     83 	} else {
     84 		newptr = *(*unsafe.Pointer)(p)
     85 	}
     86 	c, err := d.dec.Decode(ctx, cursor, depth, newptr)
     87 	if err != nil {
     88 		return 0, err
     89 	}
     90 	cursor = c
     91 	return cursor, nil
     92 }
     93 
     94 func (d *ptrDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
     95 	return nil, 0, fmt.Errorf("json: ptr decoder does not support decode path")
     96 }