Skip to content

Commit 57c7216

Browse files
authored
Make CDoc1Writer::Private subclass of XMLWriter and add some error checks (#70)
Signed-off-by: Raul Metsma <[email protected]>
1 parent 594c6eb commit 57c7216

File tree

7 files changed

+191
-192
lines changed

7 files changed

+191
-192
lines changed

cdoc/CDoc1Writer.cpp

Lines changed: 111 additions & 103 deletions
Large diffs are not rendered by default.

cdoc/CDoc1Writer.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,24 @@
2020

2121
#include "CDocWriter.h"
2222

23-
class CDoc1Writer : public libcdoc::CDocWriter
23+
#include <memory>
24+
25+
class CDoc1Writer final: public libcdoc::CDocWriter
2426
{
2527
public:
26-
CDoc1Writer(libcdoc::DataConsumer *dst, bool take_ownership, const std::string &method = "http://www.w3.org/2009/xmlenc11#aes256-gcm");
27-
~CDoc1Writer();
28+
CDoc1Writer(libcdoc::DataConsumer *dst, bool take_ownership);
29+
~CDoc1Writer() noexcept final;
2830

29-
libcdoc::result_t beginEncryption() override final;
30-
libcdoc::result_t addRecipient(const libcdoc::Recipient& rcpt) override final;
31-
libcdoc::result_t addFile(const std::string& name, size_t size) override final;
32-
libcdoc::result_t writeData(const uint8_t *src, size_t size) override final;
33-
libcdoc::result_t finishEncryption() override final;
31+
libcdoc::result_t beginEncryption() final;
32+
libcdoc::result_t addRecipient(const libcdoc::Recipient& rcpt) final;
33+
libcdoc::result_t addFile(const std::string& name, size_t size) final;
34+
libcdoc::result_t writeData(const uint8_t *src, size_t size) final;
35+
libcdoc::result_t finishEncryption() final;
3436

3537
libcdoc::result_t encrypt(libcdoc::MultiDataSource& src, const std::vector<libcdoc::Recipient>& keys) final;
38+
3639
private:
37-
CDoc1Writer(const CDoc1Writer &) = delete;
38-
CDoc1Writer &operator=(const CDoc1Writer &) = delete;
39-
class Private;
40-
Private *d;
40+
CDOC_DISABLE_COPY(CDoc1Writer)
41+
struct Private;
42+
std::unique_ptr<Private> d;
4143
};

cdoc/DDocWriter.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ using namespace libcdoc;
2727

2828
const XMLWriter::NS DDOCWriter::DDOC{ "", "http://www.sk.ee/DigiDoc/v1.3.0#" };
2929

30-
DDOCWriter::DDOCWriter(std::vector<uint8_t>& vec)
31-
: XMLWriter(vec)
30+
DDOCWriter::DDOCWriter(DataConsumer &dst)
31+
: XMLWriter(dst)
3232
{
3333
writeStartElement(DDOC, "SignedDoc", {{"format", "DIGIDOC-XML"}, {"version", "1.3"}});
3434
}
3535

36-
DDOCWriter::~DDOCWriter()
36+
DDOCWriter::~DDOCWriter() noexcept
3737
{
3838
writeEndElement(DDOC); // SignedDoc
3939
}
@@ -44,13 +44,13 @@ DDOCWriter::~DDOCWriter()
4444
* @param mime File mime type
4545
* @param data File content
4646
*/
47-
uint64_t DDOCWriter::addFile(const std::string &file, const std::string &mime, const std::vector<unsigned char> &data)
47+
int64_t DDOCWriter::addFile(const std::string &file, const std::string &mime, const std::vector<unsigned char> &data)
4848
{
4949
return writeBase64Element(DDOC, "DataFile", data, {
50-
{"ContentType", "EMBEDDED_BASE64"},
51-
{"Filename", file},
50+
{"ContentType", "EMBEDDED_BASE64"},
51+
{"Filename", file},
5252
{"Id", "D" + std::to_string(fileCount++)},
53-
{"MimeType", mime},
54-
{"Size", std::to_string(data.size())}
55-
});
53+
{"MimeType", mime},
54+
{"Size", std::to_string(data.size())}
55+
});
5656
}

cdoc/DDocWriter.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,20 @@
2222

2323
namespace libcdoc {
2424

25-
class DDOCWriter: public XMLWriter
25+
class DDOCWriter final: public XMLWriter
2626
{
2727
public:
28-
DDOCWriter(std::vector<uint8_t>& vec);
29-
~DDOCWriter();
28+
DDOCWriter(DataConsumer &dst);
29+
~DDOCWriter() noexcept final;
3030

31-
uint64_t addFile(const std::string &name, const std::string &mime, const std::vector<unsigned char> &data);
31+
int64_t addFile(const std::string &name, const std::string &mime, const std::vector<unsigned char> &data);
3232

3333
private:
34-
DDOCWriter(const DDOCWriter &) = delete;
35-
DDOCWriter &operator=(const DDOCWriter &) = delete;
34+
DDOCWriter(const DDOCWriter &) = delete;
35+
DDOCWriter &operator=(const DDOCWriter &) = delete;
3636
int fileCount = 0;
3737

3838
static const NS DDOC;
3939
};
4040

41-
}
41+
}

cdoc/Exports.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,11 @@
5858
#define CDOC_DISABLE_MOVE(Class) \
5959
Class(Class&&) noexcept = delete; \
6060
Class& operator=(Class&&) noexcept = delete;
61+
#define CDOC_DISABLE_COPY(Class) \
62+
Class(const Class&) noexcept = delete; \
63+
Class& operator=(const Class&) noexcept = delete;
64+
#define CDOC_DISABLE_MOVE_COPY(Class) \
65+
CDOC_DISABLE_MOVE(Class) \
66+
CDOC_DISABLE_COPY(Class)
6167

6268
#endif // EXPOORTS_H

cdoc/XmlWriter.cpp

Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -26,74 +26,59 @@
2626

2727
using namespace libcdoc;
2828

29-
typedef const xmlChar *pcxmlChar;
29+
using pcxmlChar = xmlChar *;
3030

3131
struct XMLWriter::Private
3232
{
33-
unique_ptr_t<xmlFreeTextWriter> w = make_unique_ptr<xmlFreeTextWriter>(xmlNewTextWriter(
34-
xmlOutputBufferCreateIO(xmlOutputWriteCallback, xmlOutputCloseCallback, this, nullptr)));
35-
std::map<std::string, int> nsmap;
33+
Private(libcdoc::DataConsumer &_dst): dst(_dst) {}
34+
libcdoc::DataConsumer &dst;
35+
std::map<std::string, int> nsmap;
3636

37-
libcdoc::DataConsumer* dst = nullptr;
38-
bool dst_owned = false;
37+
unique_ptr_t<xmlFreeTextWriter> w = make_unique_ptr<xmlFreeTextWriter>(xmlNewTextWriter(
38+
xmlOutputBufferCreateIO(xmlOutputWriteCallback, nullptr, this, nullptr)));
3939

40-
static int xmlOutputWriteCallback (void *context, const char *buffer, int len);
41-
static int xmlOutputCloseCallback (void *context);
40+
static int xmlOutputWriteCallback (void *context, const char *buffer, int len);
4241
};
4342

4443
int
4544
XMLWriter::Private::xmlOutputWriteCallback (void *context, const char *buffer, int len)
4645
{
47-
auto *d = reinterpret_cast<XMLWriter::Private *>(context);
48-
return d->dst->write((uint8_t *) buffer, len);
49-
}
50-
51-
int
52-
XMLWriter::Private::xmlOutputCloseCallback (void *context)
53-
{
54-
auto *d = reinterpret_cast<XMLWriter::Private *>(context);
55-
return d->dst->close();
56-
}
57-
58-
XMLWriter::XMLWriter(libcdoc::DataConsumer* dst)
59-
: d(new Private)
60-
{
61-
d->dst = dst;
62-
xmlTextWriterStartDocument(d->w.get(), nullptr, "UTF-8", nullptr);
46+
auto *d = reinterpret_cast<XMLWriter::Private *>(context);
47+
return d->dst.write((uint8_t *) buffer, len);
6348
}
6449

65-
XMLWriter::XMLWriter(std::vector<uint8_t>& vec)
66-
: XMLWriter(new libcdoc::VectorConsumer(vec))
50+
XMLWriter::XMLWriter(libcdoc::DataConsumer &dst)
51+
: d(std::make_unique<Private>(dst))
6752
{
68-
d->dst_owned = true;
53+
if(d->w)
54+
xmlTextWriterStartDocument(d->w.get(), nullptr, "UTF-8", nullptr);
6955
}
7056

71-
XMLWriter::~XMLWriter()
57+
XMLWriter::~XMLWriter() noexcept
7258
{
73-
xmlTextWriterEndDocument(d->w.get());
74-
// Force XmlTextWriter to finish before deleting consumer
75-
d->w.reset();
76-
if(d->dst && d->dst_owned) delete d->dst;
77-
delete d;
59+
if(d->w)
60+
xmlTextWriterEndDocument(d->w.get());
7861
}
7962

8063
int64_t XMLWriter::writeStartElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr)
8164
{
8265
if(!d->w)
8366
return WRONG_ARGUMENTS;
84-
std::map<std::string, int>::iterator pos = d->nsmap.find(ns.prefix);
85-
if (pos != d->nsmap.cend())
86-
pos->second++;
87-
else
88-
pos = d->nsmap.insert({ns.prefix, 1}).first;
89-
if(xmlTextWriterStartElementNS(d->w.get(), ns.prefix.empty() ? nullptr : pcxmlChar(ns.prefix.c_str()),
90-
pcxmlChar(name.c_str()), pos->second > 1 ? nullptr : pcxmlChar(ns.ns.c_str())) == -1)
67+
auto pos = d->nsmap.find(ns.prefix);
68+
if (pos != d->nsmap.cend())
69+
pos->second++;
70+
else
71+
pos = d->nsmap.insert({ns.prefix, 1}).first;
72+
if(xmlTextWriterStartElementNS(d->w.get(),
73+
ns.prefix.empty() ? nullptr : pcxmlChar(ns.prefix.c_str()),
74+
pcxmlChar(name.c_str()),
75+
pos->second > 1 ? nullptr : pcxmlChar(ns.ns.c_str())) == -1)
9176
return IO_ERROR;
92-
for(auto i = attr.cbegin(), end = attr.cend(); i != end; ++i)
93-
{
94-
if(xmlTextWriterWriteAttribute(d->w.get(), pcxmlChar(i->first.c_str()), pcxmlChar(i->second.c_str())) == -1)
77+
for(const auto &[name, content]: attr)
78+
{
79+
if(xmlTextWriterWriteAttribute(d->w.get(), pcxmlChar(name.c_str()), pcxmlChar(content.c_str())) == -1)
9580
return IO_ERROR;
96-
}
81+
}
9782
return OK;
9883
}
9984

@@ -103,26 +88,25 @@ int64_t XMLWriter::writeEndElement(const NS &ns)
10388
return WRONG_ARGUMENTS;
10489
if(xmlTextWriterEndElement(d->w.get()) == -1)
10590
return IO_ERROR;
106-
if(std::map<std::string, int>::iterator pos = d->nsmap.find(ns.prefix);
107-
pos != d->nsmap.cend())
108-
pos->second--;
91+
if(auto pos = d->nsmap.find(ns.prefix); pos != d->nsmap.cend())
92+
pos->second--;
10993
return OK;
11094
}
11195

112-
int64_t XMLWriter::writeElement(const NS &ns, const std::string &name, const std::function<uint64_t()> &f)
96+
int64_t XMLWriter::writeElement(const NS &ns, const std::string &name, const std::function<int64_t()> &f)
11397
{
11498
if(auto rv = writeStartElement(ns, name, {}); rv != OK)
11599
return rv;
116-
if(uint64_t rv = OK; f && (rv = f()) != OK)
100+
if(int64_t rv = OK; f && (rv = f()) != OK)
117101
return rv;
118102
return writeEndElement(ns);
119103
}
120104

121-
int64_t XMLWriter::writeElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr, const std::function<uint64_t()> &f)
105+
int64_t XMLWriter::writeElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr, const std::function<int64_t()> &f)
122106
{
123107
if(auto rv = writeStartElement(ns, name, attr); rv != OK)
124108
return rv;
125-
if(uint64_t rv = OK; f && (rv = f()) != OK)
109+
if(int64_t rv = OK; f && (rv = f()) != OK)
126110
return rv;
127111
return writeEndElement(ns);
128112
}

cdoc/XmlWriter.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <cstdint>
2222
#include <functional>
2323
#include <map>
24-
#include <ostream>
24+
#include <memory>
2525
#include <string>
2626
#include <vector>
2727

@@ -32,22 +32,21 @@ struct DataConsumer;
3232
class XMLWriter
3333
{
3434
public:
35-
struct NS { std::string prefix, ns; };
35+
struct NS { std::string prefix, ns; };
3636

37-
XMLWriter(std::vector<uint8_t>& vec);
38-
XMLWriter(DataConsumer *dst);
39-
virtual ~XMLWriter();
37+
XMLWriter(DataConsumer &dst);
38+
virtual ~XMLWriter() noexcept;
4039

4140
int64_t writeStartElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr);
4241
int64_t writeEndElement(const NS &ns);
43-
int64_t writeElement(const NS &ns, const std::string &name, const std::function<uint64_t()> &f = nullptr);
44-
int64_t writeElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr, const std::function<uint64_t()> &f = nullptr);
42+
int64_t writeElement(const NS &ns, const std::string &name, const std::function<int64_t()> &f = nullptr);
43+
int64_t writeElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr, const std::function<int64_t()> &f = nullptr);
4544
int64_t writeBase64Element(const NS &ns, const std::string &name, const std::vector<unsigned char> &data, const std::map<std::string, std::string> &attr = {});
4645
int64_t writeTextElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr, const std::string &data);
4746

4847
private:
49-
struct Private;
50-
Private *d;
48+
struct Private;
49+
std::unique_ptr<Private> d;
5150
};
5251

53-
} // namespace libcdoc
52+
} // namespace libcdoc

0 commit comments

Comments
 (0)