359 lines
7.2 KiB
Go
359 lines
7.2 KiB
Go
package q5
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io/ioutil"
|
||
"net"
|
||
"net/http"
|
||
"os"
|
||
"reflect"
|
||
"time"
|
||
"sync"
|
||
"runtime"
|
||
"hash/crc32"
|
||
"bufio"
|
||
)
|
||
|
||
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 IsDebug() bool {
|
||
return true
|
||
}
|