Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 111 additions & 103 deletions cdoc/CDoc1Writer.cpp

Large diffs are not rendered by default.

26 changes: 14 additions & 12 deletions cdoc/CDoc1Writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,24 @@

#include "CDocWriter.h"

class CDoc1Writer : public libcdoc::CDocWriter
#include <memory>

class CDoc1Writer final: public libcdoc::CDocWriter
{
public:
CDoc1Writer(libcdoc::DataConsumer *dst, bool take_ownership, const std::string &method = "http://www.w3.org/2009/xmlenc11#aes256-gcm");
~CDoc1Writer();
CDoc1Writer(libcdoc::DataConsumer *dst, bool take_ownership);
~CDoc1Writer() noexcept final;

libcdoc::result_t beginEncryption() override final;
libcdoc::result_t addRecipient(const libcdoc::Recipient& rcpt) override final;
libcdoc::result_t addFile(const std::string& name, size_t size) override final;
libcdoc::result_t writeData(const uint8_t *src, size_t size) override final;
libcdoc::result_t finishEncryption() override final;
libcdoc::result_t beginEncryption() final;
libcdoc::result_t addRecipient(const libcdoc::Recipient& rcpt) final;
libcdoc::result_t addFile(const std::string& name, size_t size) final;
libcdoc::result_t writeData(const uint8_t *src, size_t size) final;
libcdoc::result_t finishEncryption() final;

libcdoc::result_t encrypt(libcdoc::MultiDataSource& src, const std::vector<libcdoc::Recipient>& keys) final;

private:
CDoc1Writer(const CDoc1Writer &) = delete;
CDoc1Writer &operator=(const CDoc1Writer &) = delete;
class Private;
Private *d;
CDOC_DISABLE_COPY(CDoc1Writer)
struct Private;
std::unique_ptr<Private> d;
};
18 changes: 9 additions & 9 deletions cdoc/DDocWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ using namespace libcdoc;

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

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

DDOCWriter::~DDOCWriter()
DDOCWriter::~DDOCWriter() noexcept
{
writeEndElement(DDOC); // SignedDoc
}
Expand All @@ -44,13 +44,13 @@ DDOCWriter::~DDOCWriter()
* @param mime File mime type
* @param data File content
*/
uint64_t DDOCWriter::addFile(const std::string &file, const std::string &mime, const std::vector<unsigned char> &data)
int64_t DDOCWriter::addFile(const std::string &file, const std::string &mime, const std::vector<unsigned char> &data)
{
return writeBase64Element(DDOC, "DataFile", data, {
{"ContentType", "EMBEDDED_BASE64"},
{"Filename", file},
{"ContentType", "EMBEDDED_BASE64"},
{"Filename", file},
{"Id", "D" + std::to_string(fileCount++)},
{"MimeType", mime},
{"Size", std::to_string(data.size())}
});
{"MimeType", mime},
{"Size", std::to_string(data.size())}
});
}
14 changes: 7 additions & 7 deletions cdoc/DDocWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@

namespace libcdoc {

class DDOCWriter: public XMLWriter
class DDOCWriter final: public XMLWriter
{
public:
DDOCWriter(std::vector<uint8_t>& vec);
~DDOCWriter();
DDOCWriter(DataConsumer &dst);
~DDOCWriter() noexcept final;

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

private:
DDOCWriter(const DDOCWriter &) = delete;
DDOCWriter &operator=(const DDOCWriter &) = delete;
DDOCWriter(const DDOCWriter &) = delete;
DDOCWriter &operator=(const DDOCWriter &) = delete;
int fileCount = 0;

static const NS DDOC;
};

}
}
6 changes: 6 additions & 0 deletions cdoc/Exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,11 @@
#define CDOC_DISABLE_MOVE(Class) \
Class(Class&&) noexcept = delete; \
Class& operator=(Class&&) noexcept = delete;
#define CDOC_DISABLE_COPY(Class) \
Class(const Class&) noexcept = delete; \
Class& operator=(const Class&) noexcept = delete;
#define CDOC_DISABLE_MOVE_COPY(Class) \
CDOC_DISABLE_MOVE(Class) \
CDOC_DISABLE_COPY(Class)

#endif // EXPOORTS_H
86 changes: 35 additions & 51 deletions cdoc/XmlWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,74 +26,59 @@

using namespace libcdoc;

typedef const xmlChar *pcxmlChar;
using pcxmlChar = xmlChar *;

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

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

static int xmlOutputWriteCallback (void *context, const char *buffer, int len);
static int xmlOutputCloseCallback (void *context);
static int xmlOutputWriteCallback (void *context, const char *buffer, int len);
};

int
XMLWriter::Private::xmlOutputWriteCallback (void *context, const char *buffer, int len)
{
auto *d = reinterpret_cast<XMLWriter::Private *>(context);
return d->dst->write((uint8_t *) buffer, len);
}

int
XMLWriter::Private::xmlOutputCloseCallback (void *context)
{
auto *d = reinterpret_cast<XMLWriter::Private *>(context);
return d->dst->close();
}

XMLWriter::XMLWriter(libcdoc::DataConsumer* dst)
: d(new Private)
{
d->dst = dst;
xmlTextWriterStartDocument(d->w.get(), nullptr, "UTF-8", nullptr);
auto *d = reinterpret_cast<XMLWriter::Private *>(context);
return d->dst.write((uint8_t *) buffer, len);
}

XMLWriter::XMLWriter(std::vector<uint8_t>& vec)
: XMLWriter(new libcdoc::VectorConsumer(vec))
XMLWriter::XMLWriter(libcdoc::DataConsumer &dst)
: d(std::make_unique<Private>(dst))
{
d->dst_owned = true;
if(d->w)
xmlTextWriterStartDocument(d->w.get(), nullptr, "UTF-8", nullptr);
}

XMLWriter::~XMLWriter()
XMLWriter::~XMLWriter() noexcept
{
xmlTextWriterEndDocument(d->w.get());
// Force XmlTextWriter to finish before deleting consumer
d->w.reset();
if(d->dst && d->dst_owned) delete d->dst;
delete d;
if(d->w)
xmlTextWriterEndDocument(d->w.get());
}

int64_t XMLWriter::writeStartElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr)
{
if(!d->w)
return WRONG_ARGUMENTS;
std::map<std::string, int>::iterator pos = d->nsmap.find(ns.prefix);
if (pos != d->nsmap.cend())
pos->second++;
else
pos = d->nsmap.insert({ns.prefix, 1}).first;
if(xmlTextWriterStartElementNS(d->w.get(), ns.prefix.empty() ? nullptr : pcxmlChar(ns.prefix.c_str()),
pcxmlChar(name.c_str()), pos->second > 1 ? nullptr : pcxmlChar(ns.ns.c_str())) == -1)
auto pos = d->nsmap.find(ns.prefix);
if (pos != d->nsmap.cend())
pos->second++;
else
pos = d->nsmap.insert({ns.prefix, 1}).first;
if(xmlTextWriterStartElementNS(d->w.get(),
ns.prefix.empty() ? nullptr : pcxmlChar(ns.prefix.c_str()),
pcxmlChar(name.c_str()),
pos->second > 1 ? nullptr : pcxmlChar(ns.ns.c_str())) == -1)
return IO_ERROR;
for(auto i = attr.cbegin(), end = attr.cend(); i != end; ++i)
{
if(xmlTextWriterWriteAttribute(d->w.get(), pcxmlChar(i->first.c_str()), pcxmlChar(i->second.c_str())) == -1)
for(const auto &[name, content]: attr)
{
if(xmlTextWriterWriteAttribute(d->w.get(), pcxmlChar(name.c_str()), pcxmlChar(content.c_str())) == -1)
return IO_ERROR;
}
}
return OK;
}

Expand All @@ -103,26 +88,25 @@ int64_t XMLWriter::writeEndElement(const NS &ns)
return WRONG_ARGUMENTS;
if(xmlTextWriterEndElement(d->w.get()) == -1)
return IO_ERROR;
if(std::map<std::string, int>::iterator pos = d->nsmap.find(ns.prefix);
pos != d->nsmap.cend())
pos->second--;
if(auto pos = d->nsmap.find(ns.prefix); pos != d->nsmap.cend())
pos->second--;
return OK;
}

int64_t XMLWriter::writeElement(const NS &ns, const std::string &name, const std::function<uint64_t()> &f)
int64_t XMLWriter::writeElement(const NS &ns, const std::string &name, const std::function<int64_t()> &f)
{
if(auto rv = writeStartElement(ns, name, {}); rv != OK)
return rv;
if(uint64_t rv = OK; f && (rv = f()) != OK)
if(int64_t rv = OK; f && (rv = f()) != OK)
return rv;
return writeEndElement(ns);
}

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)
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)
{
if(auto rv = writeStartElement(ns, name, attr); rv != OK)
return rv;
if(uint64_t rv = OK; f && (rv = f()) != OK)
if(int64_t rv = OK; f && (rv = f()) != OK)
return rv;
return writeEndElement(ns);
}
Expand Down
19 changes: 9 additions & 10 deletions cdoc/XmlWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <cstdint>
#include <functional>
#include <map>
#include <ostream>
#include <memory>
#include <string>
#include <vector>

Expand All @@ -32,22 +32,21 @@ struct DataConsumer;
class XMLWriter
{
public:
struct NS { std::string prefix, ns; };
struct NS { std::string prefix, ns; };

XMLWriter(std::vector<uint8_t>& vec);
XMLWriter(DataConsumer *dst);
virtual ~XMLWriter();
XMLWriter(DataConsumer &dst);
virtual ~XMLWriter() noexcept;

int64_t writeStartElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr);
int64_t writeEndElement(const NS &ns);
int64_t writeElement(const NS &ns, const std::string &name, const std::function<uint64_t()> &f = nullptr);
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);
int64_t writeElement(const NS &ns, const std::string &name, const std::function<int64_t()> &f = nullptr);
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);
int64_t writeBase64Element(const NS &ns, const std::string &name, const std::vector<unsigned char> &data, const std::map<std::string, std::string> &attr = {});
int64_t writeTextElement(const NS &ns, const std::string &name, const std::map<std::string, std::string> &attr, const std::string &data);

private:
struct Private;
Private *d;
struct Private;
std::unique_ptr<Private> d;
};

} // namespace libcdoc
} // namespace libcdoc
Loading