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 :
41 : // Standard
42 : #include <limits.h>
43 : #include <cstdlib>
44 : #include <regex>
45 : #include <vector>
46 :
47 : // Project
48 : #include <ert/diametercodec/core/MultiRangeExpression.hpp>
49 :
50 :
51 : namespace ert
52 : {
53 : namespace diametercodec
54 : {
55 : namespace core
56 : {
57 :
58 6028 : void MultiRangeExpression::refresh(void) {
59 6028 : if(literal_.empty()) return;
60 :
61 613 : std::string range;
62 : unsigned int min, max;
63 613 : data_.clear();
64 :
65 613 : static std::regex commaRgx(R"(,)", std::regex::optimize);
66 613 : static std::regex dashRgx(R"(-)", std::regex::optimize);
67 :
68 : auto ranges = std::vector<std::string>(
69 2452 : std::sregex_token_iterator{begin(literal_), end(literal_), commaRgx, -1},
70 1226 : std::sregex_token_iterator{}
71 613 : );
72 :
73 1291 : for(auto ranges_it = ranges.begin(); ranges_it != ranges.end(); ranges_it ++) {
74 678 : range = *ranges_it;
75 :
76 : auto borders = std::vector<std::string>(
77 2034 : std::sregex_token_iterator{begin(range), end(range), dashRgx, -1},
78 1356 : std::sregex_token_iterator{}
79 678 : );
80 :
81 678 : auto borders_it = borders.begin();
82 :
83 678 : if(borders_it != borders.end()) {
84 678 : min = atoi(borders_it->c_str());
85 678 : max = min;
86 678 : borders_it++;
87 :
88 678 : if(borders_it != borders.end()) {
89 605 : max = atoi(borders_it->c_str());
90 : }
91 :
92 : // Update data_:
93 2918 : for(unsigned int k = min; k <= max; k++) {
94 2240 : data_[k] = 0;
95 :
96 2240 : if(k == UINT_MAX/* overflow */) break;
97 : }
98 : }
99 678 : }
100 613 : }
101 :
102 1 : std::string MultiRangeExpression::getExpandedLiteral(void) const {
103 1 : std::string result;
104 1 : std::map < unsigned int, int/*dummy*/ >::const_iterator it;
105 1 : std::map < unsigned int, int/*dummy*/ >::const_iterator it_min(data_.begin());
106 1 : std::map < unsigned int, int/*dummy*/ >::const_iterator it_max(data_.end());
107 :
108 8 : for(it = it_min; it != it_max; it++) {
109 7 : result += std::to_string((*it).first);
110 7 : result += ",";
111 : }
112 :
113 1 : int pos = result.size();
114 :
115 1 : if(pos) result.erase(pos - 1);
116 :
117 2 : return (result);
118 0 : }
119 :
120 17 : const char *MultiRangeExpression::simplifyLiteral(void) {
121 17 : if(data_.size() == 0) return nullptr;
122 :
123 17 : std::map < unsigned int, int/*dummy*/ >::const_iterator it;
124 17 : std::map < unsigned int, int/*dummy*/ >::const_iterator it_min(data_.begin());
125 17 : std::map < unsigned int, int/*dummy*/ >::const_iterator it_max(data_.end());
126 17 : unsigned int min = UINT_MAX;
127 17 : unsigned int max = 0;
128 : unsigned int value;
129 17 : unsigned int prevValue = data_.begin()->first;
130 17 : literal_ = "";
131 :
132 108 : for(it = it_min; it != it_max; it++) {
133 91 : value = (*it).first;
134 :
135 91 : if(value < min) min = value;
136 :
137 91 : if(value - prevValue > 1) {
138 2 : literal_ += std::to_string(min);
139 2 : if (max != min) {
140 1 : literal_ += "-";
141 1 : literal_ += std::to_string(max);
142 : }
143 2 : literal_ += ",";
144 2 : min = value;
145 : }
146 :
147 91 : if(value > max) max = value;
148 :
149 91 : prevValue = value;
150 : }
151 :
152 17 : literal_ += std::to_string(min);
153 :
154 17 : if(max != min) {
155 17 : literal_ += "-";
156 17 : literal_ += std::to_string(max);
157 : }
158 :
159 17 : return literal_.c_str();
160 : }
161 :
162 : }
163 : }
164 : }
165 :
|