python: move Threads class into its own file
[notmuch] / json.c
1 /* notmuch - Not much of an email program, (just index and search)
2  *
3  * Copyright © 2009 Dave Gamble
4  * Copyright © 2009 Scott Robinson
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see http://www.gnu.org/licenses/ .
18  *
19  * Authors: Dave Gamble
20  *          Scott Robinson <scott@quadhome.com>
21  *
22  */
23
24 #include "notmuch-client.h"
25
26 /* This function was derived from the print_string_ptr function of
27  * cJSON (http://cjson.sourceforge.net/) and is used by permission of
28  * the following license:
29  *
30  * Copyright (c) 2009 Dave Gamble
31  *
32  * Permission is hereby granted, free of charge, to any person obtaining a copy
33  * of this software and associated documentation files (the "Software"), to deal
34  * in the Software without restriction, including without limitation the rights
35  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36  * copies of the Software, and to permit persons to whom the Software is
37  * furnished to do so, subject to the following conditions:
38  *
39  * The above copyright notice and this permission notice shall be included in
40  * all copies or substantial portions of the Software.
41  *
42  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48  * THE SOFTWARE.
49  */
50
51 char *
52 json_quote_chararray(const void *ctx, const char *str, const size_t len)
53 {
54     const char *ptr;
55     char *ptr2;
56     char *out;
57     size_t loop;
58     size_t required;
59
60     for (loop = 0, required = 0, ptr = str;
61          loop < len;
62          loop++, required++, ptr++) {
63         if ((unsigned char)(*ptr) < 32 || *ptr == '\"' || *ptr == '\\')
64             required++;
65     }
66
67     /*
68      * + 3 for:
69      * - leading quotation mark,
70      * - trailing quotation mark,
71      * - trailing NULL.
72      */
73     out = talloc_array (ctx, char, required + 3);
74
75     ptr = str;
76     ptr2 = out;
77
78     *ptr2++ = '\"';
79     for (loop = 0; loop < len; loop++) {
80         if ((unsigned char)(*ptr) > 31 && *ptr != '\"' && *ptr != '\\') {
81                 *ptr2++ = *ptr++;
82             } else {
83                 *ptr2++ = '\\';
84                 switch (*ptr++) {
85                     case '\"':  *ptr2++ = '\"'; break;
86                     case '\\':  *ptr2++ = '\\'; break;
87                     case '\b':  *ptr2++ = 'b';  break;
88                     case '\f':  *ptr2++ = 'f';  break;
89                     case '\n':  *ptr2++ = 'n';  break;
90                     case '\r':  *ptr2++ = 'r';  break;
91                     case '\t':  *ptr2++ = 't';  break;
92                     default:     ptr2--;        break;
93                 }
94             }
95     }
96     *ptr2++ = '\"';
97     *ptr2++ = '\0';
98
99     return out;
100 }
101
102 char *
103 json_quote_str(const void *ctx, const char *str)
104 {
105     if (str == NULL)
106         str = "";
107
108     return (json_quote_chararray (ctx, str, strlen (str)));
109 }