Skip to content

Commit a76ba53

Browse files
committed
C-API: drop ZXing_ReadBarcode() + new heap allocation optimization
Use a trick from the C# playbook: return a static empty vector that does not need to be allocated and deleted on every call.
1 parent 7bed1d8 commit a76ba53

File tree

3 files changed

+9
-24
lines changed

3 files changed

+9
-24
lines changed

core/src/ZXingC.cpp

+9-22
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using namespace ZXing;
1919

2020
static thread_local std::string lastErrorMsg;
21+
static Barcodes emptyBarcodes{}; // used to prevent new heap allocation for each empty result
2122

2223
template<typename R, typename T> R transmute_cast(const T& v) noexcept
2324
{
@@ -66,19 +67,6 @@ static uint8_t* copy(const ByteArray& ba, int* len) noexcept
6667
ZX_CATCH({})
6768

6869

69-
static std::tuple<Barcodes, bool> ReadBarcodesAndSetLastError(const ZXing_ImageView* iv, const ZXing_ReaderOptions* opts,
70-
int maxSymbols)
71-
{
72-
ZX_CHECK(iv, "ImageView param is NULL")
73-
try {
74-
auto o = opts ? *opts : ReaderOptions{};
75-
if (maxSymbols)
76-
o.setMaxNumberOfSymbols(maxSymbols);
77-
return {ReadBarcodes(*iv, o), true};
78-
}
79-
ZX_CATCH({Barcodes{}, false})
80-
}
81-
8270
extern "C" {
8371
/*
8472
* ZXing/ImageView.h
@@ -238,7 +226,8 @@ void ZXing_Barcode_delete(ZXing_Barcode* barcode)
238226

239227
void ZXing_Barcodes_delete(ZXing_Barcodes* barcodes)
240228
{
241-
delete barcodes;
229+
if (barcodes != &emptyBarcodes)
230+
delete barcodes;
242231
}
243232

244233
int ZXing_Barcodes_size(const ZXing_Barcodes* barcodes)
@@ -314,16 +303,14 @@ ZX_ENUM_PROPERTY(TextMode, textMode, TextMode)
314303
* ZXing/ReadBarcode.h
315304
*/
316305

317-
ZXing_Barcode* ZXing_ReadBarcode(const ZXing_ImageView* iv, const ZXing_ReaderOptions* opts)
318-
{
319-
auto [res, ok] = ReadBarcodesAndSetLastError(iv, opts, 1);
320-
return !res.empty() ? new Barcode(std::move(res.front())) : NULL;
321-
}
322-
323306
ZXing_Barcodes* ZXing_ReadBarcodes(const ZXing_ImageView* iv, const ZXing_ReaderOptions* opts)
324307
{
325-
auto [res, ok] = ReadBarcodesAndSetLastError(iv, opts, 0);
326-
return !res.empty() || ok ? new Barcodes(std::move(res)) : NULL;
308+
ZX_CHECK(iv, "ImageView param is NULL")
309+
try {
310+
auto res = ReadBarcodes(*iv, opts ? *opts : ReaderOptions{});
311+
return res.empty() ? &emptyBarcodes : new Barcodes(std::move(res));
312+
}
313+
ZX_CATCH(NULL);
327314
}
328315

329316

core/src/ZXingC.h

-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ int ZXing_ReaderOptions_getMaxNumberOfSymbols(const ZXing_ReaderOptions* opts);
257257
*/
258258

259259
/** Note: opts is optional, i.e. it can be NULL, which will imply default settings. */
260-
ZXing_Barcode* ZXing_ReadBarcode(const ZXing_ImageView* iv, const ZXing_ReaderOptions* opts);
261260
ZXing_Barcodes* ZXing_ReadBarcodes(const ZXing_ImageView* iv, const ZXing_ReaderOptions* opts);
262261

263262
#ifdef ZXING_EXPERIMENTAL_API

wrappers/rust/src/bindings.rs

-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ extern "C" {
197197
pub fn ZXing_ReaderOptions_getTextMode(opts: *const ZXing_ReaderOptions) -> ZXing_TextMode;
198198
pub fn ZXing_ReaderOptions_getMinLineCount(opts: *const ZXing_ReaderOptions) -> ::core::ffi::c_int;
199199
pub fn ZXing_ReaderOptions_getMaxNumberOfSymbols(opts: *const ZXing_ReaderOptions) -> ::core::ffi::c_int;
200-
pub fn ZXing_ReadBarcode(iv: *const ZXing_ImageView, opts: *const ZXing_ReaderOptions) -> *mut ZXing_Barcode;
201200
pub fn ZXing_ReadBarcodes(iv: *const ZXing_ImageView, opts: *const ZXing_ReaderOptions) -> *mut ZXing_Barcodes;
202201
pub fn ZXing_CreatorOptions_new(format: ZXing_BarcodeFormat) -> *mut ZXing_CreatorOptions;
203202
pub fn ZXing_CreatorOptions_delete(opts: *mut ZXing_CreatorOptions);

0 commit comments

Comments
 (0)