Am 07.06.2018 um 16:12 schrieb [email protected]:
> From: Jeff Hostetler <[email protected]>
> +/*
> + * Add comma if we have already seen a member at this level.
> + */
> +static inline void maybe_add_comma(struct json_writer *jw)
> +{
> + if (!jw->open_stack.len)
> + return;
This is impossible. maybe_add_comma() is only called directly after
assert_in_object() and assert_in_object(), which abort if open_stack
is empty.
> + if (jw->first_stack.buf[jw->first_stack.len - 1] == '1')
> + jw->first_stack.buf[jw->first_stack.len - 1] = '0';
> + else
> + strbuf_addch(&jw->json, ',');
You only need a binary flag to indicate if a comma is needed, not a
stack. We need a comma at the current level if and only if we already
wrote a child item. If we finish a level then we do need a comma at the
previous level because we just wrote a sub-object or sub-array there.
And that should cover all cases. Am I missing something?
I get a sense of déjà vu, by the way. :)
Here's what I mean:
---
json-writer.c | 17 ++++++-----------
json-writer.h | 13 +++++--------
2 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/json-writer.c b/json-writer.c
index f35ce1912a..14a4e89188 100644
--- a/json-writer.c
+++ b/json-writer.c
@@ -5,7 +5,7 @@ void jw_init(struct json_writer *jw)
{
strbuf_reset(&jw->json);
strbuf_reset(&jw->open_stack);
- strbuf_reset(&jw->first_stack);
+ jw->need_comma = 0;
jw->pretty = 0;
}
@@ -13,7 +13,6 @@ void jw_release(struct json_writer *jw)
{
strbuf_release(&jw->json);
strbuf_release(&jw->open_stack);
- strbuf_release(&jw->first_stack);
}
/*
@@ -69,7 +68,7 @@ static inline void begin(struct json_writer *jw, char
ch_open, int pretty)
strbuf_addch(&jw->json, ch_open);
strbuf_addch(&jw->open_stack, ch_open);
- strbuf_addch(&jw->first_stack, '1');
+ jw->need_comma = 0;
}
/*
@@ -99,12 +98,10 @@ static inline void assert_in_array(const struct json_writer
*jw)
*/
static inline void maybe_add_comma(struct json_writer *jw)
{
- if (!jw->open_stack.len)
- return;
- if (jw->first_stack.buf[jw->first_stack.len - 1] == '1')
- jw->first_stack.buf[jw->first_stack.len - 1] = '0';
- else
+ if (jw->need_comma)
strbuf_addch(&jw->json, ',');
+ else
+ jw->need_comma = 1;
}
static inline void fmt_double(struct json_writer *jw, int precision,
@@ -397,8 +394,6 @@ void jw_end(struct json_writer *jw)
char ch_open;
int len;
- if (jw->open_stack.len != jw->first_stack.len)
- BUG("jwon-writer: open_ and first_ stacks out of sync");
if (!jw->open_stack.len)
BUG("json-writer: too many jw_end(): '%s'", jw->json.buf);
@@ -406,7 +401,7 @@ void jw_end(struct json_writer *jw)
ch_open = jw->open_stack.buf[len];
strbuf_setlen(&jw->open_stack, len);
- strbuf_setlen(&jw->first_stack, len);
+ jw->need_comma = 1;
if (jw->pretty)
strbuf_addch(&jw->json, '\n');
diff --git a/json-writer.h b/json-writer.h
index af9c2612f8..c437462ba8 100644
--- a/json-writer.h
+++ b/json-writer.h
@@ -59,18 +59,15 @@ struct json_writer
struct strbuf open_stack;
/*
- * Another simple stack of the currently open array and object
- * forms. This is used in parallel to "open_stack" (same length).
- * It contains a string of '1' and '0' where '1' indicates that
- * the next child-element seen will be the first child (and does
- * not need a leading comma).
+ * Indicates if the next child item needs a leading comma.
+ * Only the first item of arrays and objects doesn't need one.
*/
- struct strbuf first_stack;
+ unsigned int need_comma:1;
- int pretty;
+ unsigned int pretty:1;
};
-#define JSON_WRITER_INIT { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, 0 }
+#define JSON_WRITER_INIT { STRBUF_INIT, STRBUF_INIT, 0, 0 }
void jw_init(struct json_writer *jw);
void jw_release(struct json_writer *jw);
--
2.17.1