• 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 "util/dump_compressor.h"
16 #include <securec.h>
17 
18 using namespace std;
19 namespace OHOS {
20 namespace HiviewDFX {
DumpCompressor()21 DumpCompressor::DumpCompressor()
22 {
23 }
24 
Init(CompressBuffer * & srcBuffer)25 DumpStatus DumpCompressor::Init(CompressBuffer*& srcBuffer)
26 {
27     uint32_t bound = compressBound(srcBuffer->offset);
28     if (bound == 0) {
29         return DumpStatus::DUMP_FAIL;
30     }
31     zDataSize_ = (bound < CHUNK) ? CHUNK : bound;
32     zData_ = new unsigned char[zDataSize_];
33     if (zData_ == nullptr) {
34         return DumpStatus::DUMP_FAIL;
35     }
36     if (memset_s(zData_, zDataSize_, 0, zDataSize_) != EOK) {
37         DeleteZData();
38         return DumpStatus::DUMP_FAIL;
39     };
40 
41     zStream_.zalloc = Z_NULL;
42     zStream_.zfree = Z_NULL;
43     zStream_.opaque = Z_NULL;
44 
45     if (deflateInit2(&zStream_, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + WINDOWS_BITS,
46         MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) {
47         DeleteZData();
48         return DumpStatus::DUMP_FAIL;
49     }
50     return DumpStatus::DUMP_OK;
51 }
52 
DeleteZData()53 void DumpCompressor::DeleteZData()
54 {
55     if (zData_ != nullptr) {
56         delete[] zData_;
57     };
58     zData_ = nullptr;
59 }
DeleteZBuff(char * buffIn,char * buffOut)60 void DumpCompressor::DeleteZBuff(char* buffIn, char* buffOut)
61 {
62     delete[] buffIn;
63     delete[] buffOut;
64     buffIn = nullptr;
65     buffOut = nullptr;
66 }
Compress(CompressBuffer * & srcBuffer,CompressBuffer * & destBuffer)67 DumpStatus DumpCompressor::Compress(CompressBuffer*& srcBuffer, CompressBuffer*& destBuffer)
68 {
69     if (Init(srcBuffer) != DumpStatus::DUMP_OK) {
70         return DumpStatus::DUMP_FAIL;
71     }
72     size_t const toRead = CHUNK;
73     size_t srcPos = 0;
74     size_t dstPos = 0;
75     size_t srcBufferOffset = srcBuffer->offset;
76     int flush = 0;
77     char* buffIn = new char[CHUNK];
78     char* buffOut = new char[CHUNK];
79     if (buffIn == nullptr || buffOut == nullptr) {
80         return DumpStatus::DUMP_FAIL;
81     }
82     if (memset_s(buffIn, CHUNK, 0, CHUNK) != EOK ||
83         memset_s(buffOut, CHUNK, 0, CHUNK) != EOK) {
84         DeleteZBuff(buffIn, buffOut);
85         return DumpStatus::DUMP_FAIL;
86     };
87 
88     do {
89         if (FillBuffer(flush, srcBuffer, buffIn, toRead, srcPos, srcBufferOffset) == DumpStatus::DUMP_FAIL) {
90             DeleteZBuff(buffIn, buffOut);
91             return DumpStatus::DUMP_FAIL;
92         }
93         if (DeflateBuffer(flush, buffOut, dstPos) == DumpStatus::DUMP_FAIL) {
94             DeleteZBuff(buffIn, buffOut);
95             return DumpStatus::DUMP_FAIL;
96         }
97     } while (flush != Z_FINISH);
98 
99     /* clean up and return */
100     (void)deflateEnd(&zStream_);
101 
102     if (memcpy_s(destBuffer->content + destBuffer->offset,
103         MAX_COMPRESS_BUFFER_SIZE - destBuffer->offset, zData_, dstPos) != EOK) {
104         DeleteZData();
105         return DumpStatus::DUMP_FAIL;
106     }
107     destBuffer->offset += dstPos;
108     DeleteZData();
109     DeleteZBuff(buffIn, buffOut);
110     return DumpStatus::DUMP_OK;
111 }
112 
FillBuffer(int & flush,CompressBuffer * & srcBuffer,char * buffIn,size_t const toRead,size_t & src_pos,size_t srcBufferOffset)113 DumpStatus DumpCompressor::FillBuffer(int& flush, CompressBuffer*& srcBuffer, char* buffIn,
114     size_t const toRead, size_t& src_pos, size_t srcBufferOffset)
115 {
116     bool flag = (srcBufferOffset - src_pos) < toRead;
117     (void)memset_s(buffIn, CHUNK, 0, CHUNK);
118 
119     if (flag) {
120         if (memmove_s(buffIn, CHUNK, srcBuffer->content + src_pos, srcBufferOffset - src_pos) != EOK) {
121             DeleteZData();
122             return DumpStatus::DUMP_FAIL;
123         }
124         zStream_.avail_in = srcBufferOffset - src_pos;
125         src_pos += srcBufferOffset - src_pos;
126     } else {
127         if (memmove_s(buffIn, CHUNK, srcBuffer->content + src_pos, toRead) != EOK) {
128             DeleteZData();
129             return DumpStatus::DUMP_FAIL;
130         };
131         zStream_.avail_in = toRead;
132         src_pos += toRead;
133     }
134 
135     flush = flag ? Z_FINISH : Z_NO_FLUSH;
136     zStream_.next_in = (Bytef*)buffIn;
137     return DumpStatus::DUMP_OK;
138 }
139 
DeflateBuffer(int flush,char * buffOut,size_t & dstPos)140 DumpStatus DumpCompressor::DeflateBuffer(int flush, char* buffOut, size_t& dstPos)
141 {
142     /* run deflate() on input , finish compression until all of source has been read in. */
143     do {
144         zStream_.avail_out = CHUNK;
145         zStream_.next_out = (Bytef*)buffOut;
146         if (deflate(&zStream_, flush) == Z_STREAM_ERROR) {
147             DeleteZData();
148             return DumpStatus::DUMP_FAIL;
149         }
150         unsigned have = CHUNK - zStream_.avail_out;
151         if (memmove_s(zData_ + dstPos, zDataSize_ - dstPos, buffOut, have) != EOK) {
152             DeleteZData();
153             return DumpStatus::DUMP_FAIL;
154         }
155         dstPos += have;
156     } while (zStream_.avail_out == 0);
157 
158     return DumpStatus::DUMP_OK;
159 }
160 } // namespace HiviewDFX
161 } // namespace OHOS
162