espconn_buf.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * espconn_buf.c
  3. *
  4. * Created on: May 25, 2016
  5. * Author: liuhan
  6. */
  7. #include "lwip/memp.h"
  8. #include "lwip/def.h"
  9. #include "ets_sys.h"
  10. #include "os_type.h"
  11. #include "lwip/app/espconn_buf.h"
  12. #ifdef MEMLEAK_DEBUG
  13. static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
  14. #endif
  15. #if (!defined(lwIP_unlikely))
  16. #define lwIP_unlikely(Expression) !!(Expression)
  17. #endif
  18. #define lwIP_ASSERT(Expression) do{if(!(Expression)) {os_printf("%s %d\n", __func__, __LINE__);return;}}while(0)
  19. ringbuf_t ringbuf_new(size_t capacity)
  20. {
  21. ringbuf_t rb = (ringbuf_t)os_zalloc(sizeof(struct ringbuf_t));
  22. if (rb){
  23. rb->size = capacity + 1;
  24. rb->buf = (uint8*)os_zalloc(rb->size);
  25. if (rb->buf){
  26. ringbuf_reset(rb);
  27. }else{
  28. os_free(rb);
  29. return NULL;
  30. }
  31. }
  32. return rb;
  33. }
  34. size_t ringbuf_buffer_size(const struct ringbuf_t *rb)
  35. {
  36. return rb->size;
  37. }
  38. void ringbuf_reset(ringbuf_t rb)
  39. {
  40. rb ->head = rb->tail = rb->buf;
  41. }
  42. void ringbuf_free(ringbuf_t *rb)
  43. {
  44. lwIP_ASSERT(rb && *rb);
  45. os_free((*rb)->buf);
  46. os_free(*rb);
  47. *rb = NULL;
  48. }
  49. size_t ringbuf_capacity(const struct ringbuf_t *rb)
  50. {
  51. return ringbuf_buffer_size(rb) - 1;
  52. }
  53. static const uint8_t* ringbuf_end(const struct ringbuf_t *rb)
  54. {
  55. return rb->buf + ringbuf_buffer_size(rb);
  56. }
  57. size_t ringbuf_bytes_free(const struct ringbuf_t *rb)
  58. {
  59. if (rb->head >= rb->tail){
  60. return ringbuf_capacity(rb) - (rb->head - rb->tail);
  61. }else{
  62. return rb->tail - rb->head -1;
  63. }
  64. }
  65. size_t ringbuf_bytes_used(const struct ringbuf_t *rb)
  66. {
  67. return ringbuf_capacity(rb) - ringbuf_bytes_free(rb);
  68. }
  69. int ringbuf_is_full(const struct ringbuf_t *rb)
  70. {
  71. return ringbuf_bytes_free(rb) == 0;
  72. }
  73. int ringbuf_is_empty(const struct ringbuf_t *rb)
  74. {
  75. return ringbuf_bytes_free(rb) == ringbuf_capacity(rb);
  76. }
  77. const void* ringbuf_tail(const struct ringbuf_t *rb)
  78. {
  79. return rb->tail;
  80. }
  81. const void* ringbuf_head(const struct ringbuf_t *rb)
  82. {
  83. return rb->head;
  84. }
  85. static uint8_t *ringbuf_nextp(ringbuf_t rb, const uint8_t *p)
  86. {
  87. lwIP_ASSERT((p >= rb->buf) && (p < ringbuf_end(rb)));
  88. return rb->buf + ((++p -rb->buf) % ringbuf_buffer_size(rb));
  89. }
  90. size_t ringbuf_findchr(const struct ringbuf_t *rb, int c, size_t offset)
  91. {
  92. const uint8_t *bufend = ringbuf_end(rb);
  93. size_t bytes_used = ringbuf_bytes_used(rb);
  94. if (offset >= bytes_used)
  95. return bytes_used;
  96. const uint8_t *start = rb ->buf + (((rb->tail - rb->buf) + offset) % ringbuf_buffer_size(rb));
  97. lwIP_ASSERT(bufend > start);
  98. size_t n = LWIP_MIN(bufend - start, bytes_used - offset);
  99. const uint8_t *found = (const uint8_t *)memchr(start, c, n);
  100. if (found)
  101. return offset + (found - start);
  102. else
  103. return ringbuf_findchr(rb, c, offset + n);
  104. }
  105. size_t ringbuf_memset(ringbuf_t dst, int c, size_t len)
  106. {
  107. const uint8_t *bufend = ringbuf_end(dst);
  108. size_t nwritten = 0;
  109. size_t count = LWIP_MIN(len, ringbuf_buffer_size(dst));
  110. int overflow = count > ringbuf_bytes_free(dst);
  111. while (nwritten != count){
  112. lwIP_ASSERT(bufend > dst->head);
  113. size_t n = LWIP_MIN(bufend - dst->head, count - nwritten);
  114. os_memset(dst->head, c, n);
  115. dst->head += n;
  116. nwritten += n;
  117. if (dst->head == bufend)
  118. dst->head = dst->buf;
  119. }
  120. if (overflow){
  121. dst->tail = ringbuf_nextp(dst, dst->head);
  122. lwIP_ASSERT(ringbuf_is_full(dst));
  123. }
  124. return nwritten;
  125. }
  126. void *ringbuf_memcpy_into(ringbuf_t dst,const void *src, size_t count)
  127. {
  128. const uint8_t *u8src = src;
  129. const uint8_t *bufend = ringbuf_end(dst);
  130. int overflow = count > ringbuf_bytes_free(dst);
  131. size_t nread = 0;
  132. while (nread != count){
  133. lwIP_ASSERT(bufend > dst->head);
  134. size_t n = LWIP_MIN(bufend - dst->head, count - nread);
  135. os_memcpy(dst->head, u8src + nread, n);
  136. dst->head += n;
  137. nread += n;
  138. if (dst->head == bufend)
  139. dst->head = dst->buf;
  140. }
  141. if (overflow) {
  142. dst->tail = ringbuf_nextp(dst, dst->head);
  143. lwIP_ASSERT(ringbuf_is_full(dst));
  144. }
  145. return dst->head;
  146. }
  147. void *ringbuf_memcpy_from(void *dst,ringbuf_t src, size_t count)
  148. {
  149. size_t bytes_used = ringbuf_bytes_used(src);
  150. if (count > bytes_used)
  151. return NULL;
  152. const uint8_t *u8dst = dst;
  153. const uint8_t *bufend = ringbuf_end(src);
  154. size_t nwritten = 0;
  155. while (nwritten != count){
  156. lwIP_ASSERT(bufend > src->tail);
  157. size_t n = LWIP_MIN(bufend - src->tail, count - nwritten);
  158. os_memcpy((uint8_t*)u8dst + nwritten, src->tail, n);
  159. src->tail += n;
  160. nwritten += n;
  161. if (src->tail == bufend)
  162. src->tail = src->buf;
  163. }
  164. lwIP_ASSERT(count + ringbuf_bytes_used(src) == bytes_used);
  165. return src->tail;
  166. }