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