11cb0ef41Sopenharmony_ci/*
21cb0ef41Sopenharmony_ci * nghttp3
31cb0ef41Sopenharmony_ci *
41cb0ef41Sopenharmony_ci * Copyright (c) 2019 nghttp3 contributors
51cb0ef41Sopenharmony_ci * Copyright (c) 2017 ngtcp2 contributors
61cb0ef41Sopenharmony_ci *
71cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining
81cb0ef41Sopenharmony_ci * a copy of this software and associated documentation files (the
91cb0ef41Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
101cb0ef41Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
111cb0ef41Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to
121cb0ef41Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
131cb0ef41Sopenharmony_ci * the following conditions:
141cb0ef41Sopenharmony_ci *
151cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be
161cb0ef41Sopenharmony_ci * included in all copies or substantial portions of the Software.
171cb0ef41Sopenharmony_ci *
181cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
191cb0ef41Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
201cb0ef41Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
211cb0ef41Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
221cb0ef41Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
231cb0ef41Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
241cb0ef41Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
251cb0ef41Sopenharmony_ci */
261cb0ef41Sopenharmony_ci#include "nghttp3_gaptr.h"
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci#include <string.h>
291cb0ef41Sopenharmony_ci#include <assert.h>
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_civoid nghttp3_gaptr_init(nghttp3_gaptr *gaptr, const nghttp3_mem *mem) {
321cb0ef41Sopenharmony_ci  nghttp3_ksl_init(&gaptr->gap, nghttp3_ksl_range_compar, sizeof(nghttp3_range),
331cb0ef41Sopenharmony_ci                   mem);
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  gaptr->mem = mem;
361cb0ef41Sopenharmony_ci}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_cistatic int gaptr_gap_init(nghttp3_gaptr *gaptr) {
391cb0ef41Sopenharmony_ci  nghttp3_range range = {0, UINT64_MAX};
401cb0ef41Sopenharmony_ci  int rv;
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  rv = nghttp3_ksl_insert(&gaptr->gap, NULL, &range, NULL);
431cb0ef41Sopenharmony_ci  if (rv != 0) {
441cb0ef41Sopenharmony_ci    return rv;
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  return 0;
481cb0ef41Sopenharmony_ci}
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_civoid nghttp3_gaptr_free(nghttp3_gaptr *gaptr) {
511cb0ef41Sopenharmony_ci  if (gaptr == NULL) {
521cb0ef41Sopenharmony_ci    return;
531cb0ef41Sopenharmony_ci  }
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  nghttp3_ksl_free(&gaptr->gap);
561cb0ef41Sopenharmony_ci}
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ciint nghttp3_gaptr_push(nghttp3_gaptr *gaptr, uint64_t offset,
591cb0ef41Sopenharmony_ci                       uint64_t datalen) {
601cb0ef41Sopenharmony_ci  int rv;
611cb0ef41Sopenharmony_ci  nghttp3_range k, m, l, r, q = {offset, offset + datalen};
621cb0ef41Sopenharmony_ci  nghttp3_ksl_it it;
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  if (nghttp3_ksl_len(&gaptr->gap) == 0) {
651cb0ef41Sopenharmony_ci    rv = gaptr_gap_init(gaptr);
661cb0ef41Sopenharmony_ci    if (rv != 0) {
671cb0ef41Sopenharmony_ci      return rv;
681cb0ef41Sopenharmony_ci    }
691cb0ef41Sopenharmony_ci  }
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
721cb0ef41Sopenharmony_ci                                      nghttp3_ksl_range_exclusive_compar);
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  for (; !nghttp3_ksl_it_end(&it);) {
751cb0ef41Sopenharmony_ci    k = *(nghttp3_range *)nghttp3_ksl_it_key(&it);
761cb0ef41Sopenharmony_ci    m = nghttp3_range_intersect(&q, &k);
771cb0ef41Sopenharmony_ci    if (!nghttp3_range_len(&m)) {
781cb0ef41Sopenharmony_ci      break;
791cb0ef41Sopenharmony_ci    }
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci    if (nghttp3_range_eq(&k, &m)) {
821cb0ef41Sopenharmony_ci      nghttp3_ksl_remove_hint(&gaptr->gap, &it, &it, &k);
831cb0ef41Sopenharmony_ci      continue;
841cb0ef41Sopenharmony_ci    }
851cb0ef41Sopenharmony_ci    nghttp3_range_cut(&l, &r, &k, &m);
861cb0ef41Sopenharmony_ci    if (nghttp3_range_len(&l)) {
871cb0ef41Sopenharmony_ci      nghttp3_ksl_update_key(&gaptr->gap, &k, &l);
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci      if (nghttp3_range_len(&r)) {
901cb0ef41Sopenharmony_ci        rv = nghttp3_ksl_insert(&gaptr->gap, &it, &r, NULL);
911cb0ef41Sopenharmony_ci        if (rv != 0) {
921cb0ef41Sopenharmony_ci          return rv;
931cb0ef41Sopenharmony_ci        }
941cb0ef41Sopenharmony_ci      }
951cb0ef41Sopenharmony_ci    } else if (nghttp3_range_len(&r)) {
961cb0ef41Sopenharmony_ci      nghttp3_ksl_update_key(&gaptr->gap, &k, &r);
971cb0ef41Sopenharmony_ci    }
981cb0ef41Sopenharmony_ci    nghttp3_ksl_it_next(&it);
991cb0ef41Sopenharmony_ci  }
1001cb0ef41Sopenharmony_ci  return 0;
1011cb0ef41Sopenharmony_ci}
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ciuint64_t nghttp3_gaptr_first_gap_offset(nghttp3_gaptr *gaptr) {
1041cb0ef41Sopenharmony_ci  nghttp3_ksl_it it;
1051cb0ef41Sopenharmony_ci  nghttp3_range r;
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  if (nghttp3_ksl_len(&gaptr->gap) == 0) {
1081cb0ef41Sopenharmony_ci    return 0;
1091cb0ef41Sopenharmony_ci  }
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci  it = nghttp3_ksl_begin(&gaptr->gap);
1121cb0ef41Sopenharmony_ci  r = *(nghttp3_range *)nghttp3_ksl_it_key(&it);
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  return r.begin;
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_cinghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr,
1181cb0ef41Sopenharmony_ci                                                uint64_t offset) {
1191cb0ef41Sopenharmony_ci  nghttp3_range q = {offset, offset + 1};
1201cb0ef41Sopenharmony_ci  nghttp3_ksl_it it;
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  if (nghttp3_ksl_len(&gaptr->gap) == 0) {
1231cb0ef41Sopenharmony_ci    nghttp3_range r = {0, UINT64_MAX};
1241cb0ef41Sopenharmony_ci    return r;
1251cb0ef41Sopenharmony_ci  }
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
1281cb0ef41Sopenharmony_ci                                      nghttp3_ksl_range_exclusive_compar);
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  assert(!nghttp3_ksl_it_end(&it));
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  return *(nghttp3_range *)nghttp3_ksl_it_key(&it);
1331cb0ef41Sopenharmony_ci}
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ciint nghttp3_gaptr_is_pushed(nghttp3_gaptr *gaptr, uint64_t offset,
1361cb0ef41Sopenharmony_ci                            uint64_t datalen) {
1371cb0ef41Sopenharmony_ci  nghttp3_range q = {offset, offset + datalen};
1381cb0ef41Sopenharmony_ci  nghttp3_ksl_it it;
1391cb0ef41Sopenharmony_ci  nghttp3_range k;
1401cb0ef41Sopenharmony_ci  nghttp3_range m;
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  if (nghttp3_ksl_len(&gaptr->gap) == 0) {
1431cb0ef41Sopenharmony_ci    return 0;
1441cb0ef41Sopenharmony_ci  }
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
1471cb0ef41Sopenharmony_ci                                      nghttp3_ksl_range_exclusive_compar);
1481cb0ef41Sopenharmony_ci  k = *(nghttp3_range *)nghttp3_ksl_it_key(&it);
1491cb0ef41Sopenharmony_ci  m = nghttp3_range_intersect(&q, &k);
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  return nghttp3_range_len(&m) == 0;
1521cb0ef41Sopenharmony_ci}
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_civoid nghttp3_gaptr_drop_first_gap(nghttp3_gaptr *gaptr) {
1551cb0ef41Sopenharmony_ci  nghttp3_ksl_it it;
1561cb0ef41Sopenharmony_ci  nghttp3_range r;
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  if (nghttp3_ksl_len(&gaptr->gap) == 0) {
1591cb0ef41Sopenharmony_ci    return;
1601cb0ef41Sopenharmony_ci  }
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci  it = nghttp3_ksl_begin(&gaptr->gap);
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_ci  assert(!nghttp3_ksl_it_end(&it));
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  r = *(nghttp3_range *)nghttp3_ksl_it_key(&it);
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  nghttp3_ksl_remove_hint(&gaptr->gap, NULL, &it, &r);
1691cb0ef41Sopenharmony_ci}
170