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
28namespace glow {
29
30class FileAdapter {
31public:
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
59private:
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
71class 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
83public:
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
92class 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
99public:
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