2019-08-23 10:53:36 +00:00
|
|
|
|
package common
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"encoding/binary"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"github.com/cnlh/nps/lib/pool"
|
|
|
|
|
"io"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type NetPackager interface {
|
|
|
|
|
Pack(writer io.Writer) (err error)
|
|
|
|
|
UnPack(reader io.Reader) (err error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type BasePackager struct {
|
|
|
|
|
Length uint32
|
|
|
|
|
Content []byte
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *BasePackager) NewPac(contents ...interface{}) (err error) {
|
2019-08-26 15:29:22 +00:00
|
|
|
|
Self.Content = pool.CopyBuff.Get()
|
2019-08-23 10:53:36 +00:00
|
|
|
|
Self.clean()
|
|
|
|
|
for _, content := range contents {
|
|
|
|
|
switch content.(type) {
|
|
|
|
|
case nil:
|
|
|
|
|
Self.Content = Self.Content[:0]
|
|
|
|
|
case []byte:
|
2019-08-27 12:07:37 +00:00
|
|
|
|
err = Self.appendByte(content.([]byte))
|
2019-08-23 10:53:36 +00:00
|
|
|
|
case string:
|
2019-08-27 12:07:37 +00:00
|
|
|
|
err = Self.appendByte([]byte(content.(string)))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err = Self.appendByte([]byte(CONN_DATA_SEQ))
|
2019-08-23 10:53:36 +00:00
|
|
|
|
default:
|
|
|
|
|
err = Self.marshal(content)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Self.setLength()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-27 12:07:37 +00:00
|
|
|
|
func (Self *BasePackager) appendByte(data []byte) (err error) {
|
|
|
|
|
m := len(Self.Content)
|
|
|
|
|
n := m + len(data)
|
|
|
|
|
if n <= cap(Self.Content) {
|
|
|
|
|
Self.Content = Self.Content[0:n] // grow the length for copy
|
|
|
|
|
copy(Self.Content[m:n], data)
|
|
|
|
|
return nil
|
|
|
|
|
} else {
|
|
|
|
|
return bytes.ErrTooLarge
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-23 10:53:36 +00:00
|
|
|
|
//似乎这里涉及到父类作用域问题,当子类调用父类的方法时,其struct仅仅为父类的
|
|
|
|
|
func (Self *BasePackager) Pack(writer io.Writer) (err error) {
|
|
|
|
|
err = binary.Write(writer, binary.LittleEndian, Self.Length)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err = binary.Write(writer, binary.LittleEndian, Self.Content)
|
2019-08-26 15:29:22 +00:00
|
|
|
|
pool.CopyBuff.Put(Self.Content)
|
2019-08-23 10:53:36 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Unpack 会导致传入的数字类型转化成float64!!
|
|
|
|
|
//主要原因是json unmarshal并未传入正确的数据类型
|
|
|
|
|
func (Self *BasePackager) UnPack(reader io.Reader) (err error) {
|
2019-08-27 12:07:37 +00:00
|
|
|
|
Self.Content = pool.CopyBuff.Get()
|
2019-08-26 10:47:23 +00:00
|
|
|
|
Self.clean()
|
2019-08-23 10:53:36 +00:00
|
|
|
|
err = binary.Read(reader, binary.LittleEndian, &Self.Length)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
Self.Content = Self.Content[:Self.Length]
|
|
|
|
|
//n, err := io.ReadFull(reader, Self.Content)
|
|
|
|
|
//if n != int(Self.Length) {
|
|
|
|
|
// err = io.ErrUnexpectedEOF
|
|
|
|
|
//}
|
2019-08-26 15:29:22 +00:00
|
|
|
|
err = binary.Read(reader, binary.LittleEndian, Self.Content)
|
2019-08-23 10:53:36 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *BasePackager) marshal(content interface{}) (err error) {
|
|
|
|
|
tmp, err := json.Marshal(content)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2019-08-27 12:07:37 +00:00
|
|
|
|
err = Self.appendByte(tmp)
|
2019-08-23 10:53:36 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *BasePackager) Unmarshal(content interface{}) (err error) {
|
|
|
|
|
err = json.Unmarshal(Self.Content, content)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *BasePackager) setLength() {
|
|
|
|
|
Self.Length = uint32(len(Self.Content))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *BasePackager) clean() {
|
|
|
|
|
Self.Length = 0
|
2019-08-27 12:07:37 +00:00
|
|
|
|
Self.Content = Self.Content[:0] // reset length
|
2019-08-23 10:53:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *BasePackager) Split() (strList []string) {
|
|
|
|
|
n := bytes.IndexByte(Self.Content, 0)
|
|
|
|
|
strList = strings.Split(string(Self.Content[:n]), CONN_DATA_SEQ)
|
|
|
|
|
strList = strList[0 : len(strList)-1]
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ConnPackager struct { // Todo
|
|
|
|
|
ConnType uint8
|
|
|
|
|
BasePackager
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *ConnPackager) NewPac(connType uint8, content ...interface{}) (err error) {
|
|
|
|
|
Self.ConnType = connType
|
|
|
|
|
err = Self.BasePackager.NewPac(content...)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *ConnPackager) Pack(writer io.Writer) (err error) {
|
|
|
|
|
err = binary.Write(writer, binary.LittleEndian, Self.ConnType)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err = Self.BasePackager.Pack(writer)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *ConnPackager) UnPack(reader io.Reader) (err error) {
|
|
|
|
|
err = binary.Read(reader, binary.LittleEndian, &Self.ConnType)
|
|
|
|
|
if err != nil && err != io.EOF {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err = Self.BasePackager.UnPack(reader)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type MuxPackager struct {
|
|
|
|
|
Flag uint8
|
|
|
|
|
Id int32
|
|
|
|
|
BasePackager
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *MuxPackager) NewPac(flag uint8, id int32, content ...interface{}) (err error) {
|
|
|
|
|
Self.Flag = flag
|
|
|
|
|
Self.Id = id
|
|
|
|
|
if flag == MUX_NEW_MSG {
|
|
|
|
|
err = Self.BasePackager.NewPac(content...)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *MuxPackager) Pack(writer io.Writer) (err error) {
|
|
|
|
|
err = binary.Write(writer, binary.LittleEndian, Self.Flag)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err = binary.Write(writer, binary.LittleEndian, Self.Id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if Self.Flag == MUX_NEW_MSG {
|
|
|
|
|
err = Self.BasePackager.Pack(writer)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (Self *MuxPackager) UnPack(reader io.Reader) (err error) {
|
|
|
|
|
err = binary.Read(reader, binary.LittleEndian, &Self.Flag)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err = binary.Read(reader, binary.LittleEndian, &Self.Id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if Self.Flag == MUX_NEW_MSG {
|
|
|
|
|
err = Self.BasePackager.UnPack(reader)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|