node.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package binary
  2. import (
  3. "fmt"
  4. pb "github.com/Rhymen/go-whatsapp/binary/proto"
  5. "github.com/golang/protobuf/proto"
  6. )
  7. type Node struct {
  8. Description string
  9. Attributes map[string]string
  10. Content interface{}
  11. }
  12. func Marshal(n Node) ([]byte, error) {
  13. if n.Attributes != nil && n.Content != nil {
  14. a, err := marshalMessageArray(n.Content.([]interface{}))
  15. if err != nil {
  16. return nil, err
  17. }
  18. n.Content = a
  19. }
  20. w := NewEncoder()
  21. if err := w.WriteNode(n); err != nil {
  22. return nil, err
  23. }
  24. return w.GetData(), nil
  25. }
  26. func marshalMessageArray(messages []interface{}) ([]Node, error) {
  27. ret := make([]Node, len(messages))
  28. for i, m := range messages {
  29. if wmi, ok := m.(*pb.WebMessageInfo); ok {
  30. b, err := marshalWebMessageInfo(wmi)
  31. if err != nil {
  32. return nil, nil
  33. }
  34. ret[i] = Node{"message", nil, b}
  35. } else {
  36. ret[i], ok = m.(Node)
  37. if !ok {
  38. return nil, fmt.Errorf("invalid Node")
  39. }
  40. }
  41. }
  42. return ret, nil
  43. }
  44. func marshalWebMessageInfo(p *pb.WebMessageInfo) ([]byte, error) {
  45. b, err := proto.Marshal(p)
  46. if err != nil {
  47. return nil, err
  48. }
  49. return b, nil
  50. }
  51. func Unmarshal(data []byte) (*Node, error) {
  52. r := NewDecoder(data)
  53. n, err := r.ReadNode()
  54. if err != nil {
  55. return nil, err
  56. }
  57. if n != nil && n.Attributes != nil && n.Content != nil {
  58. n.Content, err = unmarshalMessageArray(n.Content.([]Node))
  59. if err != nil {
  60. return nil, err
  61. }
  62. }
  63. return n, nil
  64. }
  65. func unmarshalMessageArray(messages []Node) ([]interface{}, error) {
  66. ret := make([]interface{}, len(messages))
  67. for i, msg := range messages {
  68. if msg.Description == "message" {
  69. info, err := unmarshalWebMessageInfo(msg.Content.([]byte))
  70. if err != nil {
  71. return nil, err
  72. }
  73. ret[i] = info
  74. } else {
  75. ret[i] = msg
  76. }
  77. }
  78. return ret, nil
  79. }
  80. func unmarshalWebMessageInfo(msg []byte) (*pb.WebMessageInfo, error) {
  81. message := &pb.WebMessageInfo{}
  82. err := proto.Unmarshal(msg, message)
  83. if err != nil {
  84. return nil, err
  85. }
  86. return message, nil
  87. }