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 #define private public
17 #include "module_test_dump_util.h"
18 #undef private
19 
20 namespace OHOS {
21 namespace MTUtil {
22 std::mutex MTDumpUtil::mutex_;
23 std::shared_ptr<MTDumpUtil> MTDumpUtil::instance_ = nullptr;
24 
GetInstance()25 std::shared_ptr<MTDumpUtil> MTDumpUtil::GetInstance()
26 {
27     if (instance_ == nullptr) {
28         std::lock_guard<std::mutex> lock_l(mutex_);
29         if (instance_ == nullptr) {
30             instance_ = std::make_shared<MTDumpUtil>();
31         }
32     }
33     return instance_;
34 }
35 
MTDumpUtil()36 MTDumpUtil::MTDumpUtil()
37 {
38     findRgx_["Want"] = regex(".*Want\\[(.+)\\].*");
39     findRgx_["AbilityName"] = regex(".*main name \\[(.+)\\].*");
40     findRgx_["AppName"] = regex(".*app name \\[(.+)\\].*");
41     findRgx_["BundleName"] = regex(".*bundle name \\[(.+)\\].*");
42     findRgx_["AbilityType"] = regex(".*ability type \\[(.+)\\].*");
43     findRgx_["PreAbilityName"] = regex(".*previous ability app name \\[(.+)\\].*");
44     findRgx_["PreAppName"] = regex(".*previous ability file name \\[(.+)\\].*");
45     findRgx_["NextAbilityName"] = regex(".*next ability app name \\[(.+)\\].*");
46     findRgx_["NextAppName"] = regex(".*next ability file name \\[(.+)\\].*");
47     findRgx_["State"] = regex(".*state #(.+)  .*");
48     findRgx_["StartTime"] = regex(".*start time \\[(.+)\\].*");
49     findRgx_["MissionBottomApp"] = regex(".*bottom app \\[(.+)\\].*");
50     findRgx_["UserID"] = regex(".*User ID #(.+)\\].*");
51     findRgx_["Uri"] = regex(".*uri \\[(.+)\\].*");
52     findRgx_["AbilityRecordID"] = regex(".*AbilityRecord ID #(.+)   state.*");
53     findRgx_["Bindings"] = regex(".+s: (\\d+).*");
54     findRgx_["Component"] = regex(".*> (.+)   .+#.+");
55     findRgx_["BindState"] = regex(".*> .+/.+ #(.+)");
56 }
57 
~MTDumpUtil()58 MTDumpUtil::~MTDumpUtil()
59 {
60     instance_ = nullptr;
61     instance_.reset();
62 }
63 
CompStrVec(const str_vec & strVec_1,const str_vec & strVec_2)64 bool MTDumpUtil::CompStrVec(const str_vec& strVec_1, const str_vec& strVec_2)
65 {
66     if (strVec_1.size() != strVec_2.size()) {
67         return false;
68     }
69     for (unsigned int i = 0; i < strVec_1.size(); ++i) {
70         if (strVec_1[i].compare(strVec_2[i]) != 0) {
71             return false;
72         }
73     }
74     return true;
75 }
76 
GetSpecific(const string & matchStr,const str_vec & dumpInfo,const str_iter & begin)77 str_iter MTDumpUtil::GetSpecific(const string& matchStr, const str_vec& dumpInfo, const str_iter& begin)
78 {
79     auto checkCondition = [&matchStr](const str_vec::value_type& value) -> bool {
80         return value.find(matchStr) != string::npos;
81     };
82     str_iter end;
83     std::advance(end, dumpInfo.size());
84     return std::find_if(begin, end, checkCondition);
85 }
86 
MatchRegex(const regex & regex,const string & str,string & result)87 bool MTDumpUtil::MatchRegex(const regex& regex, const string& str, string& result)
88 {
89     std::smatch baseMatch;
90     std::size_t size = 2;
91     if (std::regex_match(str, baseMatch, regex)) {
92         if (baseMatch.size() == size) {
93             result = baseMatch[1].str();
94             return true;
95         }
96     }
97     return false;
98 }
99 
GetAll(const string & args,const str_vec & dumpInfo,str_vec & results)100 size_t MTDumpUtil::GetAll(const string& args, const str_vec& dumpInfo, str_vec& results)
101 {
102     results.clear();
103     // args not exist
104     if (findRgx_.find(args) == findRgx_.end()) {
105         return 0;
106     }
107     string findResult;
108     for (const auto& info : dumpInfo) {
109         if (MatchRegex(findRgx_[args], info, findResult)) {
110             results.emplace_back(findResult);
111         }
112     }
113     return results.size();
114 }
115 
GetFirst(const string & args,const str_vec & dumpInfo,const str_iter & begin,string & result)116 str_iter MTDumpUtil::GetFirst(const string& args, const str_vec& dumpInfo, const str_iter& begin, string& result)
117 {
118     result.clear();
119     str_iter end;
120     std::advance(end, dumpInfo.size());
121     // args not exist
122     if (findRgx_.find(args) == findRgx_.end()) {
123         return end;
124     }
125     string findResult;
126     for (auto it = begin; it != dumpInfo.end(); ++it) {
127         if (MatchRegex(findRgx_[args], *it, findResult)) {
128             result = std::move(findResult);
129             return it;
130         }
131     }
132     return end;
133 }
134 
GetBy(const string & key,const string & value,const string & args,const str_vec & dumpInfo)135 string MTDumpUtil::GetBy(const string& key, const string& value, const string& args, const str_vec& dumpInfo)
136 {
137     str_vec items;
138     size_t preSize = GetAll(key, dumpInfo, items);
139     auto iter = GetSpecific(value, items, items.begin());
140     if (iter != items.end() && preSize == GetAll(args, dumpInfo, items)) {
141         return *iter;
142     }
143     return "";
144 }
145 
GetBindingsByUri(const string & uri,const str_vec & dumpInfo,str_vec & result)146 size_t MTDumpUtil::GetBindingsByUri(const string& uri, const str_vec& dumpInfo, str_vec& result)
147 {
148     result.clear();
149     str_vec dump(dumpInfo);
150     string bindings;
151     auto uriBegin = GetSpecific("uri [" + uri + "]", dump, dump.begin());
152     auto bindingsBegin = GetFirst("Bindings", dump, uriBegin, bindings) + 1;
153     size_t ret = std::stoul("0" + bindings);
154     std::for_each(bindingsBegin,
155         (((bindingsBegin + ret) > dump.end()) ? (dump.end()) : (bindingsBegin + ret)),
156         [&result](auto&& it) { result.push_back(it); });
157     return ret;
158 }
159 }  // namespace MTUtil
160 }  // namespace OHOS
161