Skip to content

Commit c5d8ed5

Browse files
committed
Add Zip Read object to avoid create temporary stream objects
IB-8746 Signed-off-by: Raul Metsma <[email protected]>
1 parent 46bbb8d commit c5d8ed5

File tree

13 files changed

+148
-139
lines changed

13 files changed

+148
-139
lines changed

src/ASiC_E.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ void ASiC_E::addAdESSignature(istream &data)
129129
THROW("'%s' format is not supported", mediaType().c_str());
130130
try
131131
{
132-
loadSignatures(data, d->unique_name());
132+
loadSignatures(XMLDocument::openStream(data), d->unique_name());
133133
}
134134
catch(const Exception &e)
135135
{
@@ -149,9 +149,9 @@ unique_ptr<Container> ASiC_E::openInternal(const string &path)
149149
return unique_ptr<Container>(new ASiC_E(path));
150150
}
151151

152-
void ASiC_E::loadSignatures(istream &data, const string &file)
152+
void ASiC_E::loadSignatures(XMLDocument &&doc, const string &file)
153153
{
154-
auto signatures = make_shared<Signatures>(data, mediaType());
154+
auto signatures = make_shared<Signatures>(std::move(doc), mediaType());
155155
d->signatures.emplace(file, signatures.get());
156156
for(auto s = signatures->signature(); s; s++)
157157
addSignature(make_unique<SignatureXAdES_LTA>(signatures, s, this));
@@ -170,8 +170,7 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z)
170170

171171
try
172172
{
173-
auto manifestdata = z.extract<stringstream>("META-INF/manifest.xml");
174-
auto doc = XMLDocument::openStream(manifestdata, {"manifest", MANIFEST_NS});
173+
auto doc = XMLDocument::open(z.read("META-INF/manifest.xml"), {"manifest", MANIFEST_NS});
175174
doc.validateSchema(File::path(Conf::instance()->xsdPath(), "OpenDocument_manifest_v1_2.xsd"));
176175

177176
set<string_view> manifestFiles;
@@ -219,8 +218,7 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z)
219218
{
220219
try
221220
{
222-
auto data = z.extract<stringstream>(file);
223-
loadSignatures(data, file);
221+
loadSignatures(XMLDocument::open(z.read(file)), file);
224222
}
225223
catch(const Exception &e)
226224
{

src/ASiC_E.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ namespace digidoc
5454
ASiC_E(const std::string &path);
5555
DISABLE_COPY(ASiC_E);
5656
void canSave() final;
57-
void loadSignatures(std::istream &data, const std::string &file);
57+
void loadSignatures(XMLDocument &&doc, const std::string &file);
5858
void parseManifestAndLoadFiles(const ZipSerialize &z);
5959
void save(const ZipSerialize &s) final;
6060

src/ASiC_S.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ ASiC_S::ASiC_S(const string &path)
6666
{
6767
if(!signatures().empty())
6868
THROW("Can not add signature to ASiC-S container which already contains a signature.");
69-
auto data = z.extract<stringstream>(file);
70-
auto signatures = make_shared<Signatures>(data, mediaType());
69+
auto signatures = make_shared<Signatures>(XMLDocument::open(z.read(file)), mediaType());
7170
for(auto s = signatures->signature(); s; s++)
7271
addSignature(make_unique<SignatureXAdES_LTA>(signatures, s, this));
7372
}

src/ASiContainer.cpp

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ ZipSerialize ASiContainer::load(const string &path, bool mimetypeRequired, const
9090

9191
if(list.front() == "mimetype")
9292
{
93-
d->mimetype = readMimetype(z);
93+
d->mimetype = z.mimetype();
9494
if(!contains(supported, d->mimetype))
9595
THROW("Incorrect mimetype '%s'", d->mimetype.c_str());
9696
}
@@ -285,26 +285,3 @@ const ZipSerialize::Properties& ASiContainer::zproperty(string_view file) const
285285
return i->second;
286286
return d->properties[string(file)] = { appInfo(), time(nullptr), 0 };
287287
}
288-
289-
/**
290-
* Reads and parses container mimetype. Checks that the mimetype is supported.
291-
*
292-
* @param path path to container directory.
293-
* @throws IOException exception is thrown if there was error reading mimetype file from disk.
294-
* @throws ContainerException exception is thrown if the parsed mimetype is incorrect.
295-
*/
296-
string ASiContainer::readMimetype(const ZipSerialize &z)
297-
{
298-
DEBUG("ASiContainer::readMimetype()");
299-
string text = z.extract<stringstream>("mimetype").str();
300-
text.erase(text.find_last_not_of(" \n\r\f\t\v") + 1);
301-
if(text.empty())
302-
THROW("Failed to read mimetype.");
303-
// Contains UTF-16 BOM
304-
if(text.find("\xFF\xEF") == 0 || text.find("\xEF\xFF") == 0)
305-
THROW("Mimetype file must be UTF-8 format.");
306-
// contains UTF-8 BOM, remove
307-
if(text.find("\xEF\xBB\xBF") == 0)
308-
text.erase(text.cbegin(), text.cbegin() + 3);
309-
return text;
310-
}

src/ASiContainer.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ namespace digidoc
5858
void save(const std::string &path) override;
5959
std::vector<Signature*> signatures() const override;
6060

61-
static std::string readMimetype(const ZipSerialize &z);
62-
6361
protected:
6462
ASiContainer(std::string_view mimetype);
6563

src/DataFile.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "util/log.h"
2525
#include "util/ZipSerialize.h"
2626

27+
#include <array>
2728
#include <fstream>
2829
#include <sstream>
2930

@@ -102,12 +103,24 @@ DataFilePrivate::DataFilePrivate(const ZipSerialize &z, string filename, string
102103
, m_filename(std::move(filename))
103104
, m_mediatype(std::move(mediatype))
104105
{
105-
auto prop = z.properties(m_filename);
106-
d->size.emplace(prop.size);
107-
if(d->size.value() > MAX_MEM_FILE)
108-
m_is = make_unique<fstream>(z.extract<fstream>(m_filename));
106+
auto r = z.read(m_filename);
107+
d->size.emplace(r.size);
108+
if(r.size > MAX_MEM_FILE)
109+
{
110+
auto fs = make_unique<fstream>(util::File::tempFileName(), fstream::in|fstream::out|fstream::binary|fstream::trunc);
111+
if(!fs->is_open())
112+
THROW("Failed to open destination file");
113+
array<char,10240> buf{};
114+
for(size_t size = 0, currentStreamSize = 0;
115+
(size = r(buf.data(), buf.size())) > 0; currentStreamSize += size)
116+
{
117+
if(!fs->write(buf.data(), size))
118+
THROW("Failed to write '%s' data to stream. Stream size: %d", m_filename.c_str(), currentStreamSize);
119+
}
120+
m_is = std::move(fs);
121+
}
109122
else
110-
m_is = make_unique<stringstream>(z.extract<stringstream>(m_filename));
123+
m_is = make_unique<stringstream>(r.operator string());
111124
}
112125

113126
void DataFilePrivate::digest(const Digest &digest) const

src/SiVaContainer.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,10 @@ SiVaContainer::SiVaContainer(const string &path, ContainerOpenCB *cb, bool useHa
164164
else if(File::fileExtension(path, {"asice", "sce", "asics", "scs"}))
165165
{
166166
ZipSerialize z(path, false);
167-
vector<string> list = z.list();
168-
if(list.front() != "mimetype")
169-
THROW("Missing mimetype");
170-
if(d->mediaType = ASiContainer::readMimetype(z);
167+
if(d->mediaType = z.mimetype();
171168
d->mediaType != ASiContainer::MIMETYPE_ASIC_E && d->mediaType != ASiContainer::MIMETYPE_ASIC_S)
172169
THROW("Unknown file");
170+
vector<string> list = z.list();
173171
if(none_of(list.cbegin(), list.cend(), [](const string &file) {
174172
return file.starts_with("META-INF/") && util::File::fileExtension(file, {"p7s"});
175173
}))

src/SignatureTST.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,21 @@ struct SignatureTST::Data {
6868
SignatureTST::SignatureTST(bool manifest, const ZipSerialize &z, ASiC_S *asicSDoc)
6969
: asicSDoc(asicSDoc)
7070
{
71-
auto data = z.extract<stringstream>("META-INF/timestamp.tst").str();
71+
string data = z.read("META-INF/timestamp.tst");
7272
timestampToken = make_unique<TS>((const unsigned char*)data.data(), data.size());
7373
if(manifest)
7474
{
7575
XMLSchema schema(util::File::path(Conf::instance()->xsdPath(), "en_31916201v010101.xsd"));
7676
string file = "META-INF/ASiCArchiveManifest.xml";
7777
string mime = "text/xml";
7878
while(!file.empty()) {
79-
auto xml = z.extract<stringstream>(file);
79+
stringstream xml(z.read(file).operator string());
8080
XMLDocument doc = XMLDocument::openStream(xml, {"ASiCManifest", ASiContainer::ASIC_NS});
8181
schema.validate(doc);
8282
auto ref = doc/"SigReference";
8383
string uri = util::File::fromUriPath(ref["URI"]);
84-
string tst = z.extract<stringstream>(uri).str();
8584
metadata.emplace_back(std::move(file), std::move(mime), xml.str());
86-
metadata.emplace_back(std::move(uri), string(ref["MimeType"]), std::move(tst));
85+
metadata.emplace_back(std::move(uri), string(ref["MimeType"]), z.read(uri));
8786
file.clear();
8887

8988
for(auto ref = doc/"DataObjectReference"; ref; ref++)

src/SignatureXAdES_B.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ Signatures::Signatures()
197197
addNS(XADES_NS, "xades");
198198
}
199199

200-
Signatures::Signatures(istream &data, string_view mediaType)
201-
: XMLDocument(openStream(data))
200+
Signatures::Signatures(XMLDocument &&doc, string_view mediaType)
201+
: XMLDocument(std::move(doc))
202202
{
203203
/* http://www.etsi.org/deliver/etsi_ts/102900_102999/102918/01.03.01_60/ts_102918v010301p.pdf
204204
* 6.2.2

src/SignatureXAdES_B.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace digidoc
4040
{
4141
public:
4242
explicit Signatures();
43-
Signatures(std::istream &data, std::string_view mediaType);
43+
Signatures(XMLDocument &&doc, std::string_view mediaType);
4444

4545
constexpr XMLNode signature() const noexcept
4646
{

0 commit comments

Comments
 (0)