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