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 }