1 | /** |
2 | * Copyright (c) Glow Contributors. See CONTRIBUTORS file. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | #ifndef GLOW_SUPPORT_ZIPUTILS_H |
17 | #define GLOW_SUPPORT_ZIPUTILS_H |
18 | |
19 | #include <fstream> |
20 | #include <iostream> |
21 | #include <memory> |
22 | #include <string> |
23 | |
24 | #include <glog/logging.h> |
25 | |
26 | #include "miniz.h" |
27 | |
28 | namespace glow { |
29 | |
30 | class FileAdapter { |
31 | public: |
32 | explicit FileAdapter(const std::string &fileName) { |
33 | fileStream_.open(fileName, std::ifstream::in | std::ifstream::binary); |
34 | if (!fileStream_) { |
35 | LOG(ERROR) << "Cannot open file " << fileName; |
36 | } |
37 | istream_ = &fileStream_; |
38 | } |
39 | size_t size() const { |
40 | auto prev_pos = istream_->tellg(); |
41 | validate("getting the current position" ); |
42 | istream_->seekg(0, istream_->end); |
43 | validate("seeking to end" ); |
44 | auto result = istream_->tellg(); |
45 | validate("getting size" ); |
46 | istream_->seekg(prev_pos); |
47 | validate("seeking to the original position" ); |
48 | return result; |
49 | } |
50 | size_t read(uint64_t pos, void *buf, size_t n, const char *what = "" ) const { |
51 | istream_->seekg(pos); |
52 | validate(what); |
53 | istream_->read(static_cast<char *>(buf), n); |
54 | validate(what); |
55 | return n; |
56 | } |
57 | ~FileAdapter() = default; |
58 | |
59 | private: |
60 | std::ifstream fileStream_; |
61 | std::istream *istream_; |
62 | |
63 | void validate(const char *what) const { |
64 | if (!*istream_) { |
65 | LOG(ERROR) << "istream reader failed: " << what << "." ; |
66 | } |
67 | } |
68 | }; |
69 | |
70 | /// Zip reader |
71 | class ZipReader { |
72 | friend size_t istreamReadFunc(void *pOpaque, uint64_t file_ofs, void *pBuf, |
73 | size_t n); |
74 | std::unique_ptr<mz_zip_archive> ar_; |
75 | std::string archive_name_; |
76 | std::unique_ptr<FileAdapter> in_; |
77 | void valid(const char *what, const char *info = "" ); |
78 | size_t read(uint64_t pos, char *buf, size_t n) { |
79 | return in_->read(pos, buf, n, "reading file" ); |
80 | } |
81 | size_t getRecordID(const std::string &name); |
82 | |
83 | public: |
84 | explicit ZipReader(const std::string &file_name); |
85 | ~ZipReader(); |
86 | void init(); |
87 | std::string getRecord(const std::string &name); |
88 | bool hasRecord(const std::string &name); |
89 | }; |
90 | |
91 | /// Zip Writer |
92 | class ZipWriter { |
93 | std::ostream *out_; |
94 | bool finalized_{false}; |
95 | size_t current_pos_{0}; |
96 | std::unique_ptr<mz_zip_archive> ar_; |
97 | std::string archive_name_; |
98 | |
99 | public: |
100 | ZipWriter(std::ostream *out, const std::string &archive_name); |
101 | ~ZipWriter(); |
102 | void writeRecord(const std::string &name, const void *data, size_t size, |
103 | bool compress); |
104 | void writeEndOfFile(); |
105 | void valid(const char *what, const char *info); |
106 | friend size_t ostreamWriteFunc(void *pOpaque, uint64_t file_ofs, |
107 | const void *pBuf, size_t n); |
108 | }; |
109 | } // namespace glow |
110 | |
111 | #endif // GLOW_SUPPORT_ZIPUTILS_H |
112 | |