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 "skills.h"
17 using namespace OHOS;
18 using namespace OHOS::AppExecFwk;
19 namespace OHOS {
20 namespace AAFwk {
21 namespace {
22 const size_t LENGTH_FOR_FINDMINETYPE = 3;
23 constexpr int CYCLE_LIMIT = 1000;
24 }
25 /**
26 * @brief Default constructor used to create a Skills instance.
27 */
Skills()28 Skills::Skills()
29 {}
30
31 /**
32 * @brief A parameterized constructor used to create a Skills instance.
33 *
34 * @param skills Indicates skills used to create a Skills instance.
35 */
Skills(const Skills & skills)36 Skills::Skills(const Skills &skills)
37 {
38 // entities_
39 entities_ = skills.entities_;
40 // actions_
41 actions_ = skills.actions_;
42 // authorities_
43 authorities_ = skills.authorities_;
44 // schemes_
45 schemes_ = skills.schemes_;
46
47 // paths_
48 paths_ = skills.paths_;
49 // schemeSpecificParts_
50 schemeSpecificParts_ = skills.schemeSpecificParts_;
51 // types_
52 types_ = skills.types_;
53 }
54
~Skills()55 Skills::~Skills()
56 {
57 entities_.clear();
58 actions_.clear();
59 authorities_.clear();
60 schemes_.clear();
61
62 paths_.clear();
63 schemeSpecificParts_.clear();
64 types_.clear();
65 }
66
67 /**
68 * @brief Obtains the list of entities.
69 *
70 * @return vector of Entities.
71 */
GetEntities() const72 std::vector<std::string> Skills::GetEntities() const
73 {
74 return entities_;
75 }
76
77 /**
78 * @brief Obtains the specified entity.
79 *
80 * @param entity Id of the specified entity.
81 */
GetEntity(int index) const82 std::string Skills::GetEntity(int index) const
83 {
84 if (index < 0 || entities_.empty() || std::size_t(index) >= entities_.size()) {
85 return std::string();
86 }
87 return entities_.at(index);
88 }
89
90 /**
91 * @brief Adds an entity to this Skills object.
92 *
93 * @param entity Indicates the entity to add.
94 */
AddEntity(const std::string & entity)95 void Skills::AddEntity(const std::string &entity)
96 {
97 auto it = std::find(entities_.begin(), entities_.end(), entity);
98 if (it == entities_.end()) {
99 entities_.emplace_back(entity);
100 }
101 }
102
103 /**
104 * @brief Checks whether the specified entity is exist.
105 *
106 * @param entity Name of the specified entity.
107 */
HasEntity(const std::string & entity)108 bool Skills::HasEntity(const std::string &entity)
109 {
110 return std::find(entities_.begin(), entities_.end(), entity) != entities_.end();
111 }
112
113 /**
114 * @brief Remove the specified entity.
115 *
116 * @param entity Name of the specified entity.
117 */
RemoveEntity(const std::string & entity)118 void Skills::RemoveEntity(const std::string &entity)
119 {
120 if (!entities_.empty()) {
121 auto it = std::find(entities_.begin(), entities_.end(), entity);
122 if (it != entities_.end()) {
123 entities_.erase(it);
124 }
125 }
126 }
127
128 /**
129 * @brief Obtains the count of entities.
130 *
131 */
CountEntities() const132 int Skills::CountEntities() const
133 {
134 return entities_.empty() ? 0 : entities_.size();
135 }
136
137 /**
138 * @brief Obtains the specified action.
139 *
140 * @param actionId Id of the specified action.
141 */
GetAction(int index) const142 std::string Skills::GetAction(int index) const
143 {
144 if (index < 0 || actions_.empty() || std::size_t(index) >= actions_.size()) {
145 return std::string();
146 } else {
147 return actions_.at(index);
148 }
149 }
150
151 /**
152 * @brief Adds an action to this Skills object.
153 *
154 * @param action Indicates the action to add.
155 */
AddAction(const std::string & action)156 void Skills::AddAction(const std::string &action)
157 {
158 auto it = std::find(actions_.begin(), actions_.end(), action);
159 if (it == actions_.end()) {
160 actions_.emplace_back(action);
161 }
162 }
163
164 /**
165 * @brief Checks whether the specified action is exist.
166 *
167 * @param action Name of the specified action.
168 */
HasAction(const std::string & action)169 bool Skills::HasAction(const std::string &action)
170 {
171 return std::find(actions_.begin(), actions_.end(), action) != actions_.end();
172 }
173
174 /**
175 * @brief Remove the specified action.
176 *
177 * @param action Name of the specified action.
178 */
RemoveAction(const std::string & action)179 void Skills::RemoveAction(const std::string &action)
180 {
181 if (!actions_.empty()) {
182 auto it = std::find(actions_.begin(), actions_.end(), action);
183 if (it != actions_.end()) {
184 actions_.erase(it);
185 }
186 }
187 }
188
189 /**
190 * @brief Obtains the count of actions.
191 *
192 */
CountActions() const193 int Skills::CountActions() const
194 {
195 return actions_.empty() ? 0 : actions_.size();
196 }
197
198 /**
199 * @brief Obtains the iterator of Actions.
200 *
201 * @return iterator of Actions.
202 */
ActionsIterator()203 std::vector<std::string>::iterator Skills::ActionsIterator()
204 {
205 return actions_.begin();
206 }
207
208 /**
209 * @brief Obtains the specified authority.
210 *
211 * @param authorityId Id of the specified authority.
212 */
GetAuthority(int index) const213 std::string Skills::GetAuthority(int index) const
214 {
215 if (index < 0 || authorities_.empty() || std::size_t(index) >= authorities_.size()) {
216 return std::string();
217 } else {
218 return authorities_.at(index);
219 }
220 }
221
222 /**
223 * @brief Adds an authority to this Skills object.
224 *
225 * @param authority Indicates the authority to add.
226 */
AddAuthority(const std::string & authority)227 void Skills::AddAuthority(const std::string &authority)
228 {
229 auto it = std::find(authorities_.begin(), authorities_.end(), authority);
230 if (it == authorities_.end()) {
231 authorities_.emplace_back(authority);
232 }
233 }
234
235 /**
236 * @brief Checks whether the specified authority is exist.
237 *
238 * @param action Name of the specified authority.
239 */
HasAuthority(const std::string & authority)240 bool Skills::HasAuthority(const std::string &authority)
241 {
242 return std::find(authorities_.begin(), authorities_.end(), authority) != authorities_.end();
243 }
244
245 /**
246 * @brief Remove the specified authority.
247 *
248 * @param authority Name of the specified authority.
249 */
RemoveAuthority(const std::string & authority)250 void Skills::RemoveAuthority(const std::string &authority)
251 {
252 if (!authorities_.empty()) {
253 auto it = std::find(authorities_.begin(), authorities_.end(), authority);
254 if (it != authorities_.end()) {
255 authorities_.erase(it);
256 }
257 }
258 }
259
260 /**
261 * @brief Obtains the count of authorities.
262 *
263 */
CountAuthorities() const264 int Skills::CountAuthorities() const
265 {
266 return authorities_.empty() ? 0 : authorities_.size();
267 }
268
269 /**
270 * @brief Obtains the specified path.
271 *
272 * @param pathId Id of the specified path.
273 */
GetPath(int index) const274 std::string Skills::GetPath(int index) const
275 {
276 if (index < 0 || paths_.empty() || std::size_t(index) >= paths_.size()) {
277 return std::string();
278 }
279 return paths_.at(index).GetPattern();
280 }
281
282 /**
283 * @brief Adds a path to this Skills object.
284 *
285 * @param path Indicates the path to add.
286 */
AddPath(const std::string & path)287 void Skills::AddPath(const std::string &path)
288 {
289 PatternsMatcher pm(path, MatchType::DEFAULT);
290 AddPath(pm);
291 }
292
293 /**
294 * @brief Adds a path to this Skills object.
295 *
296 * @param path Indicates the path to add.
297 */
AddPath(const PatternsMatcher & patternsMatcher)298 void Skills::AddPath(const PatternsMatcher &patternsMatcher)
299 {
300 auto hasPath = std::find_if(paths_.begin(), paths_.end(), [&patternsMatcher](const PatternsMatcher pm) {
301 return (pm.GetPattern() == patternsMatcher.GetPattern()) && (pm.GetType() == patternsMatcher.GetType());
302 });
303 if (hasPath == paths_.end()) {
304 paths_.emplace_back(patternsMatcher);
305 }
306 }
307
308 /**
309 * @brief Adds a path to this Skills object.
310 *
311 * @param path Indicates the path to add.
312 * @param matchType the specified match type.
313 */
AddPath(const std::string & path,const MatchType & matchType)314 void Skills::AddPath(const std::string &path, const MatchType &matchType)
315 {
316 PatternsMatcher pm(path, matchType);
317 AddPath(pm);
318 }
319
320 /**
321 * @brief Checks whether the specified path is exist.
322 *
323 * @param path Name of the specified path.
324 */
HasPath(const std::string & path)325 bool Skills::HasPath(const std::string &path)
326 {
327 auto hasPath = std::find_if(
328 paths_.begin(), paths_.end(), [&path](const PatternsMatcher pm) { return pm.GetPattern() == path; });
329 return hasPath != paths_.end();
330 }
331
332 /**
333 * @brief Remove the specified path.
334 *
335 * @param path Name of the specified path.
336 */
RemovePath(const std::string & path)337 void Skills::RemovePath(const std::string &path)
338 {
339 auto hasPath = std::find_if(
340 paths_.begin(), paths_.end(), [&path](const PatternsMatcher pm) { return pm.GetPattern() == path; });
341 if (hasPath != paths_.end()) {
342 paths_.erase(hasPath);
343 }
344 }
345
346 /**
347 * @brief Remove the specified path.
348 *
349 * @param path The path to be added.
350 */
RemovePath(const PatternsMatcher & patternsMatcher)351 void Skills::RemovePath(const PatternsMatcher &patternsMatcher)
352 {
353 auto hasPath = std::find_if(paths_.begin(), paths_.end(), [&patternsMatcher](const PatternsMatcher pm) {
354 return (pm.GetPattern() == patternsMatcher.GetPattern()) && (pm.GetType() == patternsMatcher.GetType());
355 });
356 if (hasPath != paths_.end()) {
357 paths_.erase(hasPath);
358 }
359 }
360
361 /**
362 * @brief Remove the specified path.
363 *
364 * @param path Name of the specified path.
365 * @param matchType the specified match type.
366 */
RemovePath(const std::string & path,const MatchType & matchType)367 void Skills::RemovePath(const std::string &path, const MatchType &matchType)
368 {
369 PatternsMatcher pm(path, matchType);
370 RemovePath(pm);
371 }
372
373 /**
374 * @brief Obtains the count of paths.
375 *
376 */
CountPaths() const377 int Skills::CountPaths() const
378 {
379 return paths_.empty() ? 0 : paths_.size();
380 }
381
382 /**
383 * @brief Obtains the specified scheme.
384 *
385 * @param schemeId Id of the specified scheme.
386 */
GetScheme(int index) const387 std::string Skills::GetScheme(int index) const
388 {
389 if (index < 0 || schemes_.empty() || std::size_t(index) >= schemes_.size()) {
390 return std::string();
391 }
392 return schemes_.at(index);
393 }
394
395 /**
396 * @brief Adds an scheme to this Skills object.
397 *
398 * @param scheme Indicates the scheme to add.
399 */
AddScheme(const std::string & scheme)400 void Skills::AddScheme(const std::string &scheme)
401 {
402 auto it = std::find(schemes_.begin(), schemes_.end(), scheme);
403 if (it == schemes_.end()) {
404 schemes_.emplace_back(scheme);
405 }
406 }
407
408 /**
409 * @brief Checks whether the specified scheme is exist.
410 *
411 * @param scheme Name of the specified scheme.
412 */
HasScheme(const std::string & scheme)413 bool Skills::HasScheme(const std::string &scheme)
414 {
415 return std::find(schemes_.begin(), schemes_.end(), scheme) != schemes_.end();
416 }
417
418 /**
419 * @brief Remove the specified scheme.
420 *
421 * @param scheme Name of the specified scheme.
422 */
RemoveScheme(const std::string & scheme)423 void Skills::RemoveScheme(const std::string &scheme)
424 {
425 if (!schemes_.empty()) {
426 auto it = std::find(schemes_.begin(), schemes_.end(), scheme);
427 if (it != schemes_.end()) {
428 schemes_.erase(it);
429 }
430 }
431 }
432
433 /**
434 * @brief Obtains the count of schemes.
435 *
436 */
CountSchemes() const437 int Skills::CountSchemes() const
438 {
439 return schemes_.empty() ? 0 : schemes_.size();
440 }
441
442 /**
443 * @brief Obtains the specified scheme part.
444 *
445 * @param schemeId Id of the specified scheme part.
446 */
GetSchemeSpecificPart(int index) const447 std::string Skills::GetSchemeSpecificPart(int index) const
448 {
449 if (index < 0 || schemeSpecificParts_.empty() || std::size_t(index) >= schemeSpecificParts_.size()) {
450 return std::string();
451 }
452 return schemeSpecificParts_.at(index).GetPattern();
453 }
454
455 /**
456 * @brief Adds an scheme to this Skills object.
457 *
458 * @param scheme Indicates the scheme to add.
459 */
AddSchemeSpecificPart(const std::string & schemeSpecificPart)460 void Skills::AddSchemeSpecificPart(const std::string &schemeSpecificPart)
461 {
462 PatternsMatcher patternsMatcher(schemeSpecificPart, MatchType::DEFAULT);
463 auto it = std::find_if(
464 schemeSpecificParts_.begin(), schemeSpecificParts_.end(), [&patternsMatcher](const PatternsMatcher pm) {
465 return (pm.GetPattern() == patternsMatcher.GetPattern()) && (pm.GetType() == patternsMatcher.GetType());
466 });
467 if (it == schemeSpecificParts_.end()) {
468 schemeSpecificParts_.emplace_back(patternsMatcher);
469 }
470 }
471
472 /**
473 * @brief Checks whether the specified scheme part is exist.
474 *
475 * @param scheme Name of the specified scheme part.
476 */
HasSchemeSpecificPart(const std::string & schemeSpecificPart)477 bool Skills::HasSchemeSpecificPart(const std::string &schemeSpecificPart)
478 {
479 auto it = std::find_if(schemeSpecificParts_.begin(),
480 schemeSpecificParts_.end(),
481 [&schemeSpecificPart](const PatternsMatcher pm) { return pm.GetPattern() == schemeSpecificPart; });
482 return it != schemeSpecificParts_.end();
483 }
484
485 /**
486 * @brief Remove the specified scheme part.
487 *
488 * @param scheme Name of the specified scheme part.
489 */
RemoveSchemeSpecificPart(const std::string & schemeSpecificPart)490 void Skills::RemoveSchemeSpecificPart(const std::string &schemeSpecificPart)
491 {
492 auto it = std::find_if(schemeSpecificParts_.begin(),
493 schemeSpecificParts_.end(),
494 [&schemeSpecificPart](const PatternsMatcher pm) { return pm.GetPattern() == schemeSpecificPart; });
495 if (it != schemeSpecificParts_.end()) {
496 schemeSpecificParts_.erase(it);
497 }
498 }
499
500 /**
501 * @brief Obtains the count of scheme parts.
502 *
503 */
CountSchemeSpecificParts() const504 int Skills::CountSchemeSpecificParts() const
505 {
506 return schemeSpecificParts_.empty() ? 0 : schemeSpecificParts_.size();
507 }
508
509 /**
510 * @brief Obtains the specified type.
511 *
512 * @param typeId Id of the specified type.
513 */
GetType(int index) const514 std::string Skills::GetType(int index) const
515 {
516 if (index < 0 || types_.empty() || std::size_t(index) >= types_.size()) {
517 return std::string();
518 }
519 return types_.at(index).GetPattern();
520 }
521
522 /**
523 * @brief Adds a type to this Skills object.
524 *
525 * @param type Indicates the type to add.
526 */
AddType(const std::string & type)527 void Skills::AddType(const std::string &type)
528 {
529 PatternsMatcher pm(type, MatchType::DEFAULT);
530 AddType(pm);
531 }
532
533 /**
534 * @brief Adds a type to this Skills object.
535 *
536 * @param type Indicates the type to add.
537 * @param matchType the specified match type.
538 */
AddType(const std::string & type,const MatchType & matchType)539 void Skills::AddType(const std::string &type, const MatchType &matchType)
540 {
541 PatternsMatcher pm(type, matchType);
542 AddType(pm);
543 }
544
545 /**
546 * @brief Adds a type to this Skills object.
547 *
548 * @param type Indicates the type to add.
549 */
AddType(const PatternsMatcher & patternsMatcher)550 void Skills::AddType(const PatternsMatcher &patternsMatcher)
551 {
552 const size_t posNext = 1;
553 const size_t posOffset = 2;
554 std::string type = patternsMatcher.GetPattern();
555 size_t slashpos = type.find('/');
556 size_t typelen = type.length();
557 if (slashpos != std::string::npos && typelen >= slashpos + posOffset) {
558 if (typelen == slashpos + posOffset && type.at(slashpos + posNext) == '*') {
559 PatternsMatcher pm(type.substr(0, slashpos), patternsMatcher.GetType());
560 auto it = std::find_if(types_.begin(),
561 types_.end(),
562 [type = pm.GetPattern(), matchType = pm.GetType()](
563 const PatternsMatcher pm) { return (pm.GetPattern() == type) && (pm.GetType() == matchType); });
564 if (it == types_.end()) {
565 types_.emplace_back(pm);
566 }
567 hasPartialTypes_ = true;
568 } else {
569 PatternsMatcher pm(patternsMatcher);
570 auto it = std::find_if(types_.begin(),
571 types_.end(),
572 [type = pm.GetPattern(), matchType = pm.GetType()](
573 const PatternsMatcher pm) { return (pm.GetPattern() == type) && (pm.GetType() == matchType); });
574 if (it == types_.end()) {
575 types_.emplace_back(pm);
576 }
577 }
578 }
579 }
580
581 /**
582 * @brief Checks whether the specified type is exist.
583 *
584 * @param type Name of the specified type.
585 */
HasType(const std::string & type)586 bool Skills::HasType(const std::string &type)
587 {
588 auto it = std::find_if(
589 types_.begin(), types_.end(), [&type](const PatternsMatcher pm) { return pm.GetPattern() == type; });
590 return it != types_.end();
591 }
592
593 /**
594 * @brief Remove the specified type.
595 *
596 * @param type Name of the specified type.
597 */
RemoveType(const std::string & type)598 void Skills::RemoveType(const std::string &type)
599 {
600 auto it = std::find_if(
601 types_.begin(), types_.end(), [&type](const PatternsMatcher pm) { return pm.GetPattern() == type; });
602 if (it != types_.end()) {
603 types_.erase(it);
604 }
605 }
606
607 /**
608 * @brief Remove the specified scheme type.
609 *
610 * @param patternsMatcher The type to be added.
611 */
RemoveType(const PatternsMatcher & patternsMatcher)612 void Skills::RemoveType(const PatternsMatcher &patternsMatcher)
613 {
614 auto it = std::find_if(types_.begin(), types_.end(), [&patternsMatcher](const PatternsMatcher pm) {
615 return (pm.GetPattern() == patternsMatcher.GetPattern()) && (pm.GetType() == patternsMatcher.GetType());
616 });
617 if (it != types_.end()) {
618 types_.erase(it);
619 }
620 }
621
622 /**
623 * @brief Remove the specified scheme type.
624 *
625 * @param type Name of the specified type.
626 * @param matchType the specified match type.
627 */
RemoveType(const std::string & type,const MatchType & matchType)628 void Skills::RemoveType(const std::string &type, const MatchType &matchType)
629 {
630 PatternsMatcher pm(type, matchType);
631 RemoveType(pm);
632 }
633
634 /**
635 * @brief Obtains the count of types.
636 *
637 */
CountTypes() const638 int Skills::CountTypes() const
639 {
640 return types_.empty() ? 0 : types_.size();
641 }
642
643 /**
644 * @brief Match this skill against a Want's data.
645 *
646 * @param want The desired want data to match for.
647 */
Match(const Want & want)648 bool Skills::Match(const Want &want)
649 {
650 if (!MatchAction(want.GetAction())) {
651 return false;
652 }
653
654 int dataMatch = MatchData(want.GetType(), want.GetScheme(), want.GetUri());
655 if (dataMatch < 0) {
656 return false;
657 }
658
659 std::string entityMismatch = MatchEntities(want.GetEntities());
660 if (entityMismatch == std::string()) {
661 return false;
662 }
663
664 return true;
665 }
666
667 /**
668 * @brief Match this skills against a Want's entities. Each entity in
669 * the Want must be specified by the skills; if any are not in the
670 * skills, the match fails.
671 *
672 * @param entities The entities included in the want, as returned by
673 * Want.getEntities().
674 *
675 * @return If all entities match (success), null; else the name of the
676 * first entity that didn't match.
677 */
MatchEntities(const std::vector<std::string> & entities)678 std::string Skills::MatchEntities(const std::vector<std::string> &entities)
679 {
680 if (!entities.empty()) {
681 size_t size = entities.size();
682 for (size_t i = 0; i < size; i++) {
683 auto it = std::find(entities_.begin(), entities_.end(), entities[i]);
684 if (it != entities_.end()) {
685 return entities[i];
686 }
687 }
688 }
689
690 return std::string();
691 }
692
693 /**
694 * @brief Match this skills against a Want's action. If the skills does not
695 * specify any actions, the match will always fail.
696 *
697 * @param action The desired action to look for.
698 *
699 * @return True if the action is listed in the skills.
700 */
MatchAction(const std::string & action)701 bool Skills::MatchAction(const std::string &action)
702 {
703 return (action.empty() && actions_.empty()) || HasAction(action);
704 }
705
706 /**
707 * @brief Match this skills against a Want's data (type, scheme and path).
708 *
709 * @param type The desired data type to look for.
710 * @param scheme The desired data scheme to look for.
711 * @param data The full data string to match against.
712 *
713 * @return Returns either a valid match constant.
714 */
MatchData(const std::string & type,const std::string & scheme,Uri data)715 int Skills::MatchData(const std::string &type, const std::string &scheme, Uri data)
716 {
717 std::vector<std::string> types;
718 for (auto it = types_.begin(); it != types_.end(); it++) {
719 types.emplace_back(it->GetPattern());
720 }
721 std::vector<std::string> schemes = schemes_;
722
723 int match = RESULT_EMPTY;
724
725 if (types.empty() && schemes.empty()) {
726 return (type == std::string() ? (RESULT_EMPTY + RESULT_NORMAL) : DISMATCH_DATA);
727 }
728
729 if (!schemes.empty()) {
730 auto it = std::find(schemes.begin(), schemes.end(), scheme);
731 if (it != schemes.end()) {
732 match = RESULT_SCHEME;
733 } else {
734 return DISMATCH_DATA;
735 }
736
737 std::vector<PatternsMatcher> schemeSpecificParts = schemeSpecificParts_;
738 if (schemeSpecificParts.size() >= 0) {
739 match = HasSchemeSpecificPart(data.GetSchemeSpecificPart()) ? RESULT_SCHEME_SPECIFIC_PART : DISMATCH_DATA;
740 }
741 if (match != RESULT_SCHEME_SPECIFIC_PART) {
742 std::vector<std::string> authorities = authorities_;
743 if (authorities.size() >= 0) {
744 bool authMatch = HasAuthority(data.GetAuthority());
745 if (authMatch == false) {
746 return DISMATCH_DATA;
747 }
748 std::vector<PatternsMatcher> paths = paths_;
749 if (paths.size() <= 0) {
750 match = authMatch;
751 } else if (HasPath(data.GetPath())) {
752 match = RESULT_PATH;
753 } else {
754 return DISMATCH_DATA;
755 }
756 }
757 }
758 if (match == DISMATCH_DATA) {
759 return DISMATCH_DATA;
760 }
761 } else {
762 if (scheme != std::string() && scheme != "content" && scheme != "file") {
763 return DISMATCH_DATA;
764 }
765 }
766
767 if (!types.empty()) {
768 if (FindMimeType(type)) {
769 match = RESULT_TYPE;
770 } else {
771 return DISMATCH_TYPE;
772 }
773 } else {
774 if (type != std::string()) {
775 return DISMATCH_TYPE;
776 }
777 }
778
779 return match + RESULT_NORMAL;
780 }
781
FindMimeType(const std::string & type)782 bool Skills::FindMimeType(const std::string &type)
783 {
784 const int posNext = 1;
785 const int posOffset = 2;
786 std::vector<PatternsMatcher> types = types_;
787
788 if (type == std::string()) {
789 return false;
790 }
791 auto it = types.begin();
792 for (; it != types.end(); it++) {
793 if (it->GetPattern() == type) {
794 break;
795 }
796 }
797 if (it != types.end()) {
798 return true;
799 }
800
801 size_t typeLength = type.length();
802 if (typeLength == LENGTH_FOR_FINDMINETYPE && type == "*/*") {
803 return !types.empty();
804 }
805
806 auto hasType =
807 std::find_if(types.begin(), types.end(), [](const PatternsMatcher pm) { return pm.GetPattern() == "*"; });
808 if (hasPartialTypes_ && hasType != types.end()) {
809 return true;
810 }
811
812 auto typeIt = type.find(0, 1, '/');
813 size_t slashpos = type.size() - typeIt;
814 if (slashpos <= 0) {
815 return false;
816 }
817
818 std::string typeSubstr = type.substr(0, slashpos);
819
820 hasType = std::find_if(types.begin(), types.end(), [&typeSubstr](const PatternsMatcher pm) {
821 return pm.GetPattern() == typeSubstr;
822 });
823 if (hasPartialTypes_ && hasType != types.end()) {
824 return true;
825 }
826
827 if (typeLength == slashpos + posOffset && type.at(slashpos + posNext) == '*') {
828 size_t numTypes = types.size();
829 for (size_t i = 0; i < numTypes; i++) {
830 std::string value = types.at(i).GetPattern();
831 if (RegionMatches(type, 0, value, 0, slashpos + posNext)) {
832 return true;
833 }
834 }
835 }
836
837 return false;
838 }
839
RegionMatches(const std::string & type,int toffset,const std::string & other,int ooffset,int len)840 bool Skills::RegionMatches(const std::string &type, int toffset, const std::string &other, int ooffset, int len)
841 {
842 int to = toffset;
843 int po = ooffset;
844 // Note: toffset, ooffset, or len might be near -1>>>1.
845 if ((ooffset < 0) || (toffset < 0) || (toffset > (long)type.size() - len) ||
846 (ooffset > (long)other.length() - len)) {
847 return false;
848 }
849 while (len-- > 0) {
850 if (type.at(to++) != other.at(po++)) {
851 return false;
852 }
853 }
854 return true;
855 }
856
857 /**
858 * @brief Obtains the want params data.
859 *
860 * @return the WantParams object.
861 */
GetWantParams() const862 const WantParams &Skills::GetWantParams() const
863 {
864 return wantParams_;
865 }
866
867 /**
868 * @brief Sets a WantParams object in this MatchingSkills object.
869 *
870 * @param wantParams Indicates the WantParams object.
871 */
SetWantParams(const WantParams & wantParams)872 void Skills::SetWantParams(const WantParams &wantParams)
873 {
874 wantParams_ = wantParams;
875 }
876
877 /**
878 * @brief Marshals this Sequenceable object into a Parcel.
879 *
880 * @param outParcel Indicates the Parcel object to which the Sequenceable object will be marshaled.
881 */
Marshalling(Parcel & parcel) const882 bool Skills::Marshalling(Parcel &parcel) const
883 {
884 // entities_
885 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, entities_);
886 // actions_
887 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, actions_);
888 // authorities_
889 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, authorities_);
890 // schemes_
891 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, schemes_);
892 // paths_
893 if (paths_.empty()) {
894 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, VALUE_NULL);
895 } else {
896 if (!parcel.WriteInt32(VALUE_OBJECT)) {
897 return false;
898 }
899 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, paths_.size());
900 for (auto path : paths_) {
901 if (!parcel.WriteParcelable(&path)) {
902 return false;
903 }
904 }
905 }
906 // schemeSpecificParts_
907 if (schemeSpecificParts_.empty()) {
908 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, VALUE_NULL);
909 } else {
910 if (!parcel.WriteInt32(VALUE_OBJECT)) {
911 return false;
912 }
913 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, schemeSpecificParts_.size());
914 for (auto schemeSpecificPart : schemeSpecificParts_) {
915 if (!parcel.WriteParcelable(&schemeSpecificPart)) {
916 return false;
917 }
918 }
919 }
920 // types_
921 if (types_.empty()) {
922 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, VALUE_NULL);
923 } else {
924 if (!parcel.WriteInt32(VALUE_OBJECT)) {
925 return false;
926 }
927 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, types_.size());
928 for (auto type : types_) {
929 if (!parcel.WriteParcelable(&type)) {
930 return false;
931 }
932 }
933 }
934
935 // parameters_
936 if (wantParams_.GetParams().empty()) {
937 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, VALUE_NULL);
938 } else {
939 if (!parcel.WriteInt32(VALUE_OBJECT)) {
940 return false;
941 }
942 if (!parcel.WriteParcelable(&wantParams_)) {
943 return false;
944 }
945 }
946 return true;
947 }
948
949 /**
950 * @brief Unmarshals this Sequenceable object from a Parcel.
951 *
952 * @param inParcel Indicates the Parcel object into which the Sequenceable object has been marshaled.
953 */
Unmarshalling(Parcel & parcel)954 Skills *Skills::Unmarshalling(Parcel &parcel)
955 {
956 Skills *skills = new (std::nothrow) Skills();
957 if (skills != nullptr) {
958 if (!skills->ReadFromParcel(parcel)) {
959 delete skills;
960 skills = nullptr;
961 }
962 }
963 return skills;
964 }
965
ReadFromParcel(Parcel & parcel)966 bool Skills::ReadFromParcel(Parcel &parcel)
967 {
968 int32_t empty;
969 int32_t size = 0;
970 PatternsMatcher *pm = nullptr;
971
972 // entities_
973 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, &entities_);
974 // actions_
975 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, &actions_);
976 // authorities_
977 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, &authorities_);
978 // schemes_
979 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, &schemes_);
980 // paths_
981 empty = VALUE_NULL;
982 if (!parcel.ReadInt32(empty)) {
983 return false;
984 }
985
986 if (empty == VALUE_OBJECT) {
987 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, size);
988 if (size > CYCLE_LIMIT) {
989 return false;
990 }
991 for (int i = 0; i < size; i++) {
992 pm = parcel.ReadParcelable<PatternsMatcher>();
993 if (pm == nullptr) {
994 return false;
995 } else {
996 paths_.emplace_back(*pm);
997 delete pm;
998 pm = nullptr;
999 }
1000 }
1001 }
1002
1003 // schemeSpecificParts_
1004 empty = VALUE_NULL;
1005 if (!parcel.ReadInt32(empty)) {
1006 return false;
1007 }
1008
1009 if (empty == VALUE_OBJECT) {
1010 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, size);
1011 if (size > CYCLE_LIMIT) {
1012 return false;
1013 }
1014 for (int i = 0; i < size; i++) {
1015 pm = parcel.ReadParcelable<PatternsMatcher>();
1016 if (pm == nullptr) {
1017 return false;
1018 } else {
1019 schemeSpecificParts_.emplace_back(*pm);
1020 delete pm;
1021 pm = nullptr;
1022 }
1023 }
1024 }
1025
1026 // types_
1027 empty = VALUE_NULL;
1028 if (!parcel.ReadInt32(empty)) {
1029 return false;
1030 }
1031
1032 if (empty == VALUE_OBJECT) {
1033 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, size);
1034 if (size > CYCLE_LIMIT) {
1035 return false;
1036 }
1037 for (int i = 0; i < size; i++) {
1038 pm = parcel.ReadParcelable<PatternsMatcher>();
1039 if (pm == nullptr) {
1040 return false;
1041 } else {
1042 types_.emplace_back(*pm);
1043 delete pm;
1044 pm = nullptr;
1045 }
1046 }
1047 }
1048
1049 // parameters_
1050 empty = VALUE_NULL;
1051 if (!parcel.ReadInt32(empty)) {
1052 return false;
1053 }
1054
1055 if (empty == VALUE_OBJECT) {
1056 auto params = parcel.ReadParcelable<WantParams>();
1057 if (params != nullptr) {
1058 wantParams_ = *params;
1059 delete params;
1060 params = nullptr;
1061 } else {
1062 return false;
1063 }
1064 }
1065
1066 return true;
1067 }
1068 } // namespace AAFwk
1069 } // namespace OHOS