github.com/trim21/go-phpserialize@v0.0.22-0.20240301204449-2fca0319b3f0/internal/encoder/marshal.go (about)

     1  package encoder
     2  
     3  import (
     4  	"unsafe"
     5  )
     6  
     7  func Marshal(v any) ([]byte, error) {
     8  	ctx := newCtx()
     9  
    10  	b, err := encode(ctx, ctx.Buf[:0], v)
    11  	if err != nil {
    12  		freeCtx(ctx)
    13  		return nil, err
    14  	}
    15  
    16  	dst := make([]byte, len(b))
    17  	copy(dst, b)
    18  
    19  	ctx.Buf = b
    20  	freeCtx(ctx)
    21  
    22  	return dst, nil
    23  }
    24  
    25  func encode(ctx *Ctx, b []byte, v any) ([]byte, error) {
    26  	header := (*emptyInterface)(unsafe.Pointer(&v))
    27  	typ := header.typ
    28  
    29  	typeID := uintptr(unsafe.Pointer(typ))
    30  	enc, err := compileTypeIDWithCache(typeID)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  
    35  	ptr := uintptr(header.ptr)
    36  	ctx.KeepRefs = append(ctx.KeepRefs, header.ptr)
    37  
    38  	return enc(ctx, b, ptr)
    39  }