You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: raw.go
    path of file: ./repos/Stowaway/protocol
    
    the code of the file until where you have to start completion: package protocol

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
	"net"
	"reflect"

	"Stowaway/crypto"
)

type RawMessage struct {
	// Essential component to apply a Message
	UUID         string
	Conn         net.Conn
	CryptoSecret []byte
	// Prepared buffer
	HeaderBuffer []byte
	DataBuffer   []byte
}

func (message *RawMessage) ConstructHeader() {}

func (message *RawMessage) ConstructData(header *Header, mess interface{}, isPass bool) {
	var headerBuffer, dataBuffer bytes.Buffer
	// First, construct own header
	messageTypeBuf := make([]byte, 2)
	routeLenBuf := make([]byte, 4)

	binary.BigEndian.PutUint16(messageTypeBuf, header.MessageType)
	binary.BigEndian.PutUint32(routeLenBuf, header.RouteLen)

	// Write header into buffer(except for dataLen)
	headerBuffer.Write([]byte(header.Sender))
	headerBuffer.Write([]byte(header.Accepter))
	headerBuffer.Write(messageTypeBuf)
	headerBuffer.Write(routeLenBuf)
	headerBuffer.Write([]byte(header.Route))

	// Check if message's data is needed to encrypt
	if !isPass {
		// Use reflect to construct data,optimize the code,thx to the idea from @lz520520
		messType := reflect.TypeOf(mess).Elem()
		messValue := reflect.ValueOf(mess).Elem()

		messFieldNum := messType.NumField()

		for i := 0; i < mess
    
func (message *RawMessage) ConstructData(header *Header, mess interface{}, isPass bool) {
	var headerBuffer, dataBuffer bytes.Buffer
	// First, construct own header
	messageTypeBuf := make([]byte, 2)
	routeLenBuf := make([]byte, 4)

	binary.BigEndian.PutUint16(messageTypeBuf, header.MessageType)
	binary.BigEndian.PutUint32(routeLenBuf, header.RouteLen)

	// Write header into buffer(except for dataLen)
	headerBuffer.Write([]byte(header.Sender))
	headerBuffer.Write([]byte(header.Accepter))
	headerBuffer.Write(messageTypeBuf)
	headerBuffer.Write(routeLenBuf)
	headerBuffer.Write([]byte(header.Route))

	// Check if message's data is needed to encrypt
	if !isPass {
		// Use reflect to construct data,optimize the code,thx to the idea from @lz520520
		messType := reflect.TypeOf(mess).Elem()
		messValue := reflect.ValueOf(mess).Elem()

		messFieldNum := messType.NumField()

		for i := 0; i < messFieldNum; i++ {
			inter := messValue.Field(i).Interface()

			switch value := inter.(type) {
			case string:
				dataBuffer.Write([]byte(value))
			case uint16:
				buffer := make([]byte, 2)
				binary.BigEndian.PutUint16(buffer, value)
				dataBuffer.Write(buffer)
			case uint32:
				buffer := make([]byte, 4)
				binary.BigEndian.PutUint32(buffer, value)
				dataBuffer.Write(buffer)
			case uint64:
				buffer := make([]byte, 8)
				binary.BigEndian.PutUint64(buffer, value)
				dataBuffer.Write(buffer)
			case []byte:
				dataBuffer.Write(value)
			}
		}
	} else {
		mmess := mess.([]byte)
		dataBuffer.Write(mmess)
	}

	message.DataBuffer = dataBuffer.Bytes()
	// Encrypt&Compress data
	if !isPass {
		message.DataBuffer = crypto.GzipCompress(message.DataBuffer)
		message.DataBuffer = crypto.AESEncrypt(message.DataBuffer, message.CryptoSecret)
	}
	// Calculate the whole data's length
	dataLenBuf := make([]byte, 8)
	binary.BigEndian.PutUint64(dataLenBuf, uint64(len(message.DataBuffer)))
	headerBuffer.Write(dataLenBuf)
	message.HeaderBuffer = headerBuffer.Bytes()
}