333 lines
6.7 KiB
Go
333 lines
6.7 KiB
Go
// 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
|
|
}
|