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> 2021-12-16 Jay Berkenbilt <ejb@ql.org>
* Add several functions to the C API for working with pages. C * 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 QPDF_DLL
Buffer* getBuffer(); 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: private:
class Members class Members
{ {

View File

@ -3,6 +3,7 @@
#include <algorithm> #include <algorithm>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
Pl_Buffer::Members::Members() : Pl_Buffer::Members::Members() :
ready(true), ready(true),
@ -80,3 +81,25 @@ Pl_Buffer::getBuffer()
this->m = new Members(); this->m = new Members();
return b; 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 <stdexcept>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
#include <cstring>
static unsigned char* uc(char const* s) static unsigned char* uc(char const* s)
{ {
@ -98,6 +99,31 @@ int main()
b = bp3.getBuffer(); b = bp3.getBuffer();
std::cout << "size: " << b->getSize() << std::endl; std::cout << "size: " << b->getSize() << std::endl;
delete b; 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) catch (std::exception& e)
{ {

View File

@ -11,4 +11,5 @@ data: mooquack
size: 0 size: 0
size: 0 size: 0
size: 0 size: 0
malloc buffer logic error: Pl_Buffer::getMallocBuffer() called when not ready
done 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 object is not of the expected type. These warnings now have an
error code of ``qpdf_e_object`` instead of error code of ``qpdf_e_object`` instead of
``qpdf_e_damaged_pdf``. Also, comments have been added to ``qpdf_e_damaged_pdf``. Also, comments have been added to
:file:`QPDFObjectHandle.hh` to explain in :file:`QPDFObjectHandle.hh` to explain in more detail what the
more detail what the behavior is. See :ref:`ref.object-accessors` for a more in-depth behavior is. See :ref:`ref.object-accessors` for a more in-depth
discussion. discussion.
- Add ``Pl_Buffer::getMallocBuffer()`` to initialize a buffer
allocated with ``malloc()`` for better cross-language
interoperability.
- C API Enhancements - C API Enhancements
- Overhaul error handling for the object handle functions - Overhaul error handling for the object handle functions