Commit fee7489ee4c90c6dbd11e57ecc8e888c8f038716

Authored by Jay Berkenbilt
1 parent 8c4ad6b9

Add Pl_Buffer::getMallocBuffer

ChangeLog
  1 +2021-12-17 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Add Pl_Buffer::getMallocBuffer() to initialize a buffer with
  4 + malloc in support of the C API
  5 +
1 6 2021-12-16 Jay Berkenbilt <ejb@ql.org>
2 7  
3 8 * Add several functions to the C API for working with pages. C
... ...
include/qpdf/Pl_Buffer.hh
... ... @@ -55,6 +55,15 @@ class Pl_Buffer: public Pipeline
55 55 QPDF_DLL
56 56 Buffer* getBuffer();
57 57  
  58 + // getMallocBuffer behaves in the same was as getBuffer except the
  59 + // buffer is allocated with malloc(), making it suitable for use
  60 + // when calling from other languages. If there is no data, *buf is
  61 + // set to a null pointer and *len is set to 0. Otherwise, *buf is
  62 + // a buffer of size *len allocated with malloc(). It is the
  63 + // caller's responsibility to call free() on the buffer.
  64 + QPDF_DLL
  65 + void getMallocBuffer(unsigned char **buf, size_t* len);
  66 +
58 67 private:
59 68 class Members
60 69 {
... ...
libqpdf/Pl_Buffer.cc
... ... @@ -3,6 +3,7 @@
3 3 #include <algorithm>
4 4 #include <assert.h>
5 5 #include <string.h>
  6 +#include <stdlib.h>
6 7  
7 8 Pl_Buffer::Members::Members() :
8 9 ready(true),
... ... @@ -80,3 +81,25 @@ Pl_Buffer::getBuffer()
80 81 this->m = new Members();
81 82 return b;
82 83 }
  84 +
  85 +void
  86 +Pl_Buffer::getMallocBuffer(unsigned char **buf, size_t* len)
  87 +{
  88 + if (! this->m->ready)
  89 + {
  90 + throw std::logic_error(
  91 + "Pl_Buffer::getMallocBuffer() called when not ready");
  92 + }
  93 +
  94 + *len = this->m->total_size;
  95 + if (this->m->total_size > 0)
  96 + {
  97 + *buf = reinterpret_cast<unsigned char*>(malloc(this->m->total_size));
  98 + memcpy(*buf, this->m->data->getBuffer(), this->m->total_size);
  99 + }
  100 + else
  101 + {
  102 + *buf = nullptr;
  103 + }
  104 + this->m = new Members();
  105 +}
... ...
libtests/buffer.cc
... ... @@ -6,6 +6,7 @@
6 6 #include <stdexcept>
7 7 #include <iostream>
8 8 #include <cassert>
  9 +#include <cstring>
9 10  
10 11 static unsigned char* uc(char const* s)
11 12 {
... ... @@ -98,6 +99,31 @@ int main()
98 99 b = bp3.getBuffer();
99 100 std::cout << "size: " << b->getSize() << std::endl;
100 101 delete b;
  102 +
  103 + // Malloc buffer should behave similarly.
  104 + Pl_Buffer bp4("bp4");
  105 + bp4.write(uc("asdf"), 4);
  106 + unsigned char* mbuf;
  107 + size_t len;
  108 + try
  109 + {
  110 + bp4.getMallocBuffer(&mbuf, &len);
  111 + assert(false);
  112 + }
  113 + catch (std::logic_error& e)
  114 + {
  115 + std::cout << "malloc buffer logic error: " << e.what() << std::endl;
  116 + }
  117 + bp4.finish();
  118 + bp4.getMallocBuffer(&mbuf, &len);
  119 + assert(len == 4);
  120 + assert(memcmp(mbuf, uc("asdf"), 4) == 0);
  121 + free(mbuf);
  122 + bp4.write(uc(""), 0);
  123 + bp4.finish();
  124 + bp4.getMallocBuffer(&mbuf, &len);
  125 + assert(mbuf == nullptr);
  126 + assert(len == 0);
101 127 }
102 128 catch (std::exception& e)
103 129 {
... ...
libtests/qtest/buffer/buffer.out
... ... @@ -11,4 +11,5 @@ data: mooquack
11 11 size: 0
12 12 size: 0
13 13 size: 0
  14 +malloc buffer logic error: Pl_Buffer::getMallocBuffer() called when not ready
14 15 done
... ...
manual/index.rst
... ... @@ -3622,10 +3622,14 @@ For a detailed list of changes, please see the file
3622 3622 object is not of the expected type. These warnings now have an
3623 3623 error code of ``qpdf_e_object`` instead of
3624 3624 ``qpdf_e_damaged_pdf``. Also, comments have been added to
3625   - :file:`QPDFObjectHandle.hh` to explain in
3626   - more detail what the behavior is. See :ref:`ref.object-accessors` for a more in-depth
  3625 + :file:`QPDFObjectHandle.hh` to explain in more detail what the
  3626 + behavior is. See :ref:`ref.object-accessors` for a more in-depth
3627 3627 discussion.
3628 3628  
  3629 + - Add ``Pl_Buffer::getMallocBuffer()`` to initialize a buffer
  3630 + allocated with ``malloc()`` for better cross-language
  3631 + interoperability.
  3632 +
3629 3633 - C API Enhancements
3630 3634  
3631 3635 - Overhaul error handling for the object handle functions
... ...