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 #ifndef PKG_ALGORITHM_LZ4_H
16 #define PKG_ALGORITHM_LZ4_H
17 
18 #include "lz4.h"
19 #include "lz4frame.h"
20 #include "lz4hc.h"
21 #include "pkg_algorithm.h"
22 #include "pkg_stream.h"
23 #include "pkg_utils.h"
24 
25 namespace Hpackage {
26 struct PkgBufferMessage {
27     PkgAlgorithmContext context {{0, 0}, {0, 0}, 0, 0};
28     PkgBuffer inBuffer {};
29     PkgBuffer outBuffer {};
30     size_t inBuffSize {};
31     size_t outBuffSize {};
32 };
33 
34 class PkgAlgorithmLz4 : public PkgAlgorithm {
35 public:
36     static const uint32_t LZ4S_MAGIC_NUMBER = 0x184D2204;
37     static const uint32_t LZ4S_SKIPPABLE0 = 0x184D2A50;
38     static const uint32_t LZ4S_SKIPPABLE_MASK = 0xFFFFFFF0;
39     static const uint32_t LZ4B_MAGIC_NUMBER = 0x184C2102;
40     static const uint32_t LZ4B_BLOCK_SIZE = 1 << 22; // (4M)
41     static const uint32_t LZ4S_HEADER_LEN = 20;
42 
43     explicit PkgAlgorithmLz4(const Lz4FileInfo &config);
44 
~PkgAlgorithmLz4()45     ~PkgAlgorithmLz4() override {}
46 
47     int32_t PackCalculate(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
48         PkgBufferMessage &msg, size_t &dataLen, LZ4F_compressionContext_t &ctx);
49 
50     int32_t Pack(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
51         PkgAlgorithmContext &context) override;
52 
53     int32_t UnpackDecode(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
54         PkgBufferMessage &msg, size_t &nextToRead, LZ4F_decompressionContext_t &ctx);
55 
56     int32_t Unpack(const PkgStreamPtr inStream,
57         const PkgStreamPtr outStream, PkgAlgorithmContext &context) override;
58 
59     void UpdateFileInfo(PkgManager::FileInfoPtr info) const override;
60 
61 protected:
GetBlockSizeFromBlockId(int32_t id)62     int32_t GetBlockSizeFromBlockId(int32_t id) const
63     {
64         return (1 << (8 + (2 * id))); // 8,2 : Get block size from block ID
65     }
66     int32_t GetPackParam(LZ4F_compressionContext_t &ctx, LZ4F_preferences_t &preferences,
67         size_t &inBuffSize, size_t &outBuffSize) const;
68     int32_t GetUnpackParam(LZ4F_decompressionContext_t &ctx,
69         const PkgStreamPtr inStream, size_t &nextToRead, size_t &srcOffset);
70 
71     int32_t AdpLz4Compress(const uint8_t *src, uint8_t *dest, uint32_t srcSize, uint32_t dstCapacity) const;
72 
73     int32_t AdpLz4Decompress(const uint8_t *src, uint8_t *dest, uint32_t srcSize, uint32_t dstCapacity) const;
74 
75 protected:
76     int8_t compressionLevel_ {0};
77     int8_t blockIndependence_ {0};
78     int8_t contentChecksumFlag_ {0};
79     int8_t blockSizeID_ {0};
80     int8_t autoFlush_ {1};
81 };
82 
83 class PkgAlgorithmBlockLz4 : public PkgAlgorithmLz4 {
84 public:
85     static const uint32_t LZ4B_REVERSED_LEN = 4;
PkgAlgorithmBlockLz4(const Lz4FileInfo & config)86     explicit PkgAlgorithmBlockLz4(const Lz4FileInfo &config) : PkgAlgorithmLz4(config) {}
87 
~PkgAlgorithmBlockLz4()88     ~PkgAlgorithmBlockLz4() override {}
89 
90     int32_t Pack(const PkgStreamPtr inStream,
91         const PkgStreamPtr outStream, PkgAlgorithmContext &context) override;
92 
93     int32_t PackCalculate(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
94         PkgAlgorithmContext &context, PkgBuffer &inBuffer, PkgBuffer &outBuffer);
95 
96     int32_t Unpack(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
97         PkgAlgorithmContext &context) override;
98 
99     int32_t UnpackCalculate(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
100         PkgAlgorithmContext &context, int &inBuffSize);
101 };
102 } // namespace Hpackage
103 #endif
104