energy/common/common.go

583 lines
12 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 CEF Util
package common
2022-10-04 13:21:05 +08:00
import (
"bytes"
"encoding/binary"
"fmt"
"github.com/energye/energy/v2/consts"
2023-05-31 18:00:34 +08:00
"github.com/energye/energy/v2/pkgs/decimal"
"github.com/energye/golcl/energy/tools"
2022-10-04 13:21:05 +08:00
"math"
"os"
"path/filepath"
2022-10-04 13:21:05 +08:00
"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
)
2023-03-28 19:39:56 +08:00
// Concat 字符串拼接
func Concat(str ...string) string {
var c = strings.Builder{}
for _, v := range str {
c.WriteString(v)
}
return c.String()
}
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-05-31 17:41:14 +08:00
// ValueToBool bool
func ValueToBool(v interface{}) bool {
2023-02-21 23:16:35 +08:00
switch v.(type) {
2023-05-31 17:41:14 +08:00
case []byte:
bv := v.([]byte)
if len(bv) == 1 {
return ByteToInt8(bv[0]) > 0
} else if len(bv) == 2 {
return BytesToInt16(bv) > 0
} else if len(bv) == 4 {
return BytesToInt32(bv) > 0
} else if len(bv) == 8 {
return BytesToInt64(bv) > 0
}
return len(bv) > 0
2022-10-04 13:21:05 +08:00
}
switch v.(type) {
case string:
2023-05-31 17:41:14 +08:00
return len(v.(string)) > 0
case float32:
return v.(float32) > 0
case float64:
return v.(float64) > 0
2022-10-04 13:21:05 +08:00
case bool:
2023-05-31 17:41:14 +08:00
return v.(bool)
case int:
return v.(int) > 0
case int8:
return v.(int8) > 0
case int16:
return v.(int16) > 0
case int32:
return v.(int32) > 0
case int64:
return v.(int64) > 0
case uintptr:
return v.(uintptr) > 0
2022-10-04 13:21:05 +08:00
default:
2023-05-31 17:41:14 +08:00
return false
2022-10-04 13:21:05 +08:00
}
}
2023-05-31 17:41:14 +08:00
func ValueToFloat64(v interface{}) float64 {
2022-10-04 13:21:05 +08:00
switch v.(type) {
case []byte:
2023-05-31 17:41:14 +08:00
bv := v.([]byte)
if len(bv) == 4 {
return float64(BytesToFloat32(bv))
} else if len(bv) == 8 {
return BytesToFloat64(bv)
2022-10-04 13:21:05 +08:00
}
2023-05-31 17:41:14 +08:00
return 0.0
2022-10-04 13:21:05 +08:00
}
switch v.(type) {
2023-05-31 17:41:14 +08:00
case string:
return StrToFloat64(v.(string))
case float32:
return float64(v.(float32))
case float64:
return v.(float64)
case bool:
if v.(bool) {
return 1
2022-10-04 13:21:05 +08:00
} else {
2023-05-31 17:41:14 +08:00
return 0
2022-10-04 13:21:05 +08:00
}
2023-05-31 17:41:14 +08:00
case int:
return float64(v.(int))
case int8:
return float64(v.(int8))
case int16:
return float64(v.(int16))
case int32:
return float64(v.(int32))
case int64:
return float64(v.(int64))
case uintptr:
return float64(v.(uintptr))
2022-10-04 13:21:05 +08:00
default:
2023-05-31 17:41:14 +08:00
return 0
2022-10-04 13:21:05 +08:00
}
}
2023-05-31 17:41:14 +08:00
func ValueToInt(v interface{}) int {
2022-10-04 13:21:05 +08:00
switch v.(type) {
case []byte:
2023-05-31 17:41:14 +08:00
bv := v.([]byte)
if len(bv) == 1 {
return int(ByteToInt8(bv[0]))
} else if len(bv) == 2 {
return int(BytesToInt16(bv))
} else if len(bv) == 4 {
return int(BytesToInt32(bv))
} else if len(bv) == 8 {
return int(BytesToInt64(bv))
2022-10-04 13:21:05 +08:00
}
2023-05-31 17:41:14 +08:00
return 0
2022-10-04 13:21:05 +08:00
}
switch v.(type) {
2023-05-31 17:41:14 +08:00
case string:
return int(StrToInt64(v.(string)))
case float32:
return int(math.Round(float64(StrToFloat32(v.(string)))))
case float64:
return int(math.Round(StrToFloat64(v.(string))))
case bool:
if v.(bool) {
return 1
2022-10-04 13:21:05 +08:00
} else {
2023-05-31 17:41:14 +08:00
return 0
2022-10-04 13:21:05 +08:00
}
2023-05-31 17:41:14 +08:00
case int:
return v.(int)
case int8:
return int(v.(int8))
case int16:
return int(v.(int16))
case int32:
return int(v.(int32))
case int64:
return int(v.(int64))
case uintptr:
return int(v.(uintptr))
2022-10-04 13:21:05 +08:00
default:
2023-05-31 17:41:14 +08:00
return 0
2022-10-04 13:21:05 +08:00
}
}
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
}
2023-03-10 14:42:15 +08:00
func UIntToBytes(i uint) []byte {
buf := bytes.NewBuffer([]byte{})
if IntSize == IntSize32 {
if err := binary.Write(buf, binary.BigEndian, uint32(i)); err == nil {
return buf.Bytes()
}
} else {
if err := binary.Write(buf, binary.BigEndian, uint64(i)); err == nil {
return buf.Bytes()
}
}
return nil
}
2022-10-04 13:21:05 +08:00
func Int8ToBytes(i int8) []byte {
return []byte{byte(i)}
}
2023-03-10 14:42:15 +08:00
func UInt8ToBytes(i uint8) []byte {
return []byte{byte(i)}
}
2022-10-04 13:21:05 +08:00
func Int16ToBytes(i int16) []byte {
buf := bytes.NewBuffer([]byte{})
if err := binary.Write(buf, binary.BigEndian, i); err == nil {
return buf.Bytes()
}
return nil
}
2023-03-10 14:42:15 +08:00
func UInt16ToBytes(i uint16) []byte {
buf := bytes.NewBuffer([]byte{})
if err := binary.Write(buf, binary.BigEndian, i); err == nil {
return buf.Bytes()
}
return nil
}
2022-10-04 13:21:05 +08:00
func Int32ToBytes(i int32) []byte {
buf := bytes.NewBuffer([]byte{})
if err := binary.Write(buf, binary.BigEndian, i); err == nil {
return buf.Bytes()
}
return nil
}
2023-03-10 14:42:15 +08:00
func UInt32ToBytes(i uint32) []byte {
buf := bytes.NewBuffer([]byte{})
if err := binary.Write(buf, binary.BigEndian, i); err == nil {
return buf.Bytes()
}
return nil
}
2022-10-04 13:21:05 +08:00
func Int64ToBytes(i int64) []byte {
buf := bytes.NewBuffer([]byte{})
if err := binary.Write(buf, binary.BigEndian, i); err == nil {
return buf.Bytes()
}
return nil
}
2023-03-10 14:42:15 +08:00
func UInt64ToBytes(i uint64) []byte {
buf := bytes.NewBuffer([]byte{})
if err := binary.Write(buf, binary.BigEndian, i); err == nil {
return buf.Bytes()
}
return nil
}
2022-10-04 13:21:05 +08:00
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)
}
2023-03-10 14:42:15 +08:00
func BytesToUInt(b []byte) uint {
var i uint64
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return uint(i)
}
2022-10-04 13:21:05 +08:00
func ByteToInt8(b byte) int8 {
return int8(b)
}
2023-03-10 14:42:15 +08:00
func ByteToUInt8(b byte) uint8 {
return uint8(b)
}
2022-10-04 13:21:05 +08:00
func BytesToInt16(b []byte) int16 {
var i int16
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return i
}
2023-03-10 14:42:15 +08:00
func BytesToUInt16(b []byte) uint16 {
var i uint16
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return i
}
2022-10-04 13:21:05 +08:00
func BytesToInt32(b []byte) int32 {
var i int32
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return i
}
2023-03-10 14:42:15 +08:00
func BytesToUInt32(b []byte) uint32 {
var i uint32
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return i
}
2022-10-04 13:21:05 +08:00
func BytesToInt64(b []byte) int64 {
var i int64
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return i
}
2023-03-10 14:42:15 +08:00
func BytesToUInt64(b []byte) uint64 {
var i uint64
err := binary.Read(bytes.NewReader(b), binary.BigEndian, &i)
if err != nil {
return 0
}
return i
}
2022-10-04 13:21:05 +08:00
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
}
2023-02-27 20:12:54 +08:00
func GoStr(ptr uintptr) string {
if ptr == 0 {
return ""
}
resultString := (*reflect.StringHeader)(unsafe.Pointer(ptr))
if resultString == nil || resultString.Len <= 0 {
return ""
}
return *(*string)(unsafe.Pointer(resultString))
2023-03-12 20:33:45 +08:00
}
func string2bytes1(s string) []byte {
stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))
var b []byte
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
pbytes.Data = stringHeader.Data
pbytes.Len = stringHeader.Len
pbytes.Cap = stringHeader.Len
return b
2023-02-27 20:12:54 +08:00
}
func libCef() string {
if IsWindows() {
return "libcef.dll"
} else if IsLinux() {
return "libcef.so"
}
return ""
}
// FrameworkDir
// 返回CEF框架目录, 以当前执行文件所在目录开始查找
// 如果当前执行文件目录未找到再从ENERGY_HOME环境变量查找
// Darwin 平台除外
func FrameworkDir() string {
var lib = libCef() // 根据CEF libcef.xx 动态库
if lib != "" {
//当前目录
if tools.IsExist(filepath.Join(consts.ExeDir, lib)) {
return consts.ExeDir
}
//环境变量
var env = os.Getenv(consts.ENERGY_HOME_KEY)
if tools.IsExist(filepath.Join(env, lib)) {
return env
}
}
return ""
}
func SetFrameworkEnv(value string) {
os.Setenv(consts.ENERGY_HOME_KEY, value)
}