Add alloc functions
diff --git a/doc/changelog.md b/doc/changelog.md
index f5639cd..657defa 100644
--- a/doc/changelog.md
+++ b/doc/changelog.md
@@ -14,6 +14,7 @@
- Added `std/wbmp`.
- Added `WUFFS_BASE__PIXEL_BLEND__SRC_OVER`.
- Added `WUFFS_BASE__PIXEL_FORMAT__BGR_565`.
+- Added alloc functions.
- Added double-curly blocks.
- Added interfaces.
- Added preprocessor.
diff --git a/doc/note/memory-safety.md b/doc/note/memory-safety.md
index fa37b38..2072a74 100644
--- a/doc/note/memory-safety.md
+++ b/doc/note/memory-safety.md
@@ -8,18 +8,20 @@
additional performance.
A deliberate constraint in the Wuffs language is that struct fields cannot
-store any pointers to dynamically allocated memory, only to e.g. statically
+store any pointers to dynamically allocated memory, only to statically
allocated error messages (a `base.status`). When a Wuffs decompressor reads
from or writes to a buffer, that buffer has to be passed on every call, instead
-of e.g. being passed once during initialization and saved to a field. There is
-no ambiguity about whether the caller or callee owns some memory, even when
+of being passed once during initialization and saved to a field. There is no
+ambiguity about whether the caller or callee should free some memory, even when
encountering an error. It's always caller-owned and callee-borrowed.
Wuffs is also trivially safe against things like memory leaks, use-after-frees
and double-frees because Wuffs code doesn't even have the *capability* to
-allocate or free memory. Wuffs is certainly less powerful than other
-programming languages, but with less power comes easier proof-of-safety. Still,
-Wuffs is not a toy language and can do [real work](/example).
+allocate or free memory, other than its transpiled-to-C form providing
+`wuffs_foo__bar__alloc` convenience functions to set up before processing a
+single byte of input. Wuffs is certainly less powerful than other programming
+languages, but **with less power comes easier proof of safety**. Still, Wuffs
+is not a toy language and the [example programs](/example) do real work.
Wuffs is a language for writing libraries, and complete programs require
combining Wuffs with another programming language. The obvious example is the
@@ -56,8 +58,10 @@
[example/zcat](/example/zcat/zcat.c) program can decompress arbitrarily large
input using static buffers, without ever calling `malloc`. Indeed, on Linux,
that program self-imposes a `SECCOMP_MODE_STRICT` sandbox, prohibiting dynamic
-memory allocation (amongst many other useful but dangerous things) at the
-kernel level.
+memory allocation (amongst many other powerful but dangerous things) at the
+kernel level. The [example/jsonptr](/example/jsonptr/jsonptr.cc) program, which
+parses and filters [JSON](https://www.json.org/), is another example that does
+useful work within a strict sandbox.
## Thread-Safety
diff --git a/example/library/library.c b/example/library/library.c
index 78cab0f..d705cdd 100644
--- a/example/library/library.c
+++ b/example/library/library.c
@@ -33,7 +33,6 @@
*/
#include <stdio.h>
-#include <stdlib.h>
// Wuffs ships as a "single file C library" or "header file library" as per
// https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
@@ -59,7 +58,7 @@
//
// Passing --no-name to the gzip command line also means to skip the timestamp,
// which means that its output is deterministic.
-uint8_t g_src_ptr[] = {
+uint8_t g_src_array[] = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // 00..07
0x00, 0x03, 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0x57, // 08..0F
0x08, 0x2f, 0x4d, 0x4b, 0x2b, 0xd6, 0xe3, 0x02, // 10..17
@@ -79,43 +78,28 @@
static const char* //
decode() {
- wuffs_base__io_buffer dst;
- dst.data.ptr = g_dst_buffer_array;
- dst.data.len = DST_BUFFER_ARRAY_SIZE;
- dst.meta.wi = 0;
- dst.meta.ri = 0;
- dst.meta.pos = 0;
- dst.meta.closed = false;
-
- wuffs_base__io_buffer src;
- src.data.ptr = g_src_ptr;
- src.data.len = g_src_len;
- src.meta.wi = g_src_len;
- src.meta.ri = 0;
- src.meta.pos = 0;
- src.meta.closed = true;
-
- wuffs_gzip__decoder* dec =
- (wuffs_gzip__decoder*)(calloc(sizeof__wuffs_gzip__decoder(), 1));
+ wuffs_gzip__decoder* dec = wuffs_gzip__decoder__alloc();
if (!dec) {
return "out of memory";
}
- wuffs_base__status status = wuffs_gzip__decoder__initialize(
- dec, sizeof__wuffs_gzip__decoder(), WUFFS_VERSION,
- WUFFS_INITIALIZE__ALREADY_ZEROED);
- if (!wuffs_base__status__is_ok(&status)) {
- free(dec);
- return wuffs_base__status__message(&status);
- }
- status = wuffs_gzip__decoder__transform_io(
+
+ wuffs_base__io_buffer dst =
+ wuffs_base__ptr_u8__writer(&g_dst_buffer_array[0], DST_BUFFER_ARRAY_SIZE);
+
+ static const bool closed = true;
+ wuffs_base__io_buffer src =
+ wuffs_base__ptr_u8__reader(&g_src_array[0], g_src_len, closed);
+
+ wuffs_base__status status = wuffs_gzip__decoder__transform_io(
dec, &dst, &src,
- wuffs_base__make_slice_u8(g_work_buffer_array, WORK_BUFFER_ARRAY_SIZE));
+ wuffs_base__make_slice_u8(&g_work_buffer_array[0],
+ WORK_BUFFER_ARRAY_SIZE));
+ free(dec);
+
if (!wuffs_base__status__is_ok(&status)) {
- free(dec);
return wuffs_base__status__message(&status);
}
fwrite(dst.data.ptr, sizeof(uint8_t), dst.meta.wi, stdout);
- free(dec);
return NULL;
}
diff --git a/internal/cgen/base/all-impl.c b/internal/cgen/base/all-impl.c
index 405e963..0ba6e6e 100644
--- a/internal/cgen/base/all-impl.c
+++ b/internal/cgen/base/all-impl.c
@@ -28,9 +28,16 @@
#include <stdbool.h>
#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+#include <memory>
+#else
+#warning "Wuffs' C++ code requires -std=c++11 or later"
+#endif
+
extern "C" {
#endif
diff --git a/internal/cgen/cgen.go b/internal/cgen/cgen.go
index b186f97..319bdd3 100644
--- a/internal/cgen/cgen.go
+++ b/internal/cgen/cgen.go
@@ -385,7 +385,11 @@
buf.writes("wuffs_base__vtable first_vtable;\n")
buf.writes("} private_impl;\n\n")
- buf.writes("\n#ifdef __cplusplus\n\n")
+ buf.writes("\n#ifdef __cplusplus\n")
+ buf.writes("#if __cplusplus >= 201103L\n")
+ buf.printf("using unique_ptr = std::unique_ptr<wuffs_base__%s, decltype(&free)>;", n)
+ buf.writes("#endif\n\n")
+
for _, f := range builtInInterfaceMethods[qid] {
if err := g.writeFuncSignature(buf, f, wfsCppDecl); err != nil {
return err
@@ -681,13 +685,40 @@
}
}
+ b.writes("// ---------------- Allocs\n\n")
+
+ b.writes("// These functions allocate and initialize Wuffs structs. They return NULL if\n")
+ b.writes("// memory allocation fails. If they return non-NULL, there is no need to call\n")
+ b.writes("// wuffs_foo__bar__initialize, but the caller is responsible for eventually\n")
+ b.writes("// calling free on the returned pointer. That pointer is effectively a C++\n")
+ b.writes("// std::unique_ptr<T, decltype(&free)>.\n\n")
+
+ for _, n := range g.structList {
+ if !n.Public() {
+ continue
+ }
+ if err := g.writeAllocSignature(b, n); err != nil {
+ return err
+ }
+ b.writes(";\n\n")
+ structName := n.QID().Str(g.tm)
+ for _, impl := range n.Implements() {
+ iQID := impl.AsTypeExpr().QID()
+ iName := fmt.Sprintf("wuffs_%s__%s", iQID[0].Str(g.tm), iQID[1].Str(g.tm))
+ b.printf("static inline %s* //\n", iName)
+ b.printf("%s%s__alloc_as__%s(){\n", g.pkgPrefix, structName, iName)
+ b.printf("return (%s*)(%s%s__alloc());\n", iName, g.pkgPrefix, structName)
+ b.printf("}\n\n")
+ }
+ }
+
b.writes("// ---------------- Upcasts\n\n")
for _, n := range g.structList {
structName := n.QID().Str(g.tm)
for _, impl := range n.Implements() {
iQID := impl.AsTypeExpr().QID()
iName := fmt.Sprintf("wuffs_%s__%s", iQID[0].Str(g.tm), iQID[1].Str(g.tm))
- b.printf("static inline %s* //\n", iName)
+ b.printf("static inline %s* //\n", iName)
b.printf("%s%s__upcast_as__%s(%s%s* p){\n",
g.pkgPrefix, structName, iName, g.pkgPrefix, structName)
b.printf("return (%s*)p;\n", iName)
@@ -1086,6 +1117,24 @@
fullStructName := g.pkgPrefix + structName + "__struct"
b.writes("#ifdef __cplusplus\n")
+ b.writes("#if __cplusplus >= 201103L\n")
+ b.printf("using unique_ptr = std::unique_ptr<%s%s, decltype(&free)>;\n\n", g.pkgPrefix, structName)
+ b.writes("// On failure, the alloc_etc functions return nullptr. They don't throw.\n\n")
+ b.writes("static inline unique_ptr //\n")
+ b.writes("alloc() {\n")
+ b.printf("return unique_ptr(%s%s__alloc(), &free);\n", g.pkgPrefix, structName)
+ b.writes("}\n")
+ for _, impl := range n.Implements() {
+ iQID := impl.AsTypeExpr().QID()
+ iName := fmt.Sprintf("wuffs_%s__%s", iQID[0].Str(g.tm), iQID[1].Str(g.tm))
+ b.printf("\nstatic inline %s::unique_ptr //\n", iName)
+ b.printf("alloc_as__%s(){\n", iName)
+ b.printf("return %s::unique_ptr(%s%s__alloc_as__%s(), &free);\n",
+ iName, g.pkgPrefix, structName, iName)
+ b.printf("}\n")
+ }
+ b.writes("#endif // __cplusplus >= 201103L\n\n")
+
b.writes("#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)\n")
b.writes("// Disallow constructing or copying an object via standard C++ mechanisms,\n")
b.writes("// e.g. the \"new\" operator, as this struct is intentionally opaque. Its total\n")
@@ -1115,7 +1164,7 @@
// The empty // comment makes clang-format place the function name
// at the start of a line.
- b.writes("inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT //\n" +
+ b.writes("inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT //\n" +
"initialize(size_t sizeof_star_self, uint64_t wuffs_version, uint32_t initialize_flags) {\n")
b.printf("return %s%s__initialize(this, sizeof_star_self, wuffs_version, initialize_flags);\n}\n\n",
g.pkgPrefix, structName)
@@ -1123,7 +1172,7 @@
for _, impl := range n.Implements() {
iQID := impl.AsTypeExpr().QID()
iName := fmt.Sprintf("wuffs_%s__%s", iQID[0].Str(g.tm), iQID[1].Str(g.tm))
- b.printf("inline %s* //\n", iName)
+ b.printf("inline %s* //\n", iName)
b.printf("upcast_as__%s(){\n", iName)
b.printf("return (%s*)this;\n", iName)
b.printf("}\n\n")
@@ -1201,14 +1250,21 @@
func (g *gen) writeInitializerSignature(b *buffer, n *a.Struct, public bool) error {
structName := n.QID().Str(g.tm)
- b.printf("wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT //\n"+
+ b.printf("wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT //\n"+
"%s%s__initialize(%s%s *self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t initialize_flags)",
g.pkgPrefix, structName, g.pkgPrefix, structName)
return nil
}
+func (g *gen) writeAllocSignature(b *buffer, n *a.Struct) error {
+ structName := n.QID().Str(g.tm)
+ b.printf("%s%s* //\n%s%s__alloc()", g.pkgPrefix, structName, g.pkgPrefix, structName)
+ return nil
+}
+
func (g *gen) writeSizeofSignature(b *buffer, n *a.Struct) error {
- b.printf("size_t //\nsizeof__%s%s()", g.pkgPrefix, n.QID().Str(g.tm))
+ structName := n.QID().Str(g.tm)
+ b.printf("size_t //\nsizeof__%s%s()", g.pkgPrefix, structName)
return nil
}
@@ -1314,10 +1370,25 @@
b.writes("}\n\n")
if n.Public() {
+ structName := n.QID().Str(g.tm)
+ if err := g.writeAllocSignature(b, n); err != nil {
+ return err
+ }
+ b.writes("{\n")
+ b.printf("%s%s* x = (%s%s*)(calloc(sizeof(%s%s), 1));\n",
+ g.pkgPrefix, structName, g.pkgPrefix, structName, g.pkgPrefix, structName)
+ b.writes("if (!x) { return NULL; }\n")
+ b.printf("if (%s%s__initialize(x, sizeof(%s%s), "+
+ "WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {\n",
+ g.pkgPrefix, structName, g.pkgPrefix, structName)
+ b.writes("free(x); return NULL; }\n")
+ b.writes("return x;\n")
+ b.writes("}\n\n")
+
if err := g.writeSizeofSignature(b, n); err != nil {
return err
}
- b.printf("{ return sizeof (%s%s); }\n\n", g.pkgPrefix, n.QID().Str(g.tm))
+ b.printf("{ return sizeof(%s%s); }\n\n", g.pkgPrefix, structName)
}
return nil
}
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index 82a3973..3d51198 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -17,7 +17,7 @@
package cgen
const baseAllImplC = "" +
- "#ifndef WUFFS_INCLUDE_GUARD__BASE\n#define WUFFS_INCLUDE_GUARD__BASE\n\n#if defined(WUFFS_IMPLEMENTATION) && !defined(WUFFS_CONFIG__MODULES)\n#define WUFFS_CONFIG__MODULES\n#define WUFFS_CONFIG__MODULE__BASE\n#endif\n\n// !! WUFFS MONOLITHIC RELEASE DISCARDS EVERYTHING ABOVE.\n\n// !! INSERT base/copyright\n\n#include <stdbool.h>\n#include <stdint.h>\n#include <string.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// !! INSERT base/all-public.h.\n\n// !! INSERT InterfaceDeclarations.\n\n" +
+ "#ifndef WUFFS_INCLUDE_GUARD__BASE\n#define WUFFS_INCLUDE_GUARD__BASE\n\n#if defined(WUFFS_IMPLEMENTATION) && !defined(WUFFS_CONFIG__MODULES)\n#define WUFFS_CONFIG__MODULES\n#define WUFFS_CONFIG__MODULE__BASE\n#endif\n\n// !! WUFFS MONOLITHIC RELEASE DISCARDS EVERYTHING ABOVE.\n\n// !! INSERT base/copyright\n\n#include <stdbool.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef __cplusplus\n#if __cplusplus >= 201103L\n#include <memory>\n#else\n#warning \"Wuffs' C++ code requires -std=c++11 or later\"\n#endif\n\nextern \"C\" {\n#endif\n\n// !! INSERT base/all-public.h.\n\n// !! INSERT InterfaceDeclarations.\n\n" +
"" +
"// ----------------\n\n#ifdef __cplusplus\n} // extern \"C\"\n#endif\n\n// WUFFS C HEADER ENDS HERE.\n#ifdef WUFFS_IMPLEMENTATION\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// !! INSERT base/all-private.h.\n\n" +
"" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index ed2198f..50346ab 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -32,9 +32,16 @@
#include <stdbool.h>
#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+#include <memory>
+#else
+#warning "Wuffs' C++ code requires -std=c++11 or later"
+#endif
+
extern "C" {
#endif
@@ -3839,6 +3846,9 @@
} private_impl;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_base__hasher_u32, decltype(&free)>;
+#endif
inline uint32_t //
update_u32(wuffs_base__slice_u8 a_x) {
@@ -3957,6 +3967,10 @@
} private_impl;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr =
+ std::unique_ptr<wuffs_base__image_decoder, decltype(&free)>;
+#endif
inline wuffs_base__status //
ack_metadata_chunk(wuffs_base__io_buffer* a_src) {
@@ -4071,6 +4085,10 @@
} private_impl;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr =
+ std::unique_ptr<wuffs_base__io_transformer, decltype(&free)>;
+#endif
inline wuffs_base__status //
transform_io(wuffs_base__io_buffer* a_dst,
@@ -4124,6 +4142,10 @@
} private_impl;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr =
+ std::unique_ptr<wuffs_base__token_decoder, decltype(&free)>;
+#endif
inline wuffs_base__status //
decode_tokens(wuffs_base__token_buffer* a_dst,
@@ -4179,6 +4201,22 @@
size_t //
sizeof__wuffs_adler32__hasher();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_adler32__hasher* //
+wuffs_adler32__hasher__alloc();
+
+static inline wuffs_base__hasher_u32* //
+wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32() {
+ return (wuffs_base__hasher_u32*)(wuffs_adler32__hasher__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__hasher_u32* //
@@ -4222,6 +4260,23 @@
} private_impl;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_adler32__hasher, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_adler32__hasher__alloc(), &free);
+ }
+
+ static inline wuffs_base__hasher_u32::unique_ptr //
+ alloc_as__wuffs_base__hasher_u32() {
+ return wuffs_base__hasher_u32::unique_ptr(
+ wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -4312,6 +4367,22 @@
size_t //
sizeof__wuffs_bmp__decoder();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_bmp__decoder* //
+wuffs_bmp__decoder__alloc();
+
+static inline wuffs_base__image_decoder* //
+wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)(wuffs_bmp__decoder__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__image_decoder* //
@@ -4444,6 +4515,23 @@
} private_data;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_bmp__decoder, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_bmp__decoder__alloc(), &free);
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr //
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -4596,6 +4684,22 @@
size_t //
sizeof__wuffs_crc32__ieee_hasher();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_crc32__ieee_hasher* //
+wuffs_crc32__ieee_hasher__alloc();
+
+static inline wuffs_base__hasher_u32* //
+wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32() {
+ return (wuffs_base__hasher_u32*)(wuffs_crc32__ieee_hasher__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__hasher_u32* //
@@ -4638,6 +4742,23 @@
} private_impl;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_crc32__ieee_hasher, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_crc32__ieee_hasher__alloc(), &free);
+ }
+
+ static inline wuffs_base__hasher_u32::unique_ptr //
+ alloc_as__wuffs_base__hasher_u32() {
+ return wuffs_base__hasher_u32::unique_ptr(
+ wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -4740,6 +4861,22 @@
size_t //
sizeof__wuffs_deflate__decoder();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_deflate__decoder* //
+wuffs_deflate__decoder__alloc();
+
+static inline wuffs_base__io_transformer* //
+wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer() {
+ return (wuffs_base__io_transformer*)(wuffs_deflate__decoder__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__io_transformer* //
@@ -4842,6 +4979,23 @@
} private_data;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_deflate__decoder, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_deflate__decoder__alloc(), &free);
+ }
+
+ static inline wuffs_base__io_transformer::unique_ptr //
+ alloc_as__wuffs_base__io_transformer() {
+ return wuffs_base__io_transformer::unique_ptr(
+ wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -4944,6 +5098,22 @@
size_t //
sizeof__wuffs_lzw__decoder();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_lzw__decoder* //
+wuffs_lzw__decoder__alloc();
+
+static inline wuffs_base__io_transformer* //
+wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer() {
+ return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__io_transformer* //
@@ -5018,6 +5188,23 @@
} private_data;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_lzw__decoder, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_lzw__decoder__alloc(), &free);
+ }
+
+ static inline wuffs_base__io_transformer::unique_ptr //
+ alloc_as__wuffs_base__io_transformer() {
+ return wuffs_base__io_transformer::unique_ptr(
+ wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -5156,6 +5343,30 @@
size_t //
sizeof__wuffs_gif__decoder();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_gif__config_decoder* //
+wuffs_gif__config_decoder__alloc();
+
+static inline wuffs_base__image_decoder* //
+wuffs_gif__config_decoder__alloc_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)(wuffs_gif__config_decoder__alloc());
+}
+
+wuffs_gif__decoder* //
+wuffs_gif__decoder__alloc();
+
+static inline wuffs_base__image_decoder* //
+wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)(wuffs_gif__decoder__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__image_decoder* //
@@ -5410,6 +5621,25 @@
} private_data;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr =
+ std::unique_ptr<wuffs_gif__config_decoder, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_gif__config_decoder__alloc(), &free);
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr //
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_gif__config_decoder__alloc_as__wuffs_base__image_decoder(),
+ &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -5666,6 +5896,23 @@
} private_data;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_gif__decoder, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_gif__decoder__alloc(), &free);
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr //
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -5830,6 +6077,22 @@
size_t //
sizeof__wuffs_gzip__decoder();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_gzip__decoder* //
+wuffs_gzip__decoder__alloc();
+
+static inline wuffs_base__io_transformer* //
+wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer() {
+ return (wuffs_base__io_transformer*)(wuffs_gzip__decoder__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__io_transformer* //
@@ -5894,6 +6157,23 @@
} private_data;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_gzip__decoder, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_gzip__decoder__alloc(), &free);
+ }
+
+ static inline wuffs_base__io_transformer::unique_ptr //
+ alloc_as__wuffs_base__io_transformer() {
+ return wuffs_base__io_transformer::unique_ptr(
+ wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -6042,6 +6322,22 @@
size_t //
sizeof__wuffs_json__decoder();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_json__decoder* //
+wuffs_json__decoder__alloc();
+
+static inline wuffs_base__token_decoder* //
+wuffs_json__decoder__alloc_as__wuffs_base__token_decoder() {
+ return (wuffs_base__token_decoder*)(wuffs_json__decoder__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__token_decoder* //
@@ -6126,6 +6422,23 @@
} private_data;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_json__decoder, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_json__decoder__alloc(), &free);
+ }
+
+ static inline wuffs_base__token_decoder::unique_ptr //
+ alloc_as__wuffs_base__token_decoder() {
+ return wuffs_base__token_decoder::unique_ptr(
+ wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -6227,6 +6540,22 @@
size_t //
sizeof__wuffs_wbmp__decoder();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_wbmp__decoder* //
+wuffs_wbmp__decoder__alloc();
+
+static inline wuffs_base__image_decoder* //
+wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__image_decoder* //
@@ -6342,6 +6671,23 @@
} private_data;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_wbmp__decoder, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_wbmp__decoder__alloc(), &free);
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr //
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -6503,6 +6849,22 @@
size_t //
sizeof__wuffs_zlib__decoder();
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, decltype(&free)>.
+
+wuffs_zlib__decoder* //
+wuffs_zlib__decoder__alloc();
+
+static inline wuffs_base__io_transformer* //
+wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer() {
+ return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc());
+}
+
// ---------------- Upcasts
static inline wuffs_base__io_transformer* //
@@ -6578,6 +6940,23 @@
} private_data;
#ifdef __cplusplus
+#if __cplusplus >= 201103L
+ using unique_ptr = std::unique_ptr<wuffs_zlib__decoder, decltype(&free)>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr //
+ alloc() {
+ return unique_ptr(wuffs_zlib__decoder__alloc(), &free);
+ }
+
+ static inline wuffs_base__io_transformer::unique_ptr //
+ alloc_as__wuffs_base__io_transformer() {
+ return wuffs_base__io_transformer::unique_ptr(
+ wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(), &free);
+ }
+#endif // __cplusplus >= 201103L
+
#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
// Disallow constructing or copying an object via standard C++ mechanisms,
// e.g. the "new" operator, as this struct is intentionally opaque. Its total
@@ -10529,6 +10908,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_adler32__hasher* //
+wuffs_adler32__hasher__alloc() {
+ wuffs_adler32__hasher* x =
+ (wuffs_adler32__hasher*)(calloc(sizeof(wuffs_adler32__hasher), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_adler32__hasher__initialize(x, sizeof(wuffs_adler32__hasher),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_adler32__hasher() {
return sizeof(wuffs_adler32__hasher);
@@ -10727,6 +11123,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_bmp__decoder* //
+wuffs_bmp__decoder__alloc() {
+ wuffs_bmp__decoder* x =
+ (wuffs_bmp__decoder*)(calloc(sizeof(wuffs_bmp__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_bmp__decoder__initialize(x, sizeof(wuffs_bmp__decoder),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_bmp__decoder() {
return sizeof(wuffs_bmp__decoder);
@@ -12927,6 +13340,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_crc32__ieee_hasher* //
+wuffs_crc32__ieee_hasher__alloc() {
+ wuffs_crc32__ieee_hasher* x =
+ (wuffs_crc32__ieee_hasher*)(calloc(sizeof(wuffs_crc32__ieee_hasher), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_crc32__ieee_hasher__initialize(x, sizeof(wuffs_crc32__ieee_hasher),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_crc32__ieee_hasher() {
return sizeof(wuffs_crc32__ieee_hasher);
@@ -13234,6 +13664,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_deflate__decoder* //
+wuffs_deflate__decoder__alloc() {
+ wuffs_deflate__decoder* x =
+ (wuffs_deflate__decoder*)(calloc(sizeof(wuffs_deflate__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_deflate__decoder__initialize(x, sizeof(wuffs_deflate__decoder),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_deflate__decoder() {
return sizeof(wuffs_deflate__decoder);
@@ -15087,6 +15534,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_lzw__decoder* //
+wuffs_lzw__decoder__alloc() {
+ wuffs_lzw__decoder* x =
+ (wuffs_lzw__decoder*)(calloc(sizeof(wuffs_lzw__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_lzw__decoder__initialize(x, sizeof(wuffs_lzw__decoder),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_lzw__decoder() {
return sizeof(wuffs_lzw__decoder);
@@ -15807,6 +16271,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_gif__config_decoder* //
+wuffs_gif__config_decoder__alloc() {
+ wuffs_gif__config_decoder* x = (wuffs_gif__config_decoder*)(calloc(
+ sizeof(wuffs_gif__config_decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_gif__config_decoder__initialize(
+ x, sizeof(wuffs_gif__config_decoder), WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_gif__config_decoder() {
return sizeof(wuffs_gif__config_decoder);
@@ -15868,6 +16349,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_gif__decoder* //
+wuffs_gif__decoder__alloc() {
+ wuffs_gif__decoder* x =
+ (wuffs_gif__decoder*)(calloc(sizeof(wuffs_gif__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_gif__decoder__initialize(x, sizeof(wuffs_gif__decoder),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_gif__decoder() {
return sizeof(wuffs_gif__decoder);
@@ -20324,6 +20822,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_gzip__decoder* //
+wuffs_gzip__decoder__alloc() {
+ wuffs_gzip__decoder* x =
+ (wuffs_gzip__decoder*)(calloc(sizeof(wuffs_gzip__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_gzip__decoder__initialize(x, sizeof(wuffs_gzip__decoder),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_gzip__decoder() {
return sizeof(wuffs_gzip__decoder);
@@ -20958,6 +21473,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_json__decoder* //
+wuffs_json__decoder__alloc() {
+ wuffs_json__decoder* x =
+ (wuffs_json__decoder*)(calloc(sizeof(wuffs_json__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_json__decoder__initialize(x, sizeof(wuffs_json__decoder),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_json__decoder() {
return sizeof(wuffs_json__decoder);
@@ -23131,6 +23663,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_wbmp__decoder* //
+wuffs_wbmp__decoder__alloc() {
+ wuffs_wbmp__decoder* x =
+ (wuffs_wbmp__decoder*)(calloc(sizeof(wuffs_wbmp__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_wbmp__decoder__initialize(x, sizeof(wuffs_wbmp__decoder),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_wbmp__decoder() {
return sizeof(wuffs_wbmp__decoder);
@@ -23926,6 +24475,23 @@
return wuffs_base__make_status(NULL);
}
+wuffs_zlib__decoder* //
+wuffs_zlib__decoder__alloc() {
+ wuffs_zlib__decoder* x =
+ (wuffs_zlib__decoder*)(calloc(sizeof(wuffs_zlib__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_zlib__decoder__initialize(x, sizeof(wuffs_zlib__decoder),
+ WUFFS_VERSION,
+ WUFFS_INITIALIZE__ALREADY_ZEROED)
+ .repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
size_t //
sizeof__wuffs_zlib__decoder() {
return sizeof(wuffs_zlib__decoder);