123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- package b1
- import (
- "encoding/binary"
- "fmt"
- "io"
- )
- type Wire struct {
- Len uint8
- Text [127]rune
- }
- func MakeWire(s string) Wire {
- l := len(s)
- ss := Wire{}
- if l > len(ss.Text) {
- l = len(ss.Text)
- }
- ss.Len = uint8(l)
- copy(ss.Text[:], ([]rune(s))[0:l])
- return ss
- }
- func (ss Wire) String() string {
- return string(ss.Text[:ss.Len])
- }
- type Attr struct {
- Name Wire
- Value Wire
- }
- type MessageHeader struct {
- Kind int64
- From int64
- To int64
- Method Wire
- AttrCount int8
- BodyLength int64
- }
- type Message struct {
- MessageHeader
- attrs []Attr
- body []byte
- }
- func (m Message) MarshalTo(w io.Writer) error {
- err := binary.Write(w, binary.LittleEndian, m.MessageHeader)
- if err != nil {
- return err
- }
- for i := 0; i < int(m.AttrCount) && i < len(m.attrs); i++ {
- attr := m.attrs[i]
- err = binary.Write(w, binary.LittleEndian, attr)
- if err != nil {
- return err
- }
- }
- if m.BodyLength > 0 {
- l, err := w.Write(m.body[0:m.BodyLength])
- if l != int(m.BodyLength) {
- return fmt.Errorf("Message partial write: %d %d", l, m.BodyLength)
- }
- return err
- }
- return nil
- }
- func (m *Message) UnmarshalFrom(w io.Reader) error {
- err := binary.Read(w, binary.LittleEndian, &m.MessageHeader)
- if err != nil {
- return err
- }
- if m.AttrCount < 0 {
- return fmt.Errorf("Negative attr count.")
- }
- if m.BodyLength > (2 << 16) {
- return fmt.Errorf("Body too long.")
- }
- m.attrs = make([]Attr, m.AttrCount)
- m.body = make([]byte, m.BodyLength)
- for i := 0; i < int(m.AttrCount); i++ {
- err = binary.Read(w, binary.LittleEndian, &m.attrs[i])
- if err != nil {
- return err
- }
- }
- if m.BodyLength > 0 {
- l, err := w.Read(m.body)
- if l != int(m.BodyLength) {
- return fmt.Errorf("Message partial read: %d %d", l, m.BodyLength)
- }
- return err
- }
- return nil
- }
- func MakeMessage(kind, from, to int64, method string, body []byte, attrs ...string) Message {
- mh := MessageHeader{kind, from, to, MakeWire(method), int8(len(attrs) / 2), int64(len(body))}
- mm := Message{}
- mm.MessageHeader = mh
- mm.attrs = make([]Attr, len(attrs)/2)
- for i := 1; i < len(attrs); i += 2 {
- mm.attrs[i/2] = Attr{MakeWire(attrs[i-1]), MakeWire(attrs[i])}
- }
- mm.body = body
- return mm
- }
|