• 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 #include "executor/zip_output.h"
16 #include <unistd.h>
17 #include "securec.h"
18 #include "dump_utils.h"
19 #include "util/file_utils.h"
20 #include "common/dumper_constant.h"
21 namespace OHOS {
22 namespace HiviewDFX {
ZipOutput()23 ZipOutput::ZipOutput() : fd_(-1)
24 {
25 }
26 
~ZipOutput()27 ZipOutput::~ZipOutput()
28 {
29     if (fd_ >= 0) {
30         close(fd_);
31     }
32 }
33 
PreExecute(const std::shared_ptr<DumperParameter> & parameter,StringMatrix dumpDatas)34 DumpStatus ZipOutput::PreExecute(const std::shared_ptr<DumperParameter>& parameter,
35     StringMatrix dumpDatas)
36 {
37     mDumpDatas_ = dumpDatas;
38     if (mDumpDatas_.get() == nullptr) {
39         return DumpStatus::DUMP_FAIL;
40     }
41 
42     // init myself once
43     if (mFilePath_.empty()) {
44         mFilePath_ =  parameter->GetOpts().path_;
45         srcBuffer_ = std::make_shared<CompressBuffer>();
46         destBuffer_ = std::make_shared<CompressBuffer>();
47         ClearBuffer();
48         fd_= DumpUtils::FdToWrite(mFilePath_);
49         if (fd_ < 0) {
50             return DumpStatus::DUMP_FAIL;
51         }
52     }
53 
54     return DumpStatus::DUMP_OK;
55 }
56 
Execute()57 DumpStatus ZipOutput::Execute()
58 {
59     if (!mDumpDatas_.get() || (fd_ < 0)) {
60         return DumpStatus::DUMP_FAIL;
61     }
62     CompressBuffer* srcBuffer = srcBuffer_.get();
63     CompressBuffer* destBuffer = destBuffer_.get();
64     if (!srcBuffer || !destBuffer) {
65         return DumpStatus::DUMP_FAIL;
66     }
67     DumpCompressor compressor;
68     for (auto v_line : *(mDumpDatas_.get())) {
69         // whole line
70         std::string line;
71         for (auto v_content : v_line)  {
72             line.append(v_content);
73         }
74         const char* content = line.c_str();
75         uint16_t content_size = strlen(content);
76         uint16_t size = strlen(content) + 1; // include \n
77         // buffer is full
78         if ((srcBuffer->offset + size) > MAX_COMPRESS_BUFFER_SIZE) {
79             // compress and write to file
80             CompressAndWriteToFd();
81         }
82         // Process big line.
83         if (size > MAX_COMPRESS_BUFFER_SIZE) {
84             CompressAndWriteToFd(); // clear buffer
85             CompressBigLine(content, size);
86             continue;
87         }
88         // Add to buffer end with \n
89         if (memcpy_s(srcBuffer->content + srcBuffer->offset,
90             MAX_COMPRESS_BUFFER_SIZE - srcBuffer->offset, content, content_size) != EOK) {
91             LOG_DEBUG("ZipOutput::Execute() memcpy_s failed!\n");
92             return DumpStatus::DUMP_FAIL;
93         }
94         srcBuffer->offset = srcBuffer->offset + content_size;
95         srcBuffer->content[srcBuffer->offset] = '\n';
96         srcBuffer->offset = srcBuffer->offset + 1;
97     }
98     // compress and write to file
99     CompressAndWriteToFd();
100     // clear dump data.
101     mDumpDatas_->clear();
102     return DumpStatus::DUMP_OK;
103 }
104 
CompressAndWriteToFd()105 DumpStatus ZipOutput::CompressAndWriteToFd()
106 {
107     CompressBuffer* srcBuffer = srcBuffer_.get();
108     CompressBuffer* destBuffer = destBuffer_.get();
109     if (!srcBuffer || !destBuffer) {
110         return DumpStatus::DUMP_FAIL;
111     }
112     DumpStatus ret = DumpStatus::DUMP_OK;
113     if (srcBuffer->offset > 0) {
114         ret = compressor_.Compress(srcBuffer, destBuffer);
115         if (ret == DumpStatus::DUMP_OK) {
116             if (write(fd_, destBuffer->content, destBuffer->offset) < 0) {
117                 ret = DumpStatus::DUMP_FAIL;
118                 LOG_DEBUG("ZipOutput::CompressAndWriteToFd() Write to FD failed!\n");
119             }
120         } else {
121             ret = DumpStatus::DUMP_FAIL;
122             LOG_DEBUG("ZipOutput::CompressAndWriteToFd() Compress failed!\n");
123         }
124         ClearBuffer();
125     }
126 
127     return ret;
128 }
129 
CompressBigLine(const char * content,uint16_t size)130 DumpStatus ZipOutput::CompressBigLine(const char* content, uint16_t size)
131 {
132     if (!content) {
133         return DumpStatus::DUMP_FAIL;
134     }
135     CompressBuffer* srcBuffer = srcBuffer_.get();
136     CompressBuffer* destBuffer = destBuffer_.get();
137     if (!srcBuffer || !destBuffer) {
138         return DumpStatus::DUMP_FAIL;
139     }
140     DumpStatus ret = DumpStatus::DUMP_OK;
141     uint16_t remain_size = size - 1; // size include \n
142     uint16_t complete_size = 0;
143     while (remain_size > 0) {
144         uint16_t process_size = remain_size;
145         if ((srcBuffer->offset + remain_size) > MAX_COMPRESS_BUFFER_SIZE) {
146             process_size = MAX_COMPRESS_BUFFER_SIZE - srcBuffer->offset;
147         }
148         if (memcpy_s(srcBuffer->content + srcBuffer->offset,
149             MAX_COMPRESS_BUFFER_SIZE - srcBuffer->offset,
150             content + complete_size, process_size) != EOK) {
151             LOG_DEBUG("ZipOutput::CompressBigLine() memcpy_s failed!\n");
152             return DumpStatus::DUMP_FAIL;
153         }
154         srcBuffer->offset = srcBuffer->offset + process_size;
155         complete_size += process_size;
156         remain_size -= process_size;
157         CompressAndWriteToFd();
158     }
159     // process \n
160     srcBuffer->content[srcBuffer->offset] = '\n';
161     srcBuffer->offset = srcBuffer->offset + 1;
162     CompressAndWriteToFd();
163     return ret;
164 }
165 
166 
AfterExecute()167 DumpStatus ZipOutput::AfterExecute()
168 {
169     return DumpStatus::DUMP_OK;
170 }
171 
ClearBuffer()172 void ZipOutput::ClearBuffer()
173 {
174     if (srcBuffer_.get()) {
175         (void)memset_s(srcBuffer_.get(), sizeof(CompressBuffer), 0, sizeof(CompressBuffer));
176     }
177     if (destBuffer_.get()) {
178         (void)memset_s(destBuffer_.get(), sizeof(CompressBuffer), 0, sizeof(CompressBuffer));
179     }
180 }
181 } // namespace HiviewDFX
182 } // namespace OHOS
183