2025-09-15 20:06:21 +09:00
|
|
|
package haza
|
|
|
|
|
2025-09-17 19:31:37 +09:00
|
|
|
import "bytes"
|
|
|
|
import "encoding/binary"
|
|
|
|
import "io"
|
|
|
|
import "net"
|
2025-09-15 20:06:21 +09:00
|
|
|
import "sync"
|
|
|
|
import "unsafe"
|
|
|
|
|
|
|
|
type LogLevel int
|
|
|
|
type LogMask int
|
|
|
|
|
|
|
|
const (
|
|
|
|
LOG_DEBUG LogLevel = 1 << iota
|
|
|
|
LOG_INFO
|
|
|
|
LOG_WARN
|
|
|
|
LOG_ERROR
|
|
|
|
)
|
|
|
|
|
|
|
|
const LOG_ALL LogMask = LogMask(LOG_DEBUG | LOG_INFO | LOG_WARN | LOG_ERROR)
|
|
|
|
const LOG_NONE LogMask = LogMask(0)
|
|
|
|
|
|
|
|
type Named struct {
|
|
|
|
name string
|
|
|
|
}
|
|
|
|
|
|
|
|
type Logger interface {
|
|
|
|
Write(id string, level LogLevel, fmtstr string, args ...interface{})
|
|
|
|
WriteWithCallDepth(id string, level LogLevel, call_depth int, fmtstr string, args ...interface{})
|
|
|
|
Rotate()
|
|
|
|
Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
type Service interface {
|
|
|
|
RunTask(wg *sync.WaitGroup) // blocking. run the actual task loop. it must call wg.Done() upon exit from itself.
|
|
|
|
StartService(data interface{}) // non-blocking. spin up a service. it may be invokded multiple times for multiple instances
|
|
|
|
StopServices() // non-blocking. send stop request to all services spun up
|
|
|
|
FixServices() // do some fixup as needed
|
|
|
|
WaitForTermination() // blocking. must wait until all services are stopped
|
|
|
|
WriteLog(id string, level LogLevel, fmtstr string, args ...interface{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
|
|
|
|
|
|
func (n *Named) SetName(name string) {
|
|
|
|
n.name = name
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *Named) Name() string {
|
|
|
|
return n.name
|
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
|
|
|
|
|
|
var _is_big_endian bool = is_big_endian()
|
|
|
|
|
|
|
|
func is_big_endian() bool {
|
|
|
|
var v uint16
|
|
|
|
v = 1
|
|
|
|
return *(*byte)(unsafe.Pointer(&v)) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
func Hton16(v uint16) uint16 {
|
|
|
|
if _is_big_endian { return v }
|
|
|
|
return (v << 8) | (v >> 8)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Ntoh16(v uint16) uint16 {
|
|
|
|
if _is_big_endian { return v }
|
|
|
|
return (v << 8) | (v >> 8)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Hton32(v uint32) uint32 {
|
|
|
|
if _is_big_endian { return v }
|
|
|
|
return ((v >> 24) & 0xFF) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Ntoh32(v uint32) uint32 {
|
|
|
|
if _is_big_endian { return v }
|
|
|
|
return ((v >> 24) & 0xFF) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000)
|
|
|
|
}
|
2025-09-17 19:31:37 +09:00
|
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
|
|
type ByteReader struct {
|
|
|
|
r *bytes.Reader
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewByteReader(b []byte) *ByteReader {
|
|
|
|
return &ByteReader{ r: bytes.NewReader(b) }
|
|
|
|
}
|
|
|
|
|
|
|
|
func (br* ByteReader) ReadByte() (byte, error) {
|
|
|
|
return br.r.ReadByte()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (br* ByteReader) ReadUint16() (uint16, error) {
|
|
|
|
var v uint16
|
|
|
|
var err error
|
|
|
|
err = binary.Read(br.r, binary.BigEndian, &v)
|
|
|
|
if err != nil { return 0, err }
|
|
|
|
return v, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (br* ByteReader) ReadUint32() (uint32, error) {
|
|
|
|
var v uint32
|
|
|
|
var err error
|
|
|
|
err = binary.Read(br.r, binary.BigEndian, &v)
|
|
|
|
if err != nil { return 0, err }
|
|
|
|
return v, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (br* ByteReader) ReadIp4() (net.IP, error) {
|
|
|
|
var buf [4]byte
|
|
|
|
var err error
|
|
|
|
_, err = io.ReadFull(br.r, buf[:])
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
return net.IP(buf[:]), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (br *ByteReader) ReadAllBytes(buf []byte) error {
|
|
|
|
var err error
|
|
|
|
_, err = io.ReadFull(br.r, buf)
|
|
|
|
return err
|
|
|
|
}
|