Add base.token_decoder interface
diff --git a/lang/builtin/builtin.go b/lang/builtin/builtin.go
index 1bf829f..22e2dd6 100644
--- a/lang/builtin/builtin.go
+++ b/lang/builtin/builtin.go
@@ -373,12 +373,14 @@
"hasher_u32",
"image_decoder",
"io_transformer",
+ "token_decoder",
}
var InterfacesMap = map[string]bool{
"hasher_u32": true,
"image_decoder": true,
"io_transformer": true,
+ "token_decoder": true,
}
var InterfaceFuncs = []string{
@@ -408,6 +410,10 @@
"io_transformer.transform_io?(dst: io_writer, src: io_reader, workbuf: slice u8)",
"io_transformer.workbuf_len() range_ii_u64",
+
+ // ---- token_decoder
+
+ "token_decoder.decode_tokens?(dst: token_writer, src: io_reader)",
}
// The "T1" and "T2" types here are placeholders for generic "slice T" or
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 955d55c..46455c0 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -3382,6 +3382,45 @@
#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+// --------
+
+extern const char* wuffs_base__token_decoder__vtable_name;
+
+typedef struct {
+ wuffs_base__status (*decode_tokens)(void* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+} wuffs_base__token_decoder__func_ptrs;
+
+typedef struct wuffs_base__token_decoder__struct wuffs_base__token_decoder;
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__token_decoder__decode_tokens(wuffs_base__token_decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+struct wuffs_base__token_decoder__struct {
+ struct {
+ uint32_t magic;
+ uint32_t active_coroutine;
+ wuffs_base__vtable first_vtable;
+ } private_impl;
+
+#ifdef __cplusplus
+
+ inline wuffs_base__status //
+ decode_tokens(wuffs_base__token_buffer* a_dst, wuffs_base__io_buffer* a_src) {
+ return wuffs_base__token_decoder__decode_tokens(this, a_dst, a_src);
+ }
+
+#endif // __cplusplus
+
+}; // struct wuffs_base__token_decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
// ----------------
#ifdef __cplusplus
@@ -5239,6 +5278,12 @@
// ---------------- Upcasts
+static inline wuffs_base__token_decoder* //
+wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(
+ wuffs_json__decoder* p) {
+ return (wuffs_base__token_decoder*)p;
+}
+
// ---------------- Public Function Prototypes
WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
@@ -5266,6 +5311,7 @@
struct {
uint32_t magic;
uint32_t active_coroutine;
+ wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
wuffs_base__vtable null_vtable;
uint32_t p_decode_tokens[1];
@@ -5318,6 +5364,11 @@
wuffs_version, initialize_flags);
}
+ inline wuffs_base__token_decoder* //
+ upcast_as__wuffs_base__token_decoder() {
+ return (wuffs_base__token_decoder*)this;
+ }
+
inline wuffs_base__status //
decode_tokens(wuffs_base__token_buffer* a_dst, wuffs_base__io_buffer* a_src) {
return wuffs_json__decoder__decode_tokens(this, a_dst, a_src);
@@ -7077,6 +7128,41 @@
return wuffs_base__utility__empty_range_ii_u64();
}
+// --------
+
+const char* wuffs_base__token_decoder__vtable_name =
+ "{vtable}wuffs_base__token_decoder";
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__token_decoder__decode_tokens(wuffs_base__token_decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
+ const wuffs_base__token_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->decode_tokens)(self, a_dst, a_src);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
// ---------------- Images
const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {
@@ -18673,6 +18759,14 @@
// ---------------- VTables
+const wuffs_base__token_decoder__func_ptrs
+ wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__token_buffer*,
+ wuffs_base__io_buffer*))(
+ &wuffs_json__decoder__decode_tokens),
+};
+
// ---------------- Initializer Implementations
wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT //
@@ -18716,6 +18810,10 @@
}
self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
+ wuffs_base__token_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
+ (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder);
return wuffs_base__make_status(NULL);
}
diff --git a/std/json/decode_json.wuffs b/std/json/decode_json.wuffs
index 2281e30..20ee6a8 100644
--- a/std/json/decode_json.wuffs
+++ b/std/json/decode_json.wuffs
@@ -12,9 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// TODO: "decoder implements base.token_decoder".
-
-pub struct decoder?(
+pub struct decoder? implements base.token_decoder(
)(
// stack is conceptually an array of bits, implemented as an array of u32.
// The N'th bit being 0 or 1 means that we're in an array or object, where
diff --git a/test/c/std/json.c b/test/c/std/json.c
index ebc7153..efbed9f 100644
--- a/test/c/std/json.c
+++ b/test/c/std/json.c
@@ -227,33 +227,18 @@
&dec, sizeof dec, WUFFS_VERSION,
WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
- wuffs_base__token_buffer have = ((wuffs_base__token_buffer){
- .data = global_have_token_slice,
- });
- wuffs_base__io_buffer src = ((wuffs_base__io_buffer){
- .data = global_src_slice,
- });
- CHECK_STRING(read_file(&src, "test/data/github-tags.json"));
+ const uint64_t vbc = WUFFS_BASE__TOKEN__VBC__STRUCTURE;
+ const uint64_t vbd = WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP |
+ WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST |
+ WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE;
+ const uint64_t len = 1;
- wuffs_base__status status =
- wuffs_json__decoder__decode_tokens(&dec, &have, &src);
- if (0) {
- uint64_t pos = 0;
- size_t i;
- for (i = have.meta.ri; i < have.meta.wi; i++) {
- wuffs_base__token* t = &have.data.ptr[i];
- uint64_t len = wuffs_base__token__length(t);
- uint64_t bc = wuffs_base__token__value_base_category(t);
- uint64_t bd = wuffs_base__token__value_base_detail(t);
- printf("i=%3zu\tp=%4" PRIu64 " (0x%03" PRIX64 ")\tl=%3" PRIu64
- "\tbc=%3" PRIu64 "\tbd=0x%06" PRIX64 "\n",
- i, pos, pos, len, bc, bd);
- pos = wuffs_base__u64__sat_add(pos, len);
- }
- CHECK_STATUS("decode_tokens", status);
- }
-
- return NULL;
+ return do_test__wuffs_base__token_decoder(
+ wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(&dec),
+ "test/data/github-tags.json", 0, SIZE_MAX,
+ (vbc << WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT) |
+ (vbd << WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT) |
+ (len << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
}
const char* //
diff --git a/test/c/testlib/testlib.c b/test/c/testlib/testlib.c
index 713b95e..2d06613 100644
--- a/test/c/testlib/testlib.c
+++ b/test/c/testlib/testlib.c
@@ -1011,10 +1011,10 @@
}
}
- if ((want_width > 0) && (want_height > 0)) {
+ if ((have_width > 0) && (have_height > 0)) {
wuffs_base__color_u32_argb_premul have_final_pixel =
- wuffs_base__pixel_buffer__color_u32_at(&pb, want_width - 1,
- want_height - 1);
+ wuffs_base__pixel_buffer__color_u32_at(&pb, have_width - 1,
+ have_height - 1);
if (have_final_pixel != want_final_pixel) {
RETURN_FAIL("final pixel: have 0x%08" PRIX32 ", want 0x%08" PRIX32,
have_final_pixel, want_final_pixel);
@@ -1054,9 +1054,33 @@
if (have.meta.wi != want_wi) {
RETURN_FAIL("dst wi: have %zu, want %zu", have.meta.wi, want_wi);
}
- if ((want_wi > 0) && (have.data.ptr[want_wi - 1] != want_final_byte)) {
+ if ((have.meta.wi > 0) &&
+ (have.data.ptr[have.meta.wi - 1] != want_final_byte)) {
RETURN_FAIL("final byte: have 0x%02X, want 0x%02X",
- have.data.ptr[want_wi - 1], want_final_byte);
+ have.data.ptr[have.meta.wi - 1], want_final_byte);
+ }
+ return NULL;
+}
+
+const char* //
+do_test__wuffs_base__token_decoder(wuffs_base__token_decoder* b,
+ const char* src_filename,
+ size_t src_ri,
+ size_t src_wi,
+ uint64_t want_final_token_repr) {
+ wuffs_base__token_buffer have = ((wuffs_base__token_buffer){
+ .data = global_have_token_slice,
+ });
+ wuffs_base__io_buffer src = ((wuffs_base__io_buffer){
+ .data = global_src_slice,
+ });
+ CHECK_STRING(read_file_fragment(&src, src_filename, src_ri, src_wi));
+ CHECK_STATUS("decode_tokens",
+ wuffs_base__token_decoder__decode_tokens(b, &have, &src));
+ if ((have.meta.wi > 0) &&
+ (have.data.ptr[have.meta.wi - 1].repr != want_final_token_repr)) {
+ RETURN_FAIL("final token: have 0x%" PRIX64 ", want 0x%" PRIX64,
+ have.data.ptr[have.meta.wi - 1].repr, want_final_token_repr);
}
return NULL;
}