File Coverage

json-create-perl.c
Criterion Covered Total %
statement 623 724 86.0
branch 378 1200 31.5
condition n/a
subroutine n/a
pod n/a
total 1001 1924 52.0


line stmt bran cond sub pod time code
1             /*
2             This is the main part of JSON::Create.
3              
4             It's kept in a separate file but #included into the main file,
5             Create.xs.
6             */
7              
8             #ifdef __GNUC__
9             #define INLINE inline
10             #else
11             #define INLINE
12             #endif /* __GNUC__ */
13              
14             /* These are return statuses for the types of failures which can
15             occur. */
16              
17             typedef enum {
18             json_create_ok,
19              
20             /* The following set of exceptions indicate something went wrong
21             in JSON::Create's code, in other words bugs. */
22              
23             /* An error from the unicode.c library. */
24             json_create_unicode_error,
25             /* A printed number turned out to be longer than MARGIN bytes. */
26             json_create_number_too_long,
27             /* Unknown type of floating point number. */
28             json_create_unknown_floating_point,
29             /* Bad format for floating point. */
30             json_create_bad_floating_format,
31              
32             /* The following set of exceptions indicate bad input, in other
33             words these are user-generated exceptions. */
34              
35             /* Badly-formatted UTF-8. */
36             json_create_unicode_bad_utf8,
37             /* Unknown Perl svtype within the structure. */
38             json_create_unknown_type,
39             /* User's routine returned invalid stuff. */
40             json_create_invalid_user_json,
41             /* User gave us an undefined value from a user subroutine. */
42             json_create_undefined_return_value,
43             /* Rejected non-ASCII, non-character string in strict mode. */
44             json_create_non_ascii_byte,
45             /* Rejected scalar reference in strict mode. */
46             json_create_scalar_reference,
47             /* Rejected non-finite number in strict mode. */
48             json_create_non_finite_number,
49             }
50             json_create_status_t;
51              
52             #define BUFSIZE 0x4000
53              
54             /* MARGIN is the size of the "spillover" area where we can print
55             numbers or Unicode UTF-8 whole characters (runes) into the buffer
56             without having to check the printed length after each byte. */
57              
58             #define MARGIN 0x40
59              
60             #define INDENT
61              
62             typedef struct json_create {
63             /* The length of the input string. */
64             int length;
65             unsigned char * buffer;
66             /* Place to write the buffer to. */
67             SV * output;
68             /* Format for floating point numbers. */
69             char * fformat;
70             /* Memory leak counter. */
71             int n_mallocs;
72             /* Handlers for objects and booleans. If there are no handlers,
73             this is zero (a NULL pointer). */
74             HV * handlers;
75             /* User reference handler. */
76             SV * type_handler;
77             /* User obj handler. */
78             SV * obj_handler;
79             /* User non-finite-float handler, what to do with "inf", "nan"
80             type numbers. */
81             SV * non_finite_handler;
82             /* User's sorter for entries. */
83             SV * cmp;
84             #ifdef INDENT
85             /* Indentation depth (no. of tabs). */
86             unsigned int depth;
87             #endif /* def INDENT */
88              
89             /* One-bit flags. */
90              
91             /* Do any of the SVs have a Unicode flag? */
92             unsigned int unicode : 1;
93             /* Should we convert / into \/? */
94             unsigned int escape_slash : 1;
95             /* Should Unicode be upper case? */
96             unsigned int unicode_upper : 1;
97             /* Should we escape all non-ascii? */
98             unsigned int unicode_escape_all : 1;
99             /* Should we validate user-defined JSON? */
100             unsigned int validate : 1;
101             /* Do not escape U+2028 and U+2029. */
102             unsigned int no_javascript_safe : 1;
103             /* Make errors fatal. */
104             unsigned int fatal_errors : 1;
105             /* Replace bad UTF-8 with the "replacement character". */
106             unsigned int replace_bad_utf8 : 1;
107             /* Never upgrade the output to "utf8". */
108             unsigned int downgrade_utf8 : 1;
109             /* Output may contain invalid UTF-8. */
110             unsigned int utf8_dangerous : 1;
111             /* Strict mode, reject lots of things. */
112             unsigned int strict : 1;
113             #ifdef INDENT
114             /* Add whitespace to output to make it human-readable. */
115             unsigned int indent : 1;
116             /* Sort the keys of objects. */
117             unsigned int sort : 1;
118             #endif /* INDENT */
119             }
120             json_create_t;
121              
122             /* Check the length of the buffer, and if we don't have more than
123             MARGIN bytes left to write into, then we put "jc->buffer" into the
124             Perl scalar "jc->output" via "json_create_buffer_fill". We always
125             want to be at least MARGIN bytes from the end of "jc->buffer" after
126             every write operation, so that we always have room to put a number
127             or a UTF-8 "rune" in the buffer without checking the length
128             excessively. */
129              
130             #define CHECKLENGTH \
131             if (jc->length >= BUFSIZE - MARGIN) { \
132             CALL (json_create_buffer_fill (jc)); \
133             }
134              
135             /* Debug the internal handling of types. */
136              
137             //#define JCDEBUGTYPES
138             #ifdef JCDEBUGTYPES
139             #define MSG(format, args...) \
140             fprintf (stderr, "%s:%d: ", __FILE__, __LINE__);\
141             fprintf (stderr, format, ## args);\
142             fprintf (stderr, "\n");
143             #else
144             #define MSG(format, args...)
145             #endif /* def JCDEBUGTYPES */
146              
147             /* Print an error to stderr. */
148              
149             static int
150 0           json_create_error_handler_default (const char * file, int line_number, const char * msg, ...)
151             {
152             int printed;
153             va_list vargs;
154 0           va_start (vargs, msg);
155 0           printed = 0;
156 0           printed += fprintf (stderr, "%s:%d: ", file, line_number);
157 0           printed += vfprintf (stderr, msg, vargs);
158 0           printed += fprintf (stderr, "\n");
159 0           va_end (vargs);
160 0           return printed;
161             }
162              
163             static int (* json_create_error_handler) (const char * file, int line_number, const char * msg, ...) = json_create_error_handler_default;
164              
165             #define JCEH json_create_error_handler
166              
167             #define HANDLE_STATUS(x,status) { \
168             switch (status) { \
169             /* These exceptions indicate a user error. */ \
170             case json_create_unknown_type: \
171             case json_create_unicode_bad_utf8: \
172             case json_create_invalid_user_json: \
173             case json_create_undefined_return_value: \
174             case json_create_non_ascii_byte: \
175             case json_create_scalar_reference: \
176             case json_create_non_finite_number: \
177             break; \
178             \
179             /* All other exceptions are our bugs. */ \
180             default: \
181             if (JCEH) { \
182             (*JCEH) (__FILE__, __LINE__, \
183             "call to %s failed with status %d", \
184             #x, status); \
185             } \
186             } \
187             }
188              
189             #define CALL(x) { \
190             json_create_status_t status; \
191             status = x; \
192             if (status != json_create_ok) { \
193             HANDLE_STATUS (x,status); \
194             return status; \
195             } \
196             }
197              
198             static void
199 15           json_create_user_message (json_create_t * jc, json_create_status_t status, const char * format, ...)
200             {
201             va_list a;
202             /* Check the status. */
203 15           va_start (a, format);
204 15 100         if (jc->fatal_errors) {
205 2           vcroak (format, & a);
206             }
207             else {
208 13           vwarn (format, & a);
209             }
210 13           }
211              
212             /* Everything else in this file is ordered from callee at the top to
213             caller at the bottom, but because of the recursion as we look at
214             JSON values within arrays or hashes, we need to forward-declare
215             "json_create_recursively". */
216              
217             static json_create_status_t
218             json_create_recursively (json_create_t * jc, SV * input);
219              
220             /* Copy the jc buffer into its SV. */
221              
222             static INLINE json_create_status_t
223 97           json_create_buffer_fill (json_create_t * jc)
224             {
225             /* There is nothing to put in the output. */
226 97 50         if (jc->length == 0) {
227 0 0         if (jc->output == 0) {
228             /* And there was not anything before either. */
229 0           jc->output = & PL_sv_undef;
230             }
231             /* Either way, we don't need to do anything more. */
232 0           return json_create_ok;
233             }
234 97 50         if (! jc->output) {
235 97           jc->output = newSVpvn ((char *) jc->buffer, (STRLEN) jc->length);
236             }
237             else {
238 0           sv_catpvn (jc->output, (char *) jc->buffer, (STRLEN) jc->length);
239             }
240             /* "Empty" the buffer, we don't bother cleaning out the old
241             values, so "jc->length" is our only clue as to the clean/dirty
242             state of the buffer. */
243 97           jc->length = 0;
244 97           return json_create_ok;
245             }
246              
247             /* Add one character to the end of jc. */
248              
249             static INLINE json_create_status_t
250 2471           add_char (json_create_t * jc, unsigned char c)
251             {
252 2471           jc->buffer[jc->length] = c;
253 2471           jc->length++;
254             /* The size we have to use before we write the buffer out. */
255 2471 50         CHECKLENGTH;
    0          
    0          
    0          
256 2471           return json_create_ok;
257             }
258              
259             /* Add a nul-terminated string to "jc", up to the nul byte. This
260             should not be used unless it's strictly necessary, prefer to use
261             "add_str_len" instead. Basically, don't use this. This is not
262             intended to be Unicode-safe, it is only to be used for strings
263             which we know do not need to be checked for Unicode validity (for
264             example sprintf'd numbers or something). */
265              
266             static INLINE json_create_status_t
267             add_str (json_create_t * jc, const char * s)
268             {
269             int i;
270             for (i = 0; s[i]; i++) {
271             unsigned char c;
272             c = (unsigned char) s[i];
273             CALL (add_char (jc, c));
274             }
275             return json_create_ok;
276             }
277              
278             /* Add a string "s" with length "slen" to "jc". This does not test for
279             nul bytes, but just copies "slen" bytes of the string. This is not
280             intended to be Unicode-safe, it is only to be used for strings we
281             know do not need to be checked for Unicode validity. */
282              
283             static INLINE json_create_status_t
284 158           add_str_len (json_create_t * jc, const char * s, unsigned int slen)
285             {
286             int i;
287             /* We know that (BUFSIZE - jc->length) is always bigger than
288             MARGIN going into this, but the compiler doesn't. Hopefully,
289             the compiler optimizes the following "if" statement away to a
290             true value for almost all cases when this is inlined and slen
291             is known to be smaller than MARGIN. */
292 158 50         if (slen < MARGIN || slen < BUFSIZE - jc->length) {
    0          
293 783 100         for (i = 0; i < slen; i++) {
294 625           jc->buffer[jc->length + i] = s[i];
295             }
296 158           jc->length += slen;
297 158 50         CHECKLENGTH;
    0          
    0          
    0          
298             }
299             else {
300             /* A very long string which may overflow the buffer, so use
301             checking routines. */
302 0 0         for (i = 0; i < slen; i++) {
303 0 0         CALL (add_char (jc, (unsigned char) s[i]));
    0          
    0          
304             }
305             }
306 158           return json_create_ok;
307             }
308              
309             #ifdef INDENT
310              
311 117           static json_create_status_t newline_indent(json_create_t * jc)
312             {
313             int d;
314 117 50         CALL (add_char (jc, '\n'));
    0          
    0          
315 305 100         for (d = 0; d < jc->depth; d++) {
316 188 50         CALL (add_char (jc, '\t')); \
    0          
    0          
317             }
318 117           return json_create_ok;
319             }
320              
321             static INLINE json_create_status_t
322 0           add_str_len_indent (json_create_t * jc, const char * s, unsigned int slen)
323             {
324             int i;
325              
326 0 0         for (i = 0; i < slen; i++) {
327             unsigned char c;
328 0           c = (unsigned char) s[i];
329 0 0         if (c == '\n') {
330 0 0         if (i < slen - 1) {
331 0 0         CALL (newline_indent (jc));
    0          
    0          
332             }
333             // else just discard it, final newline
334             }
335             else {
336 0 0         CALL (add_char (jc, c));
    0          
    0          
337             }
338             }
339 0           return json_create_ok;
340             }
341              
342             #endif /* def INDENT */
343              
344             /* "Add a string" macro, this just saves cut and pasting a string and
345             typing "strlen" over and over again. For ASCII values only, not
346             Unicode safe. */
347              
348             #define ADD(x) CALL (add_str_len (jc, x, strlen (x)));
349              
350             static const char *uc_hex = "0123456789ABCDEF";
351             static const char *lc_hex = "0123456789abcdef";
352              
353             static INLINE json_create_status_t
354 42           add_one_u (json_create_t * jc, unsigned int u)
355             {
356             char * spillover;
357             const char * hex;
358 42           hex = lc_hex;
359 42 100         if (jc->unicode_upper) {
360 6           hex = uc_hex;
361             }
362 42           spillover = (char *) (jc->buffer) + jc->length;
363 42           spillover[0] = '\\';
364 42           spillover[1] = 'u';
365             // Method poached from https://metacpan.org/source/CHANSEN/Unicode-UTF8-0.60/UTF8.xs#L196
366 42           spillover[5] = hex[u & 0xf];
367 42           u >>= 4;
368 42           spillover[4] = hex[u & 0xf];
369 42           u >>= 4;
370 42           spillover[3] = hex[u & 0xf];
371 42           u >>= 4;
372 42           spillover[2] = hex[u & 0xf];
373 42           jc->length += 6;
374 42 50         CHECKLENGTH;
    0          
    0          
    0          
375 42           return json_create_ok;
376             }
377              
378             /* Add a "\u3000" or surrogate pair if necessary. */
379              
380             static INLINE json_create_status_t
381 21           add_u (json_create_t * jc, unsigned int u)
382             {
383 21 100         if (u > 0xffff) {
384             int hi;
385             int lo;
386 9           int status = unicode_to_surrogates (u, & hi, & lo);
387 9 50         if (status != UNICODE_OK) {
388 0 0         if (JCEH) {
389 0           (*JCEH) (__FILE__, __LINE__,
390             "Error %d making surrogate pairs from %X",
391             status, u);
392             }
393 0           return json_create_unicode_error;
394             }
395 9 50         CALL (add_one_u (jc, hi));
    0          
    0          
396             /* Backtrace fallthrough. */
397 9           return add_one_u (jc, lo);
398             }
399             else {
400             /* Backtrace fallthrough. */
401 12           return add_one_u (jc, u);
402             }
403             }
404              
405             #define BADUTF8 \
406             if (jc->replace_bad_utf8) { \
407             /* We have to switch on Unicode otherwise the replacement */ \
408             /* characters don't work as intended. */ \
409             jc->unicode = 1; \
410             /* This is �, U+FFFD, as UTF-8 bytes. */ \
411             CALL (add_str_len (jc, "\xEF\xBF\xBD", 3)); \
412             } \
413             else { \
414             json_create_user_message (jc, json_create_unicode_bad_utf8, \
415             "Invalid UTF-8"); \
416             return json_create_unicode_bad_utf8; \
417             }
418              
419             /* Jump table. Doing it this way is not the fastest possible way, but
420             it's also very difficult for a compiler to mess this
421             up. Theoretically, it would be faster to make a jump table by the
422             compiler from the switch statement, but some compilers sometimes
423             cannot do that. */
424              
425             /* In this enum, I use three letters as a compromise between
426             readability and formatting. The control character names are from
427             "man ascii" with an X tagged on the end. */
428              
429             typedef enum {
430             CTL, // control char, escape to \u
431             BSX, // backslash b
432             HTX, // Tab character
433             NLX, // backslash n, new line
434             NPX, // backslash f
435             CRX, // backslash r
436             ASC, // Non-special ASCII
437             QUO, // double quote
438             BSL, // backslash
439             FSL, // forward slash, "/"
440             BAD, // Invalid UTF-8 value.
441             UT2, // UTF-8, two bytes
442             UT3, // UTF-8, three bytes
443             UT4, // UTF-8, four bytes
444             }
445             jump_t;
446              
447             static jump_t jump[0x100] = {
448             CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,BSX,HTX,NLX,CTL,NPX,CRX,CTL,CTL,
449             CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,CTL,
450             ASC,ASC,QUO,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,FSL,
451             ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,
452             ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,
453             ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,BSL,ASC,ASC,ASC,
454             ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,
455             ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,ASC,
456             BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
457             BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
458             BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
459             BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
460             BAD,BAD,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,
461             UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,UT2,
462             UT3,UT3,UT3,UT3,UT3,UT3,UT3,UT3,UT3,UT3,UT3,UT3,UT3,UT3,UT3,UT3,
463             UT4,UT4,UT4,UT4,UT4,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
464             };
465              
466             /* Need this twice, once within the ASCII handler and once within the
467             Unicode handler. */
468              
469             #define ASCII \
470             case CTL: \
471             CALL (add_one_u (jc, (unsigned int) c)); \
472             i++; \
473             break; \
474             \
475             case BSX: \
476             ADD ("\\b"); \
477             i++; \
478             break; \
479             \
480             case HTX: \
481             ADD ("\\t"); \
482             i++; \
483             break; \
484             \
485             case NLX: \
486             ADD ("\\n"); \
487             i++; \
488             break; \
489             \
490             case NPX: \
491             ADD ("\\f"); \
492             i++; \
493             break; \
494             \
495             case CRX: \
496             ADD ("\\r"); \
497             i++; \
498             break; \
499             \
500             case ASC: \
501             CALL (add_char (jc, c)); \
502             i++; \
503             break; \
504             \
505             case QUO: \
506             ADD ("\\\""); \
507             i++; \
508             break; \
509             \
510             case FSL: \
511             if (jc->escape_slash) { \
512             ADD ("\\/"); \
513             } \
514             else { \
515             CALL (add_char (jc, c)); \
516             } \
517             i++; \
518             break; \
519             \
520             case BSL: \
521             ADD ("\\\\"); \
522             i++; \
523             break;
524              
525              
526             static INLINE json_create_status_t
527 62           json_create_add_ascii_key_len (json_create_t * jc, const unsigned char * key, STRLEN keylen)
528             {
529             int i;
530              
531 62 50         CALL (add_char (jc, '"'));
    0          
    0          
532 168 100         for (i = 0; i < keylen; ) {
533             unsigned char c;
534              
535 109           c = key[i];
536 109           switch (jump[c]) {
537              
538 106 50         ASCII;
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
539              
540 3           default:
541 3           json_create_user_message (jc, json_create_non_ascii_byte,
542             "Non-ASCII byte in non-utf8 string: %X",
543 3           key[i]);
544 2           return json_create_non_ascii_byte;
545             }
546             }
547 59 50         CALL (add_char (jc, '"'));
    0          
    0          
548 59           return json_create_ok;
549             }
550              
551              
552             /* Add a string to the buffer with quotes around it and escapes for
553             the escapables. */
554              
555             static INLINE json_create_status_t
556 271           json_create_add_key_len (json_create_t * jc, const unsigned char * key, STRLEN keylen)
557             {
558             int i;
559              
560 271 50         CALL (add_char (jc, '"'));
    0          
    0          
561 1400 100         for (i = 0; i < keylen; ) {
562             unsigned char c, d, e, f;
563 859           c = key[i];
564              
565 859           switch (jump[c]) {
566              
567 722 50         ASCII;
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
568              
569 3           case BAD:
570 3 100         BADUTF8;
    50          
    0          
    0          
571 2           i++;
572 2           break;
573              
574 5           case UT2:
575 5           d = key[i + 1];
576 5 50         if (d < 0x80 || d > 0xBF) {
    50          
577 0 0         BADUTF8;
    0          
    0          
    0          
578 0           i++;
579 0           break;
580             }
581 5 100         if (jc->unicode_escape_all) {
582             unsigned int u;
583 4           u = (c & 0x1F)<<6
584 4           | (d & 0x3F);
585 4 50         CALL (add_u (jc, u));
    0          
    0          
586             }
587             else {
588 1 50         CALL (add_str_len (jc, (const char *) key + i, 2));
    0          
    0          
589             }
590             // Increment i
591 5           i += 2;
592 5           break;
593              
594 66           case UT3:
595 66           d = key[i + 1];
596 66           e = key[i + 2];
597 66 50         if (d < 0x80 || d > 0xBF ||
    50          
598 66 50         e < 0x80 || e > 0xBF) {
    50          
599 0 0         BADUTF8;
    0          
    0          
    0          
600 0           i++;
601 0           break;
602             }
603 66 100         if (! jc->no_javascript_safe &&
    100          
604 10 100         c == 0xe2 && d == 0x80 &&
    100          
605 4 50         (e == 0xa8 || e == 0xa9)) {
606 8 50         CALL (add_one_u (jc, 0x2028 + e - 0xa8));
    0          
    0          
607             }
608             else {
609 58 100         if (jc->unicode_escape_all) {
610             unsigned int u;
611 8           u = (c & 0x0F)<<12
612 8           | (d & 0x3F)<<6
613 8           | (e & 0x3F);
614 8 50         CALL (add_u (jc, u));
    0          
    0          
615             }
616             else {
617 50 50         CALL (add_str_len (jc, (const char *) key + i, 3));
    0          
    0          
618             }
619             }
620             // Increment i
621 66           i += 3;
622 66           break;
623              
624 63           case UT4:
625 63           d = key[i + 1];
626 63           e = key[i + 2];
627 63           f = key[i + 3];
628 63 50         if (
629             // These byte values are copied from
630             // https://github.com/htacg/tidy-html5/blob/768ad46968b43e29167f4d1394a451b8c6f40b7d/src/utf8.c
631              
632             // 0x40000 - 0xfffff
633 63           (c < 0xf4 &&
634 63 50         (d < 0x80 || d > 0xBF ||
    50          
635 63 50         e < 0x80 || e > 0xBF ||
    50          
636 63 50         f < 0x80 || f > 0xBF))
    50          
637 63 50         ||
638             // 0x100000 - 0x10ffff
639 0           (c == 0xf4 &&
640 0 0         (d < 0x80 || d > 0x8F ||
    0          
641 0 0         e < 0x80 || e > 0xBF ||
    0          
642 0 0         f < 0x80 || f > 0xBF))
    0          
643             ) {
644 0 0         BADUTF8;
    0          
    0          
    0          
645 0           i++;
646 0           break;
647             }
648 63 100         if (jc->unicode_escape_all) {
649             unsigned int u;
650             const unsigned char * input;
651 9           input = key + i;
652 9           u = (c & 0x07) << 18
653 9           | (d & 0x3F) << 12
654 9           | (e & 0x3F) << 6
655 9           | (f & 0x3F);
656 9           add_u (jc, u);
657             }
658             else {
659 54 50         CALL (add_str_len (jc, (const char *) key + i, 4));
    0          
    0          
660             }
661             // Increment i
662 63           i += 4;
663 63           break;
664             }
665             }
666 270 50         CALL (add_char (jc, '"'));
    0          
    0          
667 270           return json_create_ok;
668             }
669              
670             static INLINE json_create_status_t
671 122           json_create_add_string (json_create_t * jc, SV * input)
672             {
673             char * istring;
674             STRLEN ilength;
675              
676 122           istring = SvPV (input, ilength);
677 122 100         if (SvUTF8 (input)) {
678             /* "jc->unicode" is true if Perl says that anything in the
679             whole of the input to "json_create" is a "SvUTF8"
680             scalar. We have to force everything in the whole output to
681             Unicode. */
682 54           jc->unicode = 1;
683             }
684 68 100         else if (jc->strict) {
685             /* Backtrace fall through, remember to check the caller's line. */
686 17           return json_create_add_ascii_key_len (jc, (unsigned char *) istring,
687             (STRLEN) ilength);
688             }
689             /* Backtrace fall through, remember to check the caller's line. */
690 105           return json_create_add_key_len (jc, (unsigned char *) istring,
691             (STRLEN) ilength);
692             }
693              
694             /* Extract the remainder of x when divided by ten and then turn it
695             into the equivalent ASCII digit. '0' in ASCII is 0x30, and (x)%10
696             is guaranteed not to have any of the high bits set. */
697              
698             #define DIGIT(x) (((x)%10)|0x30)
699              
700             static INLINE json_create_status_t
701 0           json_create_add_unsigned(json_create_t * jc, SV * sv) {
702             long unsigned int uv;
703             int uvlen;
704             char * spillover;
705 0           uv = SvUV (sv);
706 0           uvlen = 0;
707 0           spillover = ((char *) jc->buffer) + jc->length;
708 0           uvlen += snprintf (spillover + uvlen, MARGIN - uvlen, "%lu", uv);
709 0 0         if (uvlen >= MARGIN) {
710 0 0         if (JCEH) {
711 0           (*JCEH) (__FILE__, __LINE__,
712             "A printed integer number %ld was "
713             "longer than MARGIN=%d bytes",
714             SvIV (sv), MARGIN);
715             }
716 0           return json_create_number_too_long;
717             }
718 0           jc->length += uvlen;
719 0 0         CHECKLENGTH;
    0          
    0          
    0          
720 0           return json_create_ok;
721             }
722              
723             static INLINE json_create_status_t
724 107           json_create_add_integer (json_create_t * jc, SV * sv)
725             {
726             long int iv;
727             int ivlen;
728             char * spillover;
729              
730 107 50         if (SvIOK_UV(sv)) {
731 0           return json_create_add_unsigned (jc, sv);
732             }
733 107           iv = SvIV (sv);
734 107           ivlen = 0;
735              
736             /* Pointer arithmetic. */
737              
738 107           spillover = ((char *) jc->buffer) + jc->length;
739              
740             /* Souped-up integer printing for small integers. The following is
741             all just souped up versions of snprintf ("%d", iv);. */
742              
743 107 100         if (iv < 0) {
744 10           spillover[ivlen] = '-';
745 10           ivlen++;
746 10           iv = -iv;
747             }
748 107 100         if (iv < 10) {
749             /* iv has exactly one digit. The first digit may be zero. */
750 42           spillover[ivlen] = DIGIT (iv);
751 42           ivlen++;
752             }
753 65 100         else if (iv < 100) {
754             /* iv has exactly two digits. The first digit is not zero. */
755 9           spillover[ivlen] = DIGIT (iv/10);
756 9           ivlen++;
757 9           spillover[ivlen] = DIGIT (iv);
758 9           ivlen++;
759             }
760 56 100         else if (iv < 1000) {
761             /* iv has exactly three digits. The first digit is not
762             zero. */
763 8           spillover[ivlen] = DIGIT (iv/100);
764 8           ivlen++;
765 8           spillover[ivlen] = DIGIT (iv/10);
766 8           ivlen++;
767 8           spillover[ivlen] = DIGIT (iv);
768 8           ivlen++;
769             }
770 48 100         else if (iv < 10000) {
771             /* etc. */
772 8           spillover[ivlen] = DIGIT (iv/1000);
773 8           ivlen++;
774 8           spillover[ivlen] = DIGIT (iv/100);
775 8           ivlen++;
776 8           spillover[ivlen] = DIGIT (iv/10);
777 8           ivlen++;
778 8           spillover[ivlen] = DIGIT (iv);
779 8           ivlen++;
780             }
781 40 100         else if (iv < 100000) {
782 6           spillover[ivlen] = DIGIT (iv/10000);
783 6           ivlen++;
784 6           spillover[ivlen] = DIGIT (iv/1000);
785 6           ivlen++;
786 6           spillover[ivlen] = DIGIT (iv/100);
787 6           ivlen++;
788 6           spillover[ivlen] = DIGIT (iv/10);
789 6           ivlen++;
790 6           spillover[ivlen] = DIGIT (iv);
791 6           ivlen++;
792             }
793 34 100         else if (iv < 1000000) {
794 6           spillover[ivlen] = DIGIT (iv/100000);
795 6           ivlen++;
796 6           spillover[ivlen] = DIGIT (iv/10000);
797 6           ivlen++;
798 6           spillover[ivlen] = DIGIT (iv/1000);
799 6           ivlen++;
800 6           spillover[ivlen] = DIGIT (iv/100);
801 6           ivlen++;
802 6           spillover[ivlen] = DIGIT (iv/10);
803 6           ivlen++;
804 6           spillover[ivlen] = DIGIT (iv);
805 6           ivlen++;
806             }
807 28 100         else if (iv < 10000000) {
808 12           spillover[ivlen] = DIGIT (iv/1000000);
809 12           ivlen++;
810 12           spillover[ivlen] = DIGIT (iv/100000);
811 12           ivlen++;
812 12           spillover[ivlen] = DIGIT (iv/10000);
813 12           ivlen++;
814 12           spillover[ivlen] = DIGIT (iv/1000);
815 12           ivlen++;
816 12           spillover[ivlen] = DIGIT (iv/100);
817 12           ivlen++;
818 12           spillover[ivlen] = DIGIT (iv/10);
819 12           ivlen++;
820 12           spillover[ivlen] = DIGIT (iv);
821 12           ivlen++;
822             }
823 16 100         else if (iv < 100000000) {
824 6           spillover[ivlen] = DIGIT (iv/10000000);
825 6           ivlen++;
826 6           spillover[ivlen] = DIGIT (iv/1000000);
827 6           ivlen++;
828 6           spillover[ivlen] = DIGIT (iv/100000);
829 6           ivlen++;
830 6           spillover[ivlen] = DIGIT (iv/10000);
831 6           ivlen++;
832 6           spillover[ivlen] = DIGIT (iv/1000);
833 6           ivlen++;
834 6           spillover[ivlen] = DIGIT (iv/100);
835 6           ivlen++;
836 6           spillover[ivlen] = DIGIT (iv/10);
837 6           ivlen++;
838 6           spillover[ivlen] = DIGIT (iv);
839 6           ivlen++;
840             }
841 10 100         else if (iv < 1000000000) {
842 8           spillover[ivlen] = DIGIT (iv/100000000);
843 8           ivlen++;
844 8           spillover[ivlen] = DIGIT (iv/10000000);
845 8           ivlen++;
846 8           spillover[ivlen] = DIGIT (iv/1000000);
847 8           ivlen++;
848 8           spillover[ivlen] = DIGIT (iv/100000);
849 8           ivlen++;
850 8           spillover[ivlen] = DIGIT (iv/10000);
851 8           ivlen++;
852 8           spillover[ivlen] = DIGIT (iv/1000);
853 8           ivlen++;
854 8           spillover[ivlen] = DIGIT (iv/100);
855 8           ivlen++;
856 8           spillover[ivlen] = DIGIT (iv/10);
857 8           ivlen++;
858 8           spillover[ivlen] = DIGIT (iv);
859 8           ivlen++;
860             }
861             else {
862             /* The number is one billion (1000,000,000) or more, so we're
863             just going to print it into "jc->buffer" with snprintf. */
864 2           ivlen += snprintf (spillover + ivlen, MARGIN - ivlen, "%ld", iv);
865 2 50         if (ivlen >= MARGIN) {
866 0 0         if (JCEH) {
867 0           (*JCEH) (__FILE__, __LINE__,
868             "A printed integer number %ld was "
869             "longer than MARGIN=%d bytes",
870             SvIV (sv), MARGIN);
871             }
872 0           return json_create_number_too_long;
873             }
874             }
875 107           jc->length += ivlen;
876 107 50         CHECKLENGTH;
    0          
    0          
    0          
877 107           return json_create_ok;
878             }
879              
880             #define UNKNOWN_TYPE_FAIL(t) \
881             if (JCEH) { \
882             (*JCEH) (__FILE__, __LINE__, \
883             "Unknown Perl type %d", t); \
884             } \
885             return json_create_unknown_type
886              
887             //#define DEBUGOBJ
888              
889             static json_create_status_t
890 2           json_create_validate_user_json (json_create_t * jc, SV * json)
891             {
892             SV * error;
893 2           dSP;
894 2           ENTER;
895 2           SAVETMPS;
896 2 50         PUSHMARK (SP);
897 2 50         XPUSHs (sv_2mortal (newSVsv (json)));
898 2           PUTBACK;
899 2           call_pv ("JSON::Parse::assert_valid_json",
900             G_EVAL|G_DISCARD);
901 2 50         FREETMPS;
902 2           LEAVE;
903 2           error = get_sv ("@", 0);
904 2 50         if (! error) {
905 0           return json_create_ok;
906             }
907 2 50         if (SvOK (error) && SvCUR (error) > 0) {
    100          
908 1           json_create_user_message (jc, json_create_invalid_user_json,
909             "JSON::Parse::assert_valid_json failed for '%s': %s",
910             SvPV_nolen (json), SvPV_nolen (error));
911 1           return json_create_invalid_user_json;
912             }
913 1           return json_create_ok;
914             }
915              
916             static json_create_status_t
917 14           json_create_call_to_json (json_create_t * jc, SV * cv, SV * r)
918             {
919             SV * json;
920             char * jsonc;
921             STRLEN jsonl;
922             // https://metacpan.org/source/AMBS/Math-GSL-0.35/swig/gsl_typemaps.i#L438
923 14           dSP;
924            
925 14           ENTER;
926 14           SAVETMPS;
927            
928 14 50         PUSHMARK (SP);
929             //https://metacpan.org/source/AMBS/Math-GSL-0.35/swig/gsl_typemaps.i#L482
930 14 50         XPUSHs (sv_2mortal (newRV (r)));
931 14           PUTBACK;
932 14           call_sv (cv, 0);
933 14           json = POPs;
934 14           SvREFCNT_inc (json);
935 14 50         FREETMPS;
936 14           LEAVE;
937              
938 14 100         if (! SvOK (json)) {
939             /* User returned an undefined value. */
940 3           SvREFCNT_dec (json);
941 3           json_create_user_message (jc, json_create_undefined_return_value,
942             "Undefined value from user routine");
943 3           return json_create_undefined_return_value;
944             }
945 11 50         if (SvUTF8 (json)) {
946             /* We have to force everything in the whole output to
947             Unicode. */
948 0           jc->unicode = 1;
949             }
950 11           jsonc = SvPV (json, jsonl);
951 11 100         if (jc->validate) {
952 2 100         CALL (json_create_validate_user_json (jc, json));
    50          
    0          
953             }
954             else {
955             /* This string may contain invalid UTF-8. */
956 9           jc->utf8_dangerous = 1;
957             }
958             #ifdef INDENT
959 10 50         if (jc->indent) {
960 0 0         CALL (add_str_len_indent (jc, jsonc, jsonl));
    0          
    0          
961             }
962             else {
963             #endif
964 10 50         CALL (add_str_len (jc, jsonc, jsonl));
    0          
    0          
965             #ifdef INDENT
966             }
967             #endif
968 10           SvREFCNT_dec (json);
969 10           return json_create_ok;
970             }
971              
972             static INLINE json_create_status_t
973 102           json_create_add_float (json_create_t * jc, SV * sv)
974             {
975             double fv;
976             STRLEN fvlen;
977 102           fv = SvNV (sv);
978 102 100         if (isfinite (fv)) {
979 93 100         if (jc->fformat) {
980 57           fvlen = snprintf ((char *) jc->buffer + jc->length, MARGIN, jc->fformat, fv);
981             }
982             else {
983 36           fvlen = snprintf ((char *) jc->buffer + jc->length, MARGIN,
984             "%g", fv);
985             }
986 93 50         if (fvlen >= MARGIN) {
987 0           return json_create_number_too_long;
988             }
989 93           jc->length += fvlen;
990 93 50         CHECKLENGTH;
    0          
    0          
    0          
991             }
992             else {
993 9 100         if (jc->non_finite_handler) {
994 3 50         CALL (json_create_call_to_json (jc, jc->non_finite_handler, sv));
    0          
    0          
995             }
996             else {
997 6 100         if (jc->strict) {
998 3           json_create_user_message (jc, json_create_non_finite_number,
999             "Non-finite number in input");
1000 3           return json_create_non_finite_number;
1001             }
1002 3 100         if (isnan (fv)) {
1003 1 50         ADD ("\"nan\"");
    0          
    0          
1004             }
1005 2 50         else if (isinf (fv)) {
1006 2 100         if (fv < 0.0) {
1007 1 50         ADD ("\"-inf\"");
    0          
    0          
1008             }
1009             else {
1010 1 50         ADD ("\"inf\"");
    0          
    0          
1011             }
1012             }
1013             else {
1014 0           return json_create_unknown_floating_point;
1015             }
1016             }
1017             }
1018 99           return json_create_ok;
1019             }
1020              
1021             static INLINE json_create_status_t
1022 3           json_create_add_magic (json_create_t * jc, SV * r)
1023             {
1024             /* There are some edge cases with blessed references
1025             containing numbers which we need to handle correctly. */
1026 3 100         if (SvIOK (r)) {
1027 1 50         CALL (json_create_add_integer (jc, r));
    0          
    0          
1028             }
1029 2 50         else if (SvNOK (r)) {
1030 0 0         CALL (json_create_add_float (jc, r));
    0          
    0          
1031             }
1032             else {
1033 2 50         CALL (json_create_add_string (jc, r));
    0          
    0          
1034             }
1035 3           return json_create_ok;
1036             }
1037              
1038             /* Add a number which is already stringified. This bypasses snprintf
1039             and just copies the Perl string straight into the buffer. */
1040              
1041             static INLINE json_create_status_t
1042             json_create_add_stringified (json_create_t * jc, SV *r)
1043             {
1044             /* Stringified number. */
1045             char * s;
1046             /* Length of "r". */
1047             STRLEN rlen;
1048             int i;
1049             int notdigits = 0;
1050              
1051             s = SvPV (r, rlen);
1052            
1053             /* Somehow or another it's possible to arrive here with a
1054             non-digit string, precisely this happened with the "script"
1055             value returned by Unicode::UCD::charinfo, which had the value
1056             "Common" and was an SVt_PVIV. */
1057             for (i = 0; i < rlen; i++) {
1058             char c = s[i];
1059             if (!isdigit (c) && c != '.' && c != '-' && c != 'e' && c != 'E') {
1060             notdigits = 1;
1061             }
1062             }
1063             /* If the stringified number has leading zeros, don't skip those,
1064             but put the string in quotes. It can happen that something like
1065             a Huffman code has leading zeros and should be treated as a
1066             string, yet Perl also thinks it is a number. */
1067             if (s[0] == '0' && rlen > 1 && isdigit (s[1])) {
1068             notdigits = 1;
1069             }
1070              
1071             if (notdigits) {
1072             CALL (add_char (jc, '"'));
1073             CALL (add_str_len (jc, s, (unsigned int) rlen));
1074             CALL (add_char (jc, '"'));
1075             return json_create_ok;
1076             }
1077             /* This doesn't backtrace correctly, but the calling routine
1078             should print out that it was calling "add_stringified", so as
1079             long as we're careful not to ignore the caller line, it
1080             shouldn't matter. */
1081             return add_str_len (jc, s, (unsigned int) rlen);
1082             }
1083              
1084             #ifdef INDENT
1085             #define DINC if (jc->indent) { jc->depth++; }
1086             #define DDEC if (jc->indent) { jc->depth--; }
1087             #endif /* def INDENT */
1088              
1089             /* Add a comma where necessary. This is shared between objects and
1090             arrays. */
1091              
1092             #ifdef INDENT
1093             #define COMMA \
1094             if (i > 0) { \
1095             CALL (add_char (jc, ',')); \
1096             if (jc->indent) { \
1097             CALL (newline_indent (jc)); \
1098             } \
1099             }
1100             #else /* INDENT */
1101             #define COMMA \
1102             if (i > 0) { \
1103             CALL (add_char (jc, ',')); \
1104             }
1105             #endif /* INDENT */
1106              
1107             static INLINE json_create_status_t
1108 112           add_open (json_create_t * jc, unsigned char c)
1109             {
1110 112 50         CALL (add_char (jc, c));
    0          
    0          
1111             #ifdef INDENT
1112 112 100         if (jc->indent) {
1113 23 50         DINC;
1114 23 50         CALL (newline_indent (jc)); \
    0          
    0          
1115             }
1116             #endif /* INDENT */
1117 112           return json_create_ok;
1118             }
1119              
1120             static INLINE json_create_status_t
1121 102           add_close (json_create_t * jc, unsigned char c)
1122             {
1123             #ifdef INDENT
1124 102 100         if (jc->indent) {
1125 23 50         DDEC;
1126 23 50         CALL (newline_indent (jc)); \
    0          
    0          
1127             }
1128             #endif /* def INDENT */
1129 102 50         CALL (add_char (jc, c));
    0          
    0          
1130             #ifdef INDENT
1131 102 100         if (jc->indent) {
1132             /* Add a new line after the final brace, otherwise we have no
1133             newline on the final line of output. */
1134 23 100         if (jc->depth == 0) {
1135 6 50         CALL (add_char (jc, '\n'));
    0          
    0          
1136             }
1137             }
1138             #endif /* def INDENT */
1139 102           return json_create_ok;
1140             }
1141              
1142             //#define JCDEBUGTYPES
1143              
1144             static int
1145 10           json_create_user_compare (void * thunk, const void * va, const void * vb)
1146             {
1147 10           dSP;
1148             SV * sa;
1149             SV * sb;
1150             json_create_t * jc;
1151             int n;
1152             int c;
1153              
1154 10           sa = *(SV **) va;
1155 10           sb = *(SV **) vb;
1156 10           jc = (json_create_t *) thunk;
1157              
1158 10           ENTER;
1159 10           SAVETMPS;
1160 10 50         PUSHMARK(SP);
1161 10 50         EXTEND(SP, 2);
1162 10 50         XPUSHs(sv_2mortal (newSVsv (sa)));
1163 10 50         XPUSHs(sv_2mortal (newSVsv (sb)));
1164 10           PUTBACK;
1165 10           n = call_sv (jc->cmp, G_SCALAR);
1166 10 50         if (n != 1) {
1167 0           croak ("Wrong number of return values %d from comparison function",
1168             n);
1169             }
1170 10           SPAGAIN;
1171 10           c = POPi;
1172 10           PUTBACK;
1173 10 50         FREETMPS;
1174 10           LEAVE;
1175 10           return c;
1176             }
1177              
1178             static INLINE json_create_status_t
1179 17           json_create_add_object_sorted (json_create_t * jc, HV * input_hv)
1180             {
1181             I32 n_keys;
1182             int i;
1183             SV ** keys;
1184              
1185 17           n_keys = hv_iterinit (input_hv);
1186 17 50         if (n_keys == 0) {
1187 0 0         CALL (add_str_len (jc, "{}", strlen ("{}")));
    0          
    0          
1188 0           return json_create_ok;
1189             }
1190 17 50         CALL (add_open (jc, '{'));
    0          
    0          
1191 17           Newxz (keys, n_keys, SV *);
1192 17           jc->n_mallocs++;
1193 87 100         for (i = 0; i < n_keys; i++) {
1194             HE * he;
1195 70           he = hv_iternext (input_hv);
1196 70           keys[i] = hv_iterkeysv (he);
1197 70 50         if (HeUTF8 (he)) {
    100          
1198 33           jc->unicode = 1;
1199             }
1200             }
1201              
1202 17 100         if (jc->cmp) {
1203 2           json_create_qsort_r (keys, n_keys, sizeof (SV **), jc,
1204             json_create_user_compare);
1205             }
1206             else {
1207 15           sortsv_flags (keys, (size_t) n_keys, Perl_sv_cmp, /* flags */ 0);
1208             }
1209              
1210 87 100         for (i = 0; i < n_keys; i++) {
1211             SV * key_sv;
1212             char * key;
1213             STRLEN keylen;
1214             HE * he;
1215              
1216 70 100         COMMA;
    50          
    0          
    0          
    50          
    50          
    0          
    0          
1217 70           key_sv = keys[i];
1218 70           key = SvPV (key_sv, keylen);
1219 70 50         CALL (json_create_add_key_len (jc, (const unsigned char *) key,
    0          
    0          
1220             keylen));
1221 70           he = hv_fetch_ent (input_hv, key_sv, 0, 0);
1222 70 50         if (! he) {
1223 0           croak ("%s:%d: invalid sv_ptr for '%s' at offset %d",
1224             __FILE__, __LINE__, key, i);
1225             }
1226 70 50         CALL (add_char (jc, ':'));
    0          
    0          
1227 70 50         CALL (json_create_recursively (jc, HeVAL(he)));
    0          
    0          
1228             }
1229 17           Safefree (keys);
1230 17           jc->n_mallocs--;
1231              
1232 17 50         CALL (add_close (jc, '}'));
    0          
    0          
1233              
1234 17           return json_create_ok;
1235             }
1236              
1237             /* Given a reference to a hash in "input_hv", recursively process it
1238             into JSON. "object" here means "JSON object", not "Perl object". */
1239              
1240             static INLINE json_create_status_t
1241 80           json_create_add_object (json_create_t * jc, HV * input_hv)
1242             {
1243             I32 n_keys;
1244             int i;
1245             SV * value;
1246             char * key;
1247             /* I32 is correct, not STRLEN; see hv.c. */
1248             I32 keylen;
1249             #ifdef INDENT
1250 80 100         if (jc->sort) {
1251 17           return json_create_add_object_sorted (jc, input_hv);
1252             }
1253             #endif /* INDENT */
1254 63           n_keys = hv_iterinit (input_hv);
1255 63 100         if (n_keys == 0) {
1256 1 50         CALL (add_str_len (jc, "{}", strlen ("{}")));
    0          
    0          
1257 1           return json_create_ok;
1258             }
1259 62 50         CALL (add_open (jc, '{'));
    0          
    0          
1260 194 100         for (i = 0; i < n_keys; i++) {
1261             HE * he;
1262              
1263             /* Get the information from the hash. */
1264             /* The following is necessary because "hv_iternextsv" doesn't
1265             tell us whether the key is "SvUTF8" or not. */
1266 141           he = hv_iternext (input_hv);
1267 141           key = hv_iterkey (he, & keylen);
1268 141           value = hv_iterval (input_hv, he);
1269              
1270             /* Write the information into the buffer. */
1271              
1272 141 100         COMMA;
    50          
    0          
    0          
    100          
    50          
    0          
    0          
1273 141 50         if (HeUTF8 (he)) {
    100          
1274 4           jc->unicode = 1;
1275 4 50         CALL (json_create_add_key_len (jc, (const unsigned char *) key,
    0          
    0          
1276             (STRLEN) keylen));
1277             }
1278 137 100         else if (jc->strict) {
1279 45 100         CALL (json_create_add_ascii_key_len (jc, (unsigned char *) key,
    50          
    0          
1280             (STRLEN) keylen));
1281             }
1282             else {
1283 92 50         CALL (json_create_add_key_len (jc, (const unsigned char *) key,
    0          
    0          
1284             (STRLEN) keylen));
1285             }
1286 139 50         CALL (add_char (jc, ':'));
    0          
    0          
1287             MSG ("Creating value of hash");
1288 139 100         CALL (json_create_recursively (jc, value));
    50          
    0          
1289             }
1290 53 50         CALL (add_close (jc, '}'));
    0          
    0          
1291 53           return json_create_ok;
1292             }
1293              
1294             /* Given an array reference in "av", recursively process it into
1295             JSON. */
1296              
1297             static INLINE json_create_status_t
1298 33           json_create_add_array (json_create_t * jc, AV * av)
1299             {
1300             I32 n_keys;
1301             int i;
1302             SV * value;
1303             SV ** avv;
1304              
1305             MSG ("Adding first char [");
1306 33 50         CALL (add_open (jc, '['));
    0          
    0          
1307 33           n_keys = av_len (av) + 1;
1308             MSG ("n_keys = %ld", n_keys);
1309              
1310             /* This deals correctly with empty arrays, since av_len is -1 if
1311             the array is empty, so we do not test for a valid n_keys value
1312             before entering the loop. */
1313 195 100         for (i = 0; i < n_keys; i++) {
1314             MSG ("i = %d", i);
1315 163 100         COMMA;
    50          
    0          
    0          
    100          
    50          
    0          
    0          
1316              
1317 163           avv = av_fetch (av, i, 0 /* don't delete the array value */);
1318 163 50         if (avv) {
1319 163           value = * avv;
1320             }
1321             else {
1322             MSG ("null value returned by av_fetch");
1323 0           value = & PL_sv_undef;
1324             }
1325 163 100         CALL (json_create_recursively (jc, value));
    50          
    0          
1326             }
1327             MSG ("Adding last char ]");
1328 32 50         CALL (add_close (jc, ']'));
    0          
    0          
1329 32           return json_create_ok;
1330             }
1331              
1332              
1333             static INLINE json_create_status_t
1334 5           json_create_handle_unknown_type (json_create_t * jc, SV * r)
1335             {
1336 5 100         if (jc->type_handler) {
1337 2 100         CALL (json_create_call_to_json (jc, jc->type_handler, r));
    50          
    0          
1338 1           return json_create_ok;
1339             }
1340 3           json_create_user_message (jc, json_create_unknown_type,
1341             "Input's type cannot be serialized to JSON");
1342 3           return json_create_unknown_type;
1343             }
1344              
1345             #define STRICT_NO_SCALAR \
1346             if (jc->strict) { \
1347             goto handle_type; \
1348             }
1349              
1350             static INLINE json_create_status_t
1351 122           json_create_handle_ref (json_create_t * jc, SV * r)
1352             {
1353             svtype t;
1354 122           t = SvTYPE (r);
1355             MSG ("Type is %d", t);
1356 122           switch (t) {
1357 33           case SVt_PVAV:
1358             MSG("Array");
1359 33 100         CALL (json_create_add_array (jc, (AV *) r));
    50          
    0          
1360 32           break;
1361              
1362 80           case SVt_PVHV:
1363             MSG("Hash");
1364 80 100         CALL (json_create_add_object (jc, (HV *) r));
    50          
    0          
1365 71           break;
1366              
1367 0           case SVt_NV:
1368             case SVt_PVNV:
1369             MSG("NV/PVNV");
1370 0 0         STRICT_NO_SCALAR;
1371 0 0         CALL (json_create_add_float (jc, r));
    0          
    0          
1372 0           break;
1373              
1374 2           case SVt_IV:
1375             case SVt_PVIV:
1376             MSG("IV/PVIV");
1377 2 100         STRICT_NO_SCALAR;
1378 1 50         CALL (json_create_add_integer (jc, r));
    0          
    0          
1379 1           break;
1380              
1381 2           case SVt_PV:
1382             MSG("PV");
1383 2 100         STRICT_NO_SCALAR;
1384 1 50         CALL (json_create_add_string (jc, r));
    0          
    0          
1385 1           break;
1386              
1387 2           case SVt_PVMG:
1388             MSG("PVMG");
1389 2 50         STRICT_NO_SCALAR;
1390 2 50         CALL (json_create_add_magic (jc, r));
    0          
    0          
1391 2           break;
1392              
1393             default:
1394 5           handle_type:
1395 5 100         CALL (json_create_handle_unknown_type (jc, r));
    50          
    0          
1396             }
1397 108           return json_create_ok;
1398             }
1399              
1400             /* In strict mode, if no object handlers exist, then we reject the
1401             object. */
1402              
1403             #define REJECT_OBJECT(objtype) \
1404             json_create_user_message (jc, json_create_unknown_type, \
1405             "Object cannot be " \
1406             "serialized to JSON: %s", \
1407             objtype); \
1408             return json_create_unknown_type;
1409              
1410              
1411             static INLINE json_create_status_t
1412 17           json_create_handle_object (json_create_t * jc, SV * r,
1413             const char * objtype, I32 olen)
1414             {
1415             SV ** sv_ptr;
1416             #ifdef DEBUGOBJ
1417             fprintf (stderr, "Have found an object of type %s.\n", objtype);
1418             #endif
1419 17           sv_ptr = hv_fetch (jc->handlers, objtype, olen, 0);
1420 17 50         if (sv_ptr) {
1421             char * pv;
1422             STRLEN pvlen;
1423 17           pv = SvPV (*sv_ptr, pvlen);
1424             #ifdef DEBUGOBJ
1425             fprintf (stderr, "Have found a handler %s for %s.\n", pv, objtype);
1426             #endif
1427 17 100         if (pvlen == strlen ("bool") &&
1428 9 50         strncmp (pv, "bool", 4) == 0) {
1429 18 100         if (SvTRUE (r)) {
1430 8 50         ADD ("true");
    0          
    0          
1431             }
1432             else {
1433 3 50         ADD ("false");
    0          
    0          
1434             }
1435             }
1436 8 50         else if (SvROK (*sv_ptr)) {
1437             SV * what;
1438 8           what = SvRV (*sv_ptr);
1439 8 50         switch (SvTYPE (what)) {
1440 8           case SVt_PVCV:
1441 8 100         CALL (json_create_call_to_json (jc, what, r));
    50          
    0          
1442 6           break;
1443 0           default:
1444             /* Weird handler, not a code reference. */
1445 0           goto nothandled;
1446             }
1447             }
1448             else {
1449             /* It's an object, it's in our handlers, but we don't
1450             have any code to deal with it, so we'll print an
1451             error and then stringify it. */
1452 0 0         if (JCEH) {
1453 0           (*JCEH) (__FILE__, __LINE__, "Unhandled handler %s.\n",
1454             pv);
1455 0           goto nothandled;
1456             }
1457             }
1458             }
1459             else {
1460             #ifdef DEBUGOBJ
1461             /* Leaving this debugging code here since this is liable
1462             to change a lot. */
1463             I32 hvnum;
1464             SV * s;
1465             char * key;
1466             I32 retlen;
1467             fprintf (stderr, "Nothing in handlers for %s.\n", objtype);
1468             hvnum = hv_iterinit (jc->handlers);
1469              
1470             fprintf (stderr, "There are %ld keys in handlers.\n", hvnum);
1471             while (1) {
1472             s = hv_iternextsv (jc->handlers, & key, & retlen);
1473             if (! s) {
1474             break;
1475             }
1476             fprintf (stderr, "%s: %s\n", key, SvPV_nolen (s));
1477             }
1478             #endif /* 0 */
1479 0           nothandled:
1480 0 0         if (jc->strict) {
1481 0           REJECT_OBJECT(objtype);
1482             }
1483 0 0         CALL (json_create_handle_ref (jc, r));
    0          
    0          
1484             }
1485 15           return json_create_ok;
1486             }
1487              
1488             #define JCBOOL "JSON::Create::Bool"
1489              
1490             static json_create_status_t
1491 145           json_create_refobj (json_create_t * jc, SV * input)
1492             {
1493             SV * r;
1494 145           r = SvRV (input);
1495              
1496             MSG("A reference");
1497             /* We have a reference, so decide what to do with it. */
1498 145 100         if (sv_isobject (input)) {
1499             const char * objtype;
1500             I32 olen;
1501 28           objtype = sv_reftype (r, 1);
1502 28           olen = (I32) strlen (objtype);
1503 28 100         if (olen == strlen (JCBOOL) &&
1504 7 100         strncmp (objtype, JCBOOL, strlen (JCBOOL)) == 0) {
1505 4 100         if (SvTRUE (r)) {
1506 2 50         ADD("true");
    0          
    0          
1507             }
1508             else {
1509 2 50         ADD("false");
    0          
    0          
1510             }
1511 4           return json_create_ok;
1512             }
1513 24 100         if (jc->obj_handler) {
1514 1 50         CALL (json_create_call_to_json (jc, jc->obj_handler, r));
    50          
    0          
1515 0           return json_create_ok;
1516             }
1517 23 100         if (jc->handlers) {
1518 17 100         CALL (json_create_handle_object (jc, r, objtype, olen));
    50          
    0          
1519 15           return json_create_ok;
1520             }
1521 6 100         if (jc->strict) {
1522 1           REJECT_OBJECT (objtype);
1523             return json_create_ok;
1524             }
1525             }
1526              
1527             MSG ("create handle references");
1528              
1529 122 100         CALL (json_create_handle_ref (jc, r));
    50          
    0          
1530 108           return json_create_ok;
1531             }
1532              
1533             #ifdef INDENT
1534             #define TOP_NEWLINE \
1535             if (jc->indent && jc->depth == 0) {\
1536             MSG ("Top-level non-object non-array with indent, adding newline");\
1537             CALL (add_char (jc, '\n'));\
1538             }
1539             #else
1540             #define TOP_NEWLINE
1541             #endif /* INDENT */
1542              
1543             static json_create_status_t
1544 327           json_create_not_ref (json_create_t * jc, SV * r)
1545             {
1546             svtype t;
1547              
1548             MSG("Not a reference.");
1549              
1550 327           t = SvTYPE (r);
1551 327           switch (t) {
1552              
1553 0           case SVt_NULL:
1554 0 0         ADD ("null");
    0          
    0          
1555 0           break;
1556              
1557 1           case SVt_PVMG:
1558             MSG ("SVt_PVMG %s", SvPV_nolen (r));
1559 1 50         CALL (json_create_add_magic (jc, r));
    0          
    0          
1560 1           break;
1561              
1562 119           case SVt_PV:
1563             MSG ("SVt_PV %s", SvPV_nolen (r));
1564 119 50         CALL (json_create_add_string (jc, r));
    0          
    0          
1565 117           break;
1566              
1567 101           case SVt_IV:
1568             MSG ("SVt_IV %ld\n", SvIV (r));
1569 101 50         CALL (json_create_add_integer (jc, r));
    0          
    0          
1570 101           break;
1571              
1572 95           case SVt_NV:
1573             MSG ("SVt_NV %g", SvNV (r));
1574 95 100         CALL (json_create_add_float (jc, r));
    50          
    0          
1575 92           break;
1576              
1577 10           case SVt_PVNV:
1578 10 50         if (SvNIOK (r)) {
1579 10 100         if (SvNOK (r)) {
1580             MSG ("SVt_PVNV with double %s/%g", SvPV_nolen (r), SvNV (r));
1581              
1582             /* We need to handle non-finite numbers without using
1583             Perl's stringified forms, because we need to put quotes
1584             around them, whereas Perl will just print 'nan' the
1585             same way it will print '0.01'. 'nan' is not valid JSON,
1586             so we have to convert to '"nan"'. */
1587 7 50         CALL (json_create_add_float (jc, r));
    0          
    0          
1588             }
1589 3 50         else if (SvIOK (r)) {
1590             MSG ("SVt_PVNV with integer %s/%g", SvPV_nolen (r), SvNV (r));
1591              
1592             /* We need to handle non-finite numbers without using
1593             Perl's stringified forms, because we need to put quotes
1594             around them, whereas Perl will just print 'nan' the
1595             same way it will print '0.01'. 'nan' is not valid JSON,
1596             so we have to convert to '"nan"'. */
1597 3 50         CALL (json_create_add_integer (jc, r));
    0          
    0          
1598             }
1599             else {
1600             /* I'm not sure if this will be reached. */
1601             MSG ("SVt_PVNV without valid NV/IV %s", SvPV_nolen (r));
1602 0 0         CALL (json_create_add_string (jc, r));
    0          
    0          
1603             }
1604             }
1605             else {
1606             MSG ("SVt_PVNV without valid NV/IV %s", SvPV_nolen (r));
1607 0 0         CALL (json_create_add_string (jc, r));
    0          
    0          
1608             }
1609 10           break;
1610              
1611 1           case SVt_PVIV:
1612             /* Add numbers with a string version using the strings
1613             which Perl contains. */
1614 1 50         if (SvIOK (r)) {
1615             MSG ("SVt_PVIV %s/%ld", SvPV_nolen (r), SvIV (r));
1616 1 50         CALL (json_create_add_integer (jc, r));
    0          
    0          
1617             }
1618             else {
1619              
1620             /* This combination of things happens e.g. with the
1621             value returned under "script" by charinfo of
1622             Unicode::UCD. If we don't catch it with SvIOK as
1623             above, we get an error of the form 'Argument
1624             "Latin" isn't numeric in subroutine entry' */
1625             #if 0
1626             fprintf (stderr, "%s:%d: SVt_PVIV without valid IV %s\n",
1627             __FILE__, __LINE__, SvPV_nolen (r));
1628             #endif /* 0 */
1629 0 0         CALL (json_create_add_string (jc, r));
    0          
    0          
1630             }
1631 1           break;
1632            
1633 0           default:
1634 0 0         CALL (json_create_handle_unknown_type (jc, r));
    0          
    0          
1635             }
1636 322 100         TOP_NEWLINE;
    50          
    0          
    0          
    0          
1637 322           return json_create_ok;
1638             }
1639              
1640             /* This is the core routine, it is called recursively as hash values
1641             and array values containing array or hash references are
1642             handled. */
1643              
1644             static json_create_status_t
1645 484           json_create_recursively (json_create_t * jc, SV * input)
1646             {
1647              
1648             MSG("sv = %p.", input);
1649              
1650 484 100         if (! SvOK (input)) {
1651             /* We were told to add an undefined value, so put the literal
1652             'null' (without quotes) at the end of "jc" then return. */
1653             MSG("Adding 'null'");
1654 8 50         ADD ("null");
    0          
    0          
1655 8 100         TOP_NEWLINE;
    50          
    50          
    0          
    0          
1656 8           return json_create_ok;
1657             }
1658             /* JSON::Parse inserts pointers to &PL_sv_yes and no as literal
1659             "true" and "false" markers. */
1660 476 100         if (input == &PL_sv_yes) {
1661             MSG("Adding 'true'");
1662 2 50         ADD ("true");
    0          
    0          
1663 2           return json_create_ok;
1664             }
1665 474 100         if (input == &PL_sv_no) {
1666             MSG("Adding 'false'");
1667 2 50         ADD ("false");
    0          
    0          
1668 2           return json_create_ok;
1669             }
1670 472 100         if (SvROK (input)) {
1671 145 100         CALL (json_create_refobj (jc, input));
    50          
    0          
1672 127           return json_create_ok;
1673             }
1674 327 100         CALL (json_create_not_ref (jc, input));
    50          
    0          
1675 322           return json_create_ok;
1676             }
1677              
1678             /* Master-caller macro. Calls to subsystems from "json_create" cannot
1679             be handled using the CALL macro above, because we need to return a
1680             non-status value from json_create. If things go wrong somewhere, we
1681             return "undef". */
1682              
1683             #define FINALCALL(x) { \
1684             json_create_status_t status; \
1685             status = x; \
1686             if (status != json_create_ok) { \
1687             HANDLE_STATUS (x, status); \
1688             /* Free the memory of "output". */ \
1689             if (jc->output) { \
1690             SvREFCNT_dec (jc->output); \
1691             jc->output = 0; \
1692             } \
1693             /* return undef; */ \
1694             return & PL_sv_undef; \
1695             } \
1696             }
1697              
1698             /* This is the main routine of JSON::Create, where the JSON is
1699             produced from the Perl structure in "input". */
1700              
1701             static INLINE SV *
1702 112           json_create_create (json_create_t * jc, SV * input)
1703             {
1704             unsigned char buffer[BUFSIZE];
1705              
1706             /* Set up all the transient variables for reading. */
1707              
1708 112           jc->buffer = buffer;
1709 112           jc->length = 0;
1710             /* Tell json_create_buffer_fill that it needs to allocate an
1711             SV. */
1712 112           jc->output = 0;
1713             /* Not Unicode. */
1714 112           jc->unicode = 0;
1715              
1716 112 100         FINALCALL (json_create_recursively (jc, input));
    50          
    0          
    50          
1717 97 50         FINALCALL (json_create_buffer_fill (jc));
    0          
    0          
    0          
1718              
1719 97 100         if (jc->unicode && ! jc->downgrade_utf8) {
    100          
1720 23 50         if (jc->utf8_dangerous) {
1721 0 0         if (is_utf8_string ((U8 *) SvPV_nolen (jc->output),
1722             SvCUR (jc->output))) {
1723 0           SvUTF8_on (jc->output);
1724             }
1725             else {
1726 0           json_create_user_message (jc, json_create_unicode_bad_utf8,
1727             "Invalid UTF-8 from user routine");
1728 0           return & PL_sv_undef;
1729             }
1730             }
1731             else {
1732 23           SvUTF8_on (jc->output);
1733             }
1734             }
1735              
1736             /* We didn't allocate any memory except for the SV, all our memory
1737             is on the stack, so there is nothing to free here. */
1738              
1739 97           return jc->output;
1740             }
1741              
1742             /* __ __ _ _ _
1743             | \/ | ___| |_| |__ ___ __| |___
1744             | |\/| |/ _ \ __| '_ \ / _ \ / _` / __|
1745             | | | | __/ |_| | | | (_) | (_| \__ \
1746             |_| |_|\___|\__|_| |_|\___/ \__,_|___/ */
1747            
1748              
1749             static json_create_status_t
1750 24           json_create_new (json_create_t ** jc_ptr)
1751             {
1752             json_create_t * jc;
1753 24           Newxz (jc, 1, json_create_t);
1754 24           jc->n_mallocs = 0;
1755 24           jc->n_mallocs++;
1756 24           jc->fformat = 0;
1757 24           jc->type_handler = 0;
1758 24           jc->handlers = 0;
1759 24           * jc_ptr = jc;
1760 24           return json_create_ok;
1761             }
1762              
1763             static json_create_status_t
1764 28           json_create_free_fformat (json_create_t * jc)
1765             {
1766 28 100         if (jc->fformat) {
1767 2           Safefree (jc->fformat);
1768 2           jc->fformat = 0;
1769 2           jc->n_mallocs--;
1770             }
1771 28           return json_create_ok;
1772             }
1773              
1774             static json_create_status_t
1775 4           json_create_set_fformat (json_create_t * jc, SV * fformat)
1776             {
1777             char * ff;
1778             STRLEN fflen;
1779             int i;
1780              
1781 4 50         CALL (json_create_free_fformat (jc));
    0          
    0          
1782 4 100         if (! SvTRUE (fformat)) {
1783 2           jc->fformat = 0;
1784 2           return json_create_ok;
1785             }
1786              
1787 2           ff = SvPV (fformat, fflen);
1788 2 50         if (! strchr (ff, '%')) {
1789 0           return json_create_bad_floating_format;
1790             }
1791 2           Newx (jc->fformat, fflen + 1, char);
1792 2           jc->n_mallocs++;
1793 10 100         for (i = 0; i < fflen; i++) {
1794             /* We could also check the format in this loop. */
1795 8           jc->fformat[i] = ff[i];
1796             }
1797 2           jc->fformat[fflen] = '\0';
1798 2           return json_create_ok;
1799             }
1800              
1801             static json_create_status_t
1802 24           json_create_remove_handlers (json_create_t * jc)
1803             {
1804 24 100         if (jc->handlers) {
1805 5           SvREFCNT_dec ((SV *) jc->handlers);
1806 5           jc->handlers = 0;
1807 5           jc->n_mallocs--;
1808             }
1809 24           return json_create_ok;
1810             }
1811              
1812             static json_create_status_t
1813 26           json_create_remove_type_handler (json_create_t * jc)
1814             {
1815 26 100         if (jc->type_handler) {
1816 2           SvREFCNT_dec (jc->type_handler);
1817 2           jc->type_handler = 0;
1818 2           jc->n_mallocs--;
1819             }
1820 26           return json_create_ok;
1821             }
1822              
1823             static json_create_status_t
1824 25           json_create_remove_obj_handler (json_create_t * jc)
1825             {
1826 25 100         if (jc->obj_handler) {
1827 1           SvREFCNT_dec (jc->obj_handler);
1828 1           jc->obj_handler = 0;
1829 1           jc->n_mallocs--;
1830             }
1831 25           return json_create_ok;
1832             }
1833              
1834             static json_create_status_t
1835 25           json_create_remove_non_finite_handler (json_create_t * jc)
1836             {
1837 25 100         if (jc->non_finite_handler) {
1838 1           SvREFCNT_dec (jc->non_finite_handler);
1839 1           jc->non_finite_handler = 0;
1840 1           jc->n_mallocs--;
1841             }
1842 25           return json_create_ok;
1843             }
1844              
1845             static json_create_status_t
1846 25           json_create_remove_cmp (json_create_t * jc)
1847             {
1848 25 100         if (jc->cmp) {
1849 1           SvREFCNT_dec (jc->cmp);
1850 1           jc->cmp = 0;
1851 1           jc->n_mallocs--;
1852             }
1853 25           return json_create_ok;
1854             }
1855              
1856             static json_create_status_t
1857 24           json_create_free (json_create_t * jc)
1858             {
1859 24 50         CALL (json_create_free_fformat (jc));
    0          
    0          
1860 24 50         CALL (json_create_remove_handlers (jc));
    0          
    0          
1861 24 50         CALL (json_create_remove_type_handler (jc));
    0          
    0          
1862 24 50         CALL (json_create_remove_obj_handler (jc));
    0          
    0          
1863 24 50         CALL (json_create_remove_non_finite_handler (jc));
    0          
    0          
1864 24 50         CALL (json_create_remove_cmp (jc));
    0          
    0          
1865              
1866             /* Finished, check we have no leaks before freeing. */
1867              
1868 24           jc->n_mallocs--;
1869 24 50         if (jc->n_mallocs != 0) {
1870 0           fprintf (stderr, "%s:%d: n_mallocs = %d\n",
1871             __FILE__, __LINE__, jc->n_mallocs);
1872             }
1873 24           Safefree (jc);
1874 24           return json_create_ok;
1875             }
1876              
1877             static void
1878 4           bump (json_create_t * jc, SV * h)
1879             {
1880 4           SvREFCNT_inc (h);
1881 4           jc->n_mallocs++;
1882 4           }
1883              
1884             static void
1885 1           set_non_finite_handler (json_create_t * jc, SV * oh)
1886             {
1887 1           jc->non_finite_handler = oh;
1888 1           bump (jc, oh);
1889 1           }
1890              
1891             static void
1892 1           set_object_handler (json_create_t * jc, SV * oh)
1893             {
1894 1           jc->obj_handler = oh;
1895 1           bump (jc, oh);
1896 1           }
1897              
1898             static void
1899 2           set_type_handler (json_create_t * jc, SV * th)
1900             {
1901 2           jc->type_handler = th;
1902 2           bump (jc, th);
1903 2           }
1904              
1905             /* Use the length of the string to eliminate impossible matches before
1906             looking at the string's bytes. */
1907              
1908             #define CMP(x) (strlen(#x) == (size_t) key_len && \
1909             strncmp(#x, key, key_len) == 0)
1910              
1911             #define BOOL(x) \
1912             if (CMP(x)) { \
1913             jc->x = SvTRUE (value) ? 1 : 0; \
1914             return; \
1915             }
1916              
1917             #define HANDLER(x) \
1918             if (CMP(x ## _handler)) { \
1919             set_ ## x ## _handler (jc, value); \
1920             return; \
1921             }
1922              
1923             static void
1924 6           json_create_set (json_create_t * jc, SV * key_sv, SV * value)
1925             {
1926             const char * key;
1927             STRLEN key_len;
1928            
1929 6           key = SvPV (key_sv, key_len);
1930              
1931 12 50         BOOL (downgrade_utf8);
    0          
1932 6 50         BOOL (escape_slash);
    0          
1933 6 50         BOOL (fatal_errors);
    0          
1934 6 100         BOOL (indent);
    50          
1935 2 50         BOOL (no_javascript_safe);
    0          
1936 2 50         BOOL (replace_bad_utf8);
    0          
1937 2 50         BOOL (sort);
    50          
1938 0 0         BOOL (strict);
    0          
1939 0 0         BOOL (unicode_upper);
    0          
1940 0 0         BOOL (unicode_escape_all);
    0          
1941 0 0         BOOL (validate);
    0          
1942 0 0         HANDLER (non_finite);
    0          
1943 0 0         HANDLER (object);
    0          
1944 0 0         HANDLER (type);
    0          
1945 0           warn ("Unknown option '%s'", key);
1946             }