upload zfile
This commit is contained in:
commit
09c43d4a03
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/zlib.iml" filepath="$PROJECT_DIR$/.idea/zlib.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
9
.idea/zlib.iml
generated
Normal file
9
.idea/zlib.iml
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
9
go.mod
Normal file
9
go.mod
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module zlib
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||||
|
go.uber.org/multierr v1.10.0 // indirect
|
||||||
|
go.uber.org/zap v1.25.0 // indirect
|
||||||
|
)
|
||||||
11
go.sum
Normal file
11
go.sum
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||||
|
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
|
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||||
|
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||||
|
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
|
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
|
||||||
|
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
35
run/receiver/main.go
Normal file
35
run/receiver/main.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type demo struct {
|
||||||
|
Val int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *demo) change() {
|
||||||
|
d = nil // Assignment to the method receiver propagates only to callees but not to callers
|
||||||
|
d.myVal()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *demo) myVal() {
|
||||||
|
fmt.Printf("my val: %#v\n", d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d demo) change2() {
|
||||||
|
d = demo{} // Assignment to the method receiver doesn't propagate to other calls
|
||||||
|
d.myVal()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *demo) change3() {
|
||||||
|
d.Val = 3
|
||||||
|
d.myVal()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
d := &demo{}
|
||||||
|
d.myVal()
|
||||||
|
d.change()
|
||||||
|
d.myVal()
|
||||||
|
d.Val = 2
|
||||||
|
d.change2()
|
||||||
|
}
|
||||||
52
src/go/iface/iface_test.go
Normal file
52
src/go/iface/iface_test.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package iface
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IArchive interface {
|
||||||
|
Seek(int)
|
||||||
|
}
|
||||||
|
type FArchive struct {
|
||||||
|
Pos int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ar *FArchive) Seek(p int) {
|
||||||
|
ar.Pos = p
|
||||||
|
}
|
||||||
|
func printArchive(ar IArchive, str string) {
|
||||||
|
obj, ok := ar.(*FArchive)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("%s pos1:: %d \n", str, obj.Pos)
|
||||||
|
obj.Seek(11)
|
||||||
|
fmt.Printf("%s pos2:: %d \n", str, obj.Pos)
|
||||||
|
}
|
||||||
|
func printAnyArchive(ar any, str string) {
|
||||||
|
obj, ok := ar.(*FArchive)
|
||||||
|
if !ok {
|
||||||
|
fmt.Printf("assert failed \n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("%s pos1:: %d \n", str, obj.Pos)
|
||||||
|
obj.Seek(12)
|
||||||
|
fmt.Printf("%s pos2:: %d \n", str, obj.Pos)
|
||||||
|
}
|
||||||
|
func TestInterface(t *testing.T) {
|
||||||
|
ar := FArchive{
|
||||||
|
Pos: 1,
|
||||||
|
}
|
||||||
|
//printArchive(ar) //不合法
|
||||||
|
printArchive(&ar, "IArchive")
|
||||||
|
fmt.Printf("print pos3:: %d \n", ar.Pos)
|
||||||
|
}
|
||||||
|
func TestAnyInterface(t *testing.T) {
|
||||||
|
ar := FArchive{
|
||||||
|
Pos: 1,
|
||||||
|
}
|
||||||
|
printAnyArchive(ar, "any1")
|
||||||
|
printAnyArchive(&ar, "any2")
|
||||||
|
fmt.Printf("pos3:: %d \n", ar.Pos)
|
||||||
|
}
|
||||||
1
src/stl/data/vector.go
Normal file
1
src/stl/data/vector.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package data
|
||||||
6
src/template/factory.go
Normal file
6
src/template/factory.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package template
|
||||||
|
|
||||||
|
// DBFactory 工厂模式,为多个同类对象提供统一的创建接口(数据库、支付接口、日志接口)
|
||||||
|
// 构造函数重载也是一种工厂模式,为同一个对象提供简洁的创建方式
|
||||||
|
type DBFactory struct {
|
||||||
|
}
|
||||||
42
src/template/singleton.go
Normal file
42
src/template/singleton.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package template
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IClass interface {
|
||||||
|
New() IClass
|
||||||
|
}
|
||||||
|
|
||||||
|
var once = &sync.Once{}
|
||||||
|
|
||||||
|
// SingletonFunc 单例模式:基于全局变量实现,提供唯一的访问接口,唯一的构造方法
|
||||||
|
func SingletonFunc[T IClass](c *T) func() T {
|
||||||
|
return func() T {
|
||||||
|
if reflect.ValueOf(*c).IsNil() {
|
||||||
|
once.Do(func() {
|
||||||
|
*c = (*c).New().(T)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return *c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singleton 饿汉式单例
|
||||||
|
type Singleton struct{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
singleton *Singleton
|
||||||
|
// GetSingleton a := GetSingleton1 ==> SingletonFunc
|
||||||
|
// b := GetSingleton2 ==> SingletonFunc
|
||||||
|
GetSingleton = SingletonFunc(&singleton)
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetInstance 获取实例
|
||||||
|
func init() {
|
||||||
|
singleton = GetSingleton()
|
||||||
|
}
|
||||||
|
func (s *Singleton) New() IClass {
|
||||||
|
return &Singleton{}
|
||||||
|
}
|
||||||
14
src/template/singleton_test.go
Normal file
14
src/template/singleton_test.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package template
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"zlib/src/zlog"
|
||||||
|
)
|
||||||
|
|
||||||
|
var s *Singleton
|
||||||
|
|
||||||
|
func TestGetInstance(t *testing.T) {
|
||||||
|
s1 := GetSingleton()
|
||||||
|
s2 := GetSingleton()
|
||||||
|
zlog.Infof("TestGetInstance %s %s %i %s", s1, s2, s1 == singleton, singleton)
|
||||||
|
}
|
||||||
50
src/zfile/coff64/coff64.go
Normal file
50
src/zfile/coff64/coff64.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package coff64
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FCoff64 struct {
|
||||||
|
Header FHeader
|
||||||
|
SectHeaderList []FSectHeader
|
||||||
|
SectList []FSectData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (coff *FCoff64) Serialize(ar IArchive) {
|
||||||
|
ar.Seek(0, -1)
|
||||||
|
coff.Header.Serialize(ar)
|
||||||
|
coff.CheckSwapBytes(ar)
|
||||||
|
hdr := &coff.Header
|
||||||
|
num := int(hdr.NumSect)
|
||||||
|
SectHeaderList := make([]FSectHeader, num)
|
||||||
|
SectList := make([]FSectData, num)
|
||||||
|
coff.SectHeaderList = SectHeaderList
|
||||||
|
coff.SectList = SectList
|
||||||
|
ehSize, shSize := int(unsafe.Sizeof(coff.Header)), int(unsafe.Sizeof(SectHeaderList[0]))
|
||||||
|
for i := 0; i < num; i++ {
|
||||||
|
sh := &SectHeaderList[i]
|
||||||
|
pos := ehSize + int(hdr.SizeOptionHeader) + shSize*i
|
||||||
|
ar.Seek(pos, -1)
|
||||||
|
sh.Serialize(ar)
|
||||||
|
ar.Seek(int(sh.PtrData), int(sh.SizeData))
|
||||||
|
data := make(FSectData, sh.SizeData)
|
||||||
|
data.Serialize(ar)
|
||||||
|
SectList[i] = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (coff *FCoff64) CheckSwapBytes(ar IArchive) {
|
||||||
|
hdr := &coff.Header
|
||||||
|
if hdr.Machine == 0x6486 {
|
||||||
|
ar.SetSwapBytes(true)
|
||||||
|
ar.SwapStructBytes(hdr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (coff *FCoff64) CheckValid(ar IArchive) bool {
|
||||||
|
var hdr FHeader
|
||||||
|
ar.Seek(0, -1)
|
||||||
|
hdr.Serialize(ar)
|
||||||
|
if hdr.Machine != 0x8664 && hdr.Machine != 0x6486 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
48
src/zfile/coff64/type.go
Normal file
48
src/zfile/coff64/type.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package coff64
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
"zlib/src/zfile/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IArchive = core.IArchive
|
||||||
|
type FHeader struct {
|
||||||
|
Machine uint16
|
||||||
|
NumSect uint16
|
||||||
|
TimeStamp uint32
|
||||||
|
SymbolSectPtr uint32
|
||||||
|
NumSymbol uint32
|
||||||
|
SizeOptionHeader uint16
|
||||||
|
Characteristics uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hdr *FHeader) Serialize(ar IArchive) {
|
||||||
|
data := (*[unsafe.Sizeof(*hdr)]byte)(unsafe.Pointer(hdr))
|
||||||
|
ar.SerializeSlice(data[:])
|
||||||
|
ar.SwapStructBytes(hdr)
|
||||||
|
}
|
||||||
|
|
||||||
|
type FSectHeader struct {
|
||||||
|
Name [8]byte
|
||||||
|
VirtualSize uint32
|
||||||
|
VirtualAddr uint32
|
||||||
|
SizeData uint32
|
||||||
|
PtrData uint32
|
||||||
|
PtrRelocation uint32
|
||||||
|
PtrLineNum uint32
|
||||||
|
NumRelocation uint16
|
||||||
|
NumLine uint16
|
||||||
|
Characteristics uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sdr *FSectHeader) Serialize(ar IArchive) {
|
||||||
|
data := (*[unsafe.Sizeof(*sdr)]byte)(unsafe.Pointer(sdr))
|
||||||
|
ar.SerializeSlice(data[:])
|
||||||
|
ar.SwapStructBytes(sdr)
|
||||||
|
}
|
||||||
|
|
||||||
|
type FSectData []byte
|
||||||
|
|
||||||
|
func (sect FSectData) Serialize(ar IArchive) {
|
||||||
|
ar.SerializeSlice(sect)
|
||||||
|
}
|
||||||
98
src/zfile/core/archive.go
Normal file
98
src/zfile/core/archive.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"zlib/src/zlog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FFileArchive struct {
|
||||||
|
pos, start, stop, size int
|
||||||
|
swapBytes bool
|
||||||
|
reader FReader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ar *FFileArchive) SwapStructBytes(e any) {
|
||||||
|
if !ar.swapBytes {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var enc FBytesEncoder
|
||||||
|
enc.Encode(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileArchive(filename string) *FFileArchive {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
zlog.Errorf("os:open error %d", err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
s, _ := f.Stat()
|
||||||
|
io := NewReader(f)
|
||||||
|
return &FFileArchive{
|
||||||
|
size: int(s.Size()),
|
||||||
|
stop: -1,
|
||||||
|
reader: *io,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (ar *FFileArchive) Seek(start, offset int) {
|
||||||
|
pos := ar.pos + ar.start
|
||||||
|
if start < 0 {
|
||||||
|
start = pos
|
||||||
|
}
|
||||||
|
if offset >= 0 {
|
||||||
|
offset = offset + start
|
||||||
|
}
|
||||||
|
ar.start = start
|
||||||
|
ar.stop = offset
|
||||||
|
ar.pos = 0
|
||||||
|
ar.reader.Seek(start, start-pos)
|
||||||
|
}
|
||||||
|
func (ar *FFileArchive) Serialize(e any) {
|
||||||
|
is, ok := e.(ISerialize)
|
||||||
|
if ok {
|
||||||
|
is.Serialize(ar)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//v := reflect.ValueOf(e)
|
||||||
|
t := reflect.TypeOf(e)
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
|
||||||
|
case reflect.Int, reflect.Int32:
|
||||||
|
|
||||||
|
case reflect.Uint, reflect.Uint32:
|
||||||
|
|
||||||
|
case reflect.Bool:
|
||||||
|
|
||||||
|
case reflect.Float32:
|
||||||
|
|
||||||
|
case reflect.Float64:
|
||||||
|
|
||||||
|
default:
|
||||||
|
zlog.Error("Mongo Schema can‘t support this type : ", t.Kind())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ar *FFileArchive) SerializeSlice(data []byte) {
|
||||||
|
size := len(data)
|
||||||
|
if size == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pos := ar.pos + ar.start
|
||||||
|
if pos+size > ar.size {
|
||||||
|
zlog.Errorf("Serializing behind size (%d+%d > %d)", pos, size, ar.size)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ar.stop >= 0 && pos+size > ar.stop {
|
||||||
|
zlog.Errorf("Serializing behind stop (%d+%d > %d)", pos, size, ar.stop)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err := ar.reader.Read(data)
|
||||||
|
if err != nil {
|
||||||
|
zlog.Errorf("read error:: %s", err.Error())
|
||||||
|
}
|
||||||
|
ar.pos += size
|
||||||
|
}
|
||||||
|
func (ar *FFileArchive) SetSwapBytes(swap bool) {
|
||||||
|
ar.swapBytes = swap
|
||||||
|
}
|
||||||
90
src/zfile/core/encode.go
Normal file
90
src/zfile/core/encode.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"unsafe"
|
||||||
|
"zlib/src/zlog"
|
||||||
|
)
|
||||||
|
|
||||||
|
var dbCache sync.Map
|
||||||
|
|
||||||
|
type FBytesEncoder struct {
|
||||||
|
}
|
||||||
|
type FBytesSwap func(field uintptr)
|
||||||
|
|
||||||
|
type Field struct {
|
||||||
|
name string
|
||||||
|
offset uintptr
|
||||||
|
encoder FBytesSwap
|
||||||
|
}
|
||||||
|
|
||||||
|
// emptyInterface is the header for an interface{} value.
|
||||||
|
type emptyInterface struct {
|
||||||
|
typ *struct{}
|
||||||
|
word unsafe.Pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc FBytesEncoder) FindOrInsert(t reflect.Type) []*Field {
|
||||||
|
if t.Kind() == reflect.Struct {
|
||||||
|
zlog.Errorf("error type struct, need * struct %s", t.Name())
|
||||||
|
} else {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
key := t.Name()
|
||||||
|
if cache, ok := dbCache.Load(key); ok {
|
||||||
|
return cache.([]*Field)
|
||||||
|
}
|
||||||
|
value := make([]*Field, t.NumField())
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
f := t.Field(i)
|
||||||
|
value[i] = &Field{
|
||||||
|
name: strings.ToLower(f.Name),
|
||||||
|
offset: f.Offset,
|
||||||
|
encoder: enc.NewTypeEncoder(f.Type),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbCache.LoadOrStore(key, value)
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode 这里只能传递指针,非指针没有意义
|
||||||
|
func (enc FBytesEncoder) Encode(v any) {
|
||||||
|
structPtr := (*emptyInterface)(unsafe.Pointer(&v)).word
|
||||||
|
fieldList := enc.FindOrInsert(reflect.TypeOf(v))
|
||||||
|
for _, field := range fieldList {
|
||||||
|
ptr := uintptr(structPtr) + field.offset
|
||||||
|
field.encoder(ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (enc FBytesEncoder) NewTypeEncoder(t reflect.Type) FBytesSwap {
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Int16, reflect.Uint16:
|
||||||
|
return halfSwap
|
||||||
|
case reflect.Uint32, reflect.Int32, reflect.Float32:
|
||||||
|
return wordSwap
|
||||||
|
case reflect.Int64, reflect.Uint64, reflect.Float64:
|
||||||
|
return doubleSwap
|
||||||
|
default:
|
||||||
|
return defaultSwap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func defaultSwap(_ uintptr) {
|
||||||
|
}
|
||||||
|
func halfSwap(field uintptr) {
|
||||||
|
data := (*[2]byte)(unsafe.Pointer(field))
|
||||||
|
data[0], data[1] = data[1], data[0]
|
||||||
|
}
|
||||||
|
func wordSwap(field uintptr) {
|
||||||
|
data := (*[4]byte)(unsafe.Pointer(field))
|
||||||
|
data[0], data[3] = data[3], data[0]
|
||||||
|
data[1], data[2] = data[2], data[1]
|
||||||
|
}
|
||||||
|
func doubleSwap(field uintptr) {
|
||||||
|
data := (*[8]byte)(unsafe.Pointer(field))
|
||||||
|
data[0], data[7] = data[7], data[0]
|
||||||
|
data[1], data[6] = data[6], data[1]
|
||||||
|
data[2], data[5] = data[5], data[2]
|
||||||
|
data[3], data[4] = data[4], data[3]
|
||||||
|
}
|
||||||
5
src/zfile/core/error.go
Normal file
5
src/zfile/core/error.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var ErrBufferFull = errors.New("read: buffer full")
|
||||||
8
src/zfile/core/link.go
Normal file
8
src/zfile/core/link.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
//go:linkname memmove runtime.memmove
|
||||||
|
//goland:noinspection GoUnusedParameter
|
||||||
|
func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
|
||||||
104
src/zfile/core/reader.go
Normal file
104
src/zfile/core/reader.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func min(a int, b int) int {
|
||||||
|
if a < b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
type FReader struct {
|
||||||
|
io io.Reader
|
||||||
|
buf []byte
|
||||||
|
r, w int
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewReader(io io.Reader) *FReader {
|
||||||
|
return &FReader{
|
||||||
|
io: io,
|
||||||
|
buf: make([]byte, 4096),
|
||||||
|
r: 0,
|
||||||
|
w: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (b *FReader) Read(data []byte) (int, error) {
|
||||||
|
n, rn := len(data), 0
|
||||||
|
for rn < n {
|
||||||
|
d := min(b.w-b.r, n-rn)
|
||||||
|
if d > 0 {
|
||||||
|
copy(data[rn:rn+d], b.buf[b.r:b.r+d])
|
||||||
|
b.r += d
|
||||||
|
rn += d
|
||||||
|
if rn >= n {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err := b.fill()
|
||||||
|
if err != nil {
|
||||||
|
return rn, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rn, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
func (b *FReader) ReadLine() ([]byte, error) {
|
||||||
|
line, err := b.ReadSlice('\n')
|
||||||
|
return line, err
|
||||||
|
}
|
||||||
|
func (b *FReader) ReadSlice(delim byte) ([]byte, error) {
|
||||||
|
for {
|
||||||
|
// Search buffer.
|
||||||
|
if i := bytes.IndexByte(b.buf[b.r+0:b.w], delim); i >= 0 {
|
||||||
|
i += 1
|
||||||
|
b.r += i
|
||||||
|
return b.buf[b.r-i : b.r], nil
|
||||||
|
}
|
||||||
|
err := b.fill()
|
||||||
|
if err != nil {
|
||||||
|
return b.buf[b.r:], err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (b *FReader) fill() error {
|
||||||
|
d := b.w - b.r
|
||||||
|
if d >= len(b.buf) {
|
||||||
|
b.r = 0
|
||||||
|
b.w = 0
|
||||||
|
return ErrBufferFull
|
||||||
|
}
|
||||||
|
// Slide existing data to beginning.
|
||||||
|
if b.r > 0 {
|
||||||
|
copy(b.buf, b.buf[b.r:b.w])
|
||||||
|
b.w -= b.r
|
||||||
|
b.r = 0
|
||||||
|
}
|
||||||
|
// Read new data: try a limited number of times.
|
||||||
|
n, err := b.io.Read(b.buf[b.w:])
|
||||||
|
b.w += n
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
func (b *FReader) Clear() {
|
||||||
|
b.r = 0
|
||||||
|
b.w = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *FReader) Seek(pos, offset int) {
|
||||||
|
r := b.r + offset
|
||||||
|
if r >= 0 && r <= b.w {
|
||||||
|
b.r = r
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f, ok := b.io.(*os.File)
|
||||||
|
if ok {
|
||||||
|
f.Seek(int64(pos), 0)
|
||||||
|
b.r = 0
|
||||||
|
b.w = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/zfile/core/type.go
Normal file
19
src/zfile/core/type.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
type IArchive interface {
|
||||||
|
Seek(start int, offset int)
|
||||||
|
Serialize(e any)
|
||||||
|
SerializeSlice(data []byte)
|
||||||
|
SetSwapBytes(swap bool)
|
||||||
|
SwapStructBytes(e any)
|
||||||
|
}
|
||||||
|
type ISerialize interface {
|
||||||
|
Serialize(ar IArchive)
|
||||||
|
}
|
||||||
|
type IPackageExpansion interface {
|
||||||
|
Expansion(pack IPackage)
|
||||||
|
}
|
||||||
|
type IPackage interface {
|
||||||
|
Serialize(ar IArchive)
|
||||||
|
CheckValid(ar IArchive) bool
|
||||||
|
}
|
||||||
43
src/zfile/elf64/elf64.go
Normal file
43
src/zfile/elf64/elf64.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package elf64
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FElf64 struct {
|
||||||
|
Header FHeader
|
||||||
|
SectHeaderList []FSectHeader
|
||||||
|
SectList []FSectData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (elf *FElf64) Serialize(ar IArchive) {
|
||||||
|
ar.Seek(0, -1)
|
||||||
|
elf.Header.Serialize(ar)
|
||||||
|
hdr := &elf.Header
|
||||||
|
num := int(hdr.ShNum)
|
||||||
|
SectHeaderList := make([]FSectHeader, num)
|
||||||
|
SectList := make([]FSectData, num)
|
||||||
|
elf.SectHeaderList = SectHeaderList
|
||||||
|
elf.SectList = SectList
|
||||||
|
shSize := int(unsafe.Sizeof(SectHeaderList[0]))
|
||||||
|
for i := 0; i < num; i++ {
|
||||||
|
sh := &SectHeaderList[i]
|
||||||
|
pos := int(hdr.ShOff) + shSize*i
|
||||||
|
ar.Seek(pos, -1)
|
||||||
|
sh.Serialize(ar)
|
||||||
|
ar.Seek(int(sh.Offset), int(sh.Size))
|
||||||
|
data := make(FSectData, sh.Size)
|
||||||
|
data.Serialize(ar)
|
||||||
|
SectList[i] = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (elf *FElf64) CheckValid(ar IArchive) bool {
|
||||||
|
var hdr FHeader
|
||||||
|
ar.Seek(0, -1)
|
||||||
|
hdr.Serialize(ar)
|
||||||
|
if hdr.Ident[1] != 'E' && hdr.Ident[2] != 'L' && hdr.Ident[3] != 'F' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
88
src/zfile/elf64/type.go
Normal file
88
src/zfile/elf64/type.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package elf64
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
"zlib/src/zfile/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IArchive = core.IArchive
|
||||||
|
|
||||||
|
type (
|
||||||
|
_Word = int32
|
||||||
|
_Half = int16
|
||||||
|
_XWord = int64
|
||||||
|
_Addr = int64
|
||||||
|
_Off = int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type FHeader struct {
|
||||||
|
Ident [16]byte
|
||||||
|
Type _Half
|
||||||
|
Machine _Half
|
||||||
|
Version _Word
|
||||||
|
Entry _Addr
|
||||||
|
PhOff _Off
|
||||||
|
ShOff _Off
|
||||||
|
Flags _Word
|
||||||
|
EhSize _Half
|
||||||
|
PhEntSize _Half
|
||||||
|
PhNum _Half
|
||||||
|
ShEntSize _Half
|
||||||
|
ShNum _Half
|
||||||
|
ShStrNdx _Half
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hdr *FHeader) Serialize(ar IArchive) {
|
||||||
|
data := (*[unsafe.Sizeof(*hdr)]byte)(unsafe.Pointer(hdr))
|
||||||
|
ar.SerializeSlice(data[:])
|
||||||
|
ar.SwapStructBytes(hdr)
|
||||||
|
}
|
||||||
|
|
||||||
|
type FSectHeader struct {
|
||||||
|
Name _Word
|
||||||
|
Type _Word
|
||||||
|
Flags _XWord
|
||||||
|
Addr _Addr
|
||||||
|
Offset _Off
|
||||||
|
Size _XWord
|
||||||
|
Link _Word
|
||||||
|
Info _Word
|
||||||
|
AddrAlign _XWord
|
||||||
|
EntSize _XWord
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sdr *FSectHeader) Serialize(ar IArchive) {
|
||||||
|
data := (*[unsafe.Sizeof(*sdr)]byte)(unsafe.Pointer(sdr))
|
||||||
|
ar.SerializeSlice(data[:])
|
||||||
|
ar.SwapStructBytes(sdr)
|
||||||
|
}
|
||||||
|
|
||||||
|
type FSectData []byte
|
||||||
|
|
||||||
|
func (sect FSectData) Serialize(ar IArchive) {
|
||||||
|
ar.SerializeSlice(sect)
|
||||||
|
}
|
||||||
|
func (sect FSectData) GetStrByPos(pos int) []byte {
|
||||||
|
i, size := pos, len(sect)
|
||||||
|
for i < size {
|
||||||
|
if sect[i] == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return sect[pos:i]
|
||||||
|
}
|
||||||
|
func (sect FSectData) GetStrById(id int) []byte {
|
||||||
|
i, j := 0, 0
|
||||||
|
p1, p2 := 0, 0
|
||||||
|
size := len(sect)
|
||||||
|
for i < size && j <= id {
|
||||||
|
if sect[i] == 0 {
|
||||||
|
j++
|
||||||
|
p2 = p1
|
||||||
|
p1 = i + 1
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return sect[p2:i]
|
||||||
|
}
|
||||||
44
src/zfile/exp/exp.go
Normal file
44
src/zfile/exp/exp.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package exp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"zlib/src/zfile/coff64"
|
||||||
|
"zlib/src/zfile/core"
|
||||||
|
"zlib/src/zfile/elf64"
|
||||||
|
"zlib/src/zlog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IPackage = core.IPackage
|
||||||
|
type FElf64 = elf64.FElf64
|
||||||
|
type FCoff64 = coff64.FCoff64
|
||||||
|
type FPackageExpansion struct{}
|
||||||
|
|
||||||
|
func (exp *FPackageExpansion) Expansion(pack IPackage) {
|
||||||
|
elf, ok := pack.(*FElf64)
|
||||||
|
if ok {
|
||||||
|
exp.ExpansionElf64(elf)
|
||||||
|
}
|
||||||
|
coff, ok := pack.(*FCoff64)
|
||||||
|
if ok {
|
||||||
|
exp.ExpansionCoff64(coff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (exp *FPackageExpansion) ExpansionElf64(elf *FElf64) {
|
||||||
|
hdr := elf.Header
|
||||||
|
zlog.Infof("ExpansionElf64::%s ", hdr)
|
||||||
|
num := int(hdr.ShNum)
|
||||||
|
strData := &elf.SectList[hdr.ShStrNdx]
|
||||||
|
for i := 1; i < num; i++ {
|
||||||
|
data := &elf.SectList[i]
|
||||||
|
zlog.Infof("sect::%s::%s", strData.GetStrById(i), *data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (exp *FPackageExpansion) ExpansionCoff64(coff *FCoff64) {
|
||||||
|
hdr := coff.Header
|
||||||
|
zlog.Infof("ExpansionCoff64::%s ", hdr)
|
||||||
|
num := int(hdr.NumSect)
|
||||||
|
for i := 1; i < num; i++ {
|
||||||
|
sh := &coff.SectHeaderList[i]
|
||||||
|
data := &coff.SectList[i]
|
||||||
|
zlog.Infof("sect::%s::%s", sh.Name, *data)
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/zfile/exp/exp_test.go
Normal file
37
src/zfile/exp/exp_test.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package exp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"zlib/src/zfile"
|
||||||
|
"zlib/src/zfile/core"
|
||||||
|
"zlib/src/zlog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEncoder(t *testing.T) {
|
||||||
|
path := zfile.GetRealPath("zfile/file/main.cpp2.obj")
|
||||||
|
ar := core.NewFileArchive(path)
|
||||||
|
var coff *FCoff64
|
||||||
|
if coff.CheckValid(ar) {
|
||||||
|
coff = &FCoff64{}
|
||||||
|
coff.Serialize(ar)
|
||||||
|
hdr1 := coff.Header
|
||||||
|
hdr2 := coff.Header
|
||||||
|
ar.SetSwapBytes(true)
|
||||||
|
ar.SwapStructBytes(&hdr1)
|
||||||
|
ar.SwapStructBytes(&hdr2)
|
||||||
|
zlog.Infof("%s", hdr1)
|
||||||
|
zlog.Infof("%s", hdr2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFile(t *testing.T) {
|
||||||
|
path := zfile.GetRealPath("zfile/file/SimpleSection")
|
||||||
|
ar := core.NewFileArchive(path)
|
||||||
|
var exp FPackageExpansion
|
||||||
|
var elf *FElf64
|
||||||
|
if elf.CheckValid(ar) {
|
||||||
|
elf = &FElf64{}
|
||||||
|
elf.Serialize(ar)
|
||||||
|
exp.ExpansionElf64(elf)
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/zfile/file/SimpleSection.o
Normal file
BIN
src/zfile/file/SimpleSection.o
Normal file
Binary file not shown.
BIN
src/zfile/file/main.cpp.obj
Normal file
BIN
src/zfile/file/main.cpp.obj
Normal file
Binary file not shown.
BIN
src/zfile/file/main.cpp2.obj
Normal file
BIN
src/zfile/file/main.cpp2.obj
Normal file
Binary file not shown.
BIN
src/zfile/file/main.o
Normal file
BIN
src/zfile/file/main.o
Normal file
Binary file not shown.
BIN
src/zfile/file/zfile.exe
Normal file
BIN
src/zfile/file/zfile.exe
Normal file
Binary file not shown.
11
src/zfile/tool.go
Normal file
11
src/zfile/tool.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package zfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetRealPath(path string) string {
|
||||||
|
_, curPath, _, _ := runtime.Caller(0)
|
||||||
|
return filepath.Join(curPath, "../../", path)
|
||||||
|
}
|
||||||
16
src/zlog/type.go
Normal file
16
src/zlog/type.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package zlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Level is type of log levels
|
||||||
|
type Level = zapcore.Level
|
||||||
|
|
||||||
|
type FLogf = func(template string, args ...interface{})
|
||||||
|
type FLog = func(args ...interface{})
|
||||||
|
|
||||||
|
var (
|
||||||
|
Debugf, Infof, Warnf, Errorf, Panicf, Fatalf FLogf
|
||||||
|
Debug, Error, Panic, Fatal FLog
|
||||||
|
)
|
||||||
98
src/zlog/zlog.go
Normal file
98
src/zlog/zlog.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package zlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
cfg zap.Config
|
||||||
|
logger *zap.Logger
|
||||||
|
sugar *zap.SugaredLogger
|
||||||
|
source string
|
||||||
|
currentLevel Level
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
currentLevel = zap.DebugLevel
|
||||||
|
cfg = zap.NewDevelopmentConfig()
|
||||||
|
cfg.Development = true
|
||||||
|
rebuildLoggerFromCfg()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSource sets the component name (dispatcher/gate/game) of gwlog module
|
||||||
|
func SetSource(source_ string) {
|
||||||
|
source = source_
|
||||||
|
rebuildLoggerFromCfg()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetParseLevel(slv string) {
|
||||||
|
lv := ParseLevel(slv)
|
||||||
|
SetLevel(lv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLevel sets the zlog level
|
||||||
|
func SetLevel(lv Level) {
|
||||||
|
currentLevel = lv
|
||||||
|
cfg.Level.SetLevel(lv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLevel get the current zlog level
|
||||||
|
func GetLevel() Level {
|
||||||
|
return currentLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOutput sets the output writer
|
||||||
|
func SetOutput(outputs []string) {
|
||||||
|
cfg.OutputPaths = outputs
|
||||||
|
rebuildLoggerFromCfg()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseLevel converts string to Levels
|
||||||
|
func ParseLevel(s string) Level {
|
||||||
|
if strings.ToLower(s) == "debug" {
|
||||||
|
return zap.DebugLevel
|
||||||
|
} else if strings.ToLower(s) == "info" {
|
||||||
|
return zap.InfoLevel
|
||||||
|
} else if strings.ToLower(s) == "warn" || strings.ToLower(s) == "warning" {
|
||||||
|
return zap.WarnLevel
|
||||||
|
} else if strings.ToLower(s) == "error" {
|
||||||
|
return zap.ErrorLevel
|
||||||
|
} else if strings.ToLower(s) == "panic" {
|
||||||
|
return zap.PanicLevel
|
||||||
|
} else if strings.ToLower(s) == "fatal" {
|
||||||
|
return zap.FatalLevel
|
||||||
|
}
|
||||||
|
Errorf("ParseLevel: unknown level: %s", s)
|
||||||
|
return zap.DebugLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func rebuildLoggerFromCfg() {
|
||||||
|
newLogger, err := cfg.Build()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if logger != nil {
|
||||||
|
logger.Sync()
|
||||||
|
}
|
||||||
|
logger = newLogger
|
||||||
|
if source != "" {
|
||||||
|
logger = logger.With(zap.String("source", source))
|
||||||
|
}
|
||||||
|
sugar = logger.Sugar()
|
||||||
|
initFLog()
|
||||||
|
}
|
||||||
|
func initFLog() {
|
||||||
|
Debugf = sugar.Debugf
|
||||||
|
Infof = sugar.Infof
|
||||||
|
Warnf = sugar.Warnf
|
||||||
|
Errorf = sugar.Errorf
|
||||||
|
Panicf = sugar.Panicf
|
||||||
|
Fatalf = sugar.Fatalf
|
||||||
|
|
||||||
|
Debug = sugar.Debug
|
||||||
|
Error = sugar.Error
|
||||||
|
Panic = sugar.Panic
|
||||||
|
Fatal = sugar.Fatal
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user