Golang Deco Enco

freebird92 · · 1869 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

mproto.go

package mproto

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"reflect"
	"strconv"
)

const (
	PT_GR_LUACOMMAND        uint32 = 9299
	PT_GC_CLEARFACEBOOKBIND uint32 = 32689
	PT_GC_CLEARDEVICEBIND   uint32 = 7445
	PT_GR_BANDACCOUNT       uint32 = 29536
)

type GR_LuaCommand struct {
	LuaCommand string `key:"21868"`
}

type GC_ClearFacebookBind struct {
	AccountId int32 `key:"512"`
}

func (o *GC_ClearFacebookBind) DecoStruct(dat []byte) {
	buffer := bytes.NewBuffer(dat)

	var fKey int16
	var fLen int16

	// 取KEY
	for nil == binary.Read(buffer, binary.LittleEndian, &fKey) {
		switch fKey {
		case 512:
			{
				binary.Read(buffer, binary.LittleEndian, &fLen)
				binary.Read(buffer, binary.LittleEndian, &o.AccountId)
			}
			break
		}
	}
}

type GR_BandAccount struct {
	//AccountId int32                  `key:"24137"`
	BandTime int64  `key:"23911"`
	Result   string `key:"27966"`
	NetIndex int8   `key:"11487"`

	NetOrder  int16                  `key:"585"`
	Something GC_ClearFacebookBind   `key:"1585"`
	Array     []GC_ClearFacebookBind `key:"1024"`
}

func (o *GR_BandAccount) DecoStruct(dat []byte) {
	buffer := bytes.NewBuffer(dat)
	var fKey int16
	var fLen int16

	// 取KEY
	for nil == binary.Read(buffer, binary.LittleEndian, &fKey) {
		switch fKey {
		case 1024:
			{
				binary.Read(buffer, binary.LittleEndian, &fLen)
				f := make([]byte, fLen)
				binary.Read(buffer, binary.LittleEndian, &f)
				var aGC_ClearFacebookBind GC_ClearFacebookBind = GC_ClearFacebookBind{}
				aGC_ClearFacebookBind.DecoStruct(f)
				o.Array = append(o.Array, aGC_ClearFacebookBind)
			}

		case 1585:
			{
				binary.Read(buffer, binary.LittleEndian, &fLen)
				f := make([]byte, fLen)
				binary.Read(buffer, binary.LittleEndian, &f)
				var aGC_ClearFacebookBind GC_ClearFacebookBind = GC_ClearFacebookBind{}
				aGC_ClearFacebookBind.DecoStruct(f)
				o.Something = aGC_ClearFacebookBind
			}
		case 23911:
			{
				binary.Read(buffer, binary.LittleEndian, &fLen)
				binary.Read(buffer, binary.LittleEndian, &o.BandTime)
			}
		case 27966:
			{
				binary.Read(buffer, binary.LittleEndian, &fLen)
				f := make([]byte, fLen)
				binary.Read(buffer, binary.LittleEndian, &f)
				o.Result = string(f)
			}
		case 11487:
			{
				binary.Read(buffer, binary.LittleEndian, &fLen)
				binary.Read(buffer, binary.LittleEndian, &o.NetIndex)
			}
		case 585:
			{
				binary.Read(buffer, binary.LittleEndian, &fLen)
				binary.Read(buffer, binary.LittleEndian, &o.NetOrder)
			}
		}
	}

}

func EncoStructSize(o interface{}) int32 {
	t := reflect.TypeOf(o)
	v := reflect.ValueOf(o)
	var size int32 = 0

	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)

		if f.Type.Kind() == reflect.Array || f.Type.Kind() == reflect.Slice {
			for j := 0; j < v.Field(i).Len(); j++ {

				if v.Field(i).Index(j).Kind() == reflect.String {
					strval, _ := v.Field(i).Index(j).Interface().(string)
					size += int32(len([]byte(strval)))
				} else if v.Field(i).Index(j).Kind() == reflect.Int8 {
					size += 5
				} else if v.Field(i).Index(j).Kind() == reflect.Int16 {
					size += 6
				} else if v.Field(i).Index(j).Kind() == reflect.Int32 {
					size += 8
				} else if v.Field(i).Index(j).Kind() == reflect.Int64 {
					size += 12
				} else if v.Field(i).Index(j).Kind() == reflect.Struct {
					size += (EncoStructSize(v.Field(i).Index(j).Interface()))
				} else {
					fmt.Printf("nothing2 %6s: %v = %v tag:%s \n", f.Name, f.Type, v.Field(i).Index(j).Interface(), f.Tag)
				}
			}
		} else {

			if f.Type.Kind() == reflect.String {
				strval, _ := v.Field(i).Interface().(string)
				size += int32(len([]byte(strval)))
			} else if f.Type.Kind() == reflect.Int8 {
				size += 5
			} else if f.Type.Kind() == reflect.Int16 {
				size += 6
			} else if f.Type.Kind() == reflect.Int32 {
				size += 8
			} else if f.Type.Kind() == reflect.Int64 {
				size += 12
			} else if f.Type.Kind() == reflect.Struct {
				size += (EncoStructSize(v.Field(i).Interface()))
			} else {
				fmt.Printf("nothing1 %6s: %v = %v tag:%s %s\n", f.Name, f.Type, v.Field(i).Interface(), f.Tag, f.Type.Kind().String())
			}
		}
	}
	return size
}

func EncoStruct(o interface{}) []byte {
	t := reflect.TypeOf(o)
	v := reflect.ValueOf(o)
	buffer := bytes.NewBuffer([]byte{})

	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)

		// KEY
		k, _ := strconv.Atoi(f.Tag.Get("key"))

		if f.Type.Kind() == reflect.Array || f.Type.Kind() == reflect.Slice {
			for j := 0; j < v.Field(i).Len(); j++ {
				binary.Write(buffer, binary.LittleEndian, int16(k))

				if v.Field(i).Index(j).Kind() == reflect.String {
					strval, _ := v.Field(i).Index(j).Interface().(string)
					// 长度
					binary.Write(buffer, binary.LittleEndian, int16(len([]byte(strval))))
					// 内容
					binary.Write(buffer, binary.LittleEndian, []byte(strval))
				} else if v.Field(i).Index(j).Kind() == reflect.Int8 {
					int8val, _ := v.Field(i).Index(j).Interface().(int8)
					// 长度
					binary.Write(buffer, binary.LittleEndian, int16(1))
					// 内容
					binary.Write(buffer, binary.LittleEndian, int8(int8val))
				} else if v.Field(i).Index(j).Kind() == reflect.Int16 {
					int16val, _ := v.Field(i).Index(j).Interface().(int16)
					// 长度
					binary.Write(buffer, binary.LittleEndian, int16(2))
					// 内容
					binary.Write(buffer, binary.LittleEndian, int16(int16val))
				} else if v.Field(i).Index(j).Kind() == reflect.Int32 {
					int32val, _ := v.Field(i).Index(j).Interface().(int32)
					// 长度
					binary.Write(buffer, binary.LittleEndian, int16(4))
					// 内容
					binary.Write(buffer, binary.LittleEndian, int32(int32val))
				} else if v.Field(i).Index(j).Kind() == reflect.Int64 {
					int64val, _ := v.Field(i).Index(j).Interface().(int64)
					// 长度
					binary.Write(buffer, binary.LittleEndian, int16(8))
					// 内容
					binary.Write(buffer, binary.LittleEndian, int64(int64val))
				} else if v.Field(i).Index(j).Kind() == reflect.Struct {
					// 长度
					binary.Write(buffer, binary.LittleEndian, int16(EncoStructSize(v.Field(i).Index(j).Interface())))
					// 内容
					binary.Write(buffer, binary.LittleEndian, EncoStruct(v.Field(i).Index(j).Interface()))
				} else {
					fmt.Printf("nothing3 %6s: %v = %v tag:%s %s\n", f.Name, f.Type, v.Field(i).Index(j).Interface(), f.Tag, f.Type.Kind().String())
				}
			}
		} else {
			binary.Write(buffer, binary.LittleEndian, int16(k))
			val := v.Field(i).Interface()
			if f.Type.Kind() == reflect.String {
				strval, _ := val.(string)
				// 长度
				binary.Write(buffer, binary.LittleEndian, int16(len([]byte(strval))))
				// 内容
				binary.Write(buffer, binary.LittleEndian, []byte(strval))
			} else if f.Type.Kind() == reflect.Int8 {
				int8val, _ := val.(int8)
				// 长度
				binary.Write(buffer, binary.LittleEndian, int16(1))
				// 内容
				binary.Write(buffer, binary.LittleEndian, int8(int8val))
			} else if f.Type.Kind() == reflect.Int16 {
				int16val, _ := val.(int16)
				// 长度
				binary.Write(buffer, binary.LittleEndian, int16(2))
				// 内容
				binary.Write(buffer, binary.LittleEndian, int16(int16val))
			} else if f.Type.Kind() == reflect.Int32 {
				int32val, _ := val.(int32)
				// 长度
				binary.Write(buffer, binary.LittleEndian, int16(4))
				// 内容
				binary.Write(buffer, binary.LittleEndian, int32(int32val))
			} else if f.Type.Kind() == reflect.Int64 {
				int64val, _ := val.(int64)
				// 长度
				binary.Write(buffer, binary.LittleEndian, int16(8))
				// 内容
				binary.Write(buffer, binary.LittleEndian, int64(int64val))
			} else if f.Type.Kind() == reflect.Struct {
				// 长度
				binary.Write(buffer, binary.LittleEndian, int16(EncoStructSize(val)))
				// 内容
				binary.Write(buffer, binary.LittleEndian, EncoStruct(val))
			} else {
				fmt.Printf("nothing4 %6s: %v = %v tag:%s %s\n", f.Name, f.Type, val, f.Tag, f.Type.Kind().String())
			}
		}

	}
	return buffer.Bytes()
}

 main.go

package main

import (
	"./mproto"
	"fmt"
)

func main() {
	var gr mproto.GR_BandAccount
	var gc mproto.GC_ClearFacebookBind
	var t mproto.GR_BandAccount = mproto.GR_BandAccount{}
	gc.AccountId = 4096
	gr.BandTime = 111
	gr.Something.AccountId = 32
	gr.NetIndex = 4
	gr.NetOrder = 5
	gr.Result = "abc中车"
	gr.Array = append(gr.Array, gc)
	fmt.Println(gr)
	b := mproto.EncoStruct(gr)
	t.DecoStruct(b)
	fmt.Println(t)
}

 


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:freebird92

查看原文:Golang Deco Enco

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1869 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传