blob: 22541e6ee07ef7e24ac3fc2c7552aac8fd08ee82 [file] [log] [blame]
bnc1ad8dc62019-07-12 18:07:37 -07001// Copyright (c) 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h"
6
7#include <limits>
8
9#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
10
11namespace quic {
12
13uint64_t QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
14 uint64_t max_entries) {
15 if (required_insert_count == 0) {
16 return 0;
17 }
18
19 return required_insert_count % (2 * max_entries) + 1;
20}
21
22bool QpackDecodeRequiredInsertCount(uint64_t encoded_required_insert_count,
23 uint64_t max_entries,
24 uint64_t total_number_of_inserts,
25 uint64_t* required_insert_count) {
26 if (encoded_required_insert_count == 0) {
27 *required_insert_count = 0;
28 return true;
29 }
30
31 // |max_entries| is calculated by dividing an unsigned 64-bit integer by 32,
32 // precluding all calculations in this method from overflowing.
33 DCHECK_LE(max_entries, std::numeric_limits<uint64_t>::max() / 32);
34
35 if (encoded_required_insert_count > 2 * max_entries) {
36 return false;
37 }
38
39 *required_insert_count = encoded_required_insert_count - 1;
40 DCHECK_LT(*required_insert_count, std::numeric_limits<uint64_t>::max() / 16);
41
42 uint64_t current_wrapped = total_number_of_inserts % (2 * max_entries);
43 DCHECK_LT(current_wrapped, std::numeric_limits<uint64_t>::max() / 16);
44
45 if (current_wrapped >= *required_insert_count + max_entries) {
46 // Required Insert Count wrapped around 1 extra time.
47 *required_insert_count += 2 * max_entries;
48 } else if (current_wrapped + max_entries < *required_insert_count) {
49 // Decoder wrapped around 1 extra time.
50 current_wrapped += 2 * max_entries;
51 }
52
53 if (*required_insert_count >
54 std::numeric_limits<uint64_t>::max() - total_number_of_inserts) {
55 return false;
56 }
57
58 *required_insert_count += total_number_of_inserts;
59
60 // Prevent underflow, also disallow invalid value 0 for Required Insert Count.
61 if (current_wrapped >= *required_insert_count) {
62 return false;
63 }
64
65 *required_insert_count -= current_wrapped;
66
67 return true;
68}
69
70} // namespace quic