From 5d71710b18f4394588957e4558c06778ceaa341f Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 15 Jan 2018 09:20:28 +0000 Subject: [PATCH] enhanced the json writer to inject {} or [] manually when the outermost enclosers are not found --- qse/include/qse/cmn/opt.h | 2 +- qse/include/qse/xli/xli.h | 8 ++++++-- qse/lib/xli/read-json.c | 8 ++++---- qse/lib/xli/write-json.c | 35 +++++++++++++++++++++++++++++++++-- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/qse/include/qse/cmn/opt.h b/qse/include/qse/cmn/opt.h index 5df2a3cc..1ea5458a 100644 --- a/qse/include/qse/cmn/opt.h +++ b/qse/include/qse/cmn/opt.h @@ -30,7 +30,7 @@ #include #include -/** @file +/** \file * This file defines functions and data structures to process * command-line arguments. */ diff --git a/qse/include/qse/xli/xli.h b/qse/include/qse/xli/xli.h index a037af38..804b44cc 100644 --- a/qse/include/qse/xli/xli.h +++ b/qse/include/qse/xli/xli.h @@ -198,8 +198,12 @@ typedef enum qse_xli_list_flag_t qse_xli_list_flag_t; enum qse_xli_text_flag_t { - QSE_XLI_TEXT_VERBATIM = (1 << 0), - QSE_XLI_TEXT_DEINDENT = (1 << 1) + QSE_XLI_TEXT_VERBATIM = (1 << 0), + QSE_XLI_TEXT_DEINDENT = (1 << 1), + QSE_XLI_TEXT_LIST_OPENER = (1 << 2), + QSE_XLI_TEXT_LIST_CLOSER = (1 << 3), + QSE_XLI_TEXT_ARRAYED_LIST_OPENER = (1 << 4), + QSE_XLI_TEXT_ARRAYED_LIST_CLOSER = (1 << 5) }; typedef enum qse_xli_text_flag_t qse_xli_text_flag_t; diff --git a/qse/lib/xli/read-json.c b/qse/lib/xli/read-json.c index 960b5439..07a87f33 100644 --- a/qse/lib/xli/read-json.c +++ b/qse/lib/xli/read-json.c @@ -832,7 +832,7 @@ static int read_root_list (qse_xli_t* xli) xli->root->list.flags |= QSE_XLI_LIST_ARRAYED; ta = qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(xli->tok.name)); if (!ta) goto oops; - ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT; + ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT | QSE_XLI_TEXT_ARRAYED_LIST_OPENER; xli->tok_status &= ~TOK_STATUS_DEINDENT_TEXT; if (get_token(xli) <= -1) goto oops; break; @@ -842,7 +842,7 @@ static int read_root_list (qse_xli_t* xli) qse_xli_text_t* ta; ta = qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(xli->tok.name)); if (!ta) goto oops; - ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT; + ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT | QSE_XLI_TEXT_LIST_OPENER; xli->tok_status &= ~TOK_STATUS_DEINDENT_TEXT; if (get_token(xli) <= -1) goto oops; break; @@ -865,7 +865,7 @@ static int read_root_list (qse_xli_t* xli) if (!(xli->root->list.flags & QSE_XLI_LIST_ARRAYED)) goto oops_rbrac; ta = qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(xli->tok.name)); if (!ta) goto oops; - ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT; + ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT | QSE_XLI_TEXT_ARRAYED_LIST_CLOSER; xli->tok_status |= TOK_STATUS_DEINDENT_TEXT; if (get_token(xli) <= -1) goto oops; break; @@ -876,7 +876,7 @@ static int read_root_list (qse_xli_t* xli) if (xli->root->list.flags & QSE_XLI_LIST_ARRAYED) goto oops_rbrac; ta = qse_xli_inserttext(xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(xli->tok.name)); if (!ta) goto oops; - ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT; + ta->flags |= QSE_XLI_TEXT_VERBATIM | QSE_XLI_TEXT_DEINDENT | QSE_XLI_TEXT_LIST_CLOSER; xli->tok_status |= TOK_STATUS_DEINDENT_TEXT; if (get_token(xli) <= -1) goto oops; break; diff --git a/qse/lib/xli/write-json.c b/qse/lib/xli/write-json.c index 72393945..57075d9c 100644 --- a/qse/lib/xli/write-json.c +++ b/qse/lib/xli/write-json.c @@ -228,9 +228,25 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth) return 0; } + +static int have_opening_marker (qse_xli_t* xli, qse_xli_list_t* list) +{ + qse_xli_atom_t* curatom; + + for (curatom = list->head; curatom; curatom = curatom->next) + { + qse_xli_text_t* ta; + if (curatom->type != QSE_XLI_TEXT) break; + ta = (qse_xli_text_t*)curatom; + if (ta->flags & (QSE_XLI_TEXT_ARRAYED_LIST_OPENER | QSE_XLI_TEXT_LIST_OPENER)) return 1; + } + + return 0; +} + int qse_xli_writejson (qse_xli_t* xli, qse_xli_list_t* root_list, qse_xli_io_impl_t io) { - int n; + int n, marker; if (io == QSE_NULL) { @@ -248,8 +264,23 @@ int qse_xli_writejson (qse_xli_t* xli, qse_xli_list_t* root_list, qse_xli_io_imp /* open the top level stream */ if (qse_xli_openwstream (xli, QSE_NULL, 0) <= -1) return -1; + if (!root_list) root_list = &xli->root->list; + + marker = have_opening_marker(xli, root_list); + if (!marker) + { + /* if the data has been loaded from a different format like xli or ini, + * there are no opening and closing markers. so emit them manually */ + if (write_to_current_stream(xli, ((root_list->flags & QSE_XLI_LIST_ARRAYED)? QSE_T("[\n"): QSE_T("{\n")), 2, 0) <= -1) return -1; + } + /* begin writing the root list */ - n = write_list (xli, (root_list? root_list: &xli->root->list), 1); + n = write_list (xli, root_list, 1); + + if (!marker) + { + if (write_to_current_stream(xli, ((root_list->flags & QSE_XLI_LIST_ARRAYED)? QSE_T("]\n"): QSE_T("}\n")), 2, 0) <= -1) return -1; + } /* close all open streams. there should be only the * top-level stream here if there occurred no errors */