nps/lib/common/netpackager.go

213 lines
4.9 KiB
Go
Raw Normal View History

2019-08-23 10:53:36 +00:00
package common
import (
"bytes"
"encoding/binary"
"encoding/json"
"errors"
"github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
2019-08-23 10:53:36 +00:00
"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) {
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 {
logs.Warn(len(data), len(Self.Content), cap(Self.Content))
return errors.New("pack content too large")
2019-08-27 12:07:37 +00:00
}
}
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)
return
}
//Unpack 会导致传入的数字类型转化成float64
//主要原因是json unmarshal并未传入正确的数据类型
func (Self *BasePackager) UnPack(reader io.Reader) (err error) {
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
}
if int(Self.Length) > cap(Self.Content) {
logs.Warn("unpack", cap(Self.Content))
err = errors.New("unpack err, content length too large")
}
Self.Content = Self.Content[:int(Self.Length)]
2019-08-23 10:53:36 +00:00
//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 {
2019-09-08 15:49:16 +00:00
Flag uint8
Id int32
Window uint16
2019-08-23 10:53:36 +00:00
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...)
}
2019-09-08 15:49:16 +00:00
if flag == MUX_MSG_SEND_OK {
// MUX_MSG_SEND_OK only allows one data
switch content[0].(type) {
case int:
Self.Window = uint16(content[0].(int))
case uint16:
Self.Window = content[0].(uint16)
}
}
2019-08-23 10:53:36 +00:00
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)
}
2019-09-08 15:49:16 +00:00
if Self.Flag == MUX_MSG_SEND_OK {
err = binary.Write(writer, binary.LittleEndian, Self.Window)
}
2019-08-23 10:53:36 +00:00
return
}
func (Self *MuxPackager) UnPack(reader io.Reader) (err error) {
Self.BasePackager.clean() // also clean the content
2019-08-23 10:53:36 +00:00
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)
}
2019-09-08 15:49:16 +00:00
if Self.Flag == MUX_MSG_SEND_OK {
err = binary.Read(reader, binary.LittleEndian, &Self.Window)
}
2019-08-23 10:53:36 +00:00
return
}