12498b56bSopenharmony_ci/* 22498b56bSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 32498b56bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 42498b56bSopenharmony_ci * you may not use this file except in compliance with the License. 52498b56bSopenharmony_ci * You may obtain a copy of the License at 62498b56bSopenharmony_ci * 72498b56bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 82498b56bSopenharmony_ci * 92498b56bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 102498b56bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 112498b56bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 122498b56bSopenharmony_ci * See the License for the specific language governing permissions and 132498b56bSopenharmony_ci * limitations under the License. 142498b56bSopenharmony_ci */ 152498b56bSopenharmony_ci#include "log_compress.h" 162498b56bSopenharmony_ci 172498b56bSopenharmony_ci#include <iostream> 182498b56bSopenharmony_ci#include <cstring> 192498b56bSopenharmony_ci#include <cstdlib> 202498b56bSopenharmony_ci#include <vector> 212498b56bSopenharmony_ci 222498b56bSopenharmony_ci#include <securec.h> 232498b56bSopenharmony_ci 242498b56bSopenharmony_cinamespace OHOS { 252498b56bSopenharmony_cinamespace HiviewDFX { 262498b56bSopenharmony_ciStringMap LogCompress::g_CompressTypes = StringMap({ 272498b56bSopenharmony_ci {COMPRESS_TYPE_NONE, "none"}, {COMPRESS_TYPE_ZLIB, "zlib"}, {COMPRESS_TYPE_ZSTD, "zstd"} 282498b56bSopenharmony_ci }, COMPRESS_TYPE_ZLIB, "unknown"); 292498b56bSopenharmony_ci 302498b56bSopenharmony_cistd::string LogCompress::CompressType2Str(uint16_t compressType) 312498b56bSopenharmony_ci{ 322498b56bSopenharmony_ci return g_CompressTypes.GetValue(compressType); 332498b56bSopenharmony_ci} 342498b56bSopenharmony_ci 352498b56bSopenharmony_ciuint16_t LogCompress::Str2CompressType(const std::string& str) 362498b56bSopenharmony_ci{ 372498b56bSopenharmony_ci return g_CompressTypes.GetKey(str); 382498b56bSopenharmony_ci} 392498b56bSopenharmony_ci 402498b56bSopenharmony_ciint NoneCompress::Compress(const LogPersisterBuffer &inBuffer, LogPersisterBuffer &compressedBuffer) 412498b56bSopenharmony_ci{ 422498b56bSopenharmony_ci void *dest = compressedBuffer.content + compressedBuffer.offset; 432498b56bSopenharmony_ci size_t destSize = MAX_PERSISTER_BUFFER_SIZE - compressedBuffer.offset; 442498b56bSopenharmony_ci if (memcpy_s(dest, destSize, inBuffer.content, inBuffer.offset) != 0) { 452498b56bSopenharmony_ci return -1; 462498b56bSopenharmony_ci } 472498b56bSopenharmony_ci compressedBuffer.offset += inBuffer.offset; 482498b56bSopenharmony_ci return 0; 492498b56bSopenharmony_ci} 502498b56bSopenharmony_ci 512498b56bSopenharmony_ciint ZlibCompress::Compress(const LogPersisterBuffer &inBuffer, LogPersisterBuffer &compressedBuffer) 522498b56bSopenharmony_ci{ 532498b56bSopenharmony_ci cStream.zalloc = Z_NULL; 542498b56bSopenharmony_ci cStream.zfree = Z_NULL; 552498b56bSopenharmony_ci cStream.opaque = Z_NULL; 562498b56bSopenharmony_ci if (deflateInit2(&cStream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY) != Z_OK) { 572498b56bSopenharmony_ci return -1; 582498b56bSopenharmony_ci } 592498b56bSopenharmony_ci uint32_t zdlen = deflateBound(&cStream, inBuffer.offset); 602498b56bSopenharmony_ci std::vector<char> zdataBuf(zdlen, 0); 612498b56bSopenharmony_ci char* zdata = zdataBuf.data(); 622498b56bSopenharmony_ci if (zdata == nullptr) { 632498b56bSopenharmony_ci std::cerr << "no enough memory!\n"; 642498b56bSopenharmony_ci return -1; 652498b56bSopenharmony_ci } 662498b56bSopenharmony_ci size_t const toRead = CHUNK; 672498b56bSopenharmony_ci size_t src_pos = 0; 682498b56bSopenharmony_ci size_t dst_pos = 0; 692498b56bSopenharmony_ci size_t read = inBuffer.offset; 702498b56bSopenharmony_ci int flush = 0; 712498b56bSopenharmony_ci do { 722498b56bSopenharmony_ci bool flag = read - src_pos < toRead; 732498b56bSopenharmony_ci if (flag) { 742498b56bSopenharmony_ci (void)memset_s(buffIn, CHUNK, 0, CHUNK); 752498b56bSopenharmony_ci if (memmove_s(buffIn, CHUNK, inBuffer.content + src_pos, read - src_pos) != 0) { 762498b56bSopenharmony_ci return -1; 772498b56bSopenharmony_ci } 782498b56bSopenharmony_ci cStream.avail_in = read - src_pos; 792498b56bSopenharmony_ci src_pos += read - src_pos; 802498b56bSopenharmony_ci } else { 812498b56bSopenharmony_ci (void)memset_s(buffIn, CHUNK, 0, CHUNK); 822498b56bSopenharmony_ci if (memmove_s(buffIn, CHUNK, inBuffer.content + src_pos, toRead) != 0) { 832498b56bSopenharmony_ci return -1; 842498b56bSopenharmony_ci } 852498b56bSopenharmony_ci src_pos += toRead; 862498b56bSopenharmony_ci cStream.avail_in = toRead; 872498b56bSopenharmony_ci } 882498b56bSopenharmony_ci flush = flag ? Z_FINISH : Z_NO_FLUSH; 892498b56bSopenharmony_ci cStream.next_in = reinterpret_cast<Bytef*>(buffIn); 902498b56bSopenharmony_ci /* run deflate() on input until output buffer not full, finish 912498b56bSopenharmony_ci compression if all of source has been read in */ 922498b56bSopenharmony_ci do { 932498b56bSopenharmony_ci cStream.avail_out = CHUNK; 942498b56bSopenharmony_ci cStream.next_out = reinterpret_cast<Bytef*>(buffOut); 952498b56bSopenharmony_ci if (deflate(&cStream, flush) == Z_STREAM_ERROR) { 962498b56bSopenharmony_ci return -1; 972498b56bSopenharmony_ci } 982498b56bSopenharmony_ci unsigned have = CHUNK - cStream.avail_out; 992498b56bSopenharmony_ci if (memmove_s(zdata + dst_pos, zdlen - dst_pos, buffOut, have) != 0) { 1002498b56bSopenharmony_ci return -1; 1012498b56bSopenharmony_ci } 1022498b56bSopenharmony_ci dst_pos += have; 1032498b56bSopenharmony_ci if (unlikely(zdlen < dst_pos)) { // zdataBuf is not long enough, shoudn't happen 1042498b56bSopenharmony_ci return -1; 1052498b56bSopenharmony_ci } 1062498b56bSopenharmony_ci } while (cStream.avail_out == 0); 1072498b56bSopenharmony_ci } while (flush != Z_FINISH); 1082498b56bSopenharmony_ci /* clean up and return */ 1092498b56bSopenharmony_ci (void)deflateEnd(&cStream); 1102498b56bSopenharmony_ci if (memcpy_s(compressedBuffer.content + compressedBuffer.offset, 1112498b56bSopenharmony_ci MAX_PERSISTER_BUFFER_SIZE - compressedBuffer.offset, zdata, dst_pos) != 0) { 1122498b56bSopenharmony_ci return -1; 1132498b56bSopenharmony_ci } 1142498b56bSopenharmony_ci compressedBuffer.offset += dst_pos; 1152498b56bSopenharmony_ci return 0; 1162498b56bSopenharmony_ci} 1172498b56bSopenharmony_ci 1182498b56bSopenharmony_ciint ZstdCompress::Compress(const LogPersisterBuffer &inBuffer, LogPersisterBuffer &compressedBuffer) 1192498b56bSopenharmony_ci{ 1202498b56bSopenharmony_ci#ifdef USING_ZSTD_COMPRESS 1212498b56bSopenharmony_ci uint32_t zdlen = ZSTD_CStreamOutSize(); 1222498b56bSopenharmony_ci std::vector<char> zdataBuf(zdlen, 0); 1232498b56bSopenharmony_ci char* zdata = zdataBuf.data(); 1242498b56bSopenharmony_ci if (zdata == nullptr) { 1252498b56bSopenharmony_ci std::cerr << "no enough memory!\n"; 1262498b56bSopenharmony_ci return -1; 1272498b56bSopenharmony_ci } 1282498b56bSopenharmony_ci ZSTD_EndDirective mode; 1292498b56bSopenharmony_ci int compressionlevel = 1; 1302498b56bSopenharmony_ci cctx = ZSTD_createCCtx(); 1312498b56bSopenharmony_ci if (cctx == nullptr) { 1322498b56bSopenharmony_ci std::cerr << "ZSTD_createCCtx() failed!\n"; 1332498b56bSopenharmony_ci return -1; 1342498b56bSopenharmony_ci } 1352498b56bSopenharmony_ci ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, compressionlevel); 1362498b56bSopenharmony_ci size_t const toRead = CHUNK; 1372498b56bSopenharmony_ci auto src_pos = 0; 1382498b56bSopenharmony_ci auto dst_pos = 0; 1392498b56bSopenharmony_ci size_t read = inBuffer.offset; 1402498b56bSopenharmony_ci ZSTD_inBuffer input; 1412498b56bSopenharmony_ci do { 1422498b56bSopenharmony_ci bool flag = read - src_pos < toRead; 1432498b56bSopenharmony_ci if (flag) { 1442498b56bSopenharmony_ci (void)memset_s(buffIn, CHUNK, 0, CHUNK); 1452498b56bSopenharmony_ci if (memmove_s(buffIn, CHUNK, inBuffer.content + src_pos, read - src_pos) != 0) { 1462498b56bSopenharmony_ci return -1; 1472498b56bSopenharmony_ci } 1482498b56bSopenharmony_ci input = {buffIn, read - src_pos, 0}; 1492498b56bSopenharmony_ci src_pos += read - src_pos; 1502498b56bSopenharmony_ci } else { 1512498b56bSopenharmony_ci (void)memset_s(buffIn, CHUNK, 0, CHUNK); 1522498b56bSopenharmony_ci if (memmove_s(buffIn, CHUNK, inBuffer.content + src_pos, toRead) != 0) { 1532498b56bSopenharmony_ci return -1; 1542498b56bSopenharmony_ci } 1552498b56bSopenharmony_ci input = {buffIn, toRead, 0}; 1562498b56bSopenharmony_ci src_pos += toRead; 1572498b56bSopenharmony_ci } 1582498b56bSopenharmony_ci mode = flag ? ZSTD_e_end : ZSTD_e_continue; 1592498b56bSopenharmony_ci int finished; 1602498b56bSopenharmony_ci do { 1612498b56bSopenharmony_ci ZSTD_outBuffer output = {buffOut, CHUNK, 0}; 1622498b56bSopenharmony_ci size_t const remaining = ZSTD_compressStream2(cctx, &output, &input, mode); 1632498b56bSopenharmony_ci if (memmove_s(zdata + dst_pos, zdlen, reinterpret_cast<Bytef*>(buffOut), output.pos) != 0) { 1642498b56bSopenharmony_ci return -1; 1652498b56bSopenharmony_ci } 1662498b56bSopenharmony_ci dst_pos += output.pos; 1672498b56bSopenharmony_ci finished = flag ? (remaining == 0) : (input.pos == input.size); 1682498b56bSopenharmony_ci } while (!finished); 1692498b56bSopenharmony_ci } while (mode != ZSTD_e_end); 1702498b56bSopenharmony_ci ZSTD_freeCCtx(cctx); 1712498b56bSopenharmony_ci if (memcpy_s(compressedBuffer.content + compressedBuffer.offset, 1722498b56bSopenharmony_ci MAX_PERSISTER_BUFFER_SIZE - compressedBuffer.offset, zdata, dst_pos) != 0) { 1732498b56bSopenharmony_ci return -1; 1742498b56bSopenharmony_ci } 1752498b56bSopenharmony_ci compressedBuffer.offset += dst_pos; 1762498b56bSopenharmony_ci#endif // #ifdef USING_ZSTD_COMPRESS 1772498b56bSopenharmony_ci return 0; 1782498b56bSopenharmony_ci} 1792498b56bSopenharmony_ci} // namespace HiviewDFX 1802498b56bSopenharmony_ci} // namespace OHOS 181