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