Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id BD101429E3A for ; Thu, 2 Aug 2012 18:15:10 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.7 X-Spam-Level: X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HuF7U1DehA9G for ; Thu, 2 Aug 2012 18:15:09 -0700 (PDT) Received: from dmz-mailsec-scanner-8.mit.edu (DMZ-MAILSEC-SCANNER-8.MIT.EDU [18.7.68.37]) by olra.theworths.org (Postfix) with ESMTP id 1B500431E64 for ; Thu, 2 Aug 2012 18:15:08 -0700 (PDT) X-AuditID: 12074425-b7f9b6d0000008c4-ba-501b261b242f Received: from mailhub-auth-1.mit.edu ( [18.9.21.35]) by dmz-mailsec-scanner-8.mit.edu (Symantec Messaging Gateway) with SMTP id D8.BD.02244.B162B105; Thu, 2 Aug 2012 21:15:07 -0400 (EDT) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id q731F6dw012765; Thu, 2 Aug 2012 21:15:06 -0400 Received: from drake.dyndns.org (209-6-116-242.c3-0.arl-ubr1.sbo-arl.ma.cable.rcn.com [209.6.116.242]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q731F4Hj002786 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Thu, 2 Aug 2012 21:15:05 -0400 (EDT) Received: from amthrax by drake.dyndns.org with local (Exim 4.77) (envelope-from ) id 1Sx6To-0003wE-3m; Thu, 02 Aug 2012 21:15:04 -0400 From: Austin Clements To: notmuch@notmuchmail.org Subject: [PATCH v3 03/13] sprinter: Add a string_len method Date: Thu, 2 Aug 2012 21:14:49 -0400 Message-Id: <1343956499-14543-4-git-send-email-amdragon@mit.edu> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1343956499-14543-1-git-send-email-amdragon@mit.edu> References: <1343956499-14543-1-git-send-email-amdragon@mit.edu> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrKIsWRmVeSWpSXmKPExsUixCmqrCutJh1g8GGPrMXquTwW12/OZLZ4 s3IeqwOzx85Zd9k9Dn9dyOLxbNUt5gDmKC6blNSczLLUIn27BK6MWU39jAWbFCq2TL3N0sA4 UbKLkZNDQsBE4vrdT2wQtpjEhXvrgWwuDiGBfYwSh570MIEkhATWM0o8mW8CkXjIJLHl2Guo qrmMEp+nvgdrZxPQkNi2fzkjiC0iIC2x8+5sVhCbWSBOYsuU/2BxYQFriVc7L4BNZRFQlZiy 6jtQDQcHr4CDxNP+IIgr5CWe3u8DG8kp4Cjx+u0rRogjHCSWt3WzTmDkX8DIsIpRNiW3Sjc3 MTOnODVZtzg5MS8vtUjXQi83s0QvNaV0EyMotNhdVHcwTjikdIhRgINRiYfXSFI6QIg1say4 MvcQoyQHk5IoL7MSUIgvKT+lMiOxOCO+qDQntfgQowQHs5IIb9USqQAh3pTEyqrUonyYlDQH i5I4742Um/5CAumJJanZqakFqUUwWRkODiUJXllVoKGCRanpqRVpmTklCGkmDk6Q4TxAw+1B aniLCxJzizPTIfKnGBWlxHnZQRICIImM0jy4Xljsv2IUB3pFmPeCClAVDzBtwHW/AhrMBDTY zgzk6uKSRISUVANj7tqWCXVL/zCqaHrcUz/gLvzTMjqj68EmbcemWwWtUufc+h9p7ruTW3Zb fmvRQ7OFF1p4bO/lN3qIpGR7Cy/Q6pM7tn3xi2VRsndLb+gI759YGvxPR/BHhJ2OsAyzTfkt l8PnjX0sCz6tK5si6/E8cFVNdZ57Iu+2N/7s39j1I/7sP7Vk91UlluKMREMt5qLiRAA73IiM 2AIAAA== Cc: tomi.ollila@iki.fi X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Aug 2012 01:15:11 -0000 This method allows callers to output strings with specific lengths. It's useful both for strings with embedded NULs (which JSON can represent, though parser support is apparently spotty), and non-terminated strings. --- sprinter-json.c | 16 ++++++++++++++-- sprinter-text.c | 11 +++++++++-- sprinter.h | 9 ++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/sprinter-json.c b/sprinter-json.c index 4649655..c9b6835 100644 --- a/sprinter-json.c +++ b/sprinter-json.c @@ -88,8 +88,13 @@ json_end (struct sprinter *sp) fputc ('\n', spj->stream); } +/* This implementation supports embedded NULs as allowed by the JSON + * specification and Unicode. Support for *parsing* embedded NULs + * varies, but is generally not a problem outside of C-based parsers + * (Python's json module and Emacs' json.el take embedded NULs in + * stride). */ static void -json_string (struct sprinter *sp, const char *val) +json_string_len (struct sprinter *sp, const char *val, size_t len) { static const char *const escapes[] = { ['\"'] = "\\\"", ['\\'] = "\\\\", ['\b'] = "\\b", @@ -98,7 +103,7 @@ json_string (struct sprinter *sp, const char *val) struct sprinter_json *spj = json_begin_value (sp); fputc ('"', spj->stream); - for (; *val; ++val) { + for (; len; ++val, --len) { unsigned char ch = *val; if (ch < ARRAY_SIZE (escapes) && escapes[ch]) fputs (escapes[ch], spj->stream); @@ -111,6 +116,12 @@ json_string (struct sprinter *sp, const char *val) } static void +json_string (struct sprinter *sp, const char *val) +{ + json_string_len (sp, val, strlen (val)); +} + +static void json_integer (struct sprinter *sp, int val) { struct sprinter_json *spj = json_begin_value (sp); @@ -166,6 +177,7 @@ sprinter_json_create (const void *ctx, FILE *stream) .begin_list = json_begin_list, .end = json_end, .string = json_string, + .string_len = json_string_len, .integer = json_integer, .boolean = json_boolean, .null = json_null, diff --git a/sprinter-text.c b/sprinter-text.c index b208840..dfa54b5 100644 --- a/sprinter-text.c +++ b/sprinter-text.c @@ -25,14 +25,20 @@ struct sprinter_text { }; static void -text_string (struct sprinter *sp, const char *val) +text_string_len (struct sprinter *sp, const char *val, size_t len) { struct sprinter_text *sptxt = (struct sprinter_text *) sp; if (sptxt->current_prefix != NULL) fprintf (sptxt->stream, "%s:", sptxt->current_prefix); - fputs(val, sptxt->stream); + fwrite (val, len, 1, sptxt->stream); +} + +static void +text_string (struct sprinter *sp, const char *val) +{ + text_string_len (sp, val, strlen (val)); } static void @@ -105,6 +111,7 @@ sprinter_text_create (const void *ctx, FILE *stream) .begin_list = text_begin_list, .end = text_end, .string = text_string, + .string_len = text_string_len, .integer = text_integer, .boolean = text_boolean, .null = text_null, diff --git a/sprinter.h b/sprinter.h index 6680d41..5f43175 100644 --- a/sprinter.h +++ b/sprinter.h @@ -23,11 +23,14 @@ typedef struct sprinter { */ void (*end) (struct sprinter *); - /* Print one string/integer/boolean/null element (possibly inside a - * list or map, followed or preceded by separators). - * For string, the char * must be UTF-8 encoded. + /* Print one string/integer/boolean/null element (possibly inside + * a list or map, followed or preceded by separators). For string + * and string_len, the char * must be UTF-8 encoded. string_len + * allows non-terminated strings and strings with embedded NULs + * (though the handling of the latter is format-dependent). */ void (*string) (struct sprinter *, const char *); + void (*string_len) (struct sprinter *, const char *, size_t); void (*integer) (struct sprinter *, int); void (*boolean) (struct sprinter *, notmuch_bool_t); void (*null) (struct sprinter *); -- 1.7.10