xref: /aosp_15_r20/external/puffin/src/include/puffin/utils.h (revision 07fb1d065b7cfb4729786fadd42a612532d2f466)
1*07fb1d06SElliott Hughes // Copyright 2017 The ChromiumOS Authors
2*07fb1d06SElliott Hughes // Use of this source code is governed by a BSD-style license that can be
3*07fb1d06SElliott Hughes // found in the LICENSE file.
4*07fb1d06SElliott Hughes 
5*07fb1d06SElliott Hughes #ifndef SRC_INCLUDE_PUFFIN_UTILS_H_
6*07fb1d06SElliott Hughes #define SRC_INCLUDE_PUFFIN_UTILS_H_
7*07fb1d06SElliott Hughes 
8*07fb1d06SElliott Hughes #include <string>
9*07fb1d06SElliott Hughes #include <vector>
10*07fb1d06SElliott Hughes 
11*07fb1d06SElliott Hughes #include "puffin/common.h"
12*07fb1d06SElliott Hughes #include "puffin/stream.h"
13*07fb1d06SElliott Hughes 
14*07fb1d06SElliott Hughes namespace puffin {
15*07fb1d06SElliott Hughes 
16*07fb1d06SElliott Hughes // Converts an array of |ByteExtens| or |BitExtents| to a string. Each extent
17*07fb1d06SElliott Hughes // has format "offset:length" and are comma separated.
18*07fb1d06SElliott Hughes template <typename T>
ExtentsToString(const T & extents)19*07fb1d06SElliott Hughes std::string ExtentsToString(const T& extents) {
20*07fb1d06SElliott Hughes   std::string str;
21*07fb1d06SElliott Hughes   for (const auto& extent : extents) {
22*07fb1d06SElliott Hughes     str += std::to_string(extent.offset) + ":" + std::to_string(extent.length) +
23*07fb1d06SElliott Hughes            ",";
24*07fb1d06SElliott Hughes   }
25*07fb1d06SElliott Hughes   return str;
26*07fb1d06SElliott Hughes }
27*07fb1d06SElliott Hughes 
28*07fb1d06SElliott Hughes // Locates deflates in a deflate stream |data| with estimated minimum length of
29*07fb1d06SElliott Hughes // |size|. The data should start with a valid deflate stream otherwise, false is
30*07fb1d06SElliott Hughes // returned. |virtual_offset| defines the offset the |data| starts in the
31*07fb1d06SElliott Hughes // original deflate stream. It is used to calculate the location of deflates in
32*07fb1d06SElliott Hughes // |deflates| based on the given offset. |compressed_size| is the size of the
33*07fb1d06SElliott Hughes // input that was determined to have valid deflate blocks (including
34*07fb1d06SElliott Hughes // uncompressed blocks). This function does not clear the content of |deflates|
35*07fb1d06SElliott Hughes // and will append found deflates to the end of it.
36*07fb1d06SElliott Hughes bool LocateDeflatesInDeflateStream(const uint8_t* data,
37*07fb1d06SElliott Hughes                                    uint64_t size,
38*07fb1d06SElliott Hughes                                    uint64_t virtual_offset,
39*07fb1d06SElliott Hughes                                    std::vector<BitExtent>* deflates,
40*07fb1d06SElliott Hughes                                    uint64_t* compressed_size);
41*07fb1d06SElliott Hughes 
42*07fb1d06SElliott Hughes // Locates deflates in a zlib buffer |data| by removing header and footer bytes
43*07fb1d06SElliott Hughes // from the zlib stream.
44*07fb1d06SElliott Hughes bool LocateDeflatesInZlib(const Buffer& data, std::vector<BitExtent>* deflates);
45*07fb1d06SElliott Hughes 
46*07fb1d06SElliott Hughes // Uses the function above, to locate deflates (bit addressed) in a given file
47*07fb1d06SElliott Hughes // |file_path| using the list of zlib blocks |zlibs|.
48*07fb1d06SElliott Hughes bool LocateDeflatesInZlibBlocks(const std::string& file_path,
49*07fb1d06SElliott Hughes                                 const std::vector<ByteExtent>& zlibs,
50*07fb1d06SElliott Hughes                                 std::vector<BitExtent>* deflates);
51*07fb1d06SElliott Hughes 
52*07fb1d06SElliott Hughes // Searches for deflate locations in a gzip stream. The results are saved in
53*07fb1d06SElliott Hughes // |deflates|.
54*07fb1d06SElliott Hughes bool LocateDeflatesInGzip(const Buffer& data, std::vector<BitExtent>* deflates);
55*07fb1d06SElliott Hughes 
56*07fb1d06SElliott Hughes // Search for the deflates in a zip archive, and put the result in |deflates|.
57*07fb1d06SElliott Hughes bool LocateDeflatesInZipArchive(const Buffer& data,
58*07fb1d06SElliott Hughes                                 std::vector<BitExtent>* deflates);
59*07fb1d06SElliott Hughes 
60*07fb1d06SElliott Hughes // Reads the deflates in from |deflates| and returns a list of its subblock
61*07fb1d06SElliott Hughes // locations. Each subblock in practice is a deflate stream by itself.
62*07fb1d06SElliott Hughes // Assumption is that the first subblock in each deflate in |deflates| start in
63*07fb1d06SElliott Hughes // byte boundary.
64*07fb1d06SElliott Hughes bool FindDeflateSubBlocks(const UniqueStreamPtr& src,
65*07fb1d06SElliott Hughes                           const std::vector<ByteExtent>& deflates,
66*07fb1d06SElliott Hughes                           std::vector<BitExtent>* subblock_deflates);
67*07fb1d06SElliott Hughes 
68*07fb1d06SElliott Hughes // Finds the location of puffs in the deflate stream |src| based on the location
69*07fb1d06SElliott Hughes // of |deflates| and populates the |puffs|. We assume |deflates| are sorted by
70*07fb1d06SElliott Hughes // their offset value. |out_puff_size| will be the size of the puff stream.
71*07fb1d06SElliott Hughes bool FindPuffLocations(const UniqueStreamPtr& src,
72*07fb1d06SElliott Hughes                        const std::vector<BitExtent>& deflates,
73*07fb1d06SElliott Hughes                        std::vector<ByteExtent>* puffs,
74*07fb1d06SElliott Hughes                        uint64_t* out_puff_size);
75*07fb1d06SElliott Hughes 
76*07fb1d06SElliott Hughes // Removes any BitExtents from both |extents1| and |extents2| if the data it
77*07fb1d06SElliott Hughes // points to is found in both |extents1| and |extents2|. The order of the
78*07fb1d06SElliott Hughes // remaining BitExtents is preserved.
79*07fb1d06SElliott Hughes void RemoveEqualBitExtents(const Buffer& data1,
80*07fb1d06SElliott Hughes                            const Buffer& data2,
81*07fb1d06SElliott Hughes                            std::vector<BitExtent>* extents1,
82*07fb1d06SElliott Hughes                            std::vector<BitExtent>* extents2);
83*07fb1d06SElliott Hughes 
84*07fb1d06SElliott Hughes // Using |data| it removes all the deflate extents from |deflates| which have
85*07fb1d06SElliott Hughes // the problem identified in crbug.com/915559. Each element of |deflates| should
86*07fb1d06SElliott Hughes // contain exactly one deflate block otherwire it returns false.
87*07fb1d06SElliott Hughes bool RemoveDeflatesWithBadDistanceCaches(const Buffer& data,
88*07fb1d06SElliott Hughes                                          std::vector<BitExtent>* deflates);
89*07fb1d06SElliott Hughes 
90*07fb1d06SElliott Hughes }  // namespace puffin
91*07fb1d06SElliott Hughes 
92*07fb1d06SElliott Hughes #endif  // SRC_INCLUDE_PUFFIN_UTILS_H_
93