github.com/3JoB/go-json@v0.10.4/internal/encoder/vm_color/util.go (about)

     1  package vm_color
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"unsafe"
     7  
     8  	"github.com/3JoB/go-json/internal/encoder"
     9  	"github.com/3JoB/go-json/internal/runtime"
    10  )
    11  
    12  const uintptrSize = 4 << (^uintptr(0) >> 63)
    13  
    14  var (
    15  	errUnsupportedValue = encoder.ErrUnsupportedValue
    16  	errUnsupportedFloat = encoder.ErrUnsupportedFloat
    17  	mapiterinit         = encoder.MapIterInit
    18  	mapiterkey          = encoder.MapIterKey
    19  	mapitervalue        = encoder.MapIterValue
    20  	mapiternext         = encoder.MapIterNext
    21  	maplen              = encoder.MapLen
    22  )
    23  
    24  type emptyInterface struct {
    25  	typ *runtime.Type
    26  	ptr unsafe.Pointer
    27  }
    28  
    29  type nonEmptyInterface struct {
    30  	itab *struct {
    31  		ityp *runtime.Type // static interface type
    32  		typ  *runtime.Type // dynamic concrete type
    33  		// unused fields...
    34  	}
    35  	ptr unsafe.Pointer
    36  }
    37  
    38  func errUnimplementedOp(op encoder.OpType) error {
    39  	return fmt.Errorf("encoder: opcode %s has not been implemented", op)
    40  }
    41  
    42  func load(base uintptr, idx uint32) uintptr {
    43  	addr := base + uintptr(idx)
    44  	return **(**uintptr)(unsafe.Pointer(&addr))
    45  }
    46  
    47  func store(base uintptr, idx uint32, p uintptr) {
    48  	addr := base + uintptr(idx)
    49  	**(**uintptr)(unsafe.Pointer(&addr)) = p
    50  }
    51  
    52  func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr {
    53  	addr := base + uintptr(idx)
    54  	p := **(**uintptr)(unsafe.Pointer(&addr))
    55  	for i := uint8(0); i < ptrNum; i++ {
    56  		if p == 0 {
    57  			return 0
    58  		}
    59  		p = ptrToPtr(p)
    60  	}
    61  	return p
    62  }
    63  
    64  func ptrToUint64(p uintptr, bitSize uint8) uint64 {
    65  	switch bitSize {
    66  	case 8:
    67  		return (uint64)(**(**uint8)(unsafe.Pointer(&p)))
    68  	case 16:
    69  		return (uint64)(**(**uint16)(unsafe.Pointer(&p)))
    70  	case 32:
    71  		return (uint64)(**(**uint32)(unsafe.Pointer(&p)))
    72  	case 64:
    73  		return **(**uint64)(unsafe.Pointer(&p))
    74  	}
    75  	return 0
    76  }
    77  
    78  func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
    79  
    80  func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
    81  
    82  func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
    83  
    84  func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
    85  
    86  func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
    87  
    88  func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
    89  
    90  func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
    91  
    92  func ptrToPtr(p uintptr) uintptr {
    93  	return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
    94  }
    95  
    96  func ptrToNPtr(p uintptr, ptrNum uint8) uintptr {
    97  	for i := uint8(0); i < ptrNum; i++ {
    98  		if p == 0 {
    99  			return 0
   100  		}
   101  		p = ptrToPtr(p)
   102  	}
   103  	return p
   104  }
   105  
   106  func ptrToUnsafePtr(p uintptr) unsafe.Pointer {
   107  	return *(*unsafe.Pointer)(unsafe.Pointer(&p))
   108  }
   109  
   110  func ptrToInterface(code *encoder.Opcode, p uintptr) any {
   111  	return *(*any)(unsafe.Pointer(&emptyInterface{
   112  		typ: code.Type,
   113  		ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
   114  	}))
   115  }
   116  
   117  func appendInt(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte {
   118  	format := ctx.Option.ColorScheme.Int
   119  	b = append(b, format.Header...)
   120  	b = encoder.AppendInt(ctx, b, p, code)
   121  	return append(b, format.Footer...)
   122  }
   123  
   124  func appendUint(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte {
   125  	format := ctx.Option.ColorScheme.Uint
   126  	b = append(b, format.Header...)
   127  	b = encoder.AppendUint(ctx, b, p, code)
   128  	return append(b, format.Footer...)
   129  }
   130  
   131  func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte {
   132  	format := ctx.Option.ColorScheme.Float
   133  	b = append(b, format.Header...)
   134  	b = encoder.AppendFloat32(ctx, b, v)
   135  	return append(b, format.Footer...)
   136  }
   137  
   138  func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte {
   139  	format := ctx.Option.ColorScheme.Float
   140  	b = append(b, format.Header...)
   141  	b = encoder.AppendFloat64(ctx, b, v)
   142  	return append(b, format.Footer...)
   143  }
   144  
   145  func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte {
   146  	format := ctx.Option.ColorScheme.String
   147  	b = append(b, format.Header...)
   148  	b = encoder.AppendString(ctx, b, v)
   149  	return append(b, format.Footer...)
   150  }
   151  
   152  func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte {
   153  	format := ctx.Option.ColorScheme.Binary
   154  	b = append(b, format.Header...)
   155  	b = encoder.AppendByteSlice(ctx, b, src)
   156  	return append(b, format.Footer...)
   157  }
   158  
   159  func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) {
   160  	format := ctx.Option.ColorScheme.Int
   161  	b = append(b, format.Header...)
   162  	bb, err := encoder.AppendNumber(ctx, b, n)
   163  	if err != nil {
   164  		return nil, err
   165  	}
   166  	return append(bb, format.Footer...), nil
   167  }
   168  
   169  func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte {
   170  	format := ctx.Option.ColorScheme.Bool
   171  	b = append(b, format.Header...)
   172  	if v {
   173  		b = append(b, "true"...)
   174  	} else {
   175  		b = append(b, "false"...)
   176  	}
   177  	return append(b, format.Footer...)
   178  }
   179  
   180  func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte {
   181  	format := ctx.Option.ColorScheme.Null
   182  	b = append(b, format.Header...)
   183  	b = append(b, "null"...)
   184  	return append(b, format.Footer...)
   185  }
   186  
   187  func appendComma(_ *encoder.RuntimeContext, b []byte) []byte {
   188  	return append(b, ',')
   189  }
   190  
   191  func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte {
   192  	format := ctx.Option.ColorScheme.Null
   193  	b = append(b, format.Header...)
   194  	b = append(b, "null"...)
   195  	return append(append(b, format.Footer...), ',')
   196  }
   197  
   198  func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
   199  	last := len(b) - 1
   200  	b[last] = ':'
   201  	return b
   202  }
   203  
   204  func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte {
   205  	b = append(b, key[:len(key)-1]...)
   206  	b = append(b, ':')
   207  	return append(b, value...)
   208  }
   209  
   210  func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
   211  	last := len(b) - 1
   212  	b[last] = '}'
   213  	b = append(b, ',')
   214  	return b
   215  }
   216  
   217  func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v any) ([]byte, error) {
   218  	return encoder.AppendMarshalJSON(ctx, code, b, v)
   219  }
   220  
   221  func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v any) ([]byte, error) {
   222  	format := ctx.Option.ColorScheme.String
   223  	b = append(b, format.Header...)
   224  	bb, err := encoder.AppendMarshalText(ctx, code, b, v)
   225  	if err != nil {
   226  		return nil, err
   227  	}
   228  	return append(bb, format.Footer...), nil
   229  }
   230  
   231  func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
   232  	return append(b, '[')
   233  }
   234  
   235  func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
   236  	last := len(b) - 1
   237  	b[last] = ']'
   238  	return append(b, ',')
   239  }
   240  
   241  func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte {
   242  	return append(b, '[', ']', ',')
   243  }
   244  
   245  func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
   246  	return append(b, '{', '}', ',')
   247  }
   248  
   249  func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
   250  	last := len(b) - 1
   251  	b[last] = '}'
   252  	return append(b, ',')
   253  }
   254  
   255  func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte {
   256  	return append(b, '{')
   257  }
   258  
   259  func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
   260  	format := ctx.Option.ColorScheme.ObjectKey
   261  	b = append(b, format.Header...)
   262  	b = append(b, code.Key[:len(code.Key)-1]...)
   263  	b = append(b, format.Footer...)
   264  
   265  	return append(b, ':')
   266  }
   267  
   268  func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
   269  	return append(b, '}', ',')
   270  }
   271  
   272  func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
   273  	last := len(b) - 1
   274  	if b[last] == ',' {
   275  		b[last] = '}'
   276  		return appendComma(ctx, b)
   277  	}
   278  	return appendStructEnd(ctx, code, b)
   279  }
   280  
   281  func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr) {}
   282  
   283  func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr) {}
   284  
   285  func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }
   286  
   287  func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }