From 60366c5e3e326eb0d5b828ba8bbd81f317cd24e3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 10 Aug 2015 10:57:06 +0200 Subject: Implement support for suspending/resuming indentation in serializer --- xml/details/genx/genx.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 4 deletions(-) (limited to 'xml/details/genx/genx.c') diff --git a/xml/details/genx/genx.c b/xml/details/genx/genx.c index 1f2303d..387cc94 100644 --- a/xml/details/genx/genx.c +++ b/xml/details/genx/genx.c @@ -131,6 +131,7 @@ struct genxWriter_rec /* Pretty-printing state */ int ppIndent; int ppDepth; + int ppSuspendDepth; /* Non-0 means we are suspended. */ Boolean ppSimple; /* Canonicalization. */ @@ -693,6 +694,62 @@ int genxGetPrettyPrint(genxWriter w) } /* + * Suspend/resume pretty-printing. + */ +genxStatus genxSuspendPrettyPrint(genxWriter w) +{ + int d = w->ppDepth; + + if (w->ppIndent == 0) + return w->status = GENX_SEQUENCE_ERROR; + + switch (w->sequence) + { + case SEQUENCE_START_TAG: + case SEQUENCE_ATTRIBUTES: + d++; /* No start tag written, still outer depth. */ + case SEQUENCE_CONTENT: + break; + default: + return w->status = GENX_SEQUENCE_ERROR; + } + + if (w->ppSuspendDepth == 0) /* Ignore nested suspend/resume calls. */ + w->ppSuspendDepth = d; + + return w->status; +} + +genxStatus genxResumePrettyPrint(genxWriter w) +{ + int d = w->ppDepth; + + if (w->ppIndent == 0 || w->ppSuspendDepth == 0) + return w->status = GENX_SEQUENCE_ERROR; + + switch (w->sequence) + { + case SEQUENCE_START_TAG: + case SEQUENCE_ATTRIBUTES: + d++; /* No start tag written, still outer depth. */ + case SEQUENCE_CONTENT: + break; + default: + return w->status = GENX_SEQUENCE_ERROR; + } + + if (w->ppSuspendDepth == d) /* Ignore nested suspend/resume calls. */ + w->ppSuspendDepth = 0; + + return w->status; +} + +int genxPrettyPrintSuspended(genxWriter w) +{ + return w->ppSuspendDepth; +} + +/* * get/set canonicalization. */ genxStatus genxSetCanonical(genxWriter w, int flag) @@ -1217,8 +1274,9 @@ genxStatus genxStartDocSender(genxWriter w, genxSender * sender) if (w->ppIndent) { - w->ppSimple = True; w->ppDepth = 0; + w->ppSuspendDepth = 0; + w->ppSimple = True; } return GENX_SUCCESS; @@ -1292,7 +1350,9 @@ static genxStatus writeStartTag(genxWriter w, Boolean close) if (w->ppIndent) { - if (w->ppDepth) + if (w->ppDepth && + /* Suspend depth could be at this element's depth (after ++ below). */ + (w->ppSuspendDepth == 0 || w->ppSuspendDepth > w->ppDepth)) if (writeIndentation (w) != GENX_SUCCESS) return w->status; @@ -1301,6 +1361,15 @@ static genxStatus writeStartTag(genxWriter w, Boolean close) w->ppDepth++; w->ppSimple = True; } + else + { + /* + * Conceptually we incremented/decremented the depth, so check if we + * need to resume pretty-printing. + */ + if (w->ppSuspendDepth > w->ppDepth) + w->ppSuspendDepth = 0; + } } SendCheck(w, "<"); @@ -1789,9 +1858,12 @@ genxStatus genxEndElement(genxWriter w) { w->ppDepth--; - if (!w->ppSimple) + if (!w->ppSimple && w->ppSuspendDepth == 0) if (writeIndentation (w) != GENX_SUCCESS) return w->status; + + if (w->ppSuspendDepth > w->ppDepth) + w->ppSuspendDepth = 0; /* Resume pretty-printing. */ } SendCheck(w, ""); } - if (w->ppIndent) + /* If this element is written while pretty-printing is suspended, + treat it as simple. As an example, think of an XHTML element + for which we suspend pretty-printing before writing the opening + tag and resume it after the closing one. */ + if (w->ppIndent && w->ppSuspendDepth == 0) w->ppSimple = False; /* -- cgit v1.1