pending_queue.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package sctp
  2. import (
  3. "errors"
  4. )
  5. // pendingBaseQueue
  6. type pendingBaseQueue struct {
  7. queue []*chunkPayloadData
  8. }
  9. func newPendingBaseQueue() *pendingBaseQueue {
  10. return &pendingBaseQueue{queue: []*chunkPayloadData{}}
  11. }
  12. func (q *pendingBaseQueue) push(c *chunkPayloadData) {
  13. q.queue = append(q.queue, c)
  14. }
  15. func (q *pendingBaseQueue) pop() *chunkPayloadData {
  16. if len(q.queue) == 0 {
  17. return nil
  18. }
  19. c := q.queue[0]
  20. q.queue = q.queue[1:]
  21. return c
  22. }
  23. func (q *pendingBaseQueue) get(i int) *chunkPayloadData {
  24. if len(q.queue) == 0 || i < 0 || i >= len(q.queue) {
  25. return nil
  26. }
  27. return q.queue[i]
  28. }
  29. func (q *pendingBaseQueue) size() int {
  30. return len(q.queue)
  31. }
  32. // pendingQueue
  33. type pendingQueue struct {
  34. unorderedQueue *pendingBaseQueue
  35. orderedQueue *pendingBaseQueue
  36. nBytes int
  37. selected bool
  38. unorderedIsSelected bool
  39. }
  40. // Pending queue errors
  41. var (
  42. ErrUnexpectedChuckPoppedUnordered = errors.New("unexpected chunk popped (unordered)")
  43. ErrUnexpectedChuckPoppedOrdered = errors.New("unexpected chunk popped (ordered)")
  44. ErrUnexpectedQState = errors.New("unexpected q state (should've been selected)")
  45. )
  46. func newPendingQueue() *pendingQueue {
  47. return &pendingQueue{
  48. unorderedQueue: newPendingBaseQueue(),
  49. orderedQueue: newPendingBaseQueue(),
  50. }
  51. }
  52. func (q *pendingQueue) push(c *chunkPayloadData) {
  53. if c.unordered {
  54. q.unorderedQueue.push(c)
  55. } else {
  56. q.orderedQueue.push(c)
  57. }
  58. q.nBytes += len(c.userData)
  59. }
  60. func (q *pendingQueue) peek() *chunkPayloadData {
  61. if q.selected {
  62. if q.unorderedIsSelected {
  63. return q.unorderedQueue.get(0)
  64. }
  65. return q.orderedQueue.get(0)
  66. }
  67. if c := q.unorderedQueue.get(0); c != nil {
  68. return c
  69. }
  70. return q.orderedQueue.get(0)
  71. }
  72. func (q *pendingQueue) pop(c *chunkPayloadData) error {
  73. if q.selected {
  74. var popped *chunkPayloadData
  75. if q.unorderedIsSelected {
  76. popped = q.unorderedQueue.pop()
  77. if popped != c {
  78. return ErrUnexpectedChuckPoppedUnordered
  79. }
  80. } else {
  81. popped = q.orderedQueue.pop()
  82. if popped != c {
  83. return ErrUnexpectedChuckPoppedOrdered
  84. }
  85. }
  86. if popped.endingFragment {
  87. q.selected = false
  88. }
  89. } else {
  90. if !c.beginningFragment {
  91. return ErrUnexpectedQState
  92. }
  93. if c.unordered {
  94. popped := q.unorderedQueue.pop()
  95. if popped != c {
  96. return ErrUnexpectedChuckPoppedUnordered
  97. }
  98. if !popped.endingFragment {
  99. q.selected = true
  100. q.unorderedIsSelected = true
  101. }
  102. } else {
  103. popped := q.orderedQueue.pop()
  104. if popped != c {
  105. return ErrUnexpectedChuckPoppedOrdered
  106. }
  107. if !popped.endingFragment {
  108. q.selected = true
  109. q.unorderedIsSelected = false
  110. }
  111. }
  112. }
  113. q.nBytes -= len(c.userData)
  114. return nil
  115. }
  116. func (q *pendingQueue) getNumBytes() int {
  117. return q.nBytes
  118. }
  119. func (q *pendingQueue) size() int {
  120. return q.unorderedQueue.size() + q.orderedQueue.size()
  121. }