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