// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. //go:build script // +build script package js import ( "github.com/iwind/TeaGo/types" "rogchap.com/v8go" ) type FunctionArguments struct { ctx *Context rawInfo *v8go.FunctionCallbackInfo } func NewFunctionArguments(ctx *Context, rawInfo *v8go.FunctionCallbackInfo) *FunctionArguments { return &FunctionArguments{ ctx: ctx, rawInfo: rawInfo, } } func (this *FunctionArguments) Context() *Context { return this.ctx } func (this *FunctionArguments) Args() []*v8go.Value { return this.rawInfo.Args() } func (this *FunctionArguments) ArgAt(index int) (value *v8go.Value, ok bool) { var args = this.rawInfo.Args() if index < len(args) { return args[index], true } return nil, false } func (this *FunctionArguments) StringAt(index int) (value string, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsString() { return arg.String(), true } return "", false } return "", false } func (this *FunctionArguments) FormatStringAt(index int) (value string, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsString() || arg.IsNumber() { return arg.String(), true } return "", false } return "", false } func (this *FunctionArguments) StringsAt(index int) (value []string, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsArray() { var obj = arg.Object() arrayLengthValue, err := obj.Get("length") if err != nil { return } if arrayLengthValue.IsUint32() { var arrayLength = arrayLengthValue.Uint32() for i := uint32(0); i < arrayLength; i++ { elementValue, err := obj.GetIdx(i) if err != nil { return } if elementValue.IsString() { value = append(value, elementValue.String()) } } ok = true return } } } return } func (this *FunctionArguments) FormatStringsAt(index int) (value []string, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsArray() { var obj = arg.Object() arrayLengthValue, err := obj.Get("length") if err != nil { return } if arrayLengthValue.IsUint32() { var arrayLength = arrayLengthValue.Uint32() for i := uint32(0); i < arrayLength; i++ { elementValue, err := obj.GetIdx(i) if err != nil { return } if elementValue.IsString() || elementValue.IsNumber() { value = append(value, elementValue.String()) } } ok = true return } } } return } func (this *FunctionArguments) ObjectAt(index int) (obj *Object, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsObject() { return NewObject(arg.Object()), true } } return nil, false } func (this *FunctionArguments) GoObjectAt(index int) (value any, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsUint32() { return this.ctx.GoObject(arg.Uint32()) } } return nil, false } func (this *FunctionArguments) IntAt(index int) (value int, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsInt32() { value = types.Int(arg.Int32()) ok = true return } if arg.IsUint32() { value = types.Int(arg.Uint32()) ok = true return } if arg.IsBigInt() { value = types.Int(arg.BigInt().Int64()) ok = true return } if arg.IsNumber() { value = types.Int(arg.Number()) ok = true return } if arg.IsString() { var s = arg.String() if this.isDigitString(s) { value = types.Int(s) ok = true return } } } return 0, false } func (this *FunctionArguments) Int64At(index int) (value int64, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsInt32() { value = types.Int64(arg.Int32()) ok = true return } if arg.IsUint32() { value = types.Int64(arg.Uint32()) ok = true return } if arg.IsBigInt() { value = types.Int64(arg.BigInt().Int64()) ok = true return } if arg.IsNumber() { value = types.Int64(arg.Number()) ok = true return } if arg.IsString() { var s = arg.String() if this.isDigitString(s) { value = types.Int64(s) ok = true return } } } return 0, false } func (this *FunctionArguments) Float32At(index int) (value float32, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsInt32() { value = types.Float32(arg.Int32()) ok = true return } if arg.IsUint32() { value = types.Float32(arg.Uint32()) ok = true return } if arg.IsBigInt() { value = types.Float32(arg.BigInt().Int64()) ok = true return } if arg.IsNumber() { value = types.Float32(arg.Number()) ok = true return } if arg.IsString() { var s = arg.String() // TODO 支持小数点 if this.isDigitString(s) { value = types.Float32(s) ok = true return } } } return 0, false } func (this *FunctionArguments) Float64At(index int) (value float64, ok bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsInt32() { value = types.Float64(arg.Int32()) ok = true return } if arg.IsUint32() { value = types.Float64(arg.Uint32()) ok = true return } if arg.IsBigInt() { value = types.Float64(arg.BigInt().Int64()) ok = true return } if arg.IsNumber() { value = arg.Number() ok = true return } if arg.IsString() { var s = arg.String() // TODO 支持小数点 if this.isDigitString(s) { value = types.Float64(s) ok = true return } } } return 0, false } func (this *FunctionArguments) BytesAt(index int) ([]byte, bool) { var args = this.rawInfo.Args() if index < len(args) { var arg = args[index] if arg.IsArrayBuffer() { sizeValue, err := arg.Object().Get("byteLength") if err != nil { return nil, false } var size = int(sizeValue.Int32()) if size == 0 { return []byte{}, true } var result = make([]byte, size) for i := 0; i < size; i++ { byteValue, err := arg.Object().GetIdx(uint32(i)) if err != nil { return nil, false } result[i] = types.Uint8(byteValue.Uint32()) } return result, true } } return nil, false } func (this *FunctionArguments) This() *v8go.Object { return this.rawInfo.This() } func (this *FunctionArguments) isDigitString(s string) bool { if len(s) == 0 || len(s) > 11 /** 我们只解析不大于11位的 **/ { return false } for _, c := range s { if c < '0' || c > '9' { return false } } return true }