publish.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package packets
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/pborman/uuid"
  6. "io"
  7. )
  8. //PublishPacket is an internal representation of the fields of the
  9. //Publish MQTT packet
  10. type PublishPacket struct {
  11. FixedHeader
  12. TopicName string
  13. MessageID uint16
  14. Payload []byte
  15. uuid uuid.UUID
  16. }
  17. func (p *PublishPacket) String() string {
  18. str := fmt.Sprintf("%s\n", p.FixedHeader)
  19. str += fmt.Sprintf("topicName: %s MessageID: %d\n", p.TopicName, p.MessageID)
  20. str += fmt.Sprintf("payload: %s\n", string(p.Payload))
  21. return str
  22. }
  23. func (p *PublishPacket) Write(w io.Writer) error {
  24. var body bytes.Buffer
  25. var err error
  26. body.Write(encodeString(p.TopicName))
  27. if p.Qos > 0 {
  28. body.Write(encodeUint16(p.MessageID))
  29. }
  30. p.FixedHeader.RemainingLength = body.Len() + len(p.Payload)
  31. packet := p.FixedHeader.pack()
  32. packet.Write(body.Bytes())
  33. packet.Write(p.Payload)
  34. _, err = w.Write(packet.Bytes())
  35. return err
  36. }
  37. //Unpack decodes the details of a ControlPacket after the fixed
  38. //header has been read
  39. func (p *PublishPacket) Unpack(b io.Reader) {
  40. var payloadLength = p.FixedHeader.RemainingLength
  41. p.TopicName = decodeString(b)
  42. if p.Qos > 0 {
  43. p.MessageID = decodeUint16(b)
  44. payloadLength -= len(p.TopicName) + 4
  45. } else {
  46. payloadLength -= len(p.TopicName) + 2
  47. }
  48. p.Payload = make([]byte, payloadLength)
  49. b.Read(p.Payload)
  50. }
  51. //Copy creates a new PublishPacket with the same topic and payload
  52. //but an empty fixed header, useful for when you want to deliver
  53. //a message with different properties such as Qos but the same
  54. //content
  55. func (p *PublishPacket) Copy() *PublishPacket {
  56. newP := NewControlPacket(Publish).(*PublishPacket)
  57. newP.TopicName = p.TopicName
  58. newP.Payload = p.Payload
  59. return newP
  60. }
  61. //Details returns a Details struct containing the Qos and
  62. //MessageID of this ControlPacket
  63. func (p *PublishPacket) Details() Details {
  64. return Details{Qos: p.Qos, MessageID: p.MessageID}
  65. }
  66. //UUID returns the unique ID assigned to the ControlPacket when
  67. //it was originally received. Note: this is not related to the
  68. //MessageID field for MQTT packets
  69. func (p *PublishPacket) UUID() uuid.UUID {
  70. return p.uuid
  71. }