energy/common/common.go

641 lines
14 KiB
Go
Raw Normal View History

2022-10-04 13:21:05 +08:00
//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
// Licensed under Apache License Version 2.0, January 2004
//
// https://www.apache.org/licenses/LICENSE-2.0
2022-10-04 13:21:05 +08:00
//
//----------------------------------------
package common
2022-10-04 13:21:05 +08:00
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
2022-10-04 22:34:57 +08:00
. "github.com/energye/energy/consts"
2022-10-05 15:33:17 +08:00
"github.com/energye/energy/decimal"
2022-10-04 13:21:05 +08:00
"math"
"reflect"
"runtime"
"strconv"
"strings"
"time"
"unsafe"
)
2022-12-13 23:12:01 +08:00
const (
IntSize = strconv.IntSize //bit
IntSize32 = 32 //
intSize64 = 64 //
isWindows = runtime.GOOS == "windows" //support
isLinux = runtime.GOOS == "linux" //support
isDarwin = runtime.GOOS == "darwin" //support
isAndroid = runtime.GOOS == "android" //not support
isIos = runtime.GOOS == "ios" //not support
isPlan9 = runtime.GOOS == "plan9" //not support
isAix = runtime.GOOS == "aix" //not support
isDragonfly = runtime.GOOS == "dragonfly" //not support
isFreebsd = runtime.GOOS == "freebsd" //not support
isHurd = runtime.GOOS == "hurd" //not support
isIllumos = runtime.GOOS == "illumos" //not support
isJs = runtime.GOOS == "js" //not support
isNacl = runtime.GOOS == "nacl" //not support
isNetbsd = runtime.GOOS == "netbsd" //not support
isOpenbsd = runtime.GOOS == "openbsd" //not support
isSolaris = runtime.GOOS == "solaris" //not support
isZos = runtime.GOOS == "zos" //not support
2022-10-04 22:34:57 +08:00
)
2022-10-04 13:21:05 +08:00
func IsWindows() bool {
return isWindows
2022-10-04 13:21:05 +08:00
}
func IsLinux() bool {
return isLinux
2022-10-04 13:21:05 +08:00
}
func IsDarwin() bool {
return isDarwin
2022-10-04 13:21:05 +08:00
}
func IsPlan9() bool {
return isPlan9
}
2022-10-04 13:21:05 +08:00
func StrToInt64(value string) int64 {
v, _ := strconv.ParseInt(value, 10, 64)
return v
}
func StrToInt32(value string) int32 {
v, _ := strconv.ParseInt(value, 10, 32)
return int32(v)
}
func StrToFloat64(value string) float64 {
v, _ := strconv.ParseFloat(value, 64)
return v
}
func StrToFloat32(value string) float32 {
v, _ := strconv.ParseFloat(value, 32)
return float32(v)
}
2023-02-22 19:10:24 +08:00
// InterfaceToString 接口转 string
2022-10-04 13:21:05 +08:00
func InterfaceToString(value interface{}) string {
return fmt.Sprintf("%v", value)
}
2023-02-22 19:10:24 +08:00
// GetParamOf 获取参数指针
2022-10-04 22:34:57 +08:00
func GetParamOf(index int, ptr uintptr) uintptr {
2022-10-04 13:21:05 +08:00
return *(*uintptr)(unsafe.Pointer(ptr + uintptr(index)*unsafe.Sizeof(ptr)))
}
2023-02-22 19:10:24 +08:00
// GetParamPtr 根据指定指针位置开始 偏移获取指针
2022-10-04 22:34:57 +08:00
func GetParamPtr(ptr uintptr, offset int) unsafe.Pointer {
2022-10-04 13:21:05 +08:00
return unsafe.Pointer(ptr + uintptr(offset))
}
2023-02-22 19:10:24 +08:00
// FieldReflectType 通过返回获取字段对应 GO 和 V8 JS 类型
func FieldReflectType(v interface{}) (GO_VALUE_TYPE, V8_JS_VALUE_TYPE) {
2022-10-04 13:21:05 +08:00
if v == nil {
2023-02-22 19:10:24 +08:00
return GO_VALUE_NIL, V8_VALUE_NULL
2022-10-04 13:21:05 +08:00
}
2023-02-21 23:16:35 +08:00
var kind reflect.Kind
switch v.(type) {
case reflect.Type:
kind = v.(reflect.Type).Kind()
2023-02-22 19:10:24 +08:00
case reflect.Kind:
kind = v.(reflect.Kind)
2023-02-21 23:16:35 +08:00
default:
kind = reflect.TypeOf(v).Kind()
}
switch kind {
2022-10-04 13:21:05 +08:00
case reflect.String:
2023-02-22 19:10:24 +08:00
return GO_VALUE_STRING, V8_VALUE_STRING
2022-10-04 13:21:05 +08:00
case reflect.Int:
2023-02-22 19:10:24 +08:00
return GO_VALUE_INT, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Int8:
2023-02-22 19:10:24 +08:00
return GO_VALUE_INT8, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Int16:
2023-02-22 19:10:24 +08:00
return GO_VALUE_INT16, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Int32:
2023-02-22 19:10:24 +08:00
return GO_VALUE_INT32, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Int64:
2023-02-22 19:10:24 +08:00
return GO_VALUE_INT64, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Uint:
2023-02-22 19:10:24 +08:00
return GO_VALUE_UINT, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Uint8:
2023-02-22 19:10:24 +08:00
return GO_VALUE_UINT8, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Uint16:
2023-02-22 19:10:24 +08:00
return GO_VALUE_UINT16, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Uint32:
2023-02-22 19:10:24 +08:00
return GO_VALUE_UINT32, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Uint64:
2023-02-22 19:10:24 +08:00
return GO_VALUE_UINT64, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Uintptr:
2023-02-22 19:10:24 +08:00
return GO_VALUE_UINTPTR, V8_VALUE_INT
2022-10-04 13:21:05 +08:00
case reflect.Float32:
2023-02-22 19:10:24 +08:00
return GO_VALUE_FLOAT32, V8_VALUE_DOUBLE
2022-10-04 13:21:05 +08:00
case reflect.Float64:
2023-02-22 19:10:24 +08:00
return GO_VALUE_FLOAT64, V8_VALUE_DOUBLE
2022-10-04 13:21:05 +08:00
case reflect.Bool:
2023-02-22 19:10:24 +08:00
return GO_VALUE_BOOL, V8_VALUE_BOOLEAN
2022-10-04 13:21:05 +08:00
case reflect.Struct:
2023-02-22 19:10:24 +08:00
return GO_VALUE_STRUCT, V8_VALUE_OBJECT
2022-10-04 13:21:05 +08:00
case reflect.Slice:
2023-02-22 19:10:24 +08:00
return GO_VALUE_SLICE, V8_VALUE_ARRAY
2022-10-04 13:21:05 +08:00
case reflect.Func:
2023-02-22 19:10:24 +08:00
return GO_VALUE_FUNC, V8_VALUE_FUNCTION
2022-10-04 13:21:05 +08:00
case reflect.Ptr:
2023-02-22 19:10:24 +08:00
return GO_VALUE_PTR, V8_VALUE_PTR
2023-02-21 23:16:35 +08:00
case reflect.Map:
2023-02-22 19:10:24 +08:00
return GO_VALUE_MAP, V8_VALUE_OBJECT
2022-10-04 13:21:05 +08:00
default:
2023-02-22 19:10:24 +08:00
return -1, -1
2022-10-04 13:21:05 +08:00
}
}
func JSValueAssertType(v interface{}) V8_JS_VALUE_TYPE {
switch v.(type) {
case string:
return V8_VALUE_STRING
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr:
return V8_VALUE_INT
case float32, float64:
return V8_VALUE_DOUBLE
case bool:
return V8_VALUE_BOOLEAN
default:
return V8_VALUE_EXCEPTION
}
}
2023-02-22 19:10:24 +08:00
// ValueToBool 值转为 bool
//
// return: int > 0 = true, double > 0 = true, string != "" = true, bool = true, other = false
2022-10-04 13:21:05 +08:00
func ValueToBool(v interface{}) (bool, error) {
switch v.(type) {
case []byte:
return ByteToBool(v.([]byte)[0]), nil
case byte:
return ByteToBool(v.(byte)), nil
}
vType := JSValueAssertType(v)
switch vType {
case V8_VALUE_INT:
v := StrToInt32(InterfaceToString(v))
if v == 0 {
return false, nil
} else {
return true, nil
}
case V8_VALUE_DOUBLE:
v := StrToFloat64(InterfaceToString(v))
if v == 0 {
return false, nil
} else {
return true, nil
}
case V8_VALUE_STRING:
v := v.(string)
if v == "" {
return false, nil
} else {
return true, nil
}
case V8_VALUE_BOOLEAN:
return v.(bool), nil
default:
return false, errors.New("转换bool类型失败")
}
}
2023-02-22 19:10:24 +08:00
// ValueToFloat32
2022-10-04 13:21:05 +08:00
func ValueToFloat32(v interface{}) (float32, error) {
vType := JSValueAssertType(v)
switch vType {
case V8_VALUE_INT:
return StrToFloat32(InterfaceToString(v)), nil
case V8_VALUE_DOUBLE:
return StrToFloat32(InterfaceToString(v)), nil
case V8_VALUE_STRING:
return StrToFloat32(v.(string)), nil
case V8_VALUE_BOOLEAN:
v := v.(bool)
if v {
return 1, nil
} else {
return 0, nil
}
default:
return 0, errors.New("转换float32类型失败")
}
}
func ValueToFloat64(v interface{}) (float64, error) {
switch v.(type) {
case []byte:
return BytesToFloat64(v.([]byte)), nil
}
vType := JSValueAssertType(v)
switch vType {
case V8_VALUE_INT:
return StrToFloat64(InterfaceToString(v)), nil
case V8_VALUE_DOUBLE:
return StrToFloat64(InterfaceToString(v)), nil
case V8_VALUE_STRING:
return StrToFloat64(v.(string)), nil
case V8_VALUE_BOOLEAN:
v := v.(bool)
if v {
return 1, nil
} else {
return 0, nil
}
default:
return 0, errors.New("转换float64类型失败")
}
}
func ValueToInt32(v interface{}) (int32, error) {
switch v.(type) {
case []byte:
return BytesToInt32(v.([]byte)), nil
}
vType := JSValueAssertType(v)
switch vType {
case V8_VALUE_INT:
return StrToInt32(InterfaceToString(v)), nil
case V8_VALUE_DOUBLE:
return int32(math.Round(StrToFloat64(InterfaceToString(v)))), nil
case V8_VALUE_STRING:
return StrToInt32(v.(string)), nil
case V8_VALUE_BOOLEAN:
v := v.(bool)
if v {
return 1, nil
} else {
return 0, nil
}
default:
return 0, errors.New("转换int32类型失败")
}
}
func ValueToInt64(v interface{}) (int64, error) {
vType := JSValueAssertType(v)
switch vType {
case V8_VALUE_INT:
return StrToInt64(InterfaceToString(v)), nil
case V8_VALUE_DOUBLE:
return int64(math.Round(StrToFloat64(InterfaceToString(v)))), nil
case V8_VALUE_STRING:
return StrToInt64(v.(string)), nil
case V8_VALUE_BOOLEAN:
v := v.(bool)
if v {
return 1, nil
} else {
return 0, nil
}
default:
return 0, errors.New("转换int64类型失败")
}
}
func NumberUintPtrToInt(value uintptr, gov GO_VALUE_TYPE) interface{} {
switch gov {
case GO_VALUE_INT:
return int(value)
case GO_VALUE_INT8:
return int8(value)
case GO_VALUE_INT16:
return int16(value)
case GO_VALUE_INT32:
return int32(value)
case GO_VALUE_INT64:
return int64(value)
case GO_VALUE_UINT:
return uint(value)
case GO_VALUE_UINT8:
return uint8(value)
case GO_VALUE_UINT16:
return uint16(value)
case GO_VALUE_UINT32:
return uint32(value)
case GO_VALUE_UINT64:
return uint64(value)
case GO_VALUE_UINTPTR:
return value
default:
return nil
}
}
func NumberPtrToFloat(value unsafe.Pointer, gov GO_VALUE_TYPE) interface{} {
switch gov {
case GO_VALUE_FLOAT32:
return *(*float64)(value)
case GO_VALUE_FLOAT64:
return *(*float64)(value)
default:
return nil
}
}
func ValueToString(v interface{}) (string, error) {
switch v.(type) {
case []byte:
return BytesToString(v.([]byte)), nil
}
vType := JSValueAssertType(v)
switch vType {
case V8_VALUE_INT, V8_VALUE_DOUBLE:
return fmt.Sprintf("%v", vType), nil
case V8_VALUE_STRING, V8_VALUE_NULL, V8_VALUE_UNDEFINED:
return v.(string), nil
case V8_VALUE_BOOLEAN:
v := v.(bool)
if v {
return "true", nil
} else {
return "false", nil
}
default:
return "", errors.New("转换string类型失败")
}
}
func ValueToBytes(v interface{}) []byte {
switch v.(type) {
case []byte:
return v.([]byte)
case byte:
return []byte{v.(byte)}
}
return nil
}
2022-10-04 22:34:57 +08:00
func FuncParamJsTypeStr(jsValue V8_JS_VALUE_TYPE) string {
2022-10-04 13:21:05 +08:00
switch jsValue {
case V8_VALUE_STRING:
return "string"
case V8_VALUE_INT:
return "int"
case V8_VALUE_DOUBLE:
return "double"
case V8_VALUE_BOOLEAN:
return "boolean"
case V8_VALUE_EXCEPTION:
return "EefError"
default:
return ""
}
}
2022-10-04 22:34:57 +08:00
func FuncParamGoTypeStr(jsValue GO_VALUE_TYPE) string {
2022-10-04 13:21:05 +08:00
switch jsValue {
case GO_VALUE_STRING:
return "string"
case GO_VALUE_INT:
return "int"
case GO_VALUE_INT8:
return "int8"
case GO_VALUE_INT16:
return "int16"
case GO_VALUE_INT32:
return "int32"
case GO_VALUE_INT64:
return "int64"
case GO_VALUE_FLOAT32:
return "float32"
case GO_VALUE_FLOAT64:
return "float64"
case GO_VALUE_BOOL:
return "bool"
case GO_VALUE_EXCEPTION:
return "EefError"
default:
return ""
}
}
func CopyBytePtr(bytePtr uintptr, low, high int) []byte {
var size = high - low
var data = make([]byte, size, size)
for i := low; i < high; i++ {
data[i-low] = *(*byte)(unsafe.Pointer(bytePtr + (uintptr(i))))
}
return data
}
func IntToBytes(i int) []byte {
buf := bytes.NewBuffer([]byte{})
2022-12-13 23:12:01 +08:00
if IntSize == IntSize32 {
2022-10-04 13:21:05 +08:00
if err := binary.Write(buf, binary.BigEndian, int32(i)); err == nil {
return buf.Bytes()
}
} else {
if err := binary.Write(buf, binary.BigEndian, int64(i)); err == nil {
return buf.Bytes()
}
}
return nil
}
func Int8ToBytes(i int8) []byte {
return []byte{byte(i)}
}
func Int16ToBytes(i int16) []byte {
buf := bytes.NewBuffer([]byte{})
if err := binary.Write(buf, binary.BigEndian, i); err == nil {
return buf.Bytes()
}
return nil
}
func Int32ToBytes(i int32) []byte {
buf := bytes.NewBuffer([]byte{})
if err := binary.Write(buf, binary.BigEndian, i); err == nil {
return buf.Bytes()
}
return nil
}
func Int64ToBytes(i int64) []byte {
buf := bytes.NewBuffer([]byte{})
if err := binary.Write(buf, binary.BigEndian, i); err == nil {
return buf.Bytes()
}
return nil
}
func BytesToInt(b []byte) int {
var i int64
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return int(i)
}
func ByteToInt8(b byte) int8 {
return int8(b)
}
func BytesToInt16(b []byte) int16 {
var i int16
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return i
}
func BytesToInt32(b []byte) int32 {
var i int32
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return i
}
func BytesToInt64(b []byte) int64 {
var i int64
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return i
}
func BytesToString(data []byte) string {
return *(*string)(unsafe.Pointer(&data))
}
//func StringToBytes(data string) []byte {
// return *(*[]byte)(unsafe.Pointer(&data))
//}
// String转换Bytes数组isDStr转换DString 默认GoString
2022-10-04 13:21:05 +08:00
func StringToBytes(s string, isDStr ...bool) []byte {
if len(isDStr) > 0 && isDStr[0] {
temp := []byte(s)
utf8StrArr := make([]byte, len(temp)+1)
copy(utf8StrArr, temp)
return utf8StrArr
} else {
return []byte(s)
}
}
// Float64ToBytes Float64转byte
2022-10-04 13:21:05 +08:00
func Float64ToBytes(float float64) []byte {
bits := math.Float64bits(float)
bytes := make([]byte, 8)
binary.LittleEndian.PutUint64(bytes, bits)
return bytes
}
// BytesToFloat64 byte转Float64
2022-10-04 13:21:05 +08:00
func BytesToFloat64(bytes []byte) float64 {
bits := binary.LittleEndian.Uint64(bytes)
return math.Float64frombits(bits)
}
// Float32ToBytes Float64转byte
2022-10-04 13:21:05 +08:00
func Float32ToBytes(float float32) []byte {
bits := math.Float32bits(float)
bytes := make([]byte, 4)
binary.LittleEndian.PutUint32(bytes, bits)
return bytes
}
// BytesToFloat32 byte转Float64
2022-10-04 13:21:05 +08:00
func BytesToFloat32(bytes []byte) float32 {
bits := binary.LittleEndian.Uint32(bytes)
return math.Float32frombits(bits)
}
func BoolToByte(b bool) byte {
if b {
return 1
}
return 0
}
func ByteToBool(b byte) bool {
if b == 1 {
return true
}
return false
}
const (
dSecond float64 = 3600
dDay = 24 * dSecond
)
var dBaseDateTime = time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC)
func GoDateTimeToDDateTime(dateTime time.Time) float64 {
date := float64(dateTime.Sub(dBaseDateTime).Milliseconds() / 1000 / 60 / 60 / 24)
2022-10-05 15:33:17 +08:00
diHour := decimal.NewFromFloat(float64(dateTime.Hour()))
diMinute := decimal.NewFromFloat(float64(dateTime.Minute())).Mul(decimal.NewFromFloat(60))
diSecond := decimal.NewFromFloat(float64(dateTime.Second()))
diTime := diHour.Mul(decimal.NewFromFloat(dSecond)).Add(diMinute).Add(diSecond).Div(decimal.NewFromFloat(dDay))
var dTime, _ = diTime.Add(decimal.NewFromFloat(date)).Float64()
2022-10-04 13:21:05 +08:00
return dTime
}
func DDateTimeToGoDateTime(dateTime float64) time.Time {
dtStr := strings.Split(fmt.Sprintf("%v", dateTime), ".")
dDate, _ := strconv.Atoi(dtStr[0])
2022-10-05 15:33:17 +08:00
diDateTime := decimal.NewFromFloat(dateTime)
diDate := decimal.NewFromFloat(float64(dDate))
diTime := diDateTime.Sub(diDate)
dTime, _ := diTime.Float64()
gTime := time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC)
gTime = gTime.AddDate(0, 0, dDate)
diTime = decimal.NewFromFloat(float64(time.Second)).Mul(decimal.NewFromFloat(dTime).Mul(decimal.NewFromFloat(dDay)))
diTime = diTime.Add(decimal.NewFromFloat(dTime))
gTime = gTime.Add(time.Duration(diTime.IntPart()))
2022-10-04 13:21:05 +08:00
return gTime
}
func ArrayIndexOf[T any](array []T, a interface{}) int {
if len(array) == 0 {
return -1
}
var t any
for i := 0; i < len(array); i++ {
t = array[i]
if t == a {
return i
}
}
return -1
}
2023-02-22 08:47:48 +08:00
// GetInstancePtr 获取指针的指针的地址
2022-12-13 23:02:40 +08:00
func GetInstancePtr(ptr uintptr) unsafe.Pointer {
2022-10-04 13:21:05 +08:00
ptr = *(*uintptr)(unsafe.Pointer(ptr))
2022-12-13 23:02:40 +08:00
return unsafe.Pointer(ptr)
2022-10-04 13:21:05 +08:00
}
2023-01-29 19:10:31 +08:00
// GoroutineID 获取当前携程ID
2023-01-29 19:10:31 +08:00
func GoroutineID() (id uint64) {
var buf [30]byte
runtime.Stack(buf[:], false)
for i := 10; buf[i] != ' '; i++ {
id = id*10 + uint64(buf[i]&15)
}
return id
}