diff options
author | David Robillard <d@drobilla.net> | 2011-05-11 16:03:03 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-05-11 16:03:03 +0000 |
commit | efd2a2ecb17a8c633f634c2cf38fb8be48db9af5 (patch) | |
tree | 2513b24e985a02e10565563a2a9151c58f38d2c1 /src/writer.c | |
parent | 1dc85d2924eacef71d0cc9144c6c33e6f84248b1 (diff) | |
download | serd-efd2a2ecb17a8c633f634c2cf38fb8be48db9af5.tar.gz serd-efd2a2ecb17a8c633f634c2cf38fb8be48db9af5.tar.bz2 serd-efd2a2ecb17a8c633f634c2cf38fb8be48db9af5.zip |
Record whether strings contains quotes or newlines for smart selection of long strings vs short strings in writer output.
git-svn-id: http://svn.drobilla.net/serd/trunk@167 490d8e77-9747-427b-9fa3-0b8f29cee8a0
Diffstat (limited to 'src/writer.c')
-rw-r--r-- | src/writer.c | 61 |
1 files changed, 38 insertions, 23 deletions
diff --git a/src/writer.c b/src/writer.c index 4e4ee2eb..a9cdf6ac 100644 --- a/src/writer.c +++ b/src/writer.c @@ -31,7 +31,7 @@ typedef struct { } WriteContext; static const WriteContext WRITE_CONTEXT_NULL = { - { 0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} + { 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }; struct SerdWriterImpl { @@ -47,9 +47,9 @@ struct SerdWriterImpl { }; typedef enum { - WRITE_NORMAL, WRITE_URI, - WRITE_STRING + WRITE_STRING, + WRITE_LONG_STRING } TextContext; static inline WriteContext* @@ -67,23 +67,29 @@ write_text(SerdWriter* writer, TextContext ctx, char escape[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for (size_t i = 0; i < n_bytes;) { uint8_t in = utf8[i++]; - switch (in) { - case '\\': writer->sink("\\\\", 2, writer->stream); continue; - case '\n': writer->sink("\\n", 2, writer->stream); continue; - case '\r': writer->sink("\\r", 2, writer->stream); continue; - case '\t': writer->sink("\\t", 2, writer->stream); continue; - case '"': - if (terminator == '"') { - writer->sink("\\\"", 2, writer->stream); - continue; - } // else fall-through - default: break; - } + if (ctx == WRITE_LONG_STRING) { + if (in == '\\') { + writer->sink("\\\\", 2, writer->stream); continue; + } + } else { + switch (in) { + case '\\': writer->sink("\\\\", 2, writer->stream); continue; + case '\n': writer->sink("\\n", 2, writer->stream); continue; + case '\r': writer->sink("\\r", 2, writer->stream); continue; + case '\t': writer->sink("\\t", 2, writer->stream); continue; + case '"': + if (terminator == '"') { + writer->sink("\\\"", 2, writer->stream); + continue; + } // else fall-through + default: break; + } - if (in == terminator) { - snprintf(escape, 7, "\\u%04X", terminator); - writer->sink(escape, 6, writer->stream); - continue; + if (in == terminator) { + snprintf(escape, 7, "\\u%04X", terminator); + writer->sink(escape, 6, writer->stream); + continue; + } } uint32_t c = 0; @@ -109,7 +115,8 @@ write_text(SerdWriter* writer, TextContext ctx, return false; } - if (ctx == WRITE_STRING && !(writer->style & SERD_STYLE_ASCII)) { + if ((ctx == WRITE_STRING || ctx == WRITE_LONG_STRING) + && !(writer->style & SERD_STYLE_ASCII)) { // Write UTF-8 character directly to UTF-8 output // TODO: Scan to next escape and write entire range at once writer->sink(utf8 + i - 1, size, writer->stream); @@ -228,9 +235,17 @@ write_node(SerdWriter* writer, break; } } - writer->sink("\"", 1, writer->stream); - write_text(writer, WRITE_STRING, node->buf, node->n_bytes - 1, '"'); - writer->sink("\"", 1, writer->stream); + if (writer->syntax != SERD_NTRIPLES + && ((node->flags & SERD_HAS_NEWLINE) + || (node->flags & SERD_HAS_QUOTE))) { + writer->sink("\"\"\"", 3, writer->stream); + write_text(writer, WRITE_LONG_STRING, node->buf, node->n_bytes - 1, '\0'); + writer->sink("\"\"\"", 3, writer->stream); + } else { + writer->sink("\"", 1, writer->stream); + write_text(writer, WRITE_STRING, node->buf, node->n_bytes - 1, '"'); + writer->sink("\"", 1, writer->stream); + } if (lang && lang->buf) { writer->sink("@", 1, writer->stream); writer->sink(lang->buf, lang->n_bytes - 1, writer->stream); |