Coverage Report

Created: 2025-07-24 03:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/doris/be/src/util/zlib.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "util/zlib.h"
19
20
#include <butil/macros.h>
21
#include <zlib.h>
22
23
#include <cstring>
24
#include <memory>
25
#include <ostream>
26
#include <string>
27
28
#include "common/cast_set.h"
29
30
8.38k
#define ZRETURN_NOT_OK(call) RETURN_IF_ERROR(ZlibResultToStatus(call))
31
32
namespace doris {
33
using namespace ErrorCode;
34
namespace zlib {
35
#include "common/compile_check_begin.h"
36
37
namespace {
38
16.7k
Status ZlibResultToStatus(int rc) {
39
16.7k
    switch (rc) {
40
12.5k
    case Z_OK:
41
12.5k
        return Status::OK();
42
4.19k
    case Z_STREAM_END:
43
4.19k
        return Status::EndOfFile("zlib EOF");
44
0
    case Z_NEED_DICT:
45
0
        return Status::Corruption("zlib error: NEED_DICT");
46
0
    case Z_ERRNO:
47
0
        return Status::IOError("zlib error: Z_ERRNO");
48
0
    case Z_STREAM_ERROR:
49
0
        return Status::Corruption("zlib error: STREAM_ERROR");
50
0
    case Z_DATA_ERROR:
51
0
        return Status::Corruption("zlib error: DATA_ERROR");
52
0
    case Z_MEM_ERROR:
53
0
        return Status::RuntimeError("zlib error: MEM_ERROR");
54
0
    case Z_BUF_ERROR:
55
0
        return Status::RuntimeError("zlib error: BUF_ERROR");
56
0
    case Z_VERSION_ERROR:
57
0
        return Status::RuntimeError("zlib error: VERSION_ERROR");
58
0
    default:
59
0
        return Status::RuntimeError("zlib error: unknown error {}", rc);
60
16.7k
    }
61
16.7k
}
62
} // anonymous namespace
63
64
0
Status Compress(Slice input, std::ostream* out) {
65
0
    return CompressLevel(input, Z_DEFAULT_COMPRESSION, out);
66
0
}
67
68
4.18k
Status CompressLevel(Slice input, int level, std::ostream* out) {
69
4.18k
    z_stream zs;
70
4.18k
    memset(&zs, 0, sizeof(zs));
71
4.18k
    ZRETURN_NOT_OK(deflateInit2(&zs, level, Z_DEFLATED, 15 + 16 /* 15 window bits, enable gzip */,
72
4.18k
                                8 /* memory level, max is 9 */, Z_DEFAULT_STRATEGY));
73
74
4.18k
    zs.avail_in = cast_set<unsigned int>(input.get_size());
75
4.18k
    zs.next_in = (unsigned char*)(input.mutable_data());
76
4.18k
    const int kChunkSize = 256 * 1024;
77
4.18k
    std::unique_ptr<unsigned char[]> chunk(new unsigned char[kChunkSize]);
78
4.18k
    int flush;
79
8.37k
    do {
80
8.37k
        zs.avail_out = kChunkSize;
81
8.37k
        zs.next_out = chunk.get();
82
8.37k
        flush = (zs.avail_in == 0) ? Z_FINISH : Z_NO_FLUSH;
83
8.37k
        Status s = ZlibResultToStatus(deflate(&zs, flush));
84
8.37k
        if (!s.ok() && !s.is<END_OF_FILE>()) {
85
0
            return s;
86
0
        }
87
8.37k
        int out_size = cast_set<int>(zs.next_out - chunk.get());
88
8.37k
        if (out_size > 0) {
89
8.37k
            out->write(reinterpret_cast<char*>(chunk.get()), out_size);
90
8.37k
        }
91
8.37k
    } while (flush != Z_FINISH);
92
4.18k
    ZRETURN_NOT_OK(deflateEnd(&zs));
93
4.18k
    return Status::OK();
94
4.18k
}
95
96
2
Status Uncompress(Slice compressed, std::ostream* out) {
97
2
    z_stream zs;
98
2
    memset(&zs, 0, sizeof(zs));
99
2
    zs.next_in = (unsigned char*)(compressed.mutable_data());
100
2
    zs.avail_in = cast_set<unsigned int>(compressed.get_size());
101
2
    ZRETURN_NOT_OK(inflateInit2(&zs, 15 + 16 /* 15 window bits, enable zlib */));
102
2
    int flush;
103
2
    Status s;
104
4
    do {
105
4
        unsigned char buf[4096];
106
4
        zs.next_out = buf;
107
4
        zs.avail_out = arraysize(buf);
108
4
        flush = zs.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH;
109
4
        s = ZlibResultToStatus(inflate(&zs, flush));
110
4
        if (!s.ok() && !s.is<END_OF_FILE>()) {
111
0
            return s;
112
0
        }
113
4
        out->write(reinterpret_cast<char*>(buf), zs.next_out - buf);
114
4
    } while (flush == Z_NO_FLUSH);
115
2
    ZRETURN_NOT_OK(inflateEnd(&zs));
116
117
2
    return Status::OK();
118
2
}
119
#include "common/compile_check_end.h"
120
121
} // namespace zlib
122
} // namespace doris