Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
duk_api_codec.c File Reference
#include "duk_internal.h"

Go to the source code of this file.

Functions

DUK_LOCAL const duk_uint8_t * duk__prep_codec_arg (duk_context *ctx, duk_idx_t index, duk_size_t *out_len)
 
DUK_LOCAL void duk__base64_encode_helper (const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst)
 
DUK_LOCAL duk_bool_t duk__base64_decode_helper (const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final)
 
DUK_EXTERNAL const char * duk_base64_encode (duk_context *ctx, duk_idx_t index)
 
DUK_EXTERNAL void duk_base64_decode (duk_context *ctx, duk_idx_t index)
 
DUK_EXTERNAL const char * duk_hex_encode (duk_context *ctx, duk_idx_t index)
 
DUK_EXTERNAL void duk_hex_decode (duk_context *ctx, duk_idx_t index)
 
DUK_EXTERNAL const char * duk_json_encode (duk_context *ctx, duk_idx_t index)
 
DUK_EXTERNAL void duk_json_decode (duk_context *ctx, duk_idx_t index)
 

Function Documentation

◆ duk__base64_decode_helper()

DUK_LOCAL duk_bool_t duk__base64_decode_helper ( const duk_uint8_t * src,
duk_size_t srclen,
duk_uint8_t * dst,
duk_uint8_t ** out_dst_final )

Definition at line 139 of file duktape-1.5.2/src-separate/duk_api_codec.c.

139 {
140 duk_int_t x;
141 duk_int_t t;
142 duk_small_uint_t n_equal;
143 duk_small_uint_t n_chars;
144 const duk_uint8_t *src_end;
145 const duk_uint8_t *src_end_safe;
146
147 src_end = src + srclen;
148 src_end_safe = src_end - 4; /* if 'src < src_end_safe', safe to read 4 bytes */
149
150 /* Innermost fast path processes 4 valid base-64 characters at a time
151 * but bails out on whitespace, padding chars ('=') and invalid chars.
152 * Once the slow path segment has been processed, we return to the
153 * inner fast path again. This handles e.g. base64 with newlines
154 * reasonably well because the majority of a line is in the fast path.
155 */
156 for (;;) {
157 /* Fast path, handle units with just actual encoding characters. */
158
159 while (src <= src_end_safe) {
160 /* The lookup byte is intentionally sign extended to (at least)
161 * 32 bits and then ORed. This ensures that is at least 1 byte
162 * is negative, the highest bit of 't' will be set at the end
163 * and we don't need to check every byte.
164 */
165 DUK_DDD(DUK_DDDPRINT("fast loop: src=%p, src_end_safe=%p, src_end=%p",
166 (const void *) src, (const void *) src_end_safe, (const void *) src_end));
167
168 t = (duk_int_t) duk_base64_dectab[*src++];
169 t = (t << 6) | (duk_int_t) duk_base64_dectab[*src++];
170 t = (t << 6) | (duk_int_t) duk_base64_dectab[*src++];
171 t = (t << 6) | (duk_int_t) duk_base64_dectab[*src++];
172
173 if (DUK_UNLIKELY(t < 0)) {
174 DUK_DDD(DUK_DDDPRINT("fast loop unit was not clean, process one slow path unit"));
175 src -= 4;
176 break;
177 }
178
179 DUK_ASSERT(t <= 0xffffffL);
180 DUK_ASSERT((t >> 24) == 0);
181 *dst++ = (duk_uint8_t) (t >> 16);
182 *dst++ = (duk_uint8_t) ((t >> 8) & 0xff);
183 *dst++ = (duk_uint8_t) (t & 0xff);
184 }
185
186 /* Handle one slow path unit (or finish if we're done). */
187
188 n_equal = 0;
189 n_chars = 0;
190 t = 0;
191 for (;;) {
192 DUK_DDD(DUK_DDDPRINT("slow loop: src=%p, src_end=%p, n_chars=%ld, n_equal=%ld, t=%ld",
193 (const void *) src, (const void *) src_end, (long) n_chars, (long) n_equal, (long) t));
194
195 if (DUK_UNLIKELY(src >= src_end)) {
196 goto done; /* two level break */
197 }
198
199 x = duk_base64_dectab[*src++];
200 if (DUK_UNLIKELY(x < 0)) {
201 if (x == -2) {
202 continue; /* allowed ascii whitespace */
203 } else if (x == -3) {
204 n_equal++;
205 t <<= 6;
206 } else {
207 DUK_ASSERT(x == -1);
208 goto error;
209 }
210 } else {
211 DUK_ASSERT(x >= 0 && x <= 63);
212 if (n_equal > 0) {
213 /* Don't allow actual chars after equal sign. */
214 goto error;
215 }
216 t = (t << 6) + x;
217 }
218
219 if (DUK_UNLIKELY(n_chars == 3)) {
220 /* Emit 3 bytes and backtrack if there was padding. There's
221 * always space for the whole 3 bytes so no check needed.
222 */
223 DUK_ASSERT(t <= 0xffffffL);
224 DUK_ASSERT((t >> 24) == 0);
225 *dst++ = (duk_uint8_t) (t >> 16);
226 *dst++ = (duk_uint8_t) ((t >> 8) & 0xff);
227 *dst++ = (duk_uint8_t) (t & 0xff);
228
229 if (DUK_UNLIKELY(n_equal > 0)) {
230 DUK_ASSERT(n_equal <= 4);
231
232 /* There may be whitespace between the equal signs. */
233 if (n_equal == 1) {
234 /* XXX= */
235 dst -= 1;
236 } else if (n_equal == 2) {
237 /* XX== */
238 dst -= 2;
239 } else {
240 goto error; /* invalid padding */
241 }
242
243 /* Continue parsing after padding, allows concatenated,
244 * padded base64.
245 */
246 }
247 break; /* back to fast loop */
248 } else {
249 n_chars++;
250 }
251 }
252 }
253 done:
254 DUK_DDD(DUK_DDDPRINT("done; src=%p, src_end=%p, n_chars=%ld",
255 (const void *) src, (const void *) src_end, (long) n_chars));
256
257 DUK_ASSERT(src == src_end);
258
259 if (n_chars != 0) {
260 /* Here we'd have the option of decoding unpadded base64
261 * (e.g. "xxxxyy" instead of "xxxxyy==". Currently not
262 * accepted.
263 */
264 goto error;
265 }
266
267 *out_dst_final = dst;
268 return 1;
269
270 error:
271 return 0;
272}
unsigned int duk_small_uint_t
duk_int_fast32_t duk_int_t
DUK_INTERNAL const duk_int8_t duk_base64_dectab[256]
static void error(LoadState *S, const char *why)

References DUK_ASSERT, duk_base64_dectab, DUK_DDD, DUK_DDDPRINT, DUK_UNLIKELY, and error().

Referenced by duk_base64_decode().

◆ duk__base64_encode_helper()

DUK_LOCAL void duk__base64_encode_helper ( const duk_uint8_t * src,
duk_size_t srclen,
duk_uint8_t * dst )

Definition at line 25 of file duktape-1.5.2/src-separate/duk_api_codec.c.

25 {
26 duk_uint_t t;
27 duk_size_t n_full, n_full3, n_final;
28 const duk_uint8_t *src_end_fast;
29
30 n_full = srclen / 3; /* full 3-byte -> 4-char conversions */
31 n_full3 = n_full * 3;
32 n_final = srclen - n_full3;
33 DUK_ASSERT_DISABLE(n_final >= 0);
34 DUK_ASSERT(n_final <= 2);
35
36 src_end_fast = src + n_full3;
37 while (DUK_UNLIKELY(src != src_end_fast)) {
38 t = (duk_uint_t) (*src++);
39 t = (t << 8) + (duk_uint_t) (*src++);
40 t = (t << 8) + (duk_uint_t) (*src++);
41
42 *dst++ = duk_base64_enctab[t >> 18];
43 *dst++ = duk_base64_enctab[(t >> 12) & 0x3f];
44 *dst++ = duk_base64_enctab[(t >> 6) & 0x3f];
45 *dst++ = duk_base64_enctab[t & 0x3f];
46
47#if 0 /* Tested: not faster on x64 */
48 /* aaaaaabb bbbbcccc ccdddddd */
49 dst[0] = duk_base64_enctab[(src[0] >> 2) & 0x3f];
50 dst[1] = duk_base64_enctab[((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0f)];
51 dst[2] = duk_base64_enctab[((src[1] << 2) & 0x3f) | ((src[2] >> 6) & 0x03)];
52 dst[3] = duk_base64_enctab[src[2] & 0x3f];
53 src += 3; dst += 4;
54#endif
55 }
56
57 switch (n_final) {
58 /* case 0: nop */
59 case 1: {
60 /* XX== */
61 t = (duk_uint_t) (*src++);
62 *dst++ = duk_base64_enctab[t >> 2]; /* XXXXXX-- */
63 *dst++ = duk_base64_enctab[(t << 4) & 0x3f]; /* ------XX */
64 *dst++ = DUK_ASC_EQUALS;
65 *dst++ = DUK_ASC_EQUALS;
66 break;
67 }
68 case 2: {
69 /* XXX= */
70 t = (duk_uint_t) (*src++);
71 t = (t << 8) + (duk_uint_t) (*src++);
72 *dst++ = duk_base64_enctab[t >> 10]; /* XXXXXX-- -------- */
73 *dst++ = duk_base64_enctab[(t >> 4) & 0x3f]; /* ------XX XXXX---- */
74 *dst++ = duk_base64_enctab[(t << 2) & 0x3f]; /* -------- ----XXXX */
75 *dst++ = DUK_ASC_EQUALS;
76 break;
77 }
78 }
79}
duk_uint_fast32_t duk_uint_t
#define DUK_ASSERT_DISABLE(x)
DUK_INTERNAL const duk_uint8_t duk_base64_enctab[64]

References DUK_ASC_EQUALS, DUK_ASSERT, DUK_ASSERT_DISABLE, duk_base64_enctab, and DUK_UNLIKELY.

Referenced by duk_base64_encode().

◆ duk__prep_codec_arg()

DUK_LOCAL const duk_uint8_t * duk__prep_codec_arg ( duk_context * ctx,
duk_idx_t index,
duk_size_t * out_len )

Definition at line 15 of file duktape-1.5.2/src-separate/duk_api_codec.c.

15 {
16 DUK_ASSERT(duk_is_valid_index(ctx, index)); /* checked by caller */
17 if (duk_is_buffer(ctx, index)) {
18 return (const duk_uint8_t *) duk_get_buffer(ctx, index, out_len);
19 } else {
20 return (const duk_uint8_t *) duk_to_lstring(ctx, index, out_len);
21 }
22}
guint index
DUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL void * duk_get_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size)
DUK_EXTERNAL const char * duk_to_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len)
DUK_EXTERNAL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t index)

References DUK_ASSERT, duk_get_buffer(), duk_is_buffer(), duk_is_valid_index(), duk_to_lstring(), and index.

Referenced by duk_base64_decode(), duk_base64_encode(), duk_hex_decode(), and duk_hex_encode().

◆ duk_base64_decode()

DUK_EXTERNAL void duk_base64_decode ( duk_context * ctx,
duk_idx_t index )

Definition at line 410 of file duktape-1.5.2/src-separate/duk_api_codec.c.

410 {
411 duk_hthread *thr = (duk_hthread *) ctx;
412 const duk_uint8_t *src;
413 duk_size_t srclen;
414 duk_size_t dstlen;
415 duk_uint8_t *dst;
416 duk_uint8_t *dst_final;
417 duk_bool_t retval;
418
420
421 /* XXX: optimize for buffer inputs: no need to coerce to a string
422 * which causes an unnecessary interning.
423 */
424
426 src = duk__prep_codec_arg(ctx, index, &srclen);
427
428 /* Computation must not wrap, only srclen + 3 is at risk of
429 * wrapping because after that the number gets smaller.
430 * This limit works for 32-bit size_t:
431 * 0x100000000 - 3 - 1 = 4294967292
432 */
433 if (srclen > 4294967292UL) {
434 goto type_error;
435 }
436 dstlen = (srclen + 3) / 4 * 3; /* upper limit, assuming no whitespace etc */
437 dst = (duk_uint8_t *) duk_push_dynamic_buffer(ctx, dstlen);
438 /* Note: for dstlen=0, dst may be NULL */
439
440 retval = duk__base64_decode_helper((const duk_uint8_t *) src, srclen, dst, &dst_final);
441 if (!retval) {
442 goto type_error;
443 }
444
445 /* XXX: convert to fixed buffer? */
446 (void) duk_resize_buffer(ctx, -1, (duk_size_t) (dst_final - dst));
447 duk_replace(ctx, index);
448 return;
449
450 type_error:
452}
duk_small_int_t duk_bool_t
#define DUK_ASSERT_CTX_VALID(ctx)
DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t index)
#define DUK_ERROR_TYPE(thr, msg)
#define DUK_STR_DECODE_FAILED
DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_index)
DUK_EXTERNAL void * duk_resize_buffer(duk_context *ctx, duk_idx_t index, duk_size_t new_size)
#define duk_push_dynamic_buffer(ctx, size)
DUK_LOCAL const duk_uint8_t * duk__prep_codec_arg(duk_context *ctx, duk_idx_t index, duk_size_t *out_len)
DUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final)

References duk__base64_decode_helper(), duk__prep_codec_arg(), DUK_ASSERT_CTX_VALID, DUK_ERROR_TYPE, duk_push_dynamic_buffer, duk_replace(), duk_require_normalize_index(), duk_resize_buffer(), DUK_STR_DECODE_FAILED, and index.

◆ duk_base64_encode()

DUK_EXTERNAL const char * duk_base64_encode ( duk_context * ctx,
duk_idx_t index )

Definition at line 370 of file duktape-1.5.2/src-separate/duk_api_codec.c.

370 {
371 duk_hthread *thr = (duk_hthread *) ctx;
372 const duk_uint8_t *src;
373 duk_size_t srclen;
374 duk_size_t dstlen;
375 duk_uint8_t *dst;
376 const char *ret;
377
379
380 /* XXX: optimize for string inputs: no need to coerce to a buffer
381 * which makes a copy of the input.
382 */
383
385 src = duk__prep_codec_arg(ctx, index, &srclen);
386 /* Note: for srclen=0, src may be NULL */
387
388 /* Computation must not wrap; this limit works for 32-bit size_t:
389 * >>> srclen = 3221225469
390 * >>> '%x' % ((srclen + 2) / 3 * 4)
391 * 'fffffffc'
392 */
393 if (srclen > 3221225469UL) {
394 goto type_error;
395 }
396 dstlen = (srclen + 2) / 3 * 4;
397 dst = (duk_uint8_t *) duk_push_fixed_buffer(ctx, dstlen);
398
399 duk__base64_encode_helper((const duk_uint8_t *) src, srclen, dst);
400
401 ret = duk_to_string(ctx, -1);
402 duk_replace(ctx, index);
403 return ret;
404
405 type_error:
407 return NULL; /* never here */
408}
DUK_EXTERNAL const char * duk_to_string(duk_context *ctx, duk_idx_t index)
#define DUK_STR_ENCODE_FAILED
#define duk_push_fixed_buffer(ctx, size)
DUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst)
#define NULL
Definition gmacros.h:924

References duk__base64_encode_helper(), duk__prep_codec_arg(), DUK_ASSERT_CTX_VALID, DUK_ERROR_TYPE, duk_push_fixed_buffer, duk_replace(), duk_require_normalize_index(), DUK_STR_ENCODE_FAILED, duk_to_string(), index, and NULL.

◆ duk_hex_decode()

DUK_EXTERNAL void duk_hex_decode ( duk_context * ctx,
duk_idx_t index )

Definition at line 510 of file duktape-1.5.2/src-separate/duk_api_codec.c.

510 {
511 duk_hthread *thr = (duk_hthread *) ctx;
512 const duk_uint8_t *inp;
513 duk_size_t len;
514 duk_size_t i;
515 duk_int_t t;
516 duk_uint8_t *buf;
517#if defined(DUK_USE_HEX_FASTPATH)
518 duk_int_t chk;
519 duk_uint8_t *p;
520 duk_size_t len_safe;
521#endif
522
524
526 inp = duk__prep_codec_arg(ctx, index, &len);
527 DUK_ASSERT(inp != NULL || len == 0);
528
529 if (len & 0x01) {
530 goto type_error;
531 }
532
533 /* Fixed buffer, no zeroing because we'll fill all the data. */
534 buf = (duk_uint8_t *) duk_push_buffer_raw(ctx, len / 2, DUK_BUF_FLAG_NOZERO /*flags*/);
535 DUK_ASSERT(buf != NULL);
536
537#if defined(DUK_USE_HEX_FASTPATH)
538 p = buf;
539 len_safe = len & ~0x07U;
540 for (i = 0; i < len_safe; i += 8) {
541 t = ((duk_int_t) duk_hex_dectab_shift4[inp[i]]) |
542 ((duk_int_t) duk_hex_dectab[inp[i + 1]]);
543 chk = t;
544 p[0] = (duk_uint8_t) t;
545 t = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 2]]) |
546 ((duk_int_t) duk_hex_dectab[inp[i + 3]]);
547 chk |= t;
548 p[1] = (duk_uint8_t) t;
549 t = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 4]]) |
550 ((duk_int_t) duk_hex_dectab[inp[i + 5]]);
551 chk |= t;
552 p[2] = (duk_uint8_t) t;
553 t = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 6]]) |
554 ((duk_int_t) duk_hex_dectab[inp[i + 7]]);
555 chk |= t;
556 p[3] = (duk_uint8_t) t;
557 p += 4;
558
559 /* Check if any lookup above had a negative result. */
560 if (DUK_UNLIKELY(chk < 0)) {
561 goto type_error;
562 }
563 }
564 for (; i < len; i += 2) {
565 t = (((duk_int_t) duk_hex_dectab[inp[i]]) << 4) |
566 ((duk_int_t) duk_hex_dectab[inp[i + 1]]);
567 if (DUK_UNLIKELY(t < 0)) {
568 goto type_error;
569 }
570 *p++ = (duk_uint8_t) t;
571 }
572#else /* DUK_USE_HEX_FASTPATH */
573 for (i = 0; i < len; i += 2) {
574 /* For invalid characters the value -1 gets extended to
575 * at least 16 bits. If either nybble is invalid, the
576 * resulting 't' will be < 0.
577 */
578 t = (((duk_int_t) duk_hex_dectab[inp[i]]) << 4) |
579 ((duk_int_t) duk_hex_dectab[inp[i + 1]]);
580 if (DUK_UNLIKELY(t < 0)) {
581 goto type_error;
582 }
583 buf[i >> 1] = (duk_uint8_t) t;
584 }
585#endif /* DUK_USE_HEX_FASTPATH */
586
587 duk_replace(ctx, index);
588 return;
589
590 type_error:
592}
DUK_EXTERNAL void * duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags)
DUK_INTERNAL const duk_int8_t duk_hex_dectab[256]
DUK_INTERNAL const duk_int16_t duk_hex_dectab_shift4[256]
#define DUK_BUF_FLAG_NOZERO

References duk__prep_codec_arg(), DUK_ASSERT, DUK_ASSERT_CTX_VALID, DUK_BUF_FLAG_NOZERO, DUK_ERROR_TYPE, duk_hex_dectab, duk_hex_dectab_shift4, duk_push_buffer_raw(), duk_replace(), duk_require_normalize_index(), DUK_STR_DECODE_FAILED, DUK_UNLIKELY, index, and NULL.

◆ duk_hex_encode()

DUK_EXTERNAL const char * duk_hex_encode ( duk_context * ctx,
duk_idx_t index )

Definition at line 454 of file duktape-1.5.2/src-separate/duk_api_codec.c.

454 {
455 const duk_uint8_t *inp;
456 duk_size_t len;
457 duk_size_t i;
458 duk_uint8_t *buf;
459 const char *ret;
460#if defined(DUK_USE_HEX_FASTPATH)
461 duk_size_t len_safe;
462 duk_uint16_t *p16;
463#endif
464
466
468 inp = duk__prep_codec_arg(ctx, index, &len);
469 DUK_ASSERT(inp != NULL || len == 0);
470
471 /* Fixed buffer, no zeroing because we'll fill all the data. */
472 buf = (duk_uint8_t *) duk_push_buffer_raw(ctx, len * 2, DUK_BUF_FLAG_NOZERO /*flags*/);
473 DUK_ASSERT(buf != NULL);
474
475#if defined(DUK_USE_HEX_FASTPATH)
476 DUK_ASSERT((((duk_size_t) buf) & 0x01U) == 0); /* pointer is aligned, guaranteed for fixed buffer */
477 p16 = (duk_uint16_t *) (void *) buf;
478 len_safe = len & ~0x03U;
479 for (i = 0; i < len_safe; i += 4) {
480 p16[0] = duk_hex_enctab[inp[i]];
481 p16[1] = duk_hex_enctab[inp[i + 1]];
482 p16[2] = duk_hex_enctab[inp[i + 2]];
483 p16[3] = duk_hex_enctab[inp[i + 3]];
484 p16 += 4;
485 }
486 for (; i < len; i++) {
487 *p16++ = duk_hex_enctab[inp[i]];
488 }
489#else /* DUK_USE_HEX_FASTPATH */
490 for (i = 0; i < len; i++) {
492 t = (duk_small_uint_t) inp[i];
493 buf[i*2 + 0] = duk_lc_digits[t >> 4];
494 buf[i*2 + 1] = duk_lc_digits[t & 0x0f];
495 }
496#endif /* DUK_USE_HEX_FASTPATH */
497
498 /* XXX: Using a string return value forces a string intern which is
499 * not always necessary. As a rough performance measure, hex encode
500 * time for tests/perf/test-hex-encode.js dropped from ~35s to ~15s
501 * without string coercion. Change to returning a buffer and let the
502 * caller coerce to string if necessary?
503 */
504
505 ret = duk_to_string(ctx, -1);
506 duk_replace(ctx, index);
507 return ret;
508}
DUK_INTERNAL const duk_uint8_t duk_lc_digits[36]
DUK_INTERNAL const duk_uint16_t duk_hex_enctab[256]

References duk__prep_codec_arg(), DUK_ASSERT, DUK_ASSERT_CTX_VALID, DUK_BUF_FLAG_NOZERO, duk_hex_enctab, duk_lc_digits, duk_push_buffer_raw(), duk_replace(), duk_require_normalize_index(), duk_to_string(), index, and NULL.

◆ duk_json_decode()

DUK_EXTERNAL void duk_json_decode ( duk_context * ctx,
duk_idx_t index )

Definition at line 620 of file duktape-1.5.2/src-separate/duk_api_codec.c.

620 {
621#ifdef DUK_USE_ASSERTIONS
622 duk_idx_t top_at_entry;
623#endif
624
626#ifdef DUK_USE_ASSERTIONS
627 top_at_entry = duk_get_top(ctx);
628#endif
629
632 index /*idx_value*/,
633 DUK_INVALID_INDEX /*idx_reviver*/,
634 0 /*flags*/);
635 duk_replace(ctx, index);
636
637 DUK_ASSERT(duk_get_top(ctx) == top_at_entry);
638}
DUK_INTERNAL_DECL void duk_bi_json_parse_helper(duk_context *ctx, duk_idx_t idx_value, duk_idx_t idx_reviver, duk_small_uint_t flags)
DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx)

References DUK_ASSERT, DUK_ASSERT_CTX_VALID, duk_bi_json_parse_helper(), duk_get_top(), DUK_INVALID_INDEX, duk_replace(), duk_require_normalize_index(), and index.

◆ duk_json_encode()

DUK_EXTERNAL const char * duk_json_encode ( duk_context * ctx,
duk_idx_t index )

Definition at line 594 of file duktape-1.5.2/src-separate/duk_api_codec.c.

594 {
595#ifdef DUK_USE_ASSERTIONS
596 duk_idx_t top_at_entry;
597#endif
598 const char *ret;
599
601#ifdef DUK_USE_ASSERTIONS
602 top_at_entry = duk_get_top(ctx);
603#endif
604
607 index /*idx_value*/,
608 DUK_INVALID_INDEX /*idx_replacer*/,
609 DUK_INVALID_INDEX /*idx_space*/,
610 0 /*flags*/);
611 DUK_ASSERT(duk_is_string(ctx, -1));
612 duk_replace(ctx, index);
613 ret = duk_get_string(ctx, index);
614
615 DUK_ASSERT(duk_get_top(ctx) == top_at_entry);
616
617 return ret;
618}
DUK_INTERNAL_DECL void duk_bi_json_stringify_helper(duk_context *ctx, duk_idx_t idx_value, duk_idx_t idx_replacer, duk_idx_t idx_space, duk_small_uint_t flags)
DUK_EXTERNAL const char * duk_get_string(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t index)

References DUK_ASSERT, DUK_ASSERT_CTX_VALID, duk_bi_json_stringify_helper(), duk_get_string(), duk_get_top(), DUK_INVALID_INDEX, duk_is_string(), duk_replace(), duk_require_normalize_index(), and index.