close

處理Packet免不了就是對Byte陣列處理的需求,因為意外的找不到已經寫好的來用,乾脆土炮了一份。

因為純粹是用C/C++的作法土法煉鋼出來的,假如在Golang上有比較適切的作法還請指教修正

package utility

import (
    "bufio"
    "bytes"
    "fmt"
    "encoding/binary"
)

//BinaryReader :
type BinaryReader struct {
    _reader *bytes.Reader
    _offset int
}

//Init :
func (p *BinaryReader) Init(bs []byte) {
    p._reader = bytes.NewReader(bs)
    p._offset = 0
}

//ReadInt16 :
func (p *BinaryReader) ReadInt16() int {
    bs := make([]byte, 2)
    _, err := p._reader.ReadAt(bs, int64(p._offset))
    if err != nil {
        return 0
    }
    p._offset += 2
    return BytesToInt16(bs)
}

//ReadInt :
func (p *BinaryReader) ReadInt() int {
    bs := make([]byte, 4)
    _, err := p._reader.ReadAt(bs, int64(p._offset))
    if err != nil {
        return 0
    }
    p._offset += 4
    return BytesToInt(bs)
}

//ReadUInt :
func (p *BinaryReader) ReadUInt() uint32 {
    bs := make([]byte, 4)
    _, err := p._reader.ReadAt(bs, int64(p._offset))
    if err != nil {
        return 0
    }
    p._offset += 4
    return BytesToUInt(bs)
}

//ReadBytes :
func (p *BinaryReader) ReadBytes(length int) []byte {
    if length <= 0 {
        return nil
    }
    bs := make([]byte, length)
    _, err := p._reader.ReadAt(bs, int64(p._offset))
    if err != nil {
        return nil
    }
    p._offset += length
    return bs
}

//ReadString :
func (p *BinaryReader) ReadString() string {
    length := p.ReadInt()
    if length <= 0 {
        return ""
    }

    bs := p.ReadBytes(length)
    return BytesToString(bs)
}

//NewBinaryReader :Construtor for BinaryReader
func NewBinaryReader(bs []byte) *BinaryReader {
    reader := &BinaryReader{}
    reader.Init(bs)
    return reader
}

//BinaryWriter :
type BinaryWriter struct {
    _buffer bytes.Buffer
    _writer *bufio.Writer
}

//Init :
func (p *BinaryWriter) Init() {
    p._writer = bufio.NewWriter(&p._buffer)
}

//ToBytes :
func (p *BinaryWriter) ToBytes() []byte {
    p._writer.Flush()
    return p._buffer.Bytes()
}

//WriteInt16 :
func (p *BinaryWriter) WriteInt16(value int16) {
    bs := Int16ToBytes(value)
    p._writer.Write(bs)
}

//WriteInt :
func (p *BinaryWriter) WriteInt(value int) {
    bs := IntToBytes(value)
    p._writer.Write(bs)
}

//WriteUInt :
func (p *BinaryWriter) WriteUInt(value uint32) {
    bs := UIntToBytes(value)
    p._writer.Write(bs)
}

//WriteBytes :
func (p *BinaryWriter) WriteBytes(bytes []byte) {
    length := len(bytes)
    p.WriteInt(length)
    p._writer.Write(bytes)
}

//WriteString :
func (p *BinaryWriter) WriteString(str string) {
    tmp := StringToBytes(str)
    p.WriteBytes(tmp)
}

//Write :
func (p *BinaryWriter) Write(value interface{}) {
    switch value.(type) {
    default:
        fmt.Println("Not supported type.")
    case int16:
        p.WriteInt16(value.(int16))
    case int:
        p.WriteInt(value.(int))
    case uint32:
        p.WriteUInt(value.(uint32))
    case []byte:
        p.WriteBytes(value.([]byte))
    case string:
        p.WriteString(value.(string))
    }
}

//NewBinaryWriter :Construtor for BinaryWriter
func NewBinaryWriter() *BinaryWriter {
    writer := &BinaryWriter{}
    writer.Init()
    return writer
}

//IntToBytes :Turn int type to bytes
func IntToBytes(value int) []byte {
    bs := make([]byte, 4)
    binary.LittleEndian.PutUint32(bs, uint32(value))
    return bs
}

//BytesToInt :Turn bytes to int type
func BytesToInt(bs []byte) int {
    value := int(binary.LittleEndian.Uint32(bs))
    return value
}

//UIntToBytes :Turn uint type to bytes
func UIntToBytes(value uint32) []byte {
    bs := make([]byte, 4)
    binary.LittleEndian.PutUint32(bs, value)
    return bs
}

//BytesToUInt :Turn bytes to uint type
func BytesToUInt(bs []byte) uint32 {
    value := binary.LittleEndian.Uint32(bs)
    return value
}

//Int16ToBytes :Turn int16 type to bytes
func Int16ToBytes(value int16) []byte {
    bs := make([]byte, 2)
    binary.LittleEndian.PutUint16(bs, uint16(value))
    return bs
}

//BytesToInt :Turn bytes to int type
func BytesToInt16(bs []byte) int {
    value := int(binary.LittleEndian.Uint16(bs))
    return value
}

//StringToBytes :Turn string type to bytes
func StringToBytes(str string) []byte {
    bs := []byte(str)
    return bs
}

//BytesToString :Turn bytes to string type
func BytesToString(bs []byte) string {
    str := string(bs)
    return str
}


稍微測試一下,有正確的印出寫入的內容

writer := util.NewBinaryWriter()
writer.WriteInt(5)
writer.WriteString("Hello World!")
writer.WriteInt(10)
writer.WriteString("BIG5 雙字元")
writer.WriteString("JIS アメジストワーム")
 
reader := util.NewBinaryReader(writer.ToBytes())
fmt.Println(reader.ReadInt())
fmt.Println(reader.ReadString())
fmt.Println(reader.ReadInt())
fmt.Println(reader.ReadString())
fmt.Println(reader.ReadString())
 
下一篇:
arrow
arrow
    文章標籤
    golang binaryreader binarywriter
    全站熱搜

    不來嗯 發表在 痞客邦 留言(0) 人氣()