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