mps

morphux package server
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/mps

commit 50bda7f48ff1bd62d9b940935e86dbb808cb2732
parent 71faf0359f1faa41f26bdbf07d88da9e5aef6d8d
Author: Pierre Avisse <gosti@ns332675.ip-176-31-110.eu>
Date:   Sun, 26 Mar 2017 22:20:40 +0200

Adding Barrel as a vendor

Diffstat:
Mdatabase.go | 13+++++++------
Mmessage/error.go | 23+++++++++++++++++++++++
Mmessage/message.go | 2+-
Mmessage/payload.go | 2+-
Mmps.go | 8++++++--
Mnetwork.go | 33++++++++++++++++++++++++++-------
Mrequest/req_get_pkg.go | 6++++--
Mresponse/resp_pkg.go | 7++++++-
Avendors/Nyarum/barrel/.gitignore | 24++++++++++++++++++++++++
Avendors/Nyarum/barrel/LICENSE | 21+++++++++++++++++++++
Avendors/Nyarum/barrel/README.md | 2++
Avendors/Nyarum/barrel/barrel.go | 42++++++++++++++++++++++++++++++++++++++++++
Avendors/Nyarum/barrel/barrel_pack.go | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Avendors/Nyarum/barrel/barrel_processor.go | 511+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Avendors/Nyarum/barrel/barrel_processor_test.go | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Avendors/Nyarum/barrel/barrel_test.go | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Avendors/Nyarum/barrel/barrel_unpack.go | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
17 files changed, 1003 insertions(+), 20 deletions(-)

diff --git a/database.go b/database.go @@ -27,6 +27,7 @@ type Package struct { ArchiveSize float64 InstalledSize float64 ArchiveHash string + TimeAddPkg uint64 } func RequestPackage(data []byte, db *sql.DB) (int, Package, error) { @@ -40,7 +41,7 @@ func RequestPackage(data []byte, db *sql.DB) (int, Package, error) { return n, pkg, err } - fmt.Println(req) + fmt.Println("unpacked :", req) if req.ID != 0 && req.NameLen == 0 && req.CategLen == 0 { fmt.Println("search By id") @@ -70,9 +71,9 @@ func PkgtoRespPkg(pkg Package) (*response.RespPkg, error) { ret := new(response.RespPkg) ret.ID = pkg.ID - ret.CompTime = pkg.SBU - ret.InstSize = pkg.InstalledSize - ret.ArchSize = pkg.ArchiveSize + ret.CompTime = float64(pkg.SBU) + ret.InstSize = float64(pkg.InstalledSize) + ret.ArchSize = float64(pkg.ArchiveSize) ret.State = pkg.State ret.NameLen = uint64(len(pkg.Name)) ret.CategoryLen = uint16(len(pkg.Category)) @@ -110,7 +111,7 @@ func QueryPkgNameAndCat(name string, category string, state uint8, db *sql.DB) ( } for rows.Next() { err := rows.Scan(&pkg.ID, &pkg.Name, &pkg.State, &pkg.Version, &pkg.Category, &pkg.Description, - &pkg.Archive, &pkg.SBU, &pkg.Dependencies, &pkg.ArchiveSize, &pkg.InstalledSize, &pkg.ArchiveHash) + &pkg.Dependencies, &pkg.Archive, &pkg.SBU, &pkg.ArchiveSize, &pkg.InstalledSize, &pkg.ArchiveHash, &pkg.TimeAddPkg) if err != nil { return pkg, err log.Fatalln(err) @@ -129,7 +130,7 @@ func QueryPkgID(id uint64, state uint8, db *sql.DB) (Package, error) { } for rows.Next() { err := rows.Scan(&pkg.ID, &pkg.Name, &pkg.State, &pkg.Version, &pkg.Category, &pkg.Description, - &pkg.Archive, &pkg.SBU, &pkg.Dependencies, &pkg.ArchiveSize, &pkg.InstalledSize, &pkg.ArchiveHash) + &pkg.Dependencies, &pkg.Archive, &pkg.SBU, &pkg.ArchiveSize, &pkg.InstalledSize, &pkg.ArchiveHash, &pkg.TimeAddPkg) if err != nil { return pkg, err log.Fatalln(err) diff --git a/message/error.go b/message/error.go @@ -24,3 +24,26 @@ func (p *Error) PackError(err error, errortype uint8) ([]byte, error) { return p.Pack() } + +// Return Server Fault Message +func ServerFault() []byte { + errorMessage := []byte("An error happened server side") //len 0x1D + return append([]byte{0x03, 0x25, 0x00, 0x00, 0x01, 0x01, 0x1D, 0x00}, errorMessage...) +} + +// Return Malformed Malformed Message +func MalformedPacket() []byte { + errorMessage := []byte("A packet send by the client is wrong") //len 0x24 + return append([]byte{0x03, 0x2C, 0x00, 0x00, 0x01, 0x02, 0x24, 0x00}, errorMessage...) +} + +// Return Ressource Not Found Message +func ResNotFound() []byte { + errorMessage := []byte("A request send by the client find no result") //len 0x2B + return append([]byte{0x03, 0x33, 0x00, 0x00, 0x01, 0x03, 0x2B, 0x00}, errorMessage...) +} + +// Generate a Error Message +func GenerateError(Type uint8, message string) []byte { + return append([]byte{Type, byte(len(message) + 8), 0x00, 0x00, 0x01, 0x03, byte(len(message)), 0x00}, []byte(message)...) +} diff --git a/message/message.go b/message/message.go @@ -1,6 +1,6 @@ package message -import "github.com/Nyarum/barrel" +import "github.com/Morphux/mps/vendors/Nyarum/barrel" //Message is the basic structure to send and receive Message all the methods can be overwritted if needed type Message struct { diff --git a/message/payload.go b/message/payload.go @@ -1,6 +1,6 @@ package message -import "github.com/Nyarum/barrel" +import "github.com/Morphux/mps/vendors/Nyarum/barrel" type Payload struct { Number uint8 diff --git a/mps.go b/mps.go @@ -58,9 +58,13 @@ func handleRequest(conn net.Conn, db *sql.DB) { for { n, err := conn.Read(buf) - fmt.Println("receive :", buf[0:n]) + //fmt.Printf("receive :%#v\n\n", buf[0:n]) - ParseRequest(buf[0:n], conn, db) + errParse := ParseRequest(buf[0:n], conn, db) + + if errParse != nil { + log.Print(errParse) + } if err != nil || n == 0 { conn.Close() diff --git a/network.go b/network.go @@ -4,7 +4,6 @@ import ( "database/sql" "errors" "fmt" - "log" "net" "github.com/Morphux/mps/message" @@ -28,33 +27,53 @@ func ParseRequest(data []byte, conn net.Conn, db *sql.DB) error { return errors.New("Header too short") } - //dismiss payload for now - - cursor = cursor + 1 + //payload + cursor += 1 switch header.Type { case 0x01: conn.Write(response.GetAuthACK()) case 0x10: + c, pkg, err := RequestPackage(data[cursor+1:], db) + if err != nil { + conn.Write(message.MalformedPacket()) + return err + } + resp, err := PkgtoRespPkg(pkg) + if err != nil { + return err + } + resp_data, err := resp.Pack() if err != nil { - log.Fatal(err) + return err } + fmt.Println(resp_data) + resp_header := new(message.Header) resp_header.Build(0x20, 1, resp_data) header_data, err := resp_header.Pack() - conn.Write(append(header_data, resp_data...)) + tosend := append(header_data, resp_data...) + + fmt.Printf("PKG DATA TO BE SENT : %#v\n", tosend) + + i, err := conn.Write(tosend) + + fmt.Println(i) + + if err != nil { + return err + } - //conn.Write() cursor += c default: fmt.Println(header.Type) diff --git a/request/req_get_pkg.go b/request/req_get_pkg.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/Morphux/mps/message" - "github.com/Nyarum/barrel" + "github.com/Morphux/mps/vendors/Nyarum/barrel" ) type ReqGetPKG struct { @@ -23,6 +23,8 @@ type ReqGetPKG struct { func (h *ReqGetPKG) Unpack(data []byte) (int, error) { + fmt.Printf("=====\ndata %#v\n\n", data) + var l uint16 = 15 fmt.Println(data) @@ -35,7 +37,7 @@ func (h *ReqGetPKG) Unpack(data []byte) (int, error) { return 0, err } - fmt.Println(h.ID, h.NameLen, h.CategLen, h.VersionLen) + //fmt.Println(h.ID, h.NameLen, h.CategLen, h.VersionLen) if len(data) < int(l+h.NameLen+h.CategLen+h.VersionLen) { return 0, errors.New("A packet send by the client is wrong") diff --git a/response/resp_pkg.go b/response/resp_pkg.go @@ -1,8 +1,10 @@ package response import ( + "fmt" + "github.com/Morphux/mps/message" - "github.com/Nyarum/barrel" + "github.com/Morphux/mps/vendors/Nyarum/barrel" ) type RespPkg struct { @@ -28,6 +30,9 @@ type RespPkg struct { } func (p *RespPkg) Pack() ([]byte, error) { + + fmt.Printf("%#v\n", p) + barrel := barrel.NewBarrel() load := barrel.Load(p, []byte{}, true) diff --git a/vendors/Nyarum/barrel/.gitignore b/vendors/Nyarum/barrel/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/vendors/Nyarum/barrel/LICENSE b/vendors/Nyarum/barrel/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Nyarum + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendors/Nyarum/barrel/README.md b/vendors/Nyarum/barrel/README.md @@ -0,0 +1,2 @@ +# barrel +Very fast binary marshaller to struct and back diff --git a/vendors/Nyarum/barrel/barrel.go b/vendors/Nyarum/barrel/barrel.go @@ -0,0 +1,42 @@ +package barrel + +import "reflect" + +type ( + Unit interface { + Default() + Check(*Stats) bool + } + + Stats struct { + LenSlice int + NameField string + Endian int + } + + Barrel struct { + Object Unit + numField int + processor *Processor + Stats Stats + } +) + +func NewBarrel() *Barrel { + return &Barrel{} +} + +func (b *Barrel) Load(object Unit, buffer []byte, def bool) reflect.Value { + if def { + object.Default() + } + + b.Object = object + b.processor = NewProcessor(buffer) + + return reflect.Indirect(reflect.ValueOf(object)) +} + +func (b *Barrel) Bytes() []byte { + return b.processor.Bytes() +} diff --git a/vendors/Nyarum/barrel/barrel_pack.go b/vendors/Nyarum/barrel/barrel_pack.go @@ -0,0 +1,74 @@ +package barrel + +import ( + "fmt" + "reflect" +) + +func (b *Barrel) Pack(value reflect.Value) error { + switch value.Kind() { + case reflect.Struct: + for i := 0; i < value.NumField(); i++ { + valueType := value.Type().Field(i) + + b.Stats.NameField = valueType.Name + if !b.Object.Check(&b.Stats) { + continue + } + + if b.Stats.Endian == 1 { + b.processor.SetEndian(BigEndian) + } else if b.Stats.Endian == 0 { + b.processor.SetEndian(LittleEndian) + } + + err := b.Pack(value.Field(i)) + if err != nil { + return err + } + } + case reflect.Float64: + b.processor.WriteFloat64(float64(value.Float())) + case reflect.Uint8: + b.processor.WriteUint8(uint8(value.Uint())) + case reflect.Int8: + b.processor.WriteInt8(int8(value.Int())) + case reflect.Uint16: + b.processor.WriteUint16(uint16(value.Uint())) + case reflect.Int16: + b.processor.WriteInt16(int16(value.Int())) + case reflect.Uint, reflect.Uint32: + b.processor.WriteUint32(uint32(value.Uint())) + case reflect.Int, reflect.Int32: + b.processor.WriteInt32(int32(value.Int())) + case reflect.Uint64: + b.processor.WriteUint64(value.Uint()) + case reflect.Int64: + b.processor.WriteInt64(value.Int()) + case reflect.String: + b.processor.WriteString(value.String()) + case reflect.Slice: + if value.Type().String() == "[]uint64" { + slice := value.Interface().([]uint64) + for _, v := range slice { + err := b.Pack(reflect.ValueOf(v)) + if err != nil { + return err + } + } + } else { + b.processor.WriteBytes(value.Bytes()) + } + case reflect.Bool: + b.processor.WriteBool(value.Bool()) + case reflect.Interface: + err := b.Pack(reflect.Indirect(value.Elem())) + if err != nil { + return err + } + default: + return fmt.Errorf("Type of object is incorrect.. It is - %v %v", value.Kind(), value) + } + + return nil +} diff --git a/vendors/Nyarum/barrel/barrel_processor.go b/vendors/Nyarum/barrel/barrel_processor.go @@ -0,0 +1,511 @@ +package barrel + +import ( + "bytes" + "encoding/binary" + "errors" + "math" +) + +const ( + LittleEndian = iota + BigEndian +) + +type ( + // Processor struct for network library + Processor struct { + buffer *bytes.Buffer + endian int + + err error + } +) + +// NewProcessor method for init Processor struct +func NewProcessor(buf []byte) *Processor { + processor := new(Processor) + processor.buffer = bytes.NewBuffer(buf) + processor.endian = LittleEndian + + return processor +} + +// Error method for get error from netes +func (p *Processor) Error() error { + return p.err +} + +// Buffer method for get pointer to bytes.Buffer +func (p *Processor) Buffer() *bytes.Buffer { + return p.buffer +} + +// Bytes method for get []byte from buffer +func (p *Processor) Bytes() []byte { + return p.buffer.Bytes() +} + +// Reset method for reset buffer +func (p *Processor) Reset() { + p.buffer.Reset() +} + +// Endian method for get current endian number +func (p *Processor) Endian() int { + return p.endian +} + +// SetEndian method for set endian in buffer +func (p *Processor) SetEndian(endian int) *Processor { + p.endian = endian + + return p +} + +func (p *Processor) ReadInt8(value *int8) *Processor { + bufInt8 := make([]byte, 1) + if bufInt8 = p.buffer.Next(1); len(bufInt8) < 1 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + (*value) = int8(bufInt8[0]) + + return p +} + +func (p *Processor) ReadInt16(value *int16) *Processor { + bufInt16 := make([]byte, 2) + if bufInt16 = p.buffer.Next(2); len(bufInt16) < 2 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + if p.Endian() == LittleEndian { + (*value) = int16(binary.LittleEndian.Uint16(bufInt16)) + } else { + (*value) = int16(binary.BigEndian.Uint16(bufInt16)) + } + + return p +} + +func (p *Processor) ReadInt32(value *int32) *Processor { + bufInt := make([]byte, 4) + if bufInt = p.buffer.Next(4); len(bufInt) < 4 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + if p.Endian() == LittleEndian { + (*value) = int32(binary.LittleEndian.Uint32(bufInt)) + } else { + (*value) = int32(binary.BigEndian.Uint32(bufInt)) + } + + return p +} + +func (p *Processor) ReadInt64(value *int64) *Processor { + bufInt64 := make([]byte, 8) + if bufInt64 = p.buffer.Next(8); len(bufInt64) < 8 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + if p.Endian() == LittleEndian { + (*value) = int64(binary.LittleEndian.Uint64(bufInt64)) + } else { + (*value) = int64(binary.BigEndian.Uint64(bufInt64)) + } + + return p +} + +func (p *Processor) ReadUint8(value *uint8) *Processor { + bufUint8 := make([]byte, 1) + if bufUint8 = p.buffer.Next(1); len(bufUint8) < 1 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + (*value) = uint8(bufUint8[0]) + + return p +} + +func (p *Processor) ReadUint16(value *uint16) *Processor { + bufUint16 := make([]byte, 2) + if bufUint16 = p.buffer.Next(2); len(bufUint16) < 2 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + if p.Endian() == LittleEndian { + (*value) = binary.LittleEndian.Uint16(bufUint16) + } else { + (*value) = binary.BigEndian.Uint16(bufUint16) + } + + return p +} + +func (p *Processor) ReadUint32(value *uint32) *Processor { + bufUint32 := make([]byte, 4) + if bufUint32 = p.buffer.Next(4); len(bufUint32) < 4 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + if p.Endian() == LittleEndian { + (*value) = binary.LittleEndian.Uint32(bufUint32) + } else { + (*value) = binary.BigEndian.Uint32(bufUint32) + } + + return p +} + +func (p *Processor) ReadUint64(value *uint64) *Processor { + bufUint64 := make([]byte, 8) + if bufUint64 = p.buffer.Next(8); len(bufUint64) < 8 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + if p.Endian() == LittleEndian { + (*value) = binary.LittleEndian.Uint64(bufUint64) + } else { + (*value) = binary.BigEndian.Uint64(bufUint64) + } + + return p +} + +func (p *Processor) ReadFloat32(value *float32) *Processor { + bufFloat32 := make([]byte, 4) + if bufFloat32 = p.buffer.Next(4); len(bufFloat32) < 4 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + if p.Endian() == LittleEndian { + (*value) = math.Float32frombits(binary.LittleEndian.Uint32(bufFloat32)) + } else { + (*value) = math.Float32frombits(binary.BigEndian.Uint32(bufFloat32)) + } + + return p +} + +func (p *Processor) ReadFloat64(value *float64) *Processor { + bufFloat64 := make([]byte, 8) + if bufFloat64 = p.buffer.Next(8); len(bufFloat64) < 8 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + if p.Endian() == LittleEndian { + (*value) = math.Float64frombits(binary.LittleEndian.Uint64(bufFloat64)) + } else { + (*value) = math.Float64frombits(binary.BigEndian.Uint64(bufFloat64)) + } + + return p +} + +func (p *Processor) ReadString(value *string) *Processor { + var lnString uint16 + bufLenString := make([]byte, 2) + if bufLenString = p.buffer.Next(2); len(bufLenString) < 2 { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + if p.Endian() == LittleEndian { + lnString = binary.LittleEndian.Uint16(bufLenString) + } else { + lnString = binary.BigEndian.Uint16(bufLenString) + } + + bufString := make([]byte, lnString) + if bufString = p.buffer.Next(int(lnString)); len(bufString) < int(lnString) { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + (*value) = string(bufString) + + return p +} + +func (p *Processor) ReadStringEOF(value *string) *Processor { + str, err := p.buffer.ReadString(0x00) + if err != nil { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + (*value) = str + + return p +} + +func (p *Processor) ReadStringWithLen(ln int32, value *string) *Processor { + bufString := make([]byte, ln) + if bufString = p.buffer.Next(int(ln)); len(bufString) < int(ln) { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + (*value) = string(bufString) + + return p +} + +func (p *Processor) ReadBytes(value *[]byte, ln int) *Processor { + bufBytes := make([]byte, ln) + if bufBytes = p.buffer.Next(int(ln)); len(bufBytes) < int(ln) { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + (*value) = bufBytes + + return p +} + +func (p *Processor) ReadArray(value *[]byte, ln int) *Processor { + bufBytes := make([]byte, ln) + if bufBytes = p.buffer.Next(int(ln)); len(bufBytes) < int(ln) { + p.err = errors.New("Not enough bytes in buffer") + return p + } + + (*value) = bufBytes + + return p +} + +func (p *Processor) ReadBool(value *bool) *Processor { + return p +} + +func (p *Processor) WriteInt8(value int8) *Processor { + p.buffer.WriteByte(byte(value)) + + return p +} + +func (p *Processor) WriteInt16(value int16) *Processor { + buf := make([]byte, 2) + + if p.Endian() == LittleEndian { + buf[0] = byte(value) + buf[1] = byte(value >> 8) + } else { + buf[0] = byte(value >> 8) + buf[1] = byte(value) + } + + p.buffer.Write(buf) + + return p +} + +func (p *Processor) WriteInt32(value int32) *Processor { + buf := make([]byte, 4) + + if p.Endian() == LittleEndian { + buf[0] = byte(value) + buf[1] = byte(value >> 8) + buf[2] = byte(value >> 16) + buf[3] = byte(value >> 24) + } else { + buf[0] = byte(value >> 24) + buf[1] = byte(value >> 16) + buf[2] = byte(value >> 8) + buf[3] = byte(value) + } + + p.buffer.Write(buf) + + return p +} + +func (p *Processor) WriteInt64(value int64) *Processor { + buf := make([]byte, 8) + + if p.Endian() == LittleEndian { + buf[0] = byte(value) + buf[1] = byte(value >> 8) + buf[2] = byte(value >> 16) + buf[3] = byte(value >> 24) + buf[4] = byte(value >> 32) + buf[5] = byte(value >> 40) + buf[6] = byte(value >> 48) + buf[7] = byte(value >> 56) + } else { + buf[0] = byte(value >> 56) + buf[1] = byte(value >> 48) + buf[2] = byte(value >> 40) + buf[3] = byte(value >> 32) + buf[4] = byte(value >> 24) + buf[5] = byte(value >> 16) + buf[6] = byte(value >> 8) + buf[7] = byte(value) + } + + p.buffer.Write(buf) + + return p +} + +func (p *Processor) WriteUint8(value uint8) *Processor { + p.buffer.WriteByte(byte(value)) + + return p +} + +func (p *Processor) WriteUint16(value uint16) *Processor { + buf := make([]byte, 2) + + if p.Endian() == LittleEndian { + buf[0] = byte(value) + buf[1] = byte(value >> 8) + } else { + buf[0] = byte(value >> 8) + buf[1] = byte(value) + } + + p.buffer.Write(buf) + + return p +} + +func (p *Processor) WriteUint32(value uint32) *Processor { + buf := make([]byte, 4) + + if p.Endian() == LittleEndian { + buf[0] = byte(value) + buf[1] = byte(value >> 8) + buf[2] = byte(value >> 16) + buf[3] = byte(value >> 24) + } else { + buf[0] = byte(value >> 24) + buf[1] = byte(value >> 16) + buf[2] = byte(value >> 8) + buf[3] = byte(value) + } + + p.buffer.Write(buf) + + return p +} + +func (p *Processor) WriteUint64(value uint64) *Processor { + buf := make([]byte, 8) + + if p.Endian() == LittleEndian { + buf[0] = byte(value) + buf[1] = byte(value >> 8) + buf[2] = byte(value >> 16) + buf[3] = byte(value >> 24) + buf[4] = byte(value >> 32) + buf[5] = byte(value >> 40) + buf[6] = byte(value >> 48) + buf[7] = byte(value >> 56) + } else { + buf[0] = byte(value >> 56) + buf[1] = byte(value >> 48) + buf[2] = byte(value >> 40) + buf[3] = byte(value >> 32) + buf[4] = byte(value >> 24) + buf[5] = byte(value >> 16) + buf[6] = byte(value >> 8) + buf[7] = byte(value) + } + + p.buffer.Write(buf) + + return p +} + +func (p *Processor) WriteFloat32(value float32) *Processor { + bitsFloat32 := math.Float32bits(value) + bufFloat32 := make([]byte, 4) + + if p.Endian() == LittleEndian { + binary.BigEndian.PutUint32(bufFloat32, bitsFloat32) + } else { + binary.LittleEndian.PutUint32(bufFloat32, bitsFloat32) + } + + p.buffer.Write(bufFloat32) + + return p +} + +func (p *Processor) WriteFloat64(value float64) *Processor { + bitsFloat64 := math.Float64bits(value) + bufFloat64 := make([]byte, 8) + + if p.Endian() == LittleEndian { + binary.BigEndian.PutUint64(bufFloat64, bitsFloat64) + } else { + binary.LittleEndian.PutUint64(bufFloat64, bitsFloat64) + } + + p.buffer.Write(bufFloat64) + + return p +} + +func (p *Processor) WriteString(value string) *Processor { + value += string([]byte{0x00}) + + // Write len header for string, 2 bytes + ln := len(value) + + buf := make([]byte, 2) + + if p.Endian() == LittleEndian { + buf[0] = byte(ln) + buf[1] = byte(ln >> 8) + } else { + buf[0] = byte(ln >> 8) + buf[1] = byte(ln) + } + + p.buffer.Write(buf) + + // Write string + p.buffer.WriteString(value) + + return p +} + +func (p *Processor) WriteByte(value byte) *Processor { + p.buffer.WriteByte(value) + + return p +} + +func (p *Processor) WriteBytes(value []byte) *Processor { + p.buffer.Write(value) + + return p +} + +func (p *Processor) WriteBool(value bool) *Processor { + var boolValue uint8 = 0 + + if value { + boolValue = 1 + } + + p.WriteUint8(boolValue) + + return p +} diff --git a/vendors/Nyarum/barrel/barrel_processor_test.go b/vendors/Nyarum/barrel/barrel_processor_test.go @@ -0,0 +1,81 @@ +package barrel + +import ( + "testing" +) + +func TestReadToStruct(t *testing.T) { + var TestStruct struct { + Id int32 + Level uint32 + HP uint32 + } + + netes := NewProcessor([]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04}) + if err := netes.ReadInt32(&TestStruct.Id).Error(); err != nil { + t.Errorf("%v - %v", "Error read from bytes to Id field", err) + } + + if err := netes.ReadUint32(&TestStruct.Level).Error(); err != nil { + t.Errorf("%v - %v", "Error read from bytes to Level field", err) + } + + if err := netes.ReadUint32(&TestStruct.HP).Error(); err != nil { + t.Errorf("%v - %v", "Error read from byte to HP field", err) + } +} + +func TestWriteFromStruct(t *testing.T) { + var TestStruct = struct { + Id int32 + Level uint32 + HP uint32 + }{ + 2, 3, 4, + } + + netes := NewProcessor([]byte{}) + if err := netes.WriteInt32(TestStruct.Id).Error(); err != nil { + t.Errorf("%v - %v", "Error write to buffer from Id field", err) + } + + if err := netes.WriteUint32(TestStruct.Level).Error(); err != nil { + t.Errorf("%v - %v", "Error write to buffer from Level field", err) + } + + if err := netes.WriteUint32(TestStruct.HP).Error(); err != nil { + t.Errorf("%v - %v", "Error write to buffer from HP field", err) + } +} + +func BenchmarkReadToStruct(b *testing.B) { + var TestStruct struct { + Id int32 + Level uint32 + HP uint32 + Name string + } + + netes := NewProcessor([]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x07, 0x4e, 0x79, 0x61, 0x72, 0x75, 0x6d, 0x00}) + + for n := 0; n < b.N; n++ { + netes.ReadInt32(&TestStruct.Id).ReadUint32(&TestStruct.Level).ReadUint32(&TestStruct.HP).ReadString(&TestStruct.Name) + } +} + +func BenchmarkWriteFromStruct(b *testing.B) { + var TestStruct = struct { + Id int32 + Level int32 + HP int32 + Name string + }{ + 2, 3, 4, "Nyarum", + } + + netes := NewProcessor([]byte{}) + + for n := 0; n < b.N; n++ { + netes.WriteInt32(TestStruct.Id).WriteInt32(TestStruct.Level).WriteInt32(TestStruct.HP).WriteString(TestStruct.Name) + } +} diff --git a/vendors/Nyarum/barrel/barrel_test.go b/vendors/Nyarum/barrel/barrel_test.go @@ -0,0 +1,76 @@ +package barrel + +import ( + "log" + "testing" +) + +type Packet struct { + ID int32 + Level uint32 + HP uint32 +} + +func (p *Packet) Default() { + p.ID = 2 + p.Level = 3 + p.HP = 4 +} + +func (p Packet) Check(stats *Stats) bool { + switch stats.NameField { + case "ID": + stats.Endian = BigEndian + case "Level": + case "HP": + } + + return true +} + +func TestBarrelPack(t *testing.T) { + barrel := NewBarrel() + packet := &Packet{} + load := barrel.Load(packet, []byte{}, true) + + err := barrel.Pack(load) + if err != nil { + t.Error(err) + } + + log.Printf("Buffer result: % x\n", barrel.Bytes()) +} + +func TestBarrelUnpack(t *testing.T) { + barrel := NewBarrel() + packet := &Packet{} + load := barrel.Load(packet, []byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04}, false) + + err := barrel.Unpack(load) + if err != nil { + t.Error(err) + } + + log.Println("Struct result:", packet) +} + +func BenchmarkBarrelPack(b *testing.B) { + barrel := NewBarrel() + packet := &Packet{} + + load := barrel.Load(packet, []byte{}, true) + + for i := 0; i < b.N; i++ { + barrel.Pack(load) + } +} + +func BenchmarkBarrelUnpack(b *testing.B) { + barrel := NewBarrel() + packet := &Packet{} + load := barrel.Load(packet, []byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04}, false) + + for i := 0; i < b.N; i++ { + barrel.Unpack(load) + } +} diff --git a/vendors/Nyarum/barrel/barrel_unpack.go b/vendors/Nyarum/barrel/barrel_unpack.go @@ -0,0 +1,98 @@ +package barrel + +import ( + "fmt" + "reflect" +) + +func (b *Barrel) Unpack(value reflect.Value) error { + switch value.Kind() { + case reflect.Struct: + for i := 0; i < value.NumField(); i++ { + valueType := value.Type().Field(i) + + b.Stats.NameField = valueType.Name + if !b.Object.Check(&b.Stats) { + continue + } + + if b.Stats.Endian == 1 { + b.processor.SetEndian(BigEndian) + } else if b.Stats.Endian == 0 { + b.processor.SetEndian(LittleEndian) + } + + b.numField = i + + err := b.Unpack(value.Field(i)) + if err != nil { + return err + } + } + case reflect.Uint8: + var valueFrom uint8 + b.processor.ReadUint8(&valueFrom) + + value.SetUint(uint64(valueFrom)) + case reflect.Int8: + var valueFrom int8 + b.processor.ReadInt8(&valueFrom) + + value.SetInt(int64(valueFrom)) + case reflect.Uint16: + + var valueFrom uint16 + b.processor.ReadUint16(&valueFrom) + + value.SetUint(uint64(valueFrom)) + case reflect.Int16: + var valueFrom int16 + b.processor.ReadInt16(&valueFrom) + + value.SetInt(int64(valueFrom)) + case reflect.Uint, reflect.Uint32: + var valueFrom uint32 + b.processor.ReadUint32(&valueFrom) + + value.SetUint(uint64(valueFrom)) + case reflect.Int, reflect.Int32: + var valueFrom int32 + b.processor.ReadInt32(&valueFrom) + + value.SetInt(int64(valueFrom)) + case reflect.Uint64: + var valueFrom uint64 + b.processor.ReadUint64(&valueFrom) + + value.SetUint(valueFrom) + case reflect.Int64: + var valueFrom int64 + b.processor.ReadInt64(&valueFrom) + + value.SetInt(valueFrom) + case reflect.String: + var valueFrom string + b.processor.ReadString(&valueFrom) + + value.SetString(valueFrom) + case reflect.Slice: + var valueFrom []byte + b.processor.ReadBytes(&valueFrom, b.Stats.LenSlice) + + value.SetBytes(valueFrom) + case reflect.Bool: + var valueFrom bool + b.processor.ReadBool(&valueFrom) + + value.SetBool(valueFrom) + case reflect.Interface: + err := b.Unpack(reflect.Indirect(value.Elem())) + if err != nil { + return err + } + default: + return fmt.Errorf("Type of object is incorrect.. It is - %v", value.Kind()) + } + + return nil +}