1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "sem_ver.h"
16 
17 namespace OHOS {
18 namespace AppExecFwk {
19 namespace {
20 constexpr char PRE_RELEASE_SEPARATOR = '-';
21 constexpr char BUILD_META_SEPARATOR = '+';
22 constexpr char DOT = '.';
23 const size_t NUM_ONE = 1;
24 const size_t NUM_TWO = 2;
25 }
26 
SemVer(std::string versionString)27 SemVer::SemVer(std::string versionString) : raw(versionString)
28 {
29     if (versionString.empty()) {
30         return;
31     }
32     size_t pos1 = versionString.find(PRE_RELEASE_SEPARATOR);
33     size_t pos2 = versionString.find(BUILD_META_SEPARATOR);
34     std::string base;
35     if (pos1 != std::string::npos) {
36         base = versionString.substr(0, pos1);
37     } else if (pos2 != std::string::npos) {
38         base = versionString.substr(0, pos2);
39     } else {
40         base = versionString;
41     }
42     std::string preRel = "";
43     std::string build = "";
44     if (pos1 != std::string::npos) {
45         if (pos2 != std::string::npos) {
46             preRel = versionString.substr(pos1 + 1, pos2 - pos1 - 1);
47             build = versionString.substr(pos2 + 1);
48         } else {
49             preRel = versionString.substr(pos1 + 1);
50         }
51     } else if (pos2 != std::string::npos) {
52         build = versionString.substr(pos2 + 1);
53     }
54     std::istringstream issBase(base);
55     std::string segment;
56     std::vector<std::string> segments;
57     while (std::getline(issBase, segment, DOT)) {
58         segments.push_back(segment);
59     }
60     if (!segments.empty()) {
61         major = segments[0];
62     }
63     if (segments.size() > NUM_ONE) {
64         minor = segments[NUM_ONE];
65     }
66     if (segments.size() > NUM_TWO) {
67         patch = segments[NUM_TWO];
68     }
69 
70     std::istringstream issPreRel(preRel);
71     std::string segmentPreRel;
72     while (std::getline(issPreRel, segmentPreRel, DOT)) {
73         prerelease.push_back(segmentPreRel);
74     }
75     std::istringstream issBuild(build);
76     std::string segmentBuild;
77     while (std::getline(issBuild, segmentBuild, DOT)) {
78         buildMeta.push_back(segmentBuild);
79     }
80 }
81 } // namespace AppExecFwk
82 } // namespace OHOS