Add Pl_Buffer::getMallocBuffer

This commit is contained in:
Jay Berkenbilt 2021-12-17 07:33:42 -05:00
parent 8c4ad6b946
commit fee7489ee4
6 changed files with 70 additions and 2 deletions

View File

@ -1,3 +1,8 @@
2021-12-17 Jay Berkenbilt <ejb@ql.org>
* Add Pl_Buffer::getMallocBuffer() to initialize a buffer with
malloc in support of the C API
2021-12-16 Jay Berkenbilt <ejb@ql.org>
* Add several functions to the C API for working with pages. C

View File

@ -55,6 +55,15 @@ class Pl_Buffer: public Pipeline
QPDF_DLL
Buffer* getBuffer();
// getMallocBuffer behaves in the same was as getBuffer except the
// buffer is allocated with malloc(), making it suitable for use
// when calling from other languages. If there is no data, *buf is
// set to a null pointer and *len is set to 0. Otherwise, *buf is
// a buffer of size *len allocated with malloc(). It is the
// caller's responsibility to call free() on the buffer.
QPDF_DLL
void getMallocBuffer(unsigned char **buf, size_t* len);
private:
class Members
{

View File

@ -3,6 +3,7 @@
#include <algorithm>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
Pl_Buffer::Members::Members() :
ready(true),
@ -80,3 +81,25 @@ Pl_Buffer::getBuffer()
this->m = new Members();
return b;
}
void
Pl_Buffer::getMallocBuffer(unsigned char **buf, size_t* len)
{
if (! this->m->ready)
{
throw std::logic_error(
"Pl_Buffer::getMallocBuffer() called when not ready");
}
*len = this->m->total_size;
if (this->m->total_size > 0)
{
*buf = reinterpret_cast<unsigned char*>(malloc(this->m->total_size));
memcpy(*buf, this->m->data->getBuffer(), this->m->total_size);
}
else
{
*buf = nullptr;
}
this->m = new Members();
}

View File

@ -6,6 +6,7 @@
#include <stdexcept>
#include <iostream>
#include <cassert>
#include <cstring>
static unsigned char* uc(char const* s)
{
@ -98,6 +99,31 @@ int main()
b = bp3.getBuffer();
std::cout << "size: " << b->getSize() << std::endl;
delete b;
// Malloc buffer should behave similarly.
Pl_Buffer bp4("bp4");
bp4.write(uc("asdf"), 4);
unsigned char* mbuf;
size_t len;
try
{
bp4.getMallocBuffer(&mbuf, &len);
assert(false);
}
catch (std::logic_error& e)
{
std::cout << "malloc buffer logic error: " << e.what() << std::endl;
}
bp4.finish();
bp4.getMallocBuffer(&mbuf, &len);
assert(len == 4);
assert(memcmp(mbuf, uc("asdf"), 4) == 0);
free(mbuf);
bp4.write(uc(""), 0);
bp4.finish();
bp4.getMallocBuffer(&mbuf, &len);
assert(mbuf == nullptr);
assert(len == 0);
}
catch (std::exception& e)
{

View File

@ -11,4 +11,5 @@ data: mooquack
size: 0
size: 0
size: 0
malloc buffer logic error: Pl_Buffer::getMallocBuffer() called when not ready
done

View File

@ -3622,10 +3622,14 @@ For a detailed list of changes, please see the file
object is not of the expected type. These warnings now have an
error code of ``qpdf_e_object`` instead of
``qpdf_e_damaged_pdf``. Also, comments have been added to
:file:`QPDFObjectHandle.hh` to explain in
more detail what the behavior is. See :ref:`ref.object-accessors` for a more in-depth
:file:`QPDFObjectHandle.hh` to explain in more detail what the
behavior is. See :ref:`ref.object-accessors` for a more in-depth
discussion.
- Add ``Pl_Buffer::getMallocBuffer()`` to initialize a buffer
allocated with ``malloc()`` for better cross-language
interoperability.
- C API Enhancements
- Overhaul error handling for the object handle functions