• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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