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 "base/log/dump_log.h"
17 
18 #include <fstream>
19 #include "core/common/ace_application_info.h"
20 
21 namespace OHOS::Ace {
22 
23 DumpLog::DumpLog() = default;
24 DumpLog::~DumpLog() = default;
25 
Print(int32_t depth,const std::string & className,int32_t childSize)26 void DumpLog::Print(int32_t depth, const std::string& className, int32_t childSize)
27 {
28     if (!ostream_ || !ostream_->good()) {
29         return;
30     }
31     std::string space = "  ";
32     for (int32_t i = 0; i < depth; ++i) {
33         ostream_->write(space.c_str(), space.length());
34     }
35     ostream_->write(space.c_str(), space.length());
36     std::string data = "|-> ";
37     data.append(className);
38     data.append(" childSize:" + std::to_string(childSize));
39     data.append("\n");
40     ostream_->write(data.c_str(), data.length());
41     for (auto& desc : description_) {
42         for (int32_t i = 0; i < depth; ++i) {
43             ostream_->write(space.c_str(), space.length());
44         }
45         std::string data = "";
46         if (childSize == 0) {
47             data = "      ";
48         } else {
49             data = "    | ";
50         }
51         data.append(desc);
52         ostream_->write(data.c_str(), data.length());
53     }
54     ostream_->flush();
55     description_.clear();
56     description_.shrink_to_fit();
57 }
58 
Print(const std::string & content)59 void DumpLog::Print(const std::string& content)
60 {
61     Print(0, content);
62 }
63 
Print(int32_t depth,const std::string & content)64 void DumpLog::Print(int32_t depth, const std::string& content)
65 {
66     std::string space = " ";
67     for (int32_t i = 0; i < depth; ++i) {
68         ostream_->write(space.c_str(), space.length());
69     }
70     std::string data = content + separator_;
71     ostream_->write(data.c_str(), data.length());
72 }
73 
Reset()74 void DumpLog::Reset()
75 {
76     ostream_.reset();
77 }
78 
ShowDumpHelp(std::vector<std::string> & info)79 void DumpLog::ShowDumpHelp(std::vector<std::string>& info)
80 {
81     info.emplace_back(" -element                       |show element tree");
82     info.emplace_back(" -render                        |show render tree");
83     info.emplace_back(" -inspector                     |show inspector tree");
84     info.emplace_back(" -frontend                      |show path and components count of current page");
85     info.emplace_back(" -navigation                    |show navigation path stack");
86 }
87 
Append(int32_t depth,const std::string & className,int32_t childSize)88 void DumpLog::Append(int32_t depth, const std::string& className, int32_t childSize)
89 {
90     for (int32_t i = 0; i < depth; ++i) {
91         result_.append("  ");
92     }
93     result_.append("|-> ");
94     result_.append(className);
95     result_.append(" childSize:" + std::to_string(childSize));
96     result_.append("\n");
97     for (auto& desc : description_) {
98         for (int32_t i = 0; i < depth; ++i) {
99             result_.append("  ");
100         }
101         if (childSize == 0) {
102             result_.append("      ");
103         } else {
104             result_.append("    | ");
105         }
106         result_.append(desc);
107     }
108     description_.clear();
109     description_.shrink_to_fit();
110 }
111 
OutPutBySize()112 bool DumpLog::OutPutBySize()
113 {
114     if (!ostream_->good()) {
115         result_.clear();
116         return false;
117     }
118     // if current result size > max size, dump will output as file
119     if (result_.size() + 1 > DumpLog::MAX_DUMP_LENGTH) {
120         auto dumpFilePath = AceApplicationInfo::GetInstance().GetDataFileDirPath() + "/arkui.dump";
121         std::unique_ptr<std::ostream> ostream = std::make_unique<std::ofstream>(dumpFilePath);
122         if (!ostream) {
123             result_.clear();
124             result_.append("Dump output failed,please try again");
125             ostream_->write(result_.c_str(), result_.length());
126             result_.clear();
127         }
128         CHECK_NULL_RETURN(ostream, false);
129         DumpLog::GetInstance().SetDumpFile(std::move(ostream));
130     }
131     ostream_->write(result_.c_str(), result_.length());
132     result_.clear();
133     ostream_->flush();
134     return true;
135 }
136 
OutPutDefault()137 void DumpLog::OutPutDefault()
138 {
139     if (!ostream_ || !ostream_->good()) {
140         result_.clear();
141         return;
142     }
143     ostream_->write(result_.c_str(), result_.length());
144     result_.clear();
145     ostream_->flush();
146 }
147 } // namespace OHOS::Ace
148