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/wrt_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.
43 // Overell. January 2008.
45 // ALPHA = %x41-5A / %x61-7A
46 inline bool IsAlpha(int c)
48 return (c >= 0x41 && c <= 0x5A) ||
49 (c >= 0x61 && c <= 0x7A);
53 inline bool IsDigit(int c)
55 return c >= 0x30 && c <= 0x39;
59 inline bool IsSp(int c)
64 DPL::String RemoveLeadingZeroes(const DPL::String &str)
68 if (str[0] != LEADING_ZERO_CHAR) {
74 while (pos + 1 < str.size()) {
77 if (str[pos] != LEADING_ZERO_CHAR)
81 return str.substr(pos);
85 bool NumberLessOperator(const DPL::String &left,
86 const DPL::String &right)
88 // Assume: No leading zeroes
89 if (left.size() < right.size()) {
93 if (left.size() > right.size()) {
97 // Now: left.size() == right.size()
98 for (ssize_t i = static_cast<ssize_t>(left.size()) - 1; i >= 0; --i) {
99 if (left[i] < right[i]) {
103 if (left[i] > right[i]) {
112 bool WacCertifyNumberString(const DPL::String &str)
114 for (DPL::String::const_iterator i = str.begin(); i != str.end(); ++i) {
123 bool WacCertifyAlphaNumberStringSpace(const DPL::String &str)
125 for (DPL::String::const_iterator i = str.begin(); i != str.end(); ++i) {
126 if (!IsDigit(*i) && !IsAlpha(*i) && !IsSp(*i)) {
135 WidgetVersion::WidgetVersion(const DPL::String &str) :
139 WrtLogD("Parsing version string: %ls", str.c_str());
141 // Split optional an mandatory parts
142 size_t optionalPartPosition = str.find(
143 WAC_CERTIFY_MANDATORY_VS_OPTIONAL_SPLIT_CHAR);
145 DPL::String mandatoryPart;
146 DPL::OptionalString optionalPart;
148 if (optionalPartPosition == DPL::String::npos) {
151 mandatoryPart = str.substr(0, optionalPartPosition);
152 optionalPart = str.substr(optionalPartPosition + 1, DPL::String::npos);
155 WrtLogD("Mandatory part is: %ls", mandatoryPart.c_str());
156 WrtLogD("Optional part is: %ls",
157 optionalPart.get_value_or(DPL::String()).c_str());
159 // Split string and construct version
160 std::vector<DPL::String> parts;
161 DPL::Tokenize(mandatoryPart,
162 WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR,
163 std::back_inserter(parts),
166 WrtLogD("Tokenized mandatory parts: %i", parts.size());
168 if (parts.size() != WAC_CERTIFY_MANDATORY_PART_LOW_COUNT &&
169 parts.size() != WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT)
176 DPL::OptionalString micro;
179 major = parts[WAC_CERTIFY_MANDATORY_PART_MAJOR_INDEX];
180 minor = parts[WAC_CERTIFY_MANDATORY_PART_MINOR_INDEX];
182 if (parts.size() == WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT) {
183 micro = parts[WAC_CERTIFY_MANDATORY_PART_MICRO_INDEX];
186 WacCertify(major, minor, micro, optionalPart);
189 WidgetVersion::WidgetVersion(const DPL::String &major,
190 const DPL::String &minor,
191 const DPL::OptionalString µ,
192 const DPL::OptionalString &optional) :
195 // Create Raw version
197 m_raw += WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR;
201 m_raw += WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR;
206 m_raw += WAC_CERTIFY_MANDATORY_VS_OPTIONAL_SPLIT_CHAR;
211 WacCertify(major, minor, micro, optional);
214 void WidgetVersion::WacCertify(const DPL::String &major,
215 const DPL::String &minor,
216 const DPL::OptionalString µ,
217 const DPL::OptionalString &optional)
219 WrtLogD("Certyfing...");
221 WrtLogD("Major candidate: %ls", major.c_str());
222 WrtLogD("Minor candidate: %ls", minor.c_str());
223 WrtLogD("Micro candidate: %ls", micro.get_value_or(DPL::String()).c_str());
224 WrtLogD("Optional candidate: %ls",
225 optional.get_value_or(DPL::String()).c_str());
228 if (major.empty() || !WacCertifyNumberString(major)) {
229 WrtLogD("Major version not certified!");
233 if (minor.empty() || !WacCertifyNumberString(minor)) {
234 WrtLogD("Minor version not certified!");
238 if (!!micro && (micro->empty() || !WacCertifyNumberString(*micro))) {
239 WrtLogD("Microversion not certified!");
244 (optional->empty() || !WacCertifyAlphaNumberStringSpace(*optional)))
246 WrtLogD("Optional version not certified!");
254 m_optional = optional;
258 WrtLogD("Certified.");
261 bool WidgetVersion::IsWac() const
266 const DPL::String &WidgetVersion::Raw() const
271 const DPL::String &WidgetVersion::Major() const
276 const DPL::String &WidgetVersion::Minor() const
281 const DPL::OptionalString &WidgetVersion::Micro() const
286 const DPL::OptionalString &WidgetVersion::Optional() const
291 bool operator<(const WidgetVersion &left,
292 const WidgetVersion &right)
295 left.IsWac() && right.IsWac(),
296 "Only WAC version strings are comparable!");
298 if (NumberLessOperator(RemoveLeadingZeroes(left.Major()),
299 RemoveLeadingZeroes(right.Major())))
303 if (NumberLessOperator(RemoveLeadingZeroes(right.Major()),
304 RemoveLeadingZeroes(left.Major())))
309 if (NumberLessOperator(RemoveLeadingZeroes(left.Minor()),
310 RemoveLeadingZeroes(right.Minor())))
314 if (NumberLessOperator(RemoveLeadingZeroes(right.Minor()),
315 RemoveLeadingZeroes(left.Minor())))
320 if (!!left.Micro() && !!right.Micro() &&
321 NumberLessOperator(RemoveLeadingZeroes(*left.Micro()),
322 RemoveLeadingZeroes(*right.Micro())))
326 if (!left.Micro() && !!right.Micro()) {
333 bool operator<=(const WidgetVersion &left,
334 const WidgetVersion &right)
337 left.IsWac() && right.IsWac(),
338 "Only WAC version strings are comparable!");
340 return (left == right) || (left < right);
343 bool operator>(const WidgetVersion &left,
344 const WidgetVersion &right)
347 left.IsWac() && right.IsWac(),
348 "Only WAC version strings are comparable!");
350 return !(left <= right);
353 bool operator>=(const WidgetVersion &left,
354 const WidgetVersion &right)
357 left.IsWac() && right.IsWac(),
358 "Only WAC version strings are comparable!");
360 return (left == right) || (left > right);
363 bool operator==(const WidgetVersion &left,
364 const WidgetVersion &right)
367 left.IsWac() && right.IsWac(),
368 "Only WAC version strings are comparable!");
374 //Both Micro exist and are equal
375 //or both Micro do not exist
376 return RemoveLeadingZeroes(left.Major()) ==
377 RemoveLeadingZeroes(right.Major()) &&
378 RemoveLeadingZeroes(left.Minor()) ==
379 RemoveLeadingZeroes(right.Minor()) &&
381 (!!left.Micro() && !!right.Micro() &&
382 RemoveLeadingZeroes(*left.Micro()) ==
383 RemoveLeadingZeroes(*right.Micro())) ||
384 (!left.Micro() && !right.Micro())
388 bool operator!=(const WidgetVersion &left,
389 const WidgetVersion &right)
392 left.IsWac() && right.IsWac(),
393 "Only WAC version strings are comparable!");
395 return !(left == right);
398 std::ostream & operator<<(std::ostream& stream,
399 const WidgetVersion& version)
401 stream << version.Raw();