ZipEntry.hpp
Go to the documentation of this file.
1 // @formatter:off
2 //
3 // Balau core C++ library
4 //
5 // Copyright (C) 2008 Bora Software (contact@borasoftware.com)
6 //
7 // Licensed under the Boost Software License - Version 1.0 - August 17th, 2003.
8 // See the LICENSE file for the full license text.
9 //
10 
16 
17 #ifndef COM_BORA_SOFTWARE__BALAU_RESOURCE__ZIP_ENTRY
18 #define COM_BORA_SOFTWARE__BALAU_RESOURCE__ZIP_ENTRY
19 
23 #include <Balau/Util/Files.hpp>
24 
25 namespace Balau::Resource {
26 
35 class ZipEntry : public Uri {
36  public: std::unique_ptr<Uri> clone() const override {
37  return std::unique_ptr<Uri>(new ZipEntry(*this));
38  }
39 
40  public: std::unique_ptr<Uri> append(const std::string & pathComponent) const override {
41  ThrowBalauException(Exception::UnsupportedOperationException, "ZipEntry does not support path appending.");
42  }
43 
44  public: std::unique_ptr<Uri> resolve(std::string_view path) const override {
45  static const std::regex scheme { "[a-zA-Z][a-zA-Z0-9+-\\.]*:" };
46 
47  auto cleanPath = Util::Strings::trim(path);
48  auto str = std::string(cleanPath);
49 
50  if (Util::Strings::startsWithRegex(str, scheme)) {
51  std::unique_ptr<Uri> uri;
52  fromString(uri, str);
53  return uri;
54  }
55 
56  if (Util::Strings::startsWith(str, "/")) {
57  // Absolute path.
58  return std::unique_ptr<Uri>(new ZipEntry(archive, archive.getEntryIndex(str)));
59  } else {
60  // Relative path.
61  const std::string entryName = archive.getEntryName(entryIndex);
62  const std::string normalisedName = UriComponents::normalizePath(entryName);
63  const auto newName = normalisedName + str;
64  return std::unique_ptr<Uri>(new ZipEntry(archive, archive.getEntryIndex(newName)));
65  }
66  }
67 
68  public: std::string toUriString() const override;
69 
70  public: std::string toRawString() const override {
71  return toUriString();
72  }
73 
79  public: bool isEntryDirectory() const;
80 
86  public: bool isEntryFile() const;
87 
93  public: std::string name() const {
94  return archive.getEntryName(entryIndex);
95  }
96 
102  public: size_t size() const;
103 
110  public: std::string readEntryComment() const {
111  return archive.readEntryComment(entryIndex);
112  }
113 
120  public: std::vector<char> readEntryAsBytes() const {
121  return archive.readEntryAsBytes(entryIndex);
122  }
123 
129  public: std::string readEntryAsString() const {
130  return archive.readEntryAsString(entryIndex);
131  }
132 
133  public: size_t hashcode() const noexcept override;
134 
135  public: bool operator == (const Uri & rhs) const override;
136 
137  public: bool canReadFrom() const override {
138  return true;
139  }
140 
141  public: bool canWriteTo() const override {
142  return false;
143  }
144 
151  return ZipEntryByteReadResource(*this);
152  }
153 
160  return ZipEntryUtf8To32ReadResource(*this);
161  }
162 
163  public: std::unique_ptr<ByteReadResource> byteReadResource() const override {
164  return std::unique_ptr<ByteReadResource>(new ZipEntryByteReadResource(*this));
165  }
166 
167  public: std::unique_ptr<Utf8To32ReadResource> utf8To32ReadResource() const override {
168  return std::unique_ptr<Utf8To32ReadResource>(new ZipEntryUtf8To32ReadResource(*this));
169  }
170 
171  public: std::unique_ptr<ByteWriteResource> byteWriteResource() override {
172  ThrowBalauException(Exception::NotImplementedException, "ZipEntry URIs do not have a byte write resource.");
173  }
174 
175  public: std::unique_ptr<Utf32To8WriteResource> utf32To8WriteResource() override {
176  ThrowBalauException(Exception::NotImplementedException, "ZipEntry URIs do not have a Unicode write resource.");
177  }
178 
179  public: bool isRecursivelyIterable() const override {
180  return false;
181  }
182 
183  public: bool isIterable() const override {
184  return false;
185  }
186 
187  public: std::unique_ptr<RecursiveUriIterator> recursiveIterator() const override {
188  ThrowBalauException(Exception::NotImplementedException, "Zip entry URIs do not have recursive iterators.");
189  }
190 
191  public: std::unique_ptr<UriIterator> iterator() const override {
192  ThrowBalauException(Exception::NotImplementedException, "Zip entry URIs do not have iterators.");
193  }
194 
195  public: bool isRegularDirectory() const override {
196  return false;
197  }
198 
199  public: bool isRegularFile() const override {
200  return false;
201  }
202 
203  public: void dispatch(UriDispatcher & dispatcher) const override {
204  dispatcher.dispatch(*this);
205  }
206 
208 
209  friend class ZipFile;
210  friend class ZipEntryByteReadResource;
211  friend class ZipEntryUtf8To32ReadResource;
212 
213  private: ZipEntry(Util::Unzipper & archive_, long long entryIndex_)
214  : archive(archive_)
215  , entryIndex(entryIndex_) {}
216 
217  private: Util::Unzipper & archive;
218  private: long long entryIndex;
219 };
220 
221 } // namespace Balau::Resource
222 
223 #endif // COM_BORA_SOFTWARE__BALAU_RESOURCE__ZIP_ENTRY
bool canWriteTo() const override
Can data be written to the URI via a write resource.
Definition: ZipEntry.hpp:141
void dispatch(UriDispatcher &dispatcher) const override
Visitor pattern dispatching.
Definition: ZipEntry.hpp:203
virtual void dispatch(const File &object)=0
Visit a File URI.
bool operator==(const Uri &rhs) const override
Compare the supplied URI to the current URI.
std::string readEntryAsString(const std::string &name) const
Get the contents of the specified entry in the original archive if one exists.
Random access to the entries in a zip archive.
Definition: Zip.hpp:155
Utilities for files.
bool isRecursivelyIterable() const override
Does the URI have a recursive iterator (examples: file and zip archive URIs).
Definition: ZipEntry.hpp:179
std::unique_ptr< UriIterator > iterator() const override
Get a (non-recursive) iterator.
Definition: ZipEntry.hpp:191
#define ThrowBalauException(ExceptionClass,...)
Throw a Balau style exception, with implicit file and line number, and optional stacktrace.
Definition: BalauException.hpp:45
std::string readEntryAsString() const
Get the contents of the entry as a UTF-8 string.
Definition: ZipEntry.hpp:129
bool canReadFrom() const override
Can data be read from the URI via a read resource.
Definition: ZipEntry.hpp:137
std::vector< char > readEntryAsBytes() const
Get the contents of the entry as a char vector.
Definition: ZipEntry.hpp:120
ZipEntryByteReadResource getByteReadResource() const
Get a byte read resource for this zip entry.
Definition: ZipEntry.hpp:150
void fromString(File &destination, std::string_view value)
Overwrite the supplied file URI by assignment by converting the supplied UTF-8 string to a file URI...
Definition: File.hpp:733
A zip file on the local file system.
Definition: ZipFile.hpp:35
An abstract universal resource identifier.
Definition: Uri.hpp:131
size_t hashcode() const noexcept override
Get the URI&#39;s hash code.
std::string toUriString() const override
Get a string representing the URI, complete with scheme.
std::string readEntryComment() const
Get the comment on the entry if one exists.
Definition: ZipEntry.hpp:110
std::unique_ptr< ByteWriteResource > byteWriteResource() override
Get a byte write resource for the URI.
Definition: ZipEntry.hpp:171
The unified resource class hierarchy.
Definition: ByteReadResource.hpp:24
bool isRegularDirectory() const override
Returns true if the URI points to a file directory.
Definition: ZipEntry.hpp:195
Thrown when a feature is not yet implemented.
Definition: BalauException.hpp:162
std::unique_ptr< Uri > resolve(std::string_view path) const override
Resolve the relative or absolute path, in reference to the current URI.
Definition: ZipEntry.hpp:44
std::unique_ptr< ByteReadResource > byteReadResource() const override
Get a byte read resource for the URI.
Definition: ZipEntry.hpp:163
std::string getEntryName(long long index) const
Get the name of the entry that corresponds to the supplied index.
bool isEntryFile() const
Return true if the entry is an archive file.
static std::string normalizePath(std::string_view path)
Remove instances of "." and "blah/.." and remove any trailing slashes.
static bool startsWith(const StringT< CharT, T ... > &str, const PrefixT &prefix)
Does the string start with the specified prefix?
Definition: Strings.hpp:46
static std::string_view trim(const std::string_view &input)
Trim whitespace from the beginning and end of the supplied UTF-8 string.
Definition: Strings.hpp:706
size_t size() const
Get the uncompressed size of the entry in bytes.
long long getEntryIndex(const std::string &name) const
Get the index of the entry that corresponds to the supplied name.
ZipEntryUtf8To32ReadResource getUtf8To32ReadResource() const
Get a byte read resource for this zip entry.
Definition: ZipEntry.hpp:159
std::vector< char > readEntryAsBytes(const std::string &name) const
Get the contents of the specified entry in the original archive if one exists.
std::unique_ptr< Uri > append(const std::string &pathComponent) const override
Appends the path component to the supplied URI, returning a new URI.
Definition: ZipEntry.hpp:40
std::string name() const
Get the name of the entry.
Definition: ZipEntry.hpp:93
std::unique_ptr< Utf8To32ReadResource > utf8To32ReadResource() const override
Get a UTF-8 to UTF-32 read resource for the URI.
Definition: ZipEntry.hpp:167
A read-only UTF-8 entry in a zip file which is read as UTF-32 characters.
A read-only entry in a zip file which is read as bytes.
static bool startsWithRegex(const std::string &str, const std::regex &prefix)
Does the string start with the specified regular expression?
Definition: Strings.hpp:94
bool isRegularFile() const override
Returns true if the URI is a regular file.
Definition: ZipEntry.hpp:199
std::string readEntryComment(const std::string &name) const
Get the comment on the entry if one exists.
std::unique_ptr< Uri > clone() const override
Clone the concrete Uri.
Definition: ZipEntry.hpp:36
std::unique_ptr< Utf32To8WriteResource > utf32To8WriteResource() override
Get a UTF-32 to UTF-8 write resource for the URI.
Definition: ZipEntry.hpp:175
An entry in a zip archive on the local file system.
Definition: ZipEntry.hpp:35
A class representing the parsed components of a URI.
Thrown when an operation is deliberately not implemented.
Definition: BalauException.hpp:154
std::string toRawString() const override
Get a string representing the raw URI.
Definition: ZipEntry.hpp:70
bool isEntryDirectory() const
Return true if the entry is an archive directory.
std::unique_ptr< RecursiveUriIterator > recursiveIterator() const override
Get a recursive iterator.
Definition: ZipEntry.hpp:187
A read-only entry in a zip file which is read as UTF-8 characters and implicitly converted to UTF-32 ...
Definition: ZipEntryUtf8To32ReadResource.hpp:38
bool isIterable() const override
Does the URI have a non-recursive iterator (examples: file and zip archive URIs). ...
Definition: ZipEntry.hpp:183
A read-only entry in a zip file which is read as bytes.
Definition: ZipEntryByteReadResource.hpp:34
Visitor interface for URIs.
Definition: UriDispatcher.hpp:32