summaryrefslogtreecommitdiff
path: root/stream
diff options
context:
space:
mode:
Diffstat (limited to 'stream')
-rw-r--r--stream/upb_textprinter.c114
-rw-r--r--stream/upb_textprinter.h4
2 files changed, 71 insertions, 47 deletions
diff --git a/stream/upb_textprinter.c b/stream/upb_textprinter.c
index 2209173..7025494 100644
--- a/stream/upb_textprinter.c
+++ b/stream/upb_textprinter.c
@@ -15,34 +15,51 @@ struct _upb_textprinter {
upb_bytesink *bytesink;
int indent_depth;
bool single_line;
- upb_fielddef *f;
+ upb_status status;
};
-static void upb_textprinter_indent(upb_textprinter *p)
+#define CHECK(x) if ((x) < 0) goto err;
+
+static int upb_textprinter_indent(upb_textprinter *p)
{
if(!p->single_line)
for(int i = 0; i < p->indent_depth; i++)
- upb_bytesink_put(p->bytesink, UPB_STRLIT(" "));
+ CHECK(upb_bytesink_putstr(p->bytesink, UPB_STRLIT(" "), &p->status));
+ return 0;
+err:
+ return -1;
}
-static void upb_textprinter_endfield(upb_textprinter *p) {
- if(p->single_line)
- upb_bytesink_put(p->bytesink, UPB_STRLIT(" "));
- else
- upb_bytesink_put(p->bytesink, UPB_STRLIT("\n"));
+static int upb_textprinter_startfield(upb_textprinter *p, upb_fielddef *f) {
+ upb_textprinter_indent(p);
+ CHECK(upb_bytesink_printf(p->bytesink, &p->status, UPB_STRFMT ": ", UPB_STRARG(f->name)));
+ return 0;
+err:
+ return -1;
+}
+
+static int upb_textprinter_endfield(upb_textprinter *p) {
+ if(p->single_line) {
+ CHECK(upb_bytesink_putstr(p->bytesink, UPB_STRLIT(" "), &p->status));
+ } else {
+ CHECK(upb_bytesink_putstr(p->bytesink, UPB_STRLIT("\n"), &p->status));
+ }
+ return 0;
+err:
+ return -1;
}
static upb_flow_t upb_textprinter_value(void *_p, upb_fielddef *f,
upb_value val) {
upb_textprinter *p = _p;
- upb_textprinter_indent(p);
- upb_bytesink_printf(p->bytesink, UPB_STRFMT ": ", UPB_STRARG(f->name));
-#define CASE(fmtstr, member) upb_bytesink_printf(p->bytesink, fmtstr, val.member); break;
- switch(p->f->type) {
+ upb_textprinter_startfield(p, f);
+#define CASE(fmtstr, member) \
+ CHECK(upb_bytesink_printf(p->bytesink, &p->status, fmtstr, upb_value_get ## member(val))); break;
+ switch(f->type) {
case UPB_TYPE(DOUBLE):
- CASE("%0.f", _double);
+ CASE("%0.f", double);
case UPB_TYPE(FLOAT):
- CASE("%0.f", _float)
+ CASE("%0.f", float)
case UPB_TYPE(INT64):
case UPB_TYPE(SFIXED64):
case UPB_TYPE(SINT64):
@@ -50,40 +67,48 @@ static upb_flow_t upb_textprinter_value(void *_p, upb_fielddef *f,
case UPB_TYPE(UINT64):
case UPB_TYPE(FIXED64):
CASE("%" PRIu64, uint64)
- case UPB_TYPE(INT32):
- case UPB_TYPE(SFIXED32):
- case UPB_TYPE(SINT32):
- CASE("%" PRId32, int32)
case UPB_TYPE(UINT32):
case UPB_TYPE(FIXED32):
CASE("%" PRIu32, uint32);
case UPB_TYPE(ENUM): {
- upb_enumdef *enum_def;
- upb_string *enum_label;
- (enum_def = upb_downcast_enumdef(p->f->def)) != NULL &&
- (enum_label = upb_enumdef_iton(enum_def, val.int32)) != NULL) {
- // This is an enum value for which we found a corresponding string.
- upb_bytesink_put(p->bytesink, enum_label);
- CASE("%" PRIu32, uint32);
+ upb_enumdef *enum_def = upb_downcast_enumdef(f->def);
+ upb_string *enum_label =
+ upb_enumdef_iton(enum_def, upb_value_getint32(val));
+ if (enum_label) {
+ // We found a corresponding string for this enum. Otherwise we fall
+ // through to the int32 code path.
+ CHECK(upb_bytesink_putstr(p->bytesink, enum_label, &p->status));
+ break;
+ }
}
+ case UPB_TYPE(INT32):
+ case UPB_TYPE(SFIXED32):
+ case UPB_TYPE(SINT32):
+ CASE("%" PRId32, int32)
case UPB_TYPE(BOOL):
- CASE("%hhu", _bool);
+ CASE("%hhu", bool);
case UPB_TYPE(STRING):
case UPB_TYPE(BYTES):
- upb_bytesink_put(p->bytesink, UPB_STRLIT(": \""));
- upb_bytesink_put(p->bytesink, str);
- upb_bytesink_put(p->bytesink, UPB_STRLIT("\""));
+ // TODO: escaping.
+ CHECK(upb_bytesink_putstr(p->bytesink, UPB_STRLIT(": \""), &p->status));
+ CHECK(upb_bytesink_putstr(p->bytesink, upb_value_getstr(val), &p->status))
+ CHECK(upb_bytesink_putstr(p->bytesink, UPB_STRLIT("\""), &p->status));
break;
}
upb_textprinter_endfield(p);
return UPB_CONTINUE;
+err:
+ return UPB_BREAK;
}
-static upb_flow_t upb_textprinter_startsubmsg(void *_p, upb_fielddef *f) {
+static upb_flow_t upb_textprinter_startsubmsg(void *_p, upb_fielddef *f,
+ upb_handlers *delegate_to) {
+ (void)delegate_to;
upb_textprinter *p = _p;
+ upb_textprinter_startfield(p, f);
p->indent_depth++;
- upb_bytesink_put(p->bytesink, UPB_STRLIT(" {"));
- if(!p->single_line) upb_bytesink_put(p->bytesink, UPB_STRLIT("\n"));
+ upb_bytesink_putstr(p->bytesink, UPB_STRLIT(" {"), &p->status);
+ if(!p->single_line) upb_bytesink_putstr(p->bytesink, UPB_STRLIT("\n"), &p->status);
return UPB_CONTINUE;
}
@@ -92,21 +117,13 @@ static upb_flow_t upb_textprinter_endsubmsg(void *_p)
upb_textprinter *p = _p;
p->indent_depth--;
upb_textprinter_indent(p);
- upb_bytesink_put(p->bytesink, UPB_STRLIT("}"));
+ upb_bytesink_putstr(p->bytesink, UPB_STRLIT("}"), &p->status);
upb_textprinter_endfield(p);
return UPB_CONTINUE;
}
upb_textprinter *upb_textprinter_new() {
- static upb_handlerset handlers = {
- NULL, // startmsg
- NULL, // endmsg
- upb_textprinter_putval,
- upb_textprinter_startsubmsg,
- upb_textprinter_endsubmsg,
- };
upb_textprinter *p = malloc(sizeof(*p));
- upb_byte_init(&p->sink, &upb_textprinter_vtbl);
return p;
}
@@ -114,11 +131,18 @@ void upb_textprinter_free(upb_textprinter *p) {
free(p);
}
-void upb_textprinter_reset(upb_textprinter *p, upb_bytesink *sink,
- bool single_line) {
+void upb_textprinter_reset(upb_textprinter *p, upb_handlers *handlers,
+ upb_bytesink *sink, bool single_line) {
+ static upb_handlerset handlerset = {
+ NULL, // startmsg
+ NULL, // endmsg
+ upb_textprinter_value,
+ upb_textprinter_startsubmsg,
+ upb_textprinter_endsubmsg,
+ };
p->bytesink = sink;
p->single_line = single_line;
p->indent_depth = 0;
+ upb_register_handlerset(handlers, &handlerset);
+ upb_set_handler_closure(handlers, p, &p->status);
}
-
-upb_sink *upb_textprinter_sink(upb_textprinter *p) { return &p->sink; }
diff --git a/stream/upb_textprinter.h b/stream/upb_textprinter.h
index b40d9fa..a880626 100644
--- a/stream/upb_textprinter.h
+++ b/stream/upb_textprinter.h
@@ -18,8 +18,8 @@ typedef struct _upb_textprinter upb_textprinter;
upb_textprinter *upb_textprinter_new();
void upb_textprinter_free(upb_textprinter *p);
-void upb_textprinter_reset(upb_textprinter *p, upb_bytesink *sink,
- bool single_line);
+void upb_textprinter_reset(upb_textprinter *p, upb_handlers *handlers,
+ upb_bytesink *sink, bool single_line);
void upb_textprinter_sethandlers(upb_textprinter *p, upb_handlers *h);
#ifdef __cplusplus
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback