message.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package b1
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "io"
  6. )
  7. type Wire struct {
  8. Len uint8
  9. Text [127]rune
  10. }
  11. func MakeWire(s string) Wire {
  12. l := len(s)
  13. ss := Wire{}
  14. if l > len(ss.Text) {
  15. l = len(ss.Text)
  16. }
  17. ss.Len = uint8(l)
  18. copy(ss.Text[:], ([]rune(s))[0:l])
  19. return ss
  20. }
  21. func (ss Wire) String() string {
  22. return string(ss.Text[:ss.Len])
  23. }
  24. type Attr struct {
  25. Name Wire
  26. Value Wire
  27. }
  28. type MessageHeader struct {
  29. Kind int64
  30. From int64
  31. To int64
  32. Method Wire
  33. AttrCount int8
  34. BodyLength int64
  35. }
  36. type Message struct {
  37. MessageHeader
  38. attrs []Attr
  39. body []byte
  40. }
  41. func (m Message) MarshalTo(w io.Writer) error {
  42. err := binary.Write(w, binary.LittleEndian, m.MessageHeader)
  43. if err != nil {
  44. return err
  45. }
  46. for i := 0; i < int(m.AttrCount) && i < len(m.attrs); i++ {
  47. attr := m.attrs[i]
  48. err = binary.Write(w, binary.LittleEndian, attr)
  49. if err != nil {
  50. return err
  51. }
  52. }
  53. if m.BodyLength > 0 {
  54. l, err := w.Write(m.body[0:m.BodyLength])
  55. if l != int(m.BodyLength) {
  56. return fmt.Errorf("Message partial write: %d %d", l, m.BodyLength)
  57. }
  58. return err
  59. }
  60. return nil
  61. }
  62. func (m *Message) UnmarshalFrom(w io.Reader) error {
  63. err := binary.Read(w, binary.LittleEndian, &m.MessageHeader)
  64. if err != nil {
  65. return err
  66. }
  67. if m.AttrCount < 0 {
  68. return fmt.Errorf("Negative attr count.")
  69. }
  70. if m.BodyLength > (2 << 16) {
  71. return fmt.Errorf("Body too long.")
  72. }
  73. m.attrs = make([]Attr, m.AttrCount)
  74. m.body = make([]byte, m.BodyLength)
  75. for i := 0; i < int(m.AttrCount); i++ {
  76. err = binary.Read(w, binary.LittleEndian, &m.attrs[i])
  77. if err != nil {
  78. return err
  79. }
  80. }
  81. if m.BodyLength > 0 {
  82. l, err := w.Read(m.body)
  83. if l != int(m.BodyLength) {
  84. return fmt.Errorf("Message partial read: %d %d", l, m.BodyLength)
  85. }
  86. return err
  87. }
  88. return nil
  89. }
  90. func MakeMessage(kind, from, to int64, method string, body []byte, attrs ...string) Message {
  91. mh := MessageHeader{kind, from, to, MakeWire(method), int8(len(attrs) / 2), int64(len(body))}
  92. mm := Message{}
  93. mm.MessageHeader = mh
  94. mm.attrs = make([]Attr, len(attrs)/2)
  95. for i := 1; i < len(attrs); i += 2 {
  96. mm.attrs[i/2] = Attr{MakeWire(attrs[i-1]), MakeWire(attrs[i])}
  97. }
  98. mm.body = body
  99. return mm
  100. }