q5/sysutils.go
aozhiwei b065fccf5c 1
2024-08-07 15:02:42 +08:00

382 lines
7.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package q5
import (
"bufio"
"encoding/json"
"fmt"
"hash/crc32"
"io/ioutil"
"net"
"net/http"
"os"
"reflect"
"runtime"
"sync"
"time"
)
func GetDaySeconds(seconds int64, timeZone int64) int64 {
return ((seconds+timeZone*3600)/3600/24)*3600*24 - 3600*timeZone
}
func GetYesterDaySeconds(seconds int64, timeZone int64) int64 {
return ((seconds+timeZone*3600)/3600/24)*3600*24 - 3600*timeZone
}
func GetTickCount() int64 {
return time.Now().UnixNano() / 1e6
}
func MkUInt16(b1 byte, b2 byte) uint16 {
return uint16(b1) + (uint16(b2) << 8)
}
func MkUInt32(b1 byte, b2 byte, b3 byte, b4 byte) uint32 {
return uint32(b1) +
(uint32(b2) << 8) +
(uint32(b3) << 16) +
(uint32(b4) << 24)
}
func MkInt64(lo32 int32, hi32 int32) int64 {
return int64(lo32) + (int64(hi32) << 32)
}
func Request(r *http.Request, name string) string {
if r.Form == nil {
r.ParseForm()
}
if vs, ok := r.Form[name]; ok {
if len(vs) > 0 {
return vs[0]
}
}
return ""
}
func Response(w *http.ResponseWriter, data string) {
(*w).Write([]byte(data))
}
func ResponseOk(w *http.ResponseWriter) {
(*w).Write([]byte(`{"errcode":0, "errmsg":""}`))
}
func ResponseErr(w *http.ResponseWriter, errCode int32, errMsg string) {
rspObj := map[string]interface{}{}
rspObj["errcode"] = errCode
rspObj["errmsg"] = errMsg
jsonObj, _ := json.Marshal(rspObj)
Response(w, string(jsonObj))
}
func ResponseInt32Ok(w *http.ResponseWriter, key string, val int32) {
(*w).Write([]byte(fmt.Sprintf(`{"errcode":0, "errmsg":"", "%s":%d}`, key, val)))
}
func GetPostBody(r *http.Request) string {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return ""
}
return string(body)
}
func GetRequestRemoteAddr(r *http.Request) string {
remoteAddr := r.RemoteAddr
if ip := r.Header.Get("X-Real-Ip"); ip != "" {
remoteAddr = ip
} else if ip = r.Header.Get("X-Forwarded-For"); ip != "" {
remoteAddr = ip
} else {
remoteAddr, _, _ = net.SplitHostPort(remoteAddr)
}
if remoteAddr == "::1" {
remoteAddr = "127.0.0.1"
}
return remoteAddr
}
func ForceCreateDir(dir string) bool {
os.MkdirAll(dir, os.ModePerm)
return true
}
func IsNumberType(v interface{}) bool {
switch reflect.TypeOf(v).Kind() {
case
reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Float32,
reflect.Float64:
return true
default:
return false
}
}
func FormatUnixDateTime(sec int64, loc *time.Location) string {
strTime := time.Unix(sec, 0).In(loc).Format("2006-01-02 15:04:05")
return strTime
}
func FormatUnixDate(sec int64, loc *time.Location) string {
strTime := time.Unix(sec, 0).In(loc).Format("2006-01-02")
return strTime
}
func FormatUnixDateEx(sec int64, loc *time.Location) string {
strTime := time.Unix(sec, 0).In(loc).Format("20060102")
return strTime
}
func HasBitFlag(val int64, bitNum int32) bool {
if bitNum < 0 || bitNum > 63 {
return false
}
mask := int64(1) << bitNum
return (val & mask) != 0
}
func SetBitFlag(val *int64, bitNum int32) {
if bitNum < 0 || bitNum > 63 {
return
}
*val |= int64(1) << bitNum
}
func UnSetBitFlag(val *int64, bitNum int32) {
if bitNum < 0 || bitNum > 63 {
return
}
*val &= ^(int64(1) << bitNum)
}
func GetLocalIP() string {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
return ""
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP.String()
//interfaces, err := net.Interfaces()
//if err != nil {
// panic(err)
//}
//ipList := []string{}
//for _, iface := range interfaces {
// if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
// continue
// }
// addrs, err := iface.Addrs()
// if err != nil {
// panic(err)
// }
// for _, addr := range addrs {
// ipnet, ok := addr.(*net.IPNet)
// if !ok || ipnet.IP.IsLoopback() {
// continue
// }
// if ipnet.IP.To4() != nil {
// ipList = append(ipList, ipnet.IP.String())
// }
// }
//}
//if len(ipList) != 1 {
// panic("GetLocalIP error")
//} else {
// return ipList[0]
//}
}
func NewSlice[T any](s *[]T, len int32, cap int32) {
*s = make([]T, len, cap)
}
func NewSliceElement[T any](s *[]T) *T {
v := new(T)
*s = append(*s, *v)
return &(*s)[len(*s)-1]
}
func AppendSlice[T any](s *[]T, val T) {
*s = append(*s, val)
}
func GetTypeName(v interface{}) string {
return reflect.TypeOf(v).String()
}
func PrintCallStack() {
// 获取当前函数的调用者信息
pc, file, line, ok := runtime.Caller(1)
if !ok {
fmt.Println("runtime.Caller error")
return
}
funcName := runtime.FuncForPC(pc).Name()
fmt.Printf("Function: %s\nFile: %s\nLine: %d\n", funcName, file, line)
// 使用Stack打印完整的调用栈信息可以用于debug
buf := make([]byte, 1024)
for {
n := runtime.Stack(buf, false)
if n < len(buf) {
break
}
buf = make([]byte, 2*len(buf))
}
fmt.Println(string(buf))
}
func GetCallStack() string {
// 获取当前函数的调用者信息
//pc, file, line, ok := runtime.Caller(1)
_, _, _, ok := runtime.Caller(1)
if !ok {
fmt.Println("runtime.Caller error")
return ""
}
//funcName := runtime.FuncForPC(pc).Name()
//fmt.Printf("Function: %s\nFile: %s\nLine: %d\n", funcName, file, line)
// 使用Stack打印完整的调用栈信息可以用于debug
buf := make([]byte, 1024)
for {
n := runtime.Stack(buf, false)
if n < len(buf) {
break
}
buf = make([]byte, 2*len(buf))
}
return string(buf)
}
func CalcCrc32(data string) uint32 {
tbl := crc32.MakeTable(crc32.Castagnoli)
c := crc32.New(tbl)
if _, err := c.Write([]byte(data)); err != nil {
}
return c.Sum32()
}
func SmartParseTimeToMills(timeStr string) int64 {
if IsPureNumber(timeStr) {
return ToInt64(timeStr) * 1000
}
if StrContains(timeStr, "T") {
t, err := time.Parse(time.RFC3339, timeStr)
if err == nil {
return t.UnixNano() / int64(time.Millisecond)
}
} else if StrContains(timeStr, ".") {
const layout = "2006-01-02 15:04:05.000"
if len(timeStr) > len(layout) {
timeStr = timeStr[0:len(layout)]
}
t, err := time.Parse(layout, timeStr)
if err == nil {
return t.UnixNano() / int64(time.Millisecond)
}
} else {
const layout = "2006-01-02 15:04:05"
t, err := time.Parse(layout, timeStr)
if err == nil {
return t.UnixNano() / int64(time.Millisecond)
}
}
return 0
}
func LoadFileAsString(fileName string) (string, error) {
if f, err := os.Open(fileName); err == nil {
data, err1 := ioutil.ReadAll(bufio.NewReader(f))
return string(data), err1
} else {
return "", err
}
}
func GetSyncMapSize(m sync.Map) int {
var size int
m.Range(func(key, value interface{}) bool {
size++
return true
})
return size
}
func MapClone(m map[string]interface{}) map[string]interface{} {
result := map[string]interface{}{}
for k, v := range m {
result[k] = v
}
return result
}
func AdjustRangeValue[T int | int32 | int64 | float32 | float64](value T, minV T, maxV T) T {
if value < minV {
value = minV
}
if value > maxV {
value = maxV
}
return value
}
func CreateCondTimer(ch chan int64, cond *sync.Cond, initSeconds int64) {
waitSecond := initSeconds
for {
select {
case waitSecond = <-ch:
if waitSecond < 10 {
waitSecond = 10
}
case <-time.After(time.Second * time.Duration(waitSecond)):
cond.Broadcast()
}
}
}
func ExcUntilOk(cb func() bool) {
for !cb() {
}
}
func ReadTextFile(fileName string) (string, error) {
if f, err := os.Open(fileName); err == nil {
data, err := ioutil.ReadAll(bufio.NewReader(f))
return string(data), err
} else {
return "", err
}
}
func IsDebug() bool {
return true
}
func PowInt64(base int64, exponent int64) int64 {
var result int64 = 1
var i int64 = 0
for ; i < exponent; i++ {
result *= base
}
return result
}