1 /*
2  * Copyright (c) 2021-2022 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 
16 #include "patterns_matcher.h"
17 #include "parcel_macro_base.h"
18 using namespace OHOS::AppExecFwk;
19 
20 namespace OHOS {
21 namespace AAFwk {
22 /**
23  * @brief A parameterized constructor used to create a PatternsMatcher instance.
24  *
25  */
PatternsMatcher()26 PatternsMatcher::PatternsMatcher()
27 {
28     pattern_ = "";
29     type_ = MatchType::DEFAULT;
30 }
31 
32 /**
33  * @brief A parameterized constructor used to create a PatternsMatcher instance.
34  *
35  * @param patternsMatcher Indicates patternsMatcher used to create a patternsMatcher instance.
36  */
PatternsMatcher(const PatternsMatcher & patternsMatcher)37 PatternsMatcher::PatternsMatcher(const PatternsMatcher &patternsMatcher)
38 {
39     pattern_ = patternsMatcher.GetPattern();
40     type_ = patternsMatcher.GetType();
41 }
42 
43 /**
44  * @brief A parameterized constructor used to create a PatternsMatcher instance.
45  *
46  * @param pattern Indicates pattern used to create a patternsMatcher instance.
47  * @param type Indicates type used to create a patternsMatcher instance.
48  */
PatternsMatcher(std::string pattern,MatchType type)49 PatternsMatcher::PatternsMatcher(std::string pattern, MatchType type)
50 {
51     pattern_ = pattern;
52     type_ = type;
53 }
54 
~PatternsMatcher()55 PatternsMatcher::~PatternsMatcher()
56 {}
57 
58 /**
59  * @brief Obtains the pattern.
60  *
61  * @return the specified pattern.
62  */
GetPattern() const63 std::string PatternsMatcher::GetPattern() const
64 {
65     return pattern_;
66 }
67 
68 /**
69  * @brief Obtains the specified type.
70  *
71  * @return the specified type.
72  */
GetType() const73 MatchType PatternsMatcher::GetType() const
74 {
75     return type_;
76 }
77 
78 /**
79  * @brief Match this PatternsMatcher against a string data.
80  *
81  * @param str The desired string to look for.
82  * @return Returns either a valid match constant.
83  */
match(std::string match)84 bool PatternsMatcher::match(std::string match)
85 {
86     return MatchPattern(pattern_, match, type_);
87 }
88 
89 /**
90  * @brief Match this PatternsMatcher against an Pattern's data.
91  *
92  * @param pattern The desired data to look for.
93  * @param match The full data string to match against.
94  * @param type The desired tyoe to look for.
95  *
96  * @return Returns either a valid match constant.
97  */
MatchPattern(std::string pattern,std::string match,MatchType type)98 bool PatternsMatcher::MatchPattern(std::string pattern, std::string match, MatchType type)
99 {
100     if (match.empty()) {
101         return false;
102     }
103     switch (type) {
104         case MatchType::DEFAULT: {
105             return pattern == match;
106         }
107         case MatchType::PREFIX: {
108             return match.find(pattern) == 0;
109         }
110         case MatchType::PATTERN: {
111             std::regex regex_(pattern);
112             return regex_match(match, regex_);
113         }
114         case MatchType::GLOBAL: {
115             return GlobPattern(pattern, match);
116         }
117         default: {
118             ABILITYBASE_LOGE("invalid type");
119             return false;
120         }
121     }
122 }
123 
124 /**
125  * @brief Match this PatternsMatcher against an Pattern's data.
126  *
127  * @param pattern The desired data to look for.
128  * @param match The full data string to match against.
129  *
130  * @return Returns either a valid match constant.
131  */
GlobPattern(std::string pattern,std::string match)132 bool PatternsMatcher::GlobPattern(std::string pattern, std::string match)
133 {
134     size_t indexP = 0;
135     size_t find_pos = 0;
136     size_t indexM = 0;
137     while (indexP < pattern.length() && find_pos != std::string::npos) {
138         find_pos = pattern.find("*", indexP);
139         std::string p;
140         if (find_pos == std::string::npos) {
141             p = pattern.substr(indexP, pattern.length());
142         } else {
143             p = pattern.substr(indexP, find_pos - indexP);
144         }
145         if (p.length() == 0) {
146             indexP = indexP + 1;
147             continue;
148         }
149         size_t find_pos_m = match.find(p, indexM);
150         if (find_pos_m == std::string::npos) {
151             return false;
152         }
153         indexP = find_pos;
154         indexM = find_pos_m + p.length();
155     }
156     if (indexM < match.length() && !(pattern.rfind("*") == pattern.length() - 1)) {
157         return false;
158     }
159     return true;
160 }
161 
162 /**
163  * @brief Marshals this Sequenceable object into a Parcel.
164  *
165  * @param outParcel Indicates the Parcel object to which the Sequenceable object will be marshaled.
166  */
Marshalling(Parcel & parcel) const167 bool PatternsMatcher::Marshalling(Parcel &parcel) const
168 {
169     // write pattern_
170     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(pattern_));
171     // type_
172     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(type_));
173 
174     return true;
175 }
176 
177 /**
178  * @brief Unmarshals this Sequenceable object from a Parcel.
179  *
180  * @param inParcel Indicates the Parcel object into which the Sequenceable object has been marshaled.
181  */
Unmarshalling(Parcel & parcel)182 PatternsMatcher *PatternsMatcher::Unmarshalling(Parcel &parcel)
183 {
184     PatternsMatcher *patternsMatcher = new (std::nothrow) PatternsMatcher();
185     if (patternsMatcher != nullptr && !patternsMatcher->ReadFromParcel(parcel)) {
186         delete patternsMatcher;
187         patternsMatcher = nullptr;
188     }
189     return patternsMatcher;
190 }
191 
ReadFromParcel(Parcel & parcel)192 bool PatternsMatcher::ReadFromParcel(Parcel &parcel)
193 {
194     // pattern_
195     std::u16string readString16;
196     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, readString16);
197     pattern_ = Str16ToStr8(readString16);
198 
199     // flags_
200     int32_t type;
201     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, type);
202     type_ = static_cast<MatchType>(type);
203 
204     return true;
205 }
206 }  // namespace AAFwk
207 }  // namespace OHOS