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