go-ethereum/p2p/message.go

76 lines
1.7 KiB
Go
Raw Normal View History

2014-10-23 18:57:54 +03:00
package p2p
import (
// "fmt"
"github.com/ethereum/go-ethereum/ethutil"
2014-10-23 18:57:54 +03:00
)
type MsgCode uint8
type Msg struct {
code MsgCode // this is the raw code as per adaptive msg code scheme
data *ethutil.Value
encoded []byte
}
func (self *Msg) Code() MsgCode {
return self.code
}
func (self *Msg) Data() *ethutil.Value {
return self.data
}
func NewMsg(code MsgCode, params ...interface{}) (msg *Msg, err error) {
// // data := [][]interface{}{}
// data := []interface{}{}
// for _, value := range params {
// if encodable, ok := value.(ethutil.RlpEncodeDecode); ok {
// data = append(data, encodable.RlpValue())
// } else if raw, ok := value.([]interface{}); ok {
// data = append(data, raw)
// } else {
// // data = append(data, interface{}(raw))
// err = fmt.Errorf("Unable to encode object of type %T", value)
// return
// }
// }
return &Msg{
code: code,
data: ethutil.NewValue(interface{}(params)),
}, nil
}
func NewMsgFromBytes(encoded []byte) (msg *Msg, err error) {
value := ethutil.NewValueFromBytes(encoded)
// Type of message
code := value.Get(0).Uint()
// Actual data
data := value.SliceFrom(1)
msg = &Msg{
code: MsgCode(code),
data: data,
// data: ethutil.NewValue(data),
encoded: encoded,
}
return
}
func (self *Msg) Decode(offset MsgCode) {
self.code = self.code - offset
}
// encode takes an offset argument to implement adaptive message coding
// the encoded message is memoized to make msgs relayed to several peers more efficient
func (self *Msg) Encode(offset MsgCode) (res []byte) {
if len(self.encoded) == 0 {
res = ethutil.NewValue(append([]interface{}{byte(self.code + offset)}, self.data.Slice()...)).Encode()
self.encoded = res
} else {
res = self.encoded
}
return
}