marshal.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package sdp
  2. import (
  3. "strings"
  4. )
  5. // Marshal takes a SDP struct to text
  6. // https://tools.ietf.org/html/rfc4566#section-5
  7. // Session description
  8. // v= (protocol version)
  9. // o= (originator and session identifier)
  10. // s= (session name)
  11. // i=* (session information)
  12. // u=* (URI of description)
  13. // e=* (email address)
  14. // p=* (phone number)
  15. // c=* (connection information -- not required if included in
  16. // all media)
  17. // b=* (zero or more bandwidth information lines)
  18. // One or more time descriptions ("t=" and "r=" lines; see below)
  19. // z=* (time zone adjustments)
  20. // k=* (encryption key)
  21. // a=* (zero or more session attribute lines)
  22. // Zero or more media descriptions
  23. //
  24. // Time description
  25. // t= (time the session is active)
  26. // r=* (zero or more repeat times)
  27. //
  28. // Media description, if present
  29. // m= (media name and transport address)
  30. // i=* (media title)
  31. // c=* (connection information -- optional if included at
  32. // session level)
  33. // b=* (zero or more bandwidth information lines)
  34. // k=* (encryption key)
  35. // a=* (zero or more media attribute lines)
  36. func (s *SessionDescription) Marshal() ([]byte, error) {
  37. m := make(marshaller, 0, 1024)
  38. m.addKeyValue("v=", s.Version.String())
  39. m.addKeyValue("o=", s.Origin.String())
  40. m.addKeyValue("s=", s.SessionName.String())
  41. if s.SessionInformation != nil {
  42. m.addKeyValue("i=", s.SessionInformation.String())
  43. }
  44. if s.URI != nil {
  45. m.addKeyValue("u=", s.URI.String())
  46. }
  47. if s.EmailAddress != nil {
  48. m.addKeyValue("e=", s.EmailAddress.String())
  49. }
  50. if s.PhoneNumber != nil {
  51. m.addKeyValue("p=", s.PhoneNumber.String())
  52. }
  53. if s.ConnectionInformation != nil {
  54. m.addKeyValue("c=", s.ConnectionInformation.String())
  55. }
  56. for _, b := range s.Bandwidth {
  57. m.addKeyValue("b=", b.String())
  58. }
  59. for _, td := range s.TimeDescriptions {
  60. m.addKeyValue("t=", td.Timing.String())
  61. for _, r := range td.RepeatTimes {
  62. m.addKeyValue("r=", r.String())
  63. }
  64. }
  65. if len(s.TimeZones) > 0 {
  66. var b strings.Builder
  67. for i, z := range s.TimeZones {
  68. if i > 0 {
  69. b.WriteString(" ")
  70. }
  71. b.WriteString(z.String())
  72. }
  73. m.addKeyValue("z=", b.String())
  74. }
  75. if s.EncryptionKey != nil {
  76. m.addKeyValue("k=", s.EncryptionKey.String())
  77. }
  78. for _, a := range s.Attributes {
  79. m.addKeyValue("a=", a.String())
  80. }
  81. for _, md := range s.MediaDescriptions {
  82. m.addKeyValue("m=", md.MediaName.String())
  83. if md.MediaTitle != nil {
  84. m.addKeyValue("i=", md.MediaTitle.String())
  85. }
  86. if md.ConnectionInformation != nil {
  87. m.addKeyValue("c=", md.ConnectionInformation.String())
  88. }
  89. for _, b := range md.Bandwidth {
  90. m.addKeyValue("b=", b.String())
  91. }
  92. if md.EncryptionKey != nil {
  93. m.addKeyValue("k=", md.EncryptionKey.String())
  94. }
  95. for _, a := range md.Attributes {
  96. m.addKeyValue("a=", a.String())
  97. }
  98. }
  99. return m.bytes(), nil
  100. }
  101. // marshaller contains state during marshaling.
  102. type marshaller []byte
  103. func (m *marshaller) addKeyValue(key, value string) {
  104. if value == "" {
  105. return
  106. }
  107. *m = append(*m, key...)
  108. *m = append(*m, value...)
  109. *m = append(*m, "\r\n"...)
  110. }
  111. func (m *marshaller) bytes() []byte {
  112. return *m
  113. }