gotosocial/vendor/github.com/bytedance/sonic/internal/decoder/optdec/stringopts.go

361 lines
6.1 KiB
Go
Raw Normal View History

package optdec
import (
"encoding/json"
"math"
"unsafe"
"github.com/bytedance/sonic/internal/rt"
)
type ptrStrDecoder struct {
typ *rt.GoType
deref decFunc
}
// Pointer Value is allocated in the Caller
func (d *ptrStrDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
*(*unsafe.Pointer)(vp) = nil
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
*(*unsafe.Pointer)(vp) = nil
return nil
}
if *(*unsafe.Pointer)(vp) == nil {
*(*unsafe.Pointer)(vp) = rt.Mallocgc(d.typ.Size, d.typ, true)
}
return d.deref.FromDom(*(*unsafe.Pointer)(vp), node, ctx)
}
type boolStringDecoder struct {
}
func (d *boolStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
b, err := ParseBool(s)
if err != nil {
return error_mismatch(node, ctx, boolType)
}
*(*bool)(vp) = b
return nil
}
func parseI64(node Node, ctx *context) (int64, error, bool) {
if node.IsNull() {
return 0, nil, true
}
s, ok := node.AsStrRef(ctx)
if !ok {
return 0, error_mismatch(node, ctx, stringType), false
}
if s == "null" {
return 0, nil, true
}
ret, err := ParseI64(s)
return ret, err, false
}
type i8StringDecoder struct{}
func (d *i8StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseI64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxInt8 || ret < math.MinInt8 {
return error_mismatch(node, ctx, int8Type)
}
*(*int8)(vp) = int8(ret)
return nil
}
type i16StringDecoder struct{}
func (d *i16StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseI64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxInt16 || ret < math.MinInt16 {
return error_mismatch(node, ctx, int16Type)
}
*(*int16)(vp) = int16(ret)
return nil
}
type i32StringDecoder struct{}
func (d *i32StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseI64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxInt32 || ret < math.MinInt32 {
return error_mismatch(node, ctx, int32Type)
}
*(*int32)(vp) = int32(ret)
return nil
}
type i64StringDecoder struct{}
func (d *i64StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseI64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
*(*int64)(vp) = int64(ret)
return nil
}
func parseU64(node Node, ctx *context) (uint64, error, bool) {
if node.IsNull() {
return 0, nil, true
}
s, ok := node.AsStrRef(ctx)
if !ok {
return 0, error_mismatch(node, ctx, stringType), false
}
if s == "null" {
return 0, nil, true
}
ret, err := ParseU64(s)
return ret, err, false
}
type u8StringDecoder struct{}
func (d *u8StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseU64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxUint8 {
return error_mismatch(node, ctx, uint8Type)
}
*(*uint8)(vp) = uint8(ret)
return nil
}
type u16StringDecoder struct{}
func (d *u16StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseU64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxUint16 {
return error_mismatch(node, ctx, uint16Type)
}
*(*uint16)(vp) = uint16(ret)
return nil
}
type u32StringDecoder struct{}
func (d *u32StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseU64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
if ret > math.MaxUint32 {
return error_mismatch(node, ctx, uint32Type)
}
*(*uint32)(vp) = uint32(ret)
return nil
}
type u64StringDecoder struct{}
func (d *u64StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
ret, err, null := parseU64(node, ctx)
if null {
return nil
}
if err != nil {
return err
}
*(*uint64)(vp) = uint64(ret)
return nil
}
type f32StringDecoder struct{}
func (d *f32StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
ret, err := ParseF64(s)
if err != nil || ret > math.MaxFloat32 || ret < -math.MaxFloat32 {
return error_mismatch(node, ctx, float32Type)
}
*(*float32)(vp) = float32(ret)
return nil
}
type f64StringDecoder struct{}
func (d *f64StringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
ret, err := ParseF64(s)
if err != nil {
return error_mismatch(node, ctx, float64Type)
}
*(*float64)(vp) = float64(ret)
return nil
}
/* parse string field with string options */
type strStringDecoder struct{}
func (d *strStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
s, err := Unquote(s)
if err != nil {
return error_mismatch(node, ctx, stringType)
}
*(*string)(vp) = s
return nil
}
type numberStringDecoder struct{}
func (d *numberStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
if node.IsNull() {
return nil
}
s, ok := node.AsStrRef(ctx)
if !ok {
return error_mismatch(node, ctx, stringType)
}
if s == "null" {
return nil
}
num, ok := node.ParseNumber(ctx)
if !ok {
return error_mismatch(node, ctx, jsonNumberType)
}
end, ok := SkipNumberFast(s, 0)
// has error or trailing chars
if !ok || end != len(s) {
return error_mismatch(node, ctx, jsonNumberType)
}
*(*json.Number)(vp) = json.Number(num)
return nil
}