HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
zipFile.h
Go to the documentation of this file.
1 //
2 // Copyright 2018 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_SDF_ZIP_FILE_H
8 #define PXR_USD_SDF_ZIP_FILE_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/usd/sdf/api.h"
12 
13 #include <cstdint>
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
20 
21 class ArAsset;
22 
23 /// \class SdfZipFile
24 ///
25 /// Class for reading a zip file. This class is primarily intended to support
26 /// the .usdz file format. It is not a general-purpose zip reader, as it does
27 /// not implement the full zip file specification. In particular:
28 ///
29 /// - This class does not natively support decompressing data from a zip
30 /// archive. Clients may access the data exactly as stored in the file and
31 /// perform their own decompression if desired.
32 ///
33 /// - This class does not rely on the central directory in order to read the
34 /// contents of the file. This allows it to operate on partial zip archives.
35 /// However, this also means it may handle certain zip files incorrectly.
36 /// For example, if a file was deleted from a zip archive by just removing
37 /// its central directory header, that file will still be found by this
38 /// class.
39 ///
41 {
42 private:
43  class _Impl;
44 
45 public:
46  /// Opens the zip archive at \p filePath.
47  /// Returns invalid object on error.
48  SDF_API
49  static SdfZipFile Open(const std::string& filePath);
50 
51  /// Opens the zip archive \p asset.
52  /// Returns invalid object on error.
53  SDF_API
54  static SdfZipFile Open(const std::shared_ptr<ArAsset>& asset);
55 
56  /// Create an invalid SdfZipFile object.
57  SDF_API
58  SdfZipFile();
59 
60  SDF_API
61  ~SdfZipFile();
62 
63  /// Return true if this object is valid, false otherwise.
64  SDF_API
65  explicit operator bool() const { return static_cast<bool>(_impl); }
66 
67  /// \class FileInfo
68  /// Information for a file in the zip archive.
69  class FileInfo
70  {
71  public:
72  /// Offset of the beginning of this file's data from the start of
73  /// the zip archive.
74  size_t dataOffset = 0;
75 
76  /// Size of this file as stored in the zip archive. If this file is
77  /// compressed, this is its compressed size. Otherwise, this is the
78  /// same as the uncompressed size.
79  size_t size = 0;
80 
81  /// Uncompressed size of this file. This may not be the same as the
82  /// size of the file as stored in the zip archive.
83  size_t uncompressedSize = 0;
84 
85  /// CRC-32 value of the uncompressed file.
86  size_t crc = 0;
87 
88  /// Compression method for this file. See section 4.4.5 of the zip
89  /// file specification for valid values. In particular, a value of 0
90  /// means this file is stored with no compression.
91  uint16_t compressionMethod = 0;
92 
93  /// Whether or not this file is encrypted.
94  bool encrypted = false;
95  };
96 
97  /// \class Iterator
98  /// Iterator for traversing and inspecting the contents of the zip archive.
99  class Iterator
100  {
101  // Proxy type for operator->(), needed since this iterator's value
102  // is generated on the fly.
103  class _ArrowProxy
104  {
105  public:
106  explicit _ArrowProxy(const std::string& s) : _s(s) { }
107  const std::string* operator->() const { return &_s; }
108  private:
109  std::string _s;
110  };
111 
112  public:
113  SDF_API
114  Iterator();
115 
116  SDF_API
117  ~Iterator();
118 
119  SDF_API
120  Iterator(const Iterator& rhs);
121 
122  SDF_API
123  Iterator(Iterator&& rhs);
124 
125  SDF_API
126  Iterator& operator=(const Iterator& rhs);
127 
128  SDF_API
129  Iterator& operator=(Iterator&& rhs);
130 
131  using difference_type = std::ptrdiff_t;
132  using value_type = std::string;
133  using pointer = _ArrowProxy;
134  using reference = std::string;
135  using iterator_category = std::forward_iterator_tag;
136 
137  SDF_API
138  Iterator& operator++();
139  SDF_API
140  Iterator operator++(int);
141 
142  SDF_API
143  bool operator==(const Iterator& rhs) const;
144  SDF_API
145  bool operator!=(const Iterator& rhs) const;
146 
147  /// Returns filename of the current file in the zip archive.
148  SDF_API
149  reference operator*() const;
150 
151  /// Returns filename of the current file in the zip archive.
152  SDF_API
153  pointer operator->() const;
154 
155  /// Returns pointer to the beginning of the current file in the
156  /// zip archive. The contents of the current file span the range
157  /// [GetFile(), GetFile() + GetFileInfo().size).
158  ///
159  /// Note that this points to the raw data stored in the zip archive;
160  /// no decompression or other transformation is applied.
161  SDF_API
162  const char* GetFile() const;
163 
164  /// Returns FileInfo object containing information about the
165  /// current file.
166  SDF_API
167  FileInfo GetFileInfo() const;
168 
169  private:
170  friend class SdfZipFile;
171  Iterator(const _Impl* impl, size_t offset = 0);
172 
173  class _IteratorData;
174  std::unique_ptr<_IteratorData> _data;
175  };
176 
177  /// Returns iterator pointing to the first file in the zip archive.
178  SDF_API
179  Iterator begin() const;
180 
181  /// Returns iterator pointing to the first file in the zip archive.
182  Iterator cbegin() const { return begin(); }
183 
184  /// Returns end iterator for this zip archive.
185  SDF_API
186  Iterator end() const;
187 
188  /// Returns end iterator for this zip archive.
189  Iterator cend() const { return end(); }
190 
191  /// Returns iterator to the file with the given \p path in this zip
192  /// archive, or end() if no such file exists.
193  SDF_API
194  Iterator Find(const std::string& path) const;
195 
196  /// Print out listing of contents of this zip archive to stdout.
197  /// For diagnostic purposes only.
198  SDF_API
199  void DumpContents() const;
200 
201 private:
202  SdfZipFile(std::shared_ptr<_Impl>&& impl);
203 
204  std::shared_ptr<_Impl> _impl;
205 };
206 
207 /// \class SdfZipFileWriter
208 ///
209 /// Class for writing a zip file. This class is primarily intended to support
210 /// the .usdz file format. It is not a general-purpose zip writer, as it does
211 /// not implement the full zip file specification. However, all files written
212 /// by this class should be valid zip files and readable by external zip
213 /// libraries and utilities.
214 ///
216 {
217 public:
218  /// Create a new file writer with \p filePath as the destination file path
219  /// where the zip archive will be written. The zip file will not be written
220  /// to \p filePath until the writer is destroyed or Save() is called.
221  ///
222  /// Returns an invalid object on error.
223  SDF_API
224  static SdfZipFileWriter CreateNew(const std::string& filePath);
225 
226  /// Create an invalid SdfZipFileWriter object.
227  SDF_API
229 
230  /// Calls Save()
231  SDF_API
233 
234  SdfZipFileWriter(const SdfZipFileWriter&) = delete;
235  SdfZipFileWriter& operator=(const SdfZipFileWriter&) = delete;
236 
237  SDF_API
238  SdfZipFileWriter(SdfZipFileWriter&& rhs);
239  SDF_API
240  SdfZipFileWriter& operator=(SdfZipFileWriter&& rhs);
241 
242  /// Returns true if this is a valid object, false otherwise.
243  SDF_API
244  explicit operator bool() const { return static_cast<bool>(_impl); }
245 
246  /// Adds the file at \p filePath to the zip archive with no compression
247  /// applied. If \p filePathInArchive is non-empty, the file will be
248  /// added at that path in the archive. Otherwise, it will be added
249  /// at \p filePath.
250  ///
251  /// Returns the file path used to identify the file in the zip archive
252  /// on success. This path conforms to the zip file specification and may
253  /// not be the same as \p filePath or \p filePathInArchive. Returns an
254  /// empty string on failure.
255  SDF_API
256  std::string AddFile(const std::string& filePath,
257  const std::string& filePathInArchive = std::string());
258 
259  /// Finalizes the zip archive and saves it to the destination file path.
260  /// Once saved, the file writer is invalid and may not be reused.
261  /// Returns true on success, false otherwise.
262  SDF_API
263  bool Save();
264 
265  /// Discards the zip archive so that it is not saved to the destination
266  /// file path. Once discarded, the file writer is invalid and may not be
267  /// reused.
268  SDF_API
269  void Discard();
270 
271 private:
272  class _Impl;
273  SdfZipFileWriter(std::unique_ptr<_Impl>&& impl);
274 
275  std::unique_ptr<_Impl> _impl;
276 };
277 
279 
280 #endif // PXR_USD_SDF_ZIP_FILE_H
std::ptrdiff_t difference_type
Definition: zipFile.h:131
size_t uncompressedSize
Definition: zipFile.h:83
SDF_API bool Save()
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
SDF_API Iterator Find(const std::string &path) const
SDF_API FileInfo GetFileInfo() const
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
Definition: asset.h:27
GLdouble s
Definition: glad.h:3009
OutGridT const XformOp bool bool
SDF_API void DumpContents() const
SDF_API Iterator & operator=(const Iterator &rhs)
_ArrowProxy pointer
Definition: zipFile.h:133
static SDF_API SdfZipFileWriter CreateNew(const std::string &filePath)
GLintptr offset
Definition: glcorearb.h:665
SDF_API bool operator!=(const Iterator &rhs) const
SdfZipFileWriter & operator=(const SdfZipFileWriter &)=delete
SDF_API Iterator end() const
Returns end iterator for this zip archive.
Iterator cbegin() const
Returns iterator pointing to the first file in the zip archive.
Definition: zipFile.h:182
SDF_API ~SdfZipFileWriter()
Calls Save()
SDF_API Iterator begin() const
Returns iterator pointing to the first file in the zip archive.
Iterator cend() const
Returns end iterator for this zip archive.
Definition: zipFile.h:189
SDF_API reference operator*() const
Returns filename of the current file in the zip archive.
static SDF_API SdfZipFile Open(const std::string &filePath)
SDF_API void Discard()
SDF_API SdfZipFileWriter()
Create an invalid SdfZipFileWriter object.
SDF_API const char * GetFile() const
#define SDF_API
Definition: api.h:23
GLsizeiptr size
Definition: glcorearb.h:664
std::string value_type
Definition: zipFile.h:132
size_t crc
CRC-32 value of the uncompressed file.
Definition: zipFile.h:86
SDF_API std::string AddFile(const std::string &filePath, const std::string &filePathInArchive=std::string())
bool encrypted
Whether or not this file is encrypted.
Definition: zipFile.h:94
SDF_API bool operator==(const Iterator &rhs) const
SDF_API pointer operator->() const
Returns filename of the current file in the zip archive.
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
std::string reference
Definition: zipFile.h:134
SDF_API Iterator & operator++()
SDF_API ~SdfZipFile()
std::forward_iterator_tag iterator_category
Definition: zipFile.h:135
uint16_t compressionMethod
Definition: zipFile.h:91
SDF_API SdfZipFile()
Create an invalid SdfZipFile object.