2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file widget_version.cpp
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief Implementation file for widget version
23 #include <dpl/utils/widget_version.h>
24 #include <dpl/assert.h>
25 #include <dpl/log/log.h>
29 namespace // anonymous
31 size_t WAC_CERTIFY_MANDATORY_PART_LOW_COUNT = 2;
32 size_t WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT = 3;
33 size_t WAC_CERTIFY_MANDATORY_PART_MAJOR_INDEX = 0;
34 size_t WAC_CERTIFY_MANDATORY_PART_MINOR_INDEX = 1;
35 size_t WAC_CERTIFY_MANDATORY_PART_MICRO_INDEX = 2;
36 DPL::String::value_type WAC_CERTIFY_MANDATORY_VS_OPTIONAL_SPLIT_CHAR = L' ';
37 DPL::String::value_type WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR = L'.';
38 DPL::String::value_type LEADING_ZERO_CHAR = L'0';
42 // Augmented BNF for Syntax Specifications: ABNF. RFC5234. D. Crocker and P. Overell. January 2008.
44 // ALPHA = %x41-5A / %x61-7A
45 inline bool IsAlpha(int c)
47 return (c >= 0x41 && c <= 0x5A) ||
48 (c >= 0x61 && c <= 0x7A);
52 inline bool IsDigit(int c)
54 return c >= 0x30 && c <= 0x39;
58 inline bool IsSp(int c)
63 DPL::String RemoveLeadingZeroes(const DPL::String &str)
67 if (str[0] != LEADING_ZERO_CHAR) {
73 while (pos + 1 < str.size() && str[pos + 1] == LEADING_ZERO_CHAR) {
77 return str.substr(pos);
81 bool NumberLessOperator(const DPL::String &left,
82 const DPL::String &right)
84 // Assume: No leading zeroes
85 if (left.size() < right.size()) {
89 if (left.size() > right.size()) {
93 // Now: left.size() == right.size()
94 for (ssize_t i = static_cast<ssize_t>(left.size()) - 1; i >= 0; --i) {
95 if (left[i] < right[i]) {
99 if (left[i] > right[i]) {
108 bool WacCertifyNumberString(const DPL::String &str)
110 for (DPL::String::const_iterator i = str.begin(); i != str.end(); ++i) {
119 bool WacCertifyAlphaNumberStringSpace(const DPL::String &str)
121 for (DPL::String::const_iterator i = str.begin(); i != str.end(); ++i) {
122 if (!IsDigit(*i) && !IsAlpha(*i) && !IsSp(*i)) {
131 WidgetVersion::WidgetVersion(const DPL::String &str) :
135 LogDebug("Parsing version string: " << str);
137 // Split optional an mandatory parts
138 size_t optionalPartPosition = str.find(
139 WAC_CERTIFY_MANDATORY_VS_OPTIONAL_SPLIT_CHAR);
141 DPL::String mandatoryPart;
142 DPL::Optional<DPL::String> optionalPart;
144 if (optionalPartPosition == DPL::String::npos) {
147 mandatoryPart = str.substr(0, optionalPartPosition);
148 optionalPart = str.substr(optionalPartPosition + 1, DPL::String::npos);
151 LogDebug("Mandatory part is: " << mandatoryPart);
152 LogDebug("Optional part is: " << optionalPart);
154 // Split string and construct version
155 std::vector<DPL::String> parts;
156 DPL::Tokenize(mandatoryPart,
157 WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR,
158 std::back_inserter(parts),
161 LogDebug("Tokenized mandatory parts: " << parts.size());
163 if (parts.size() != WAC_CERTIFY_MANDATORY_PART_LOW_COUNT &&
164 parts.size() != WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT) {
170 DPL::Optional<DPL::String> micro;
173 major = parts[WAC_CERTIFY_MANDATORY_PART_MAJOR_INDEX];
174 minor = parts[WAC_CERTIFY_MANDATORY_PART_MINOR_INDEX];
176 if (parts.size() == WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT) {
177 micro = parts[WAC_CERTIFY_MANDATORY_PART_MICRO_INDEX];
180 WacCertify(major, minor, micro, optionalPart);
183 WidgetVersion::WidgetVersion(const DPL::String &major,
184 const DPL::String &minor,
185 const DPL::Optional<DPL::String> µ,
186 const DPL::Optional<DPL::String> &optional) :
189 // Create Raw version
191 m_raw += WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR;
193 m_raw += WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR;
200 m_raw += WAC_CERTIFY_MANDATORY_VS_OPTIONAL_SPLIT_CHAR;
205 WacCertify(major, minor, micro, optional);
208 void WidgetVersion::WacCertify(const DPL::String &major,
209 const DPL::String &minor,
210 const DPL::Optional<DPL::String> µ,
211 const DPL::Optional<DPL::String> &optional)
213 LogDebug("Certyfing...");
215 LogDebug("Major candidate: " << major);
216 LogDebug("Minor candidate: " << minor);
217 LogDebug("Micro candidate: " << micro);
218 LogDebug("Optional candidate: " << optional);
221 if (major.empty() || !WacCertifyNumberString(major)) {
222 LogDebug("Major version not certified!");
226 if (minor.empty() || !WacCertifyNumberString(minor)) {
227 LogDebug("Minor version not certified!");
231 if (!!micro && (micro->empty() || !WacCertifyNumberString(*micro))) {
232 LogDebug("Microversion not certified!");
237 (optional->empty() || !WacCertifyAlphaNumberStringSpace(*optional))) {
238 LogDebug("Optional version not certified!");
246 m_optional = optional;
250 LogDebug("Certified.");
253 bool WidgetVersion::IsWac() const
258 const DPL::String &WidgetVersion::Raw() const
263 const DPL::String &WidgetVersion::Major() const
268 const DPL::String &WidgetVersion::Minor() const
273 const DPL::Optional<DPL::String> &WidgetVersion::Micro() const
278 const DPL::Optional<DPL::String> &WidgetVersion::Optional() const
283 bool operator<(const WidgetVersion &left,
284 const WidgetVersion &right)
287 left.IsWac() && right.IsWac() &&
288 "Only WAC version strings are comparable!");
290 if (NumberLessOperator(RemoveLeadingZeroes(left.Major()),
291 RemoveLeadingZeroes(right.Major()))) { return true; }
292 if (NumberLessOperator(RemoveLeadingZeroes(right.Major()),
293 RemoveLeadingZeroes(left.Major()))) { return false; }
295 if (NumberLessOperator(RemoveLeadingZeroes(left.Minor()),
296 RemoveLeadingZeroes(right.Minor()))) { return true; }
297 if (NumberLessOperator(RemoveLeadingZeroes(right.Minor()),
298 RemoveLeadingZeroes(left.Minor()))) { return false; }
300 if (!!left.Micro() && !!right.Micro() &&
301 NumberLessOperator(RemoveLeadingZeroes(*left.Micro()),
302 RemoveLeadingZeroes(*right.Micro()))) { return true; }
303 if (!left.Micro() && !!right.Micro()) { return true; }
308 bool operator<=(const WidgetVersion &left,
309 const WidgetVersion &right)
312 left.IsWac() && right.IsWac() &&
313 "Only WAC version strings are comparable!");
315 return (left == right) || (left < right);
318 bool operator>(const WidgetVersion &left,
319 const WidgetVersion &right)
322 left.IsWac() && right.IsWac() &&
323 "Only WAC version strings are comparable!");
325 return !(left <= right);
328 bool operator>=(const WidgetVersion &left,
329 const WidgetVersion &right)
332 left.IsWac() && right.IsWac() &&
333 "Only WAC version strings are comparable!");
335 return (left == right) || (left > right);
338 bool operator==(const WidgetVersion &left,
339 const WidgetVersion &right)
342 left.IsWac() && right.IsWac() &&
343 "Only WAC version strings are comparable!");
345 return RemoveLeadingZeroes(left.Major()) ==
346 RemoveLeadingZeroes(right.Major()) && // Major are equal
347 RemoveLeadingZeroes(left.Minor()) ==
348 RemoveLeadingZeroes(right.Minor()) && // and Minor are equal
350 (!!left.Micro() && !!right.Micro() &&
351 RemoveLeadingZeroes(*left.Micro()) ==
352 RemoveLeadingZeroes(*right.Micro())) || // Both Micro exist and are equal
353 (!left.Micro() && !right.Micro()) // or both Micro do not exist
357 bool operator!=(const WidgetVersion &left,
358 const WidgetVersion &right)
361 left.IsWac() && right.IsWac() &&
362 "Only WAC version strings are comparable!");
364 return !(left == right);
367 std::ostream & operator<<(std::ostream& stream,
368 const WidgetVersion& version)
370 stream << version.Raw();