Line data Source code
1 : /*
2 : ________________________________________________________________________
3 : | |
4 : | _ _ _ _ |
5 : | | (_) | | | | |
6 : | __| |_ __ _ _ __ ___ ___| |_ ___ _ __ ___ ___ __| | ___ ___ |
7 : | / _` | |/ _` | '_ ` _ \ / _ \ __/ _ \ '__/ __/ _ \ / _` |/ _ \/ __| |
8 : | | (_| | | (_| | | | | | | __/ || __/ | | (_| (_) | (_| | __/ (__ |
9 : | \__,_|_|\__,_|_| |_| |_|\___|\__\___|_| \___\___/ \__,_|\___|\___| |
10 : | |
11 : |________________________________________________________________________|
12 :
13 : C++ CODEC FOR DIAMETER PROTOCOL (RFC 6733)
14 : Version 0.0.z
15 : https://github.com/testillano/diametercodec
16 :
17 : Licensed under the MIT License <http://opensource.org/licenses/MIT>.
18 : SPDX-License-Identifier: MIT
19 : Copyright (c) 2021 Eduardo Ramos
20 :
21 : Permission is hereby granted, free of charge, to any person obtaining a copy
22 : of this software and associated documentation files (the "Software"), to deal
23 : in the Software without restriction, including without limitation the rights
24 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25 : copies of the Software, and to permit persons to whom the Software is
26 : furnished to do so, subject to the following conditions:
27 :
28 : The above copyright notice and this permission notice shall be included in all
29 : copies or substantial portions of the Software.
30 :
31 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37 : SOFTWARE.
38 : */
39 :
40 : // Standard
41 : #include <limits.h>
42 :
43 : #include <cstdlib>
44 : #include <regex>
45 : #include <vector>
46 :
47 : // Project
48 : #include <ert/diametercodec/core/MultiRangeExpression.hpp>
49 :
50 : namespace ert {
51 : namespace diametercodec {
52 : namespace core {
53 :
54 34995 : void MultiRangeExpression::refresh(void) {
55 34995 : if (literal_.empty()) return;
56 :
57 : unsigned int min, max;
58 3396 : data_.clear();
59 :
60 3396 : static std::regex commaRgx(R"(,)", std::regex::optimize);
61 3396 : static std::regex dashRgx(R"(-)", std::regex::optimize);
62 :
63 13584 : auto ranges = std::vector<std::string>(std::sregex_token_iterator{begin(literal_), end(literal_), commaRgx, -1},
64 10188 : std::sregex_token_iterator{});
65 :
66 6857 : for (const auto &range : ranges) {
67 6922 : auto borders = std::vector<std::string>(std::sregex_token_iterator{begin(range), end(range), dashRgx, -1},
68 10383 : std::sregex_token_iterator{});
69 :
70 3461 : auto borders_it = borders.begin();
71 :
72 3461 : if (borders_it != borders.end()) {
73 3461 : min = atoi(borders_it->c_str());
74 3461 : max = min;
75 3461 : borders_it++;
76 :
77 3461 : if (borders_it != borders.end()) {
78 3388 : max = atoi(borders_it->c_str());
79 : }
80 :
81 : // Update data_:
82 15744 : for (unsigned int k = min; k <= max; k++) {
83 12283 : data_[k] = 0;
84 :
85 12283 : if (k == UINT_MAX /* overflow */) break;
86 : }
87 : }
88 3461 : }
89 3396 : }
90 :
91 1 : std::string MultiRangeExpression::getExpandedLiteral(void) const {
92 1 : std::string result;
93 1 : std::map<unsigned int, int /*dummy*/>::const_iterator it;
94 1 : std::map<unsigned int, int /*dummy*/>::const_iterator it_min(data_.begin());
95 1 : std::map<unsigned int, int /*dummy*/>::const_iterator it_max(data_.end());
96 :
97 8 : for (it = it_min; it != it_max; it++) {
98 7 : result += std::to_string((*it).first);
99 7 : result += ",";
100 : }
101 :
102 1 : int pos = result.size();
103 :
104 1 : if (pos) result.erase(pos - 1);
105 :
106 2 : return (result);
107 0 : }
108 :
109 17 : const char *MultiRangeExpression::simplifyLiteral(void) {
110 17 : if (data_.size() == 0) return nullptr;
111 :
112 17 : std::map<unsigned int, int /*dummy*/>::const_iterator it;
113 17 : std::map<unsigned int, int /*dummy*/>::const_iterator it_min(data_.begin());
114 17 : std::map<unsigned int, int /*dummy*/>::const_iterator it_max(data_.end());
115 17 : unsigned int min = UINT_MAX;
116 17 : unsigned int max = 0;
117 : unsigned int value;
118 17 : unsigned int prevValue = data_.begin()->first;
119 17 : literal_ = "";
120 :
121 108 : for (it = it_min; it != it_max; it++) {
122 91 : value = (*it).first;
123 :
124 91 : if (value < min) min = value;
125 :
126 91 : if (value - prevValue > 1) {
127 2 : literal_ += std::to_string(min);
128 2 : if (max != min) {
129 1 : literal_ += "-";
130 1 : literal_ += std::to_string(max);
131 : }
132 2 : literal_ += ",";
133 2 : min = value;
134 : }
135 :
136 91 : if (value > max) max = value;
137 :
138 91 : prevValue = value;
139 : }
140 :
141 17 : literal_ += std::to_string(min);
142 :
143 17 : if (max != min) {
144 17 : literal_ += "-";
145 17 : literal_ += std::to_string(max);
146 : }
147 :
148 17 : return literal_.c_str();
149 : }
150 :
151 : } // namespace core
152 : } // namespace diametercodec
153 : } // namespace ert
|