blob: 0cf7f15d9f72fc5c76bf54c267e52a7d23ff1ed7 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
6#define QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
7
8#include <limits>
9#include <ostream>
vasilvv872e7a32019-03-12 16:42:44 -070010#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050011
12#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h"
15
16namespace quic {
17
18// QuicPacketNumber can either initialized or uninitialized. An initialized
19// packet number is simply an ordinal number. A sentinel value is used to
20// represent an uninitialized packet number.
21class QUIC_EXPORT_PRIVATE QuicPacketNumber {
22 public:
23 // Construct an uninitialized packet number.
24 QuicPacketNumber();
25 // Construct a packet number from uint64_t. |packet_number| cannot equal the
26 // sentinel value.
27 explicit QuicPacketNumber(uint64_t packet_number);
28
29 // Packet number becomes uninitialized after calling this function.
30 void Clear();
31
QUICHE teamc264e362019-03-19 14:21:06 -070032 // Updates this packet number to be |new_value| if it is greater than current
33 // value.
34 void UpdateMax(QuicPacketNumber new_value);
35
QUICHE teama6ef0a62019-03-07 20:34:33 -050036 // REQUIRES: IsInitialized() == true.
37 uint64_t Hash() const;
38
39 // Converts packet number to uint64_t.
40 // REQUIRES: IsInitialized() == true.
41 uint64_t ToUint64() const;
42
43 // Returns true if packet number is considered initialized.
44 bool IsInitialized() const;
45
46 // REQUIRES: IsInitialized() == true && ToUint64() <
47 // numeric_limits<uint64_t>::max() - 1.
48 QuicPacketNumber& operator++();
49 QuicPacketNumber operator++(int);
50 // REQUIRES: IsInitialized() == true && ToUint64() >= 1.
51 QuicPacketNumber& operator--();
52 QuicPacketNumber operator--(int);
53
54 // REQUIRES: IsInitialized() == true && numeric_limits<uint64_t>::max() -
55 // ToUint64() > |delta|.
56 QuicPacketNumber& operator+=(uint64_t delta);
57 // REQUIRES: IsInitialized() == true && ToUint64() >= |delta|.
58 QuicPacketNumber& operator-=(uint64_t delta);
59
60 QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
61 std::ostream& os,
62 const QuicPacketNumber& p);
63
64 private:
65 // All following operators REQUIRE operands.Initialized() == true.
66 friend inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs);
67 friend inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs);
68 friend inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs);
69 friend inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs);
70 friend inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs);
71 friend inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs);
72
73 // REQUIRES: numeric_limits<uint64_t>::max() - lhs.ToUint64() > |delta|.
74 friend inline QuicPacketNumber operator+(QuicPacketNumber lhs,
75 uint64_t delta);
76 // REQUIRES: lhs.ToUint64() >= |delta|.
77 friend inline QuicPacketNumber operator-(QuicPacketNumber lhs,
78 uint64_t delta);
79 // REQUIRES: lhs >= rhs.
80 friend inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs);
81
82 // The sentinel value representing an uninitialized packet number.
83 static uint64_t UninitializedPacketNumber();
84
85 uint64_t packet_number_;
86};
87
88class QuicPacketNumberHash {
89 public:
90 uint64_t operator()(QuicPacketNumber packet_number) const noexcept {
91 return packet_number.Hash();
92 }
93};
94
95inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs) {
96 DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
97 return lhs.packet_number_ == rhs.packet_number_;
98}
99
100inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
101 DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
102 return lhs.packet_number_ != rhs.packet_number_;
103}
104
105inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs) {
106 DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
107 return lhs.packet_number_ < rhs.packet_number_;
108}
109
110inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
111 DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
112 return lhs.packet_number_ <= rhs.packet_number_;
113}
114
115inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs) {
116 DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
117 return lhs.packet_number_ > rhs.packet_number_;
118}
119
120inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
121 DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
122 return lhs.packet_number_ >= rhs.packet_number_;
123}
124
125inline QuicPacketNumber operator+(QuicPacketNumber lhs, uint64_t delta) {
126#ifndef NDEBUG
127 DCHECK(lhs.IsInitialized());
QUICHE team577718a2019-03-20 09:00:59 -0700128 DCHECK_GT(std::numeric_limits<uint64_t>::max() - lhs.ToUint64(), delta);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500129#endif
130 return QuicPacketNumber(lhs.packet_number_ + delta);
131}
132
133inline QuicPacketNumber operator-(QuicPacketNumber lhs, uint64_t delta) {
134#ifndef NDEBUG
135 DCHECK(lhs.IsInitialized());
QUICHE team577718a2019-03-20 09:00:59 -0700136 DCHECK_GE(lhs.ToUint64(), delta);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137#endif
138 return QuicPacketNumber(lhs.packet_number_ - delta);
139}
140
141inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs) {
142 DCHECK(lhs.IsInitialized() && rhs.IsInitialized() && lhs >= rhs)
143 << lhs << " vs. " << rhs;
144 return lhs.packet_number_ - rhs.packet_number_;
145}
146
147} // namespace quic
148
149#endif // QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_