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