OpenVPN 3 Core Library
Loading...
Searching...
No Matches
circ_list.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// A general-purpose circular list collection class.
13// Used by the OpenVPN anti-replay logic.
14
15#ifndef OPENVPN_COMMON_CIRC_LIST_H
16#define OPENVPN_COMMON_CIRC_LIST_H
17
18#include <vector>
19
22
23namespace openvpn {
24
25template <typename T>
27{
28 public:
29 OPENVPN_SIMPLE_EXCEPTION(circ_list_reset);
30 OPENVPN_SIMPLE_EXCEPTION(circ_list_index);
31 OPENVPN_SIMPLE_EXCEPTION(circ_list_const_index);
32 OPENVPN_SIMPLE_EXCEPTION(circ_list_push);
33
35 {
36 init(0);
37 }
38
39 explicit CircList(const size_t capacity)
40 {
41 init(capacity);
42 }
43
44 void init(const size_t capacity)
45 {
46 if (capacity)
47 {
48 data_.reserve(capacity);
49 capacity_ = capacity;
50 reset();
51 }
52 else
53 {
54 head_ = capacity_ = 0;
55 data_.clear();
56 }
57 }
58
59 void reset()
60 {
61 if (capacity_)
62 {
63 head_ = capacity_ - 1;
64 data_.clear();
65 }
66 else
67 throw circ_list_reset();
68 }
69
70 size_t size() const
71 {
72 return data_.size();
73 }
74
75 bool defined() const
76 {
77 return capacity_ > 0;
78 }
79
80 void push(const T &item)
81 {
82 if (++head_ >= capacity_)
83 head_ = 0;
84 if (head_ < data_.size())
85 data_[head_] = item;
86 else if (head_ == data_.size() && data_.size() < capacity_)
87 data_.push_back(item);
88 else
89 throw circ_list_push(); // could occur if object isn't properly initialized
90 }
91
92 T &operator[](const size_t index)
93 {
94 if (index >= data_.size())
95 throw circ_list_index();
96 else if (index <= head_)
97 return data_[head_ - index];
98 else
99 return data_[head_ + capacity_ - index];
100 }
101
102 const T &operator[](const size_t index) const
103 {
104 if (index >= data_.size())
105 throw circ_list_const_index();
106 else if (index <= head_)
107 return data_[head_ - index];
108 else
109 return data_[head_ + capacity_ - index];
110 }
111
112 private:
113 size_t capacity_;
114 size_t head_;
115 std::vector<T> data_;
116};
117
118} // namespace openvpn
119
120#endif // OPENVPN_COMMON_CIRC_LIST_H
CircList(const size_t capacity)
Definition circ_list.hpp:39
void push(const T &item)
Definition circ_list.hpp:80
OPENVPN_SIMPLE_EXCEPTION(circ_list_reset)
size_t size() const
Definition circ_list.hpp:70
const T & operator[](const size_t index) const
void init(const size_t capacity)
Definition circ_list.hpp:44
bool defined() const
Definition circ_list.hpp:75
T & operator[](const size_t index)
Definition circ_list.hpp:92
OPENVPN_SIMPLE_EXCEPTION(circ_list_index)
std::vector< T > data_
OPENVPN_SIMPLE_EXCEPTION(circ_list_push)
OPENVPN_SIMPLE_EXCEPTION(circ_list_const_index)