ngtcp2_vec.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * ngtcp2
  3. *
  4. * Copyright (c) 2018 ngtcp2 contributors
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sublicense, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  21. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. */
  25. #include "ngtcp2_vec.h"
  26. #include <string.h>
  27. #include <assert.h>
  28. #include "ngtcp2_str.h"
  29. ngtcp2_vec *ngtcp2_vec_init(ngtcp2_vec *vec, const uint8_t *base, size_t len) {
  30. vec->base = (uint8_t *)base;
  31. vec->len = len;
  32. return vec;
  33. }
  34. int ngtcp2_vec_new(ngtcp2_vec **pvec, const uint8_t *data, size_t datalen,
  35. const ngtcp2_mem *mem) {
  36. size_t len;
  37. uint8_t *p;
  38. len = sizeof(ngtcp2_vec) + datalen;
  39. *pvec = ngtcp2_mem_malloc(mem, len);
  40. if (*pvec == NULL) {
  41. return NGTCP2_ERR_NOMEM;
  42. }
  43. p = (uint8_t *)(*pvec) + sizeof(ngtcp2_vec);
  44. (*pvec)->base = p;
  45. (*pvec)->len = datalen;
  46. if (datalen) {
  47. /* p = */ ngtcp2_cpymem(p, data, datalen);
  48. }
  49. return 0;
  50. }
  51. void ngtcp2_vec_del(ngtcp2_vec *vec, const ngtcp2_mem *mem) {
  52. ngtcp2_mem_free(mem, vec);
  53. }
  54. uint64_t ngtcp2_vec_len(const ngtcp2_vec *vec, size_t n) {
  55. size_t i;
  56. size_t res = 0;
  57. for (i = 0; i < n; ++i) {
  58. res += vec[i].len;
  59. }
  60. return res;
  61. }
  62. int64_t ngtcp2_vec_len_varint(const ngtcp2_vec *vec, size_t n) {
  63. uint64_t res = 0;
  64. size_t len;
  65. size_t i;
  66. for (i = 0; i < n; ++i) {
  67. len = vec[i].len;
  68. if (len > NGTCP2_MAX_VARINT - res) {
  69. return -1;
  70. }
  71. res += len;
  72. }
  73. return (int64_t)res;
  74. }
  75. ngtcp2_ssize ngtcp2_vec_split(ngtcp2_vec *dst, size_t *pdstcnt, ngtcp2_vec *src,
  76. size_t *psrccnt, size_t left, size_t maxcnt) {
  77. size_t i;
  78. size_t srccnt = *psrccnt;
  79. size_t nmove;
  80. size_t extra = 0;
  81. for (i = 0; i < srccnt; ++i) {
  82. if (left >= src[i].len) {
  83. left -= src[i].len;
  84. continue;
  85. }
  86. if (*pdstcnt && src[srccnt - 1].base + src[srccnt - 1].len == dst[0].base) {
  87. if (*pdstcnt + srccnt - i - 1 > maxcnt) {
  88. return -1;
  89. }
  90. dst[0].len += src[srccnt - 1].len;
  91. dst[0].base = src[srccnt - 1].base;
  92. extra = src[srccnt - 1].len;
  93. --srccnt;
  94. } else if (*pdstcnt + srccnt - i > maxcnt) {
  95. return -1;
  96. }
  97. if (left == 0) {
  98. *psrccnt = i;
  99. } else {
  100. *psrccnt = i + 1;
  101. }
  102. nmove = srccnt - i;
  103. if (nmove) {
  104. memmove(dst + nmove, dst, sizeof(ngtcp2_vec) * (*pdstcnt));
  105. *pdstcnt += nmove;
  106. memcpy(dst, src + i, sizeof(ngtcp2_vec) * nmove);
  107. }
  108. dst[0].len -= left;
  109. dst[0].base += left;
  110. src[i].len = left;
  111. if (nmove == 0) {
  112. extra -= left;
  113. }
  114. return (ngtcp2_ssize)(ngtcp2_vec_len(dst, nmove) + extra);
  115. }
  116. return 0;
  117. }
  118. size_t ngtcp2_vec_merge(ngtcp2_vec *dst, size_t *pdstcnt, ngtcp2_vec *src,
  119. size_t *psrccnt, size_t left, size_t maxcnt) {
  120. size_t orig_left = left;
  121. size_t i = 0;
  122. ngtcp2_vec *a, *b;
  123. assert(maxcnt);
  124. if (*pdstcnt == 0) {
  125. if (*psrccnt == 0) {
  126. return 0;
  127. }
  128. a = &dst[0];
  129. b = &src[0];
  130. if (left < b->len) {
  131. a->len = left;
  132. a->base = b->base;
  133. b->len -= left;
  134. b->base += left;
  135. return left;
  136. }
  137. *a = *b;
  138. ++*pdstcnt;
  139. left -= b->len;
  140. i = 1;
  141. }
  142. for (; left && i < *psrccnt; ++i) {
  143. a = &dst[*pdstcnt - 1];
  144. b = &src[i];
  145. if (left < b->len) {
  146. if (a->base + a->len == b->base) {
  147. a->len += left;
  148. } else if (*pdstcnt == maxcnt) {
  149. break;
  150. } else {
  151. dst[*pdstcnt].len = left;
  152. dst[*pdstcnt].base = b->base;
  153. ++*pdstcnt;
  154. }
  155. b->len -= left;
  156. b->base += left;
  157. left = 0;
  158. break;
  159. }
  160. if (a->base + a->len == b->base) {
  161. a->len += b->len;
  162. } else if (*pdstcnt == maxcnt) {
  163. break;
  164. } else {
  165. dst[(*pdstcnt)++] = *b;
  166. }
  167. left -= b->len;
  168. }
  169. memmove(src, src + i, sizeof(ngtcp2_vec) * (*psrccnt - i));
  170. *psrccnt -= i;
  171. return orig_left - left;
  172. }
  173. size_t ngtcp2_vec_copy_at_most(ngtcp2_vec *dst, size_t dstcnt,
  174. const ngtcp2_vec *src, size_t srccnt,
  175. size_t left) {
  176. size_t i, j;
  177. for (i = 0, j = 0; left > 0 && i < srccnt && j < dstcnt;) {
  178. if (src[i].len == 0) {
  179. ++i;
  180. continue;
  181. }
  182. dst[j] = src[i];
  183. if (dst[j].len > left) {
  184. dst[j].len = left;
  185. return j + 1;
  186. }
  187. left -= dst[j].len;
  188. ++i;
  189. ++j;
  190. }
  191. return j;
  192. }
  193. void ngtcp2_vec_copy(ngtcp2_vec *dst, const ngtcp2_vec *src, size_t cnt) {
  194. memcpy(dst, src, sizeof(ngtcp2_vec) * cnt);
  195. }