Files
waf-platform/EdgeNode/internal/js/function_arguments.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
}