24
#include "PreCompiled.h"
27
#include <zipios++/zipinputstream.h>
29
using zipios::ConstEntryPointer;
30
using zipios::FileCollection;
31
using zipios::ZipHeader;
34
ZipHeader::ZipHeader(std::istream& inp, int s_off, int e_off)
42
FileCollection* ZipHeader::clone() const
44
return new ZipHeader(*this);
47
void ZipHeader::close()
52
std::istream* ZipHeader::getInputStream(const ConstEntryPointer& entry)
55
throw zipios::InvalidStateException("Attempt to use an invalid FileCollection");
57
return getInputStream(entry->getName());
60
std::istream* ZipHeader::getInputStream(const std::string& entry_name, MatchPath matchpath)
63
throw zipios::InvalidStateException("Attempt to use an invalid ZipHeader");
66
zipios::ConstEntryPointer ent = getEntry(entry_name, matchpath);
72
return new zipios::ZipInputStream(
74
static_cast<const zipios::ZipCDirEntry*>(ent.get())->getLocalHeaderOffset()
78
bool ZipHeader::init(std::istream& _zipfile)
82
setError("Error reading from file");
86
_valid = readCentralDirectory(_zipfile);
90
bool ZipHeader::readCentralDirectory(std::istream& _zipfile)
93
if (!readEndOfCentralDirectory(_zipfile)) {
94
throw zipios::FCollException("Unable to find zip structure: End-of-central-directory");
98
_vs.vseekg(_zipfile, _eocd.offset(), std::ios::beg);
102
_entries.resize(_eocd.totalCount(), nullptr);
103
while ((entry_num < _eocd.totalCount())) {
104
zipios::ZipCDirEntry* ent = new zipios::ZipCDirEntry;
105
_entries[entry_num] = ent;
108
if (_zipfile.bad()) {
109
throw zipios::IOException(
110
"Error reading zip file while reading zip file central directory");
112
if (_zipfile.fail()) {
113
throw zipios::FCollException("Zip file consistency problem. Failure while reading "
114
"zip file central directory");
116
if (_zipfile.eof()) {
117
throw zipios::IOException(
118
"Premature end of file while reading zip file central directory");
126
int pos = _vs.vtellg(_zipfile);
127
_vs.vseekg(_zipfile, 0, std::ios::end);
128
int remaining = static_cast<int>(_vs.vtellg(_zipfile)) - pos;
129
if (remaining != _eocd.eocdOffSetFromEnd()) {
130
throw zipios::FCollException("Zip file consistency problem. Zip file data fields are "
131
"inconsistent with zip file layout");
136
if (!confirmLocalHeaders(_zipfile)) {
137
throw zipios::FCollException("Zip file consistency problem. Zip file data fields are "
138
"inconsistent with zip file layout");
144
bool ZipHeader::readEndOfCentralDirectory(std::istream& _zipfile)
146
zipios::BackBuffer bb(_zipfile, _vs);
151
if (!bb.readChunk(read_p)) {
156
if (_eocd.read(bb, read_p)) {
166
bool ZipHeader::confirmLocalHeaders(std::istream& _zipfile)
168
zipios::Entries::const_iterator it;
169
zipios::ZipCDirEntry* ent {};
170
int inconsistencies = 0;
171
zipios::ZipLocalEntry zlh;
172
for (it = _entries.begin(); it != _entries.end(); ++it) {
173
ent = static_cast<zipios::ZipCDirEntry*>((*it).get());
174
_vs.vseekg(_zipfile, ent->getLocalHeaderOffset(), std::ios::beg);
176
if (!_zipfile || zlh != *ent) {
181
return !inconsistencies;
184
void ZipHeader::setError(std::string )