Golang Deco Enco

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)

}

 

你可能感兴趣的:(golang)