1 /*
2  * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>
3  *
4  * Jansson is free software; you can redistribute it and/or modify
5  * it under the terms of the MIT license. See LICENSE for details.
6  */
7 /**
8  * License: MIT
9  */
10 module jansson_d.value;
11 
12 
13 package:
14 
15 private static import core.stdc.math;
16 private static import core.stdc.stdarg;
17 private static import core.stdc.string;
18 private static import jansson_d.hashtable;
19 private static import jansson_d.hashtable_seed;
20 private static import jansson_d.jansson;
21 private static import jansson_d.jansson_private;
22 private static import jansson_d.utf;
23 
24 /* Work around nonstandard isnan() and isinf() implementations */
25 static if (!__traits(compiles, core.stdc.math.isnan)) {
26 	//version (Solaris) {
27 	//} else {
28 		pragma(inline, true)
29 		pure nothrow @safe @nogc @live
30 		private int isnan(double x)
31 
32 			do
33 			{
34 				return x != x;
35 			}
36 	//}
37 } else {
38 	alias isnan = core.stdc.math.isnan;
39 }
40 
41 static if (!__traits(compiles, core.stdc.math.isinf)) {
42 	pragma(inline, true)
43 	pure nothrow @safe @nogc @live
44 	private int isinf(double x)
45 
46 		do
47 		{
48 			return (!.isnan(x)) && (.isnan(x - x));
49 		}
50 } else {
51 	alias isinf = core.stdc.math.isinf;
52 }
53 
54 pragma(inline, true)
55 pure nothrow @trusted @nogc @live
56 private void json_init(scope jansson_d.jansson.json_t* json, jansson_d.jansson.json_type type)
57 
58 	in
59 	{
60 		assert(json != null);
61 	}
62 
63 	do
64 	{
65 		json.type = type;
66 		json.refcount = 1;
67 	}
68 
69 nothrow @trusted @nogc
70 int jsonp_loop_check(scope jansson_d.hashtable.hashtable_t* parents, scope const jansson_d.jansson.json_t* json, scope char* key, size_t key_size, scope size_t* key_len_out)
71 
72 	do
73 	{
74 		size_t key_len = jansson_d.jansson_private.snprintf(key, key_size, "%p", json);
75 
76 		if (key_len_out != null) {
77 			*key_len_out = key_len;
78 		}
79 
80 		if (jansson_d.hashtable.hashtable_get(parents, key, key_len)) {
81 			return -1;
82 		}
83 
84 		return jansson_d.hashtable.hashtable_set(parents, key, key_len, .json_null());
85 	}
86 
87 /* object */
88 
89 ///
90 extern (C)
91 nothrow @nogc
92 public jansson_d.jansson.json_t* json_object()
93 
94 	do
95 	{
96 		jansson_d.jansson_private.json_object_t* object = cast(jansson_d.jansson_private.json_object_t*)(jansson_d.jansson_private.jsonp_malloc(jansson_d.jansson_private.json_object_t.sizeof));
97 
98 		if (object == null) {
99 			return null;
100 		}
101 
102 		if (!jansson_d.hashtable_seed.hashtable_seed) {
103 			/* Autoseed */
104 			jansson_d.hashtable_seed.json_object_seed(0);
105 		}
106 
107 		.json_init(&object.json, jansson_d.jansson.json_type.JSON_OBJECT);
108 
109 		if (jansson_d.hashtable.hashtable_init(&object.hashtable)) {
110 			jansson_d.jansson_private.jsonp_free(object);
111 
112 			return null;
113 		}
114 
115 		return &object.json;
116 	}
117 
118 nothrow @trusted @nogc
119 private void json_delete_object(scope jansson_d.jansson_private.json_object_t* object)
120 
121 	in
122 	{
123 		assert(object != null);
124 	}
125 
126 	do
127 	{
128 		jansson_d.hashtable.hashtable_close(&object.hashtable);
129 		jansson_d.jansson_private.jsonp_free(object);
130 	}
131 
132 ///
133 extern (C)
134 pure nothrow @trusted @nogc @live
135 public size_t json_object_size(scope const jansson_d.jansson.json_t* json)
136 
137 	do
138 	{
139 		if (!mixin (jansson_d.jansson.json_is_object!("json"))) {
140 			return 0;
141 		}
142 
143 		jansson_d.jansson_private.json_object_t* object = mixin (jansson_d.jansson_private.json_to_object!("json"));
144 
145 		return object.hashtable.size;
146 	}
147 
148 ///
149 extern (C)
150 nothrow @trusted @nogc @live //ToDo: @nodiscard
151 public jansson_d.jansson.json_t* json_object_get(scope const jansson_d.jansson.json_t* json, scope const char* key)
152 
153 	do
154 	{
155 		if (key == null) {
156 			return null;
157 		}
158 
159 		return .json_object_getn(json, key, core.stdc..string.strlen(key));
160 	}
161 
162 ///
163 extern (C)
164 nothrow @trusted @nogc @live //ToDo: @nodiscard
165 public jansson_d.jansson.json_t* json_object_getn(scope const jansson_d.jansson.json_t* json, scope const char* key, size_t key_len)
166 
167 	do
168 	{
169 		if ((key == null) || (!mixin (jansson_d.jansson.json_is_object!("json")))) {
170 			return null;
171 		}
172 
173 		jansson_d.jansson_private.json_object_t* object = mixin (jansson_d.jansson_private.json_to_object!("json"));
174 
175 		return cast(jansson_d.jansson.json_t*)(jansson_d.hashtable.hashtable_get(&object.hashtable, key, key_len));
176 	}
177 
178 ///
179 extern (C)
180 nothrow @trusted @nogc
181 public int json_object_set_new_nocheck(scope jansson_d.jansson.json_t* json, scope const char* key, scope jansson_d.jansson.json_t* value)
182 
183 	do
184 	{
185 		if (key == null) {
186 			jansson_d.jansson.json_decref(value);
187 
188 			return -1;
189 		}
190 
191 		return .json_object_setn_new_nocheck(json, key, core.stdc..string.strlen(key), value);
192 	}
193 
194 ///
195 extern (C)
196 nothrow @trusted @nogc
197 public int json_object_setn_new_nocheck(scope jansson_d.jansson.json_t* json, scope const char* key, size_t key_len, scope jansson_d.jansson.json_t* value)
198 
199 	do
200 	{
201 		if (value == null) {
202 			return -1;
203 		}
204 
205 		if ((key == null) || (!mixin (jansson_d.jansson.json_is_object!("json"))) || (json == value)) {
206 			jansson_d.jansson.json_decref(value);
207 
208 			return -1;
209 		}
210 
211 		jansson_d.jansson_private.json_object_t* object = mixin (jansson_d.jansson_private.json_to_object!("json"));
212 
213 		if (jansson_d.hashtable.hashtable_set(&object.hashtable, key, key_len, value)) {
214 			jansson_d.jansson.json_decref(value);
215 
216 			return -1;
217 		}
218 
219 		return 0;
220 	}
221 
222 ///
223 extern (C)
224 nothrow @trusted @nogc
225 public int json_object_set_new(scope jansson_d.jansson.json_t* json, scope const char* key, scope jansson_d.jansson.json_t* value)
226 
227 	do
228 	{
229 		if (key == null) {
230 			jansson_d.jansson.json_decref(value);
231 
232 			return -1;
233 		}
234 
235 		return .json_object_setn_new(json, key, core.stdc..string.strlen(key), value);
236 	}
237 
238 ///
239 extern (C)
240 nothrow @trusted @nogc
241 public int json_object_setn_new(scope jansson_d.jansson.json_t* json, scope const char* key, size_t key_len, scope jansson_d.jansson.json_t* value)
242 
243 	do
244 	{
245 		if ((key == null) || (!jansson_d.utf.utf8_check_string(key, key_len))) {
246 			jansson_d.jansson.json_decref(value);
247 
248 			return -1;
249 		}
250 
251 		return .json_object_setn_new_nocheck(json, key, key_len, value);
252 	}
253 
254 ///
255 extern (C)
256 nothrow @trusted @nogc
257 public int json_object_del(scope jansson_d.jansson.json_t* json, scope const char* key)
258 
259 	do
260 	{
261 		if (key == null) {
262 			return -1;
263 		}
264 
265 		return .json_object_deln(json, key, core.stdc..string.strlen(key));
266 	}
267 
268 ///
269 extern (C)
270 nothrow @trusted @nogc
271 public int json_object_deln(scope jansson_d.jansson.json_t* json, scope const char* key, size_t key_len)
272 
273 	do
274 	{
275 		if ((key == null) || (!mixin (jansson_d.jansson.json_is_object!("json")))) {
276 			return -1;
277 		}
278 
279 		jansson_d.jansson_private.json_object_t* object = mixin (jansson_d.jansson_private.json_to_object!("json"));
280 
281 		return jansson_d.hashtable.hashtable_del(&object.hashtable, key, key_len);
282 	}
283 
284 ///
285 extern (C)
286 nothrow @trusted @nogc
287 public int json_object_clear(scope jansson_d.jansson.json_t* json)
288 
289 	do
290 	{
291 		if (!mixin (jansson_d.jansson.json_is_object!("json"))) {
292 			return -1;
293 		}
294 
295 		jansson_d.jansson_private.json_object_t* object = mixin (jansson_d.jansson_private.json_to_object!("json"));
296 		jansson_d.hashtable.hashtable_clear(&object.hashtable);
297 
298 		return 0;
299 	}
300 
301 ///
302 extern (C)
303 nothrow @trusted @nogc
304 public int json_object_update(scope jansson_d.jansson.json_t* object, scope jansson_d.jansson.json_t* other)
305 
306 	do
307 	{
308 		if ((!mixin (jansson_d.jansson.json_is_object!("object"))) || (!mixin (jansson_d.jansson.json_is_object!("other")))) {
309 			return -1;
310 		}
311 
312 		const (char)* key = void;
313 		jansson_d.jansson.json_t* value = void;
314 
315 		//jansson_d.jansson.json_object_foreach(other, key, value)
316 		for (key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter(other)); (key != null) && ((value = jansson_d.value.json_object_iter_value(jansson_d.value.json_object_key_to_iter(key))) != null); key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter_next(other, jansson_d.value.json_object_key_to_iter(key)))) {
317 			if (jansson_d.jansson.json_object_set_nocheck(object, key, value)) {
318 				return -1;
319 			}
320 		}
321 
322 		return 0;
323 	}
324 
325 ///
326 extern (C)
327 nothrow @trusted @nogc
328 public int json_object_update_existing(scope jansson_d.jansson.json_t* object, scope jansson_d.jansson.json_t* other)
329 
330 	do
331 	{
332 		if ((!mixin (jansson_d.jansson.json_is_object!("object"))) || (!mixin (jansson_d.jansson.json_is_object!("other")))) {
333 			return -1;
334 		}
335 
336 		const (char)* key = void;
337 		size_t key_len = void;
338 		jansson_d.jansson.json_t* value = void;
339 
340 		//jansson_d.jansson.json_object_keylen_foreach(other, key, key_len, value)
341 		for (key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter(other)), key_len = jansson_d.value.json_object_iter_key_len(jansson_d.value.json_object_key_to_iter(key)); (key != null) && ((value = jansson_d.value.json_object_iter_value(jansson_d.value.json_object_key_to_iter(key))) != null); key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter_next(other, jansson_d.value.json_object_key_to_iter(key))), key_len = jansson_d.value.json_object_iter_key_len(jansson_d.value.json_object_key_to_iter(key))) {
342 			if (.json_object_getn(object, key, key_len)) {
343 				jansson_d.jansson.json_object_setn_nocheck(object, key, key_len, value);
344 			}
345 		}
346 
347 		return 0;
348 	}
349 
350 ///
351 extern (C)
352 nothrow @trusted @nogc
353 public int json_object_update_missing(scope jansson_d.jansson.json_t* object, scope jansson_d.jansson.json_t* other)
354 
355 	do
356 	{
357 		if ((!mixin (jansson_d.jansson.json_is_object!("object"))) || (!mixin (jansson_d.jansson.json_is_object!("other")))) {
358 			return -1;
359 		}
360 
361 		const (char)* key = void;
362 		jansson_d.jansson.json_t* value = void;
363 
364 		//jansson_d.jansson.json_object_foreach(other, key, value)
365 		for (key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter(other)); (key != null) && ((value = jansson_d.value.json_object_iter_value(jansson_d.value.json_object_key_to_iter(key))) != null); key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter_next(other, jansson_d.value.json_object_key_to_iter(key)))) {
366 			if (!.json_object_get(object, key)) {
367 				jansson_d.jansson.json_object_set_nocheck(object, key, value);
368 			}
369 		}
370 
371 		return 0;
372 	}
373 
374 nothrow @trusted @nogc
375 int do_object_update_recursive(scope jansson_d.jansson.json_t* object, scope jansson_d.jansson.json_t* other, scope jansson_d.hashtable.hashtable_t* parents)
376 
377 	do
378 	{
379 		if ((!mixin (jansson_d.jansson.json_is_object!("object"))) || (!mixin (jansson_d.jansson.json_is_object!("other")))) {
380 			return -1;
381 		}
382 
383 		char[jansson_d.jansson_private.LOOP_KEY_LEN] loop_key = void;
384 		size_t loop_key_len = void;
385 
386 		if (.jsonp_loop_check(parents, other, &(loop_key[0]), loop_key.length, &loop_key_len)) {
387 			return -1;
388 		}
389 
390 		const (char)* key = void;
391 		size_t key_len = void;
392 		jansson_d.jansson.json_t* value = void;
393 		int res = 0;
394 
395 		//jansson_d.jansson.json_object_keylen_foreach(other, key, key_len, value)
396 		for (key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter(other)), key_len = jansson_d.value.json_object_iter_key_len(jansson_d.value.json_object_key_to_iter(key)); (key != null) && ((value = jansson_d.value.json_object_iter_value(jansson_d.value.json_object_key_to_iter(key))) != null); key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter_next(other, jansson_d.value.json_object_key_to_iter(key))), key_len = jansson_d.value.json_object_iter_key_len(jansson_d.value.json_object_key_to_iter(key))) {
397 			jansson_d.jansson.json_t* v = .json_object_get(object, key);
398 
399 			if ((mixin (jansson_d.jansson.json_is_object!("v"))) && (mixin (jansson_d.jansson.json_is_object!("value")))) {
400 				if (.do_object_update_recursive(v, value, parents)) {
401 					res = -1;
402 
403 					break;
404 				}
405 			} else {
406 				if (jansson_d.jansson.json_object_setn_nocheck(object, key, key_len, value)) {
407 					res = -1;
408 
409 					break;
410 				}
411 			}
412 		}
413 
414 		jansson_d.hashtable.hashtable_del(parents, &(loop_key[0]), loop_key_len);
415 
416 		return res;
417 	}
418 
419 ///
420 extern (C)
421 nothrow @trusted @nogc
422 public int json_object_update_recursive(scope jansson_d.jansson.json_t* object, scope jansson_d.jansson.json_t* other)
423 
424 	do
425 	{
426 		jansson_d.hashtable.hashtable_t parents_set = void;
427 
428 		if (jansson_d.hashtable.hashtable_init(&parents_set)) {
429 			return -1;
430 		}
431 
432 		int res = .do_object_update_recursive(object, other, &parents_set);
433 		jansson_d.hashtable.hashtable_close(&parents_set);
434 
435 		return res;
436 	}
437 
438 ///
439 extern (C)
440 pure nothrow @trusted @nogc @live
441 public void* json_object_iter(scope jansson_d.jansson.json_t* json)
442 
443 	do
444 	{
445 		if (!mixin (jansson_d.jansson.json_is_object!("json"))) {
446 			return null;
447 		}
448 
449 		jansson_d.jansson_private.json_object_t* object = mixin (jansson_d.jansson_private.json_to_object!("json"));
450 
451 		return jansson_d.hashtable.hashtable_iter(&object.hashtable);
452 	}
453 
454 ///
455 extern (C)
456 nothrow @trusted @nogc @live
457 public void* json_object_iter_at(scope jansson_d.jansson.json_t* json, scope const char* key)
458 
459 	do
460 	{
461 		if ((key == null) || (!mixin (jansson_d.jansson.json_is_object!("json")))) {
462 			return null;
463 		}
464 
465 		jansson_d.jansson_private.json_object_t* object = mixin (jansson_d.jansson_private.json_to_object!("json"));
466 
467 		return jansson_d.hashtable.hashtable_iter_at(&object.hashtable, key, core.stdc..string.strlen(key));
468 	}
469 
470 ///
471 extern (C)
472 pure nothrow @trusted @nogc @live
473 public void* json_object_iter_next(scope jansson_d.jansson.json_t* json, scope void* iter)
474 
475 	do
476 	{
477 		if ((!mixin (jansson_d.jansson.json_is_object!("json"))) || (iter == null)) {
478 			return null;
479 		}
480 
481 		jansson_d.jansson_private.json_object_t* object = mixin (jansson_d.jansson_private.json_to_object!("json"));
482 
483 		return jansson_d.hashtable.hashtable_iter_next(&object.hashtable, iter);
484 	}
485 
486 ///
487 extern (C)
488 pure nothrow @trusted @nogc @live
489 public const (char)* json_object_iter_key(scope void* iter)
490 
491 	do
492 	{
493 		if (iter == null) {
494 			return null;
495 		}
496 
497 		return cast(const (char)*)(jansson_d.hashtable.hashtable_iter_key(iter));
498 	}
499 
500 ///
501 extern (C)
502 pure nothrow @trusted @nogc @live
503 public size_t json_object_iter_key_len(scope void* iter)
504 
505 	do
506 	{
507 		if (iter == null) {
508 			return 0;
509 		}
510 
511 		return jansson_d.hashtable.hashtable_iter_key_len(iter);
512 	}
513 
514 ///
515 extern (C)
516 pure nothrow @trusted @nogc @live
517 public jansson_d.jansson.json_t* json_object_iter_value(scope void* iter)
518 
519 	do
520 	{
521 		if (iter == null) {
522 			return null;
523 		}
524 
525 		return cast(jansson_d.jansson.json_t*)(jansson_d.hashtable.hashtable_iter_value(iter));
526 	}
527 
528 ///
529 extern (C)
530 nothrow @trusted @nogc
531 public int json_object_iter_set_new(scope jansson_d.jansson.json_t* json, scope void* iter, scope jansson_d.jansson.json_t* value)
532 
533 	do
534 	{
535 		if ((!mixin (jansson_d.jansson.json_is_object!("json"))) || (iter == null) || (value == null)) {
536 			jansson_d.jansson.json_decref(value);
537 
538 			return -1;
539 		}
540 
541 		jansson_d.hashtable.hashtable_iter_set(iter, value);
542 
543 		return 0;
544 	}
545 
546 ///
547 extern (C)
548 pure nothrow @trusted @nogc @live
549 public void* json_object_key_to_iter(scope const char* key)
550 
551 	do
552 	{
553 		if (key == null) {
554 			return null;
555 		}
556 
557 		return mixin (jansson_d.hashtable.hashtable_key_to_iter!("key"));
558 	}
559 
560 nothrow @trusted @nogc @live
561 private int json_object_equal(scope const jansson_d.jansson.json_t* object1, scope const jansson_d.jansson.json_t* object2)
562 
563 	do
564 	{
565 		if (.json_object_size(object1) != .json_object_size(object2)) {
566 			return 0;
567 		}
568 
569 		const (char)* key = void;
570 		const (jansson_d.jansson.json_t)* value1 = void;
571 		const (jansson_d.jansson.json_t)* value2 = void;
572 
573 		//jansson_d.jansson.json_object_foreach(cast(jansson_d.jansson.json_t*)(object1), key, value1)
574 		for (key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter(cast(jansson_d.jansson.json_t*)(object1))); (key != null) && ((value1 = jansson_d.value.json_object_iter_value(jansson_d.value.json_object_key_to_iter(key))) != null); key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter_next(cast(jansson_d.jansson.json_t*)(object1), jansson_d.value.json_object_key_to_iter(key)))) {
575 			value2 = .json_object_get(object2, key);
576 
577 			if (!.json_equal(value1, value2)) {
578 				return 0;
579 			}
580 		}
581 
582 		return 1;
583 	}
584 
585 nothrow @trusted @nogc
586 private jansson_d.jansson.json_t* json_object_copy(scope jansson_d.jansson.json_t* object)
587 
588 	do
589 	{
590 		jansson_d.jansson.json_t* result = .json_object();
591 
592 		if (result == null) {
593 			return null;
594 		}
595 
596 		const (char)* key = void;
597 		jansson_d.jansson.json_t* value = void;
598 
599 		//jansson_d.jansson.json_object_foreach(object, key, value)
600 		for (key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter(object)); (key != null) && ((value = jansson_d.value.json_object_iter_value(jansson_d.value.json_object_key_to_iter(key))) != null); key = jansson_d.value.json_object_iter_key(jansson_d.value.json_object_iter_next(object, jansson_d.value.json_object_key_to_iter(key)))) {
601 			jansson_d.jansson.json_object_set_nocheck(result, key, value);
602 		}
603 
604 		return result;
605 	}
606 
607 nothrow @trusted @nogc
608 private jansson_d.jansson.json_t* json_object_deep_copy(scope const jansson_d.jansson.json_t* object, scope jansson_d.hashtable.hashtable_t* parents)
609 
610 	do
611 	{
612 		char[jansson_d.jansson_private.LOOP_KEY_LEN] loop_key = void;
613 		size_t loop_key_len = void;
614 		void* iter = void;
615 
616 		if (.jsonp_loop_check(parents, object, &(loop_key[0]), loop_key.length, &loop_key_len)) {
617 			return null;
618 		}
619 
620 		jansson_d.jansson.json_t* result = .json_object();
621 
622 		if (result == null) {
623 			goto out_;
624 		}
625 
626 		/*
627 		 * Cannot use jansson_d.jansson.json_object_foreach because object has to be cast
628 		 * non-const
629 		 */
630 		iter = .json_object_iter(cast(jansson_d.jansson.json_t*)(object));
631 
632 		while (iter != null) {
633 			const char* key = .json_object_iter_key(iter);
634 			const jansson_d.jansson.json_t* value = .json_object_iter_value(iter);
635 
636 			if (.json_object_set_new_nocheck(result, key, .do_deep_copy(value, parents))) {
637 				jansson_d.jansson.json_decref(result);
638 				result = null;
639 
640 				break;
641 			}
642 
643 			iter = .json_object_iter_next(cast(jansson_d.jansson.json_t*)(object), iter);
644 		}
645 
646 	out_:
647 		jansson_d.hashtable.hashtable_del(parents, &(loop_key[0]), loop_key_len);
648 
649 		return result;
650 	}
651 
652 /* array */
653 
654 ///
655 extern (C)
656 nothrow @trusted @nogc
657 public jansson_d.jansson.json_t* json_array()
658 
659 	do
660 	{
661 		jansson_d.jansson_private.json_array_t* array = cast(jansson_d.jansson_private.json_array_t*)(jansson_d.jansson_private.jsonp_malloc(jansson_d.jansson_private.json_array_t.sizeof));
662 
663 		if (array == null) {
664 			return null;
665 		}
666 
667 		.json_init(&array.json, jansson_d.jansson.json_type.JSON_ARRAY);
668 
669 		array.entries = 0;
670 		array.size = 8;
671 
672 		array.table = cast(jansson_d.jansson.json_t**)(jansson_d.jansson_private.jsonp_malloc(array.size * (jansson_d.jansson.json_t*).sizeof));
673 
674 		if (array.table == null) {
675 			jansson_d.jansson_private.jsonp_free(array);
676 
677 			return null;
678 		}
679 
680 		return &array.json;
681 	}
682 
683 nothrow @trusted @nogc
684 private void json_delete_array(scope jansson_d.jansson_private.json_array_t* array)
685 
686 	in
687 	{
688 		assert(array != null);
689 	}
690 
691 	do
692 	{
693 		for (size_t i = 0; i < array.entries; i++) {
694 			jansson_d.jansson.json_decref(array.table[i]);
695 		}
696 
697 		jansson_d.jansson_private.jsonp_free(array.table);
698 		array.table = null;
699 		jansson_d.jansson_private.jsonp_free(array);
700 	}
701 
702 ///
703 extern (C)
704 pure nothrow @trusted @nogc @live
705 public size_t json_array_size(scope const jansson_d.jansson.json_t* json)
706 
707 	do
708 	{
709 		if (!mixin (jansson_d.jansson.json_is_array!("json"))) {
710 			return 0;
711 		}
712 
713 		return (mixin (jansson_d.jansson_private.json_to_array!("json"))).entries;
714 	}
715 
716 ///
717 extern (C)
718 pure nothrow @trusted @nogc @live
719 public jansson_d.jansson.json_t* json_array_get(scope const jansson_d.jansson.json_t* json, size_t index)
720 
721 	do
722 	{
723 		if (!mixin (jansson_d.jansson.json_is_array!("json"))) {
724 			return null;
725 		}
726 
727 		jansson_d.jansson_private.json_array_t* array = mixin (jansson_d.jansson_private.json_to_array!("json"));
728 
729 		if (index >= array.entries) {
730 			return null;
731 		}
732 
733 		return array.table[index];
734 	}
735 
736 ///
737 extern (C)
738 nothrow @trusted @nogc
739 public int json_array_set_new(scope jansson_d.jansson.json_t* json, size_t index, scope jansson_d.jansson.json_t* value)
740 
741 	do
742 	{
743 		if (value == null) {
744 			return -1;
745 		}
746 
747 		if ((!mixin (jansson_d.jansson.json_is_array!("json"))) || (json == value)) {
748 			jansson_d.jansson.json_decref(value);
749 
750 			return -1;
751 		}
752 
753 		jansson_d.jansson_private.json_array_t* array = mixin (jansson_d.jansson_private.json_to_array!("json"));
754 
755 		if (index >= array.entries) {
756 			jansson_d.jansson.json_decref(value);
757 
758 			return -1;
759 		}
760 
761 		jansson_d.jansson.json_decref(array.table[index]);
762 		array.table[index] = value;
763 
764 		return 0;
765 	}
766 
767 pure nothrow @trusted @nogc @live
768 private void array_move(scope jansson_d.jansson_private.json_array_t* array, size_t dest, size_t src, size_t count)
769 
770 	in
771 	{
772 		assert(array != null);
773 	}
774 
775 	do
776 	{
777 		core.stdc..string.memmove(&array.table[dest], &array.table[src], count * (jansson_d.jansson.json_t*).sizeof);
778 	}
779 
780 pure nothrow @trusted @nogc @live
781 private void array_copy(scope jansson_d.jansson.json_t** dest, size_t dpos, scope jansson_d.jansson.json_t** src, size_t spos, size_t count)
782 
783 	in
784 	{
785 		assert(dest != null);
786 		assert(src != null);
787 	}
788 
789 	do
790 	{
791 		core.stdc..string.memcpy(&dest[dpos], &src[spos], count * (jansson_d.jansson.json_t*).sizeof);
792 	}
793 
794 nothrow @trusted @nogc
795 private jansson_d.jansson.json_t** json_array_grow(scope jansson_d.jansson_private.json_array_t* array, size_t amount, int copy)
796 
797 	in
798 	{
799 		assert(array != null);
800 	}
801 
802 	do
803 	{
804 		if ((array.entries + amount) <= array.size) {
805 			return array.table;
806 		}
807 
808 		jansson_d.jansson.json_t** old_table = array.table;
809 
810 		size_t new_size = mixin (jansson_d.jansson_private.max!("array.size + amount", "array.size * 2"));
811 		jansson_d.jansson.json_t** new_table = cast(jansson_d.jansson.json_t**)(jansson_d.jansson_private.jsonp_malloc(new_size * (jansson_d.jansson.json_t*).sizeof));
812 
813 		if (new_table == null) {
814 			return null;
815 		}
816 
817 		array.size = new_size;
818 		array.table = new_table;
819 
820 		if (copy) {
821 			.array_copy(array.table, 0, old_table, 0, array.entries);
822 			jansson_d.jansson_private.jsonp_free(old_table);
823 
824 			return array.table;
825 		}
826 
827 		return old_table;
828 	}
829 
830 ///
831 extern (C)
832 nothrow @trusted @nogc
833 public int json_array_append_new(scope jansson_d.jansson.json_t* json, scope jansson_d.jansson.json_t* value)
834 
835 	do
836 	{
837 		if (value == null) {
838 			return -1;
839 		}
840 
841 		if ((!mixin (jansson_d.jansson.json_is_array!("json"))) || (json == value)) {
842 			jansson_d.jansson.json_decref(value);
843 
844 			return -1;
845 		}
846 
847 		jansson_d.jansson_private.json_array_t* array = mixin (jansson_d.jansson_private.json_to_array!("json"));
848 
849 		if (!.json_array_grow(array, 1, 1)) {
850 			jansson_d.jansson.json_decref(value);
851 
852 			return -1;
853 		}
854 
855 		array.table[array.entries] = value;
856 		array.entries++;
857 
858 		return 0;
859 	}
860 
861 ///
862 extern (C)
863 nothrow @trusted @nogc
864 public int json_array_insert_new(scope jansson_d.jansson.json_t* json, size_t index, scope jansson_d.jansson.json_t* value)
865 
866 	do
867 	{
868 		if (value == null) {
869 			return -1;
870 		}
871 
872 		if ((!mixin (jansson_d.jansson.json_is_array!("json"))) || (json == value)) {
873 			jansson_d.jansson.json_decref(value);
874 
875 			return -1;
876 		}
877 
878 		jansson_d.jansson_private.json_array_t* array = mixin (jansson_d.jansson_private.json_to_array!("json"));
879 
880 		if (index > array.entries) {
881 			jansson_d.jansson.json_decref(value);
882 
883 			return -1;
884 		}
885 
886 		jansson_d.jansson.json_t** old_table = .json_array_grow(array, 1, 0);
887 
888 		if (old_table == null) {
889 			jansson_d.jansson.json_decref(value);
890 
891 			return -1;
892 		}
893 
894 		if (old_table != array.table) {
895 			.array_copy(array.table, 0, old_table, 0, index);
896 			.array_copy(array.table, index + 1, old_table, index, array.entries - index);
897 			jansson_d.jansson_private.jsonp_free(old_table);
898 		} else {
899 			.array_move(array, index + 1, index, array.entries - index);
900 		}
901 
902 		array.table[index] = value;
903 		array.entries++;
904 
905 		return 0;
906 	}
907 
908 ///
909 extern (C)
910 nothrow @trusted @nogc
911 public int json_array_remove(scope jansson_d.jansson.json_t* json, size_t index)
912 
913 	do
914 	{
915 		if (!mixin (jansson_d.jansson.json_is_array!("json"))) {
916 			return -1;
917 		}
918 
919 		jansson_d.jansson_private.json_array_t* array = mixin (jansson_d.jansson_private.json_to_array!("json"));
920 
921 		if (index >= array.entries) {
922 			return -1;
923 		}
924 
925 		jansson_d.jansson.json_decref(array.table[index]);
926 
927 		/* If we're removing the last element, nothing has to be moved */
928 		if (index < (array.entries - 1)) {
929 			.array_move(array, index, index + 1, array.entries - index - 1);
930 		}
931 
932 		array.entries--;
933 
934 		return 0;
935 	}
936 
937 ///
938 extern (C)
939 nothrow @trusted @nogc
940 public int json_array_clear(scope jansson_d.jansson.json_t* json)
941 
942 	do
943 	{
944 		if (!mixin (jansson_d.jansson.json_is_array!("json"))) {
945 			return -1;
946 		}
947 
948 		jansson_d.jansson_private.json_array_t* array = mixin (jansson_d.jansson_private.json_to_array!("json"));
949 
950 		for (size_t i = 0; i < array.entries; i++) {
951 			jansson_d.jansson.json_decref(array.table[i]);
952 		}
953 
954 		array.entries = 0;
955 
956 		return 0;
957 	}
958 
959 ///
960 extern (C)
961 nothrow @trusted @nogc
962 public int json_array_extend(scope jansson_d.jansson.json_t* json, scope jansson_d.jansson.json_t* other_json)
963 
964 	do
965 	{
966 		if ((!mixin (jansson_d.jansson.json_is_array!("json"))) || (!mixin (jansson_d.jansson.json_is_array!("other_json")))) {
967 			return -1;
968 		}
969 
970 		jansson_d.jansson_private.json_array_t* array = mixin (jansson_d.jansson_private.json_to_array!("json"));
971 		jansson_d.jansson_private.json_array_t* other = mixin (jansson_d.jansson_private.json_to_array!("other_json"));
972 
973 		if (!.json_array_grow(array, other.entries, 1)) {
974 			return -1;
975 		}
976 
977 		for (size_t i = 0; i < other.entries; i++) {
978 			jansson_d.jansson.json_incref(other.table[i]);
979 		}
980 
981 		.array_copy(array.table, array.entries, other.table, 0, other.entries);
982 
983 		array.entries += other.entries;
984 
985 		return 0;
986 	}
987 
988 nothrow @trusted @nogc @live
989 private int json_array_equal(scope const jansson_d.jansson.json_t* array1, scope const jansson_d.jansson.json_t* array2)
990 
991 	do
992 	{
993 		size_t size = .json_array_size(array1);
994 
995 		if (size != .json_array_size(array2)) {
996 			return 0;
997 		}
998 
999 		for (size_t i = 0; i < size; i++) {
1000 			jansson_d.jansson.json_t* value1 = .json_array_get(array1, i);
1001 			jansson_d.jansson.json_t* value2 = .json_array_get(array2, i);
1002 
1003 			if (!.json_equal(value1, value2)) {
1004 				return 0;
1005 			}
1006 		}
1007 
1008 		return 1;
1009 	}
1010 
1011 nothrow @trusted @nogc
1012 private jansson_d.jansson.json_t* json_array_copy(scope jansson_d.jansson.json_t* array)
1013 
1014 	do
1015 	{
1016 		jansson_d.jansson.json_t* result = .json_array();
1017 
1018 		if (result == null) {
1019 			return null;
1020 		}
1021 
1022 		for (size_t i = 0; i < .json_array_size(array); i++) {
1023 			jansson_d.jansson.json_array_append(result, .json_array_get(array, i));
1024 		}
1025 
1026 		return result;
1027 	}
1028 
1029 nothrow @trusted @nogc
1030 private jansson_d.jansson.json_t* json_array_deep_copy(scope const jansson_d.jansson.json_t* array, scope jansson_d.hashtable.hashtable_t* parents)
1031 
1032 	do
1033 	{
1034 		char[jansson_d.jansson_private.LOOP_KEY_LEN] loop_key = void;
1035 		size_t loop_key_len = void;
1036 
1037 		if (.jsonp_loop_check(parents, array, &(loop_key[0]), loop_key.length, &loop_key_len)) {
1038 			return null;
1039 		}
1040 
1041 		jansson_d.jansson.json_t* result = .json_array();
1042 
1043 		if (result == null) {
1044 			goto out_;
1045 		}
1046 
1047 		for (size_t i = 0; i < .json_array_size(array); i++) {
1048 			if (.json_array_append_new(result, .do_deep_copy(.json_array_get(array, i), parents))) {
1049 				jansson_d.jansson.json_decref(result);
1050 				result = null;
1051 
1052 				break;
1053 			}
1054 		}
1055 
1056 	out_:
1057 		jansson_d.hashtable.hashtable_del(parents, &(loop_key[0]), loop_key_len);
1058 
1059 		return result;
1060 	}
1061 
1062 /* string */
1063 
1064 nothrow @trusted @nogc
1065 private jansson_d.jansson.json_t* string_create(scope const char* value, size_t len, int own)
1066 
1067 	do
1068 	{
1069 		if (value == null) {
1070 			return null;
1071 		}
1072 
1073 		char* v = void;
1074 
1075 		if (own) {
1076 			v = cast(char*)(value);
1077 		} else {
1078 			v = jansson_d.jansson_private.jsonp_strndup(value, len);
1079 
1080 			if (v == null) {
1081 				return null;
1082 			}
1083 		}
1084 
1085 		jansson_d.jansson_private.json_string_t* string_ = cast(jansson_d.jansson_private.json_string_t*)(jansson_d.jansson_private.jsonp_malloc(jansson_d.jansson_private.json_string_t.sizeof));
1086 
1087 		if (string_ == null) {
1088 			jansson_d.jansson_private.jsonp_free(v);
1089 
1090 			return null;
1091 		}
1092 
1093 		.json_init(&string_.json, jansson_d.jansson.json_type.JSON_STRING);
1094 		string_.value = v;
1095 		string_.length_ = len;
1096 
1097 		return &string_.json;
1098 	}
1099 
1100 ///
1101 extern (C)
1102 nothrow @trusted @nogc
1103 public jansson_d.jansson.json_t* json_string_nocheck(scope const char* value)
1104 
1105 	do
1106 	{
1107 		if (value == null) {
1108 			return null;
1109 		}
1110 
1111 		return .string_create(value, core.stdc..string.strlen(value), 0);
1112 	}
1113 
1114 ///
1115 extern (C)
1116 nothrow @trusted @nogc
1117 public jansson_d.jansson.json_t* json_stringn_nocheck(scope const char* value, size_t len)
1118 
1119 	do
1120 	{
1121 		return .string_create(value, len, 0);
1122 	}
1123 
1124 /* this is private; "steal" is not a public API concept */
1125 nothrow @trusted @nogc
1126 jansson_d.jansson.json_t* jsonp_stringn_nocheck_own(scope const char* value, size_t len)
1127 
1128 	do
1129 	{
1130 		return .string_create(value, len, 1);
1131 	}
1132 
1133 ///
1134 extern (C)
1135 nothrow @trusted @nogc
1136 public jansson_d.jansson.json_t* json_string(scope const char* value)
1137 
1138 	do
1139 	{
1140 		if (value == null) {
1141 			return null;
1142 		}
1143 
1144 		return .json_stringn(value, core.stdc..string.strlen(value));
1145 	}
1146 
1147 ///
1148 extern (C)
1149 nothrow @trusted @nogc
1150 public jansson_d.jansson.json_t* json_stringn(scope const char* value, size_t len)
1151 
1152 	do
1153 	{
1154 		if ((value == null) || (!jansson_d.utf.utf8_check_string(value, len))) {
1155 			return null;
1156 		}
1157 
1158 		return .json_stringn_nocheck(value, len);
1159 	}
1160 
1161 ///
1162 extern (C)
1163 pure nothrow @trusted @nogc @live
1164 public const (char)* json_string_value(scope const jansson_d.jansson.json_t* json)
1165 
1166 	do
1167 	{
1168 		if (!mixin (jansson_d.jansson.json_is_string!("json"))) {
1169 			return null;
1170 		}
1171 
1172 		return (mixin (jansson_d.jansson_private.json_to_string!("json"))).value;
1173 	}
1174 
1175 ///
1176 extern (C)
1177 pure nothrow @trusted @nogc @live
1178 public size_t json_string_length(scope const jansson_d.jansson.json_t* json)
1179 
1180 	do
1181 	{
1182 		if (!mixin (jansson_d.jansson.json_is_string!("json"))) {
1183 			return 0;
1184 		}
1185 
1186 		return (mixin (jansson_d.jansson_private.json_to_string!("json"))).length_;
1187 	}
1188 
1189 ///
1190 extern (C)
1191 nothrow @trusted @nogc @live
1192 public int json_string_set_nocheck(scope jansson_d.jansson.json_t* json, scope const char* value)
1193 
1194 	do
1195 	{
1196 		if (value == null) {
1197 			return -1;
1198 		}
1199 
1200 		return .json_string_setn_nocheck(json, value, core.stdc..string.strlen(value));
1201 	}
1202 
1203 ///
1204 extern (C)
1205 nothrow @trusted @nogc
1206 public int json_string_setn_nocheck(scope jansson_d.jansson.json_t* json, scope const char* value, size_t len)
1207 
1208 	do
1209 	{
1210 		if ((!mixin (jansson_d.jansson.json_is_string!("json"))) || (value == null)) {
1211 			return -1;
1212 		}
1213 
1214 		char* dup = jansson_d.jansson_private.jsonp_strndup(value, len);
1215 
1216 		if (dup == null) {
1217 			return -1;
1218 		}
1219 
1220 		jansson_d.jansson_private.json_string_t* string_ = mixin (jansson_d.jansson_private.json_to_string!("json"));
1221 		jansson_d.jansson_private.jsonp_free(string_.value);
1222 		string_.value = dup;
1223 		string_.length_ = len;
1224 
1225 		return 0;
1226 	}
1227 
1228 ///
1229 extern (C)
1230 nothrow @trusted @nogc
1231 public int json_string_set(scope jansson_d.jansson.json_t* json, scope const char* value)
1232 
1233 	do
1234 	{
1235 		if (value == null) {
1236 			return -1;
1237 		}
1238 
1239 		return .json_string_setn(json, value, core.stdc..string.strlen(value));
1240 	}
1241 
1242 ///
1243 extern (C)
1244 nothrow @trusted @nogc
1245 public int json_string_setn(scope jansson_d.jansson.json_t* json, scope const char* value, size_t len)
1246 
1247 	do
1248 	{
1249 		if ((value == null) || (!jansson_d.utf.utf8_check_string(value, len))) {
1250 			return -1;
1251 		}
1252 
1253 		return .json_string_setn_nocheck(json, value, len);
1254 	}
1255 
1256 nothrow @trusted @nogc
1257 private void json_delete_string(scope jansson_d.jansson_private.json_string_t* string_)
1258 
1259 	in
1260 	{
1261 		assert(string_ != null);
1262 	}
1263 
1264 	do
1265 	{
1266 		jansson_d.jansson_private.jsonp_free(string_.value);
1267 		string_.value = null;
1268 		jansson_d.jansson_private.jsonp_free(string_);
1269 	}
1270 
1271 pure nothrow @trusted @nogc @live
1272 private int json_string_equal(scope const jansson_d.jansson.json_t* string1, scope const jansson_d.jansson.json_t* string2)
1273 
1274 	in
1275 	{
1276 		assert(string1 != null);
1277 		assert(string2 != null);
1278 	}
1279 
1280 	do
1281 	{
1282 		jansson_d.jansson_private.json_string_t* s1 = mixin (jansson_d.jansson_private.json_to_string!("string1"));
1283 		jansson_d.jansson_private.json_string_t* s2 = mixin (jansson_d.jansson_private.json_to_string!("string2"));
1284 
1285 		return (s1.length_ == s2.length_) && (core.stdc..string.memcmp(s1.value, s2.value, s1.length_) == 0);
1286 	}
1287 
1288 nothrow @trusted @nogc
1289 private jansson_d.jansson.json_t* json_string_copy(scope const jansson_d.jansson.json_t* string_)
1290 
1291 	in
1292 	{
1293 		assert(string_ != null);
1294 	}
1295 
1296 	do
1297 	{
1298 		jansson_d.jansson_private.json_string_t* s = mixin (jansson_d.jansson_private.json_to_string!("string_"));
1299 
1300 		return .json_stringn_nocheck(s.value, s.length_);
1301 	}
1302 
1303 ///
1304 //JANSSON_ATTRS((warn_unused_result, format(printf, 1, 0)))
1305 extern (C)
1306 nothrow @nogc //ToDo: @nodiscard
1307 public jansson_d.jansson.json_t* json_vsprintf(scope const char* fmt, core.stdc.stdarg.va_list ap)
1308 
1309 	do
1310 	{
1311 		char* buf = void;
1312 		jansson_d.jansson.json_t* json = null;
1313 		core.stdc.stdarg.va_list aq;
1314 		jansson_d.jansson_private.va_copy(aq, ap);
1315 
1316 		int length_ = jansson_d.jansson_private.vsnprintf(null, 0, fmt, ap);
1317 
1318 		if (length_ < 0) {
1319 			goto out_;
1320 		}
1321 
1322 		if (length_ == 0) {
1323 			json = .json_string("\0");
1324 
1325 			goto out_;
1326 		}
1327 
1328 		buf = cast(char*)(jansson_d.jansson_private.jsonp_malloc(cast(size_t)(length_) + 1));
1329 
1330 		if (buf == null) {
1331 			goto out_;
1332 		}
1333 
1334 		jansson_d.jansson_private.vsnprintf(buf, cast(size_t)(length_) + 1, fmt, aq);
1335 
1336 		if (!jansson_d.utf.utf8_check_string(buf, length_)) {
1337 			jansson_d.jansson_private.jsonp_free(buf);
1338 
1339 			goto out_;
1340 		}
1341 
1342 		json = .jsonp_stringn_nocheck_own(buf, length_);
1343 
1344 	out_:
1345 		core.stdc.stdarg.va_end(aq);
1346 
1347 		return json;
1348 	}
1349 
1350 ///
1351 //JANSSON_ATTRS((warn_unused_result, format(printf, 1, 2)))
1352 extern (C)
1353 nothrow @nogc //ToDo: @nodiscard
1354 public jansson_d.jansson.json_t* json_sprintf(scope const char* fmt, ...)
1355 
1356 	do
1357 	{
1358 		core.stdc.stdarg.va_list ap;
1359 
1360 		core.stdc.stdarg.va_start(ap, fmt);
1361 		jansson_d.jansson.json_t* result = .json_vsprintf(fmt, ap);
1362 		core.stdc.stdarg.va_end(ap);
1363 
1364 		return result;
1365 	}
1366 
1367 /* integer */
1368 
1369 ///
1370 extern (C)
1371 nothrow @trusted @nogc
1372 public jansson_d.jansson.json_t* json_integer(jansson_d.jansson.json_int_t value)
1373 
1374 	do
1375 	{
1376 		jansson_d.jansson_private.json_integer_t* integer = cast(jansson_d.jansson_private.json_integer_t*)(jansson_d.jansson_private.jsonp_malloc(jansson_d.jansson_private.json_integer_t.sizeof));
1377 
1378 		if (integer == null) {
1379 			return null;
1380 		}
1381 
1382 		.json_init(&integer.json, jansson_d.jansson.json_type.JSON_INTEGER);
1383 
1384 		integer.value = value;
1385 
1386 		return &integer.json;
1387 	}
1388 
1389 ///
1390 extern (C)
1391 pure nothrow @trusted @nogc @live
1392 public jansson_d.jansson.json_int_t json_integer_value(scope const jansson_d.jansson.json_t* json)
1393 
1394 	do
1395 	{
1396 		if (!mixin (jansson_d.jansson.json_is_integer!("json"))) {
1397 			return 0;
1398 		}
1399 
1400 		return (mixin (jansson_d.jansson_private.json_to_integer!("json"))).value;
1401 	}
1402 
1403 ///
1404 extern (C)
1405 pure nothrow @trusted @nogc @live
1406 public int json_integer_set(scope jansson_d.jansson.json_t* json, jansson_d.jansson.json_int_t value)
1407 
1408 	do
1409 	{
1410 		if (!mixin (jansson_d.jansson.json_is_integer!("json"))) {
1411 			return -1;
1412 		}
1413 
1414 		(mixin (jansson_d.jansson_private.json_to_integer!("json"))).value = value;
1415 
1416 		return 0;
1417 	}
1418 
1419 nothrow @trusted @nogc
1420 private void json_delete_integer(scope jansson_d.jansson_private.json_integer_t* integer)
1421 
1422 	do
1423 	{
1424 		jansson_d.jansson_private.jsonp_free(integer);
1425 	}
1426 
1427 pure nothrow @trusted @nogc @live
1428 private int json_integer_equal(scope const jansson_d.jansson.json_t* integer1, scope const jansson_d.jansson.json_t* integer2)
1429 
1430 	do
1431 	{
1432 		return .json_integer_value(integer1) == .json_integer_value(integer2);
1433 	}
1434 
1435 nothrow @trusted @nogc @live
1436 private jansson_d.jansson.json_t* json_integer_copy(scope const jansson_d.jansson.json_t* integer)
1437 
1438 	do
1439 	{
1440 		return .json_integer(.json_integer_value(integer));
1441 	}
1442 
1443 /* real */
1444 
1445 ///
1446 extern (C)
1447 nothrow @trusted @nogc
1448 public jansson_d.jansson.json_t* json_real(double value)
1449 
1450 	do
1451 	{
1452 		if ((.isnan(value)) || (.isinf(value))) {
1453 			return null;
1454 		}
1455 
1456 		jansson_d.jansson_private.json_real_t* real_ = cast(jansson_d.jansson_private.json_real_t*)(jansson_d.jansson_private.jsonp_malloc(jansson_d.jansson_private.json_real_t.sizeof));
1457 
1458 		if (real_ == null) {
1459 			return null;
1460 		}
1461 
1462 		.json_init(&real_.json, jansson_d.jansson.json_type.JSON_REAL);
1463 
1464 		real_.value = value;
1465 
1466 		return &real_.json;
1467 	}
1468 
1469 ///
1470 extern (C)
1471 pure nothrow @trusted @nogc @live
1472 public double json_real_value(scope const jansson_d.jansson.json_t* json)
1473 
1474 	do
1475 	{
1476 		if (!mixin (jansson_d.jansson.json_is_real!("json"))) {
1477 			return 0;
1478 		}
1479 
1480 		return (mixin (jansson_d.jansson_private.json_to_real!("json"))).value;
1481 	}
1482 
1483 ///
1484 extern (C)
1485 pure nothrow @trusted @nogc @live
1486 public int json_real_set(scope jansson_d.jansson.json_t* json, double value)
1487 
1488 	do
1489 	{
1490 		if ((!mixin (jansson_d.jansson.json_is_real!("json"))) || (.isnan(value)) || (.isinf(value))) {
1491 			return -1;
1492 		}
1493 
1494 		(mixin (jansson_d.jansson_private.json_to_real!("json"))).value = value;
1495 
1496 		return 0;
1497 	}
1498 
1499 nothrow @trusted @nogc
1500 private void json_delete_real(scope jansson_d.jansson_private.json_real_t* real_)
1501 
1502 	do
1503 	{
1504 		jansson_d.jansson_private.jsonp_free(real_);
1505 	}
1506 
1507 pure nothrow @trusted @nogc @live
1508 private int json_real_equal(scope const jansson_d.jansson.json_t* real1, scope const jansson_d.jansson.json_t* real2)
1509 
1510 	do
1511 	{
1512 		return .json_real_value(real1) == .json_real_value(real2);
1513 	}
1514 
1515 nothrow @trusted @nogc
1516 private jansson_d.jansson.json_t* json_real_copy(scope const jansson_d.jansson.json_t* real_)
1517 
1518 	do
1519 	{
1520 		return .json_real(.json_real_value(real_));
1521 	}
1522 
1523 /* number */
1524 
1525 ///
1526 extern (C)
1527 pure nothrow @trusted @nogc @live
1528 public double json_number_value(scope const jansson_d.jansson.json_t* json)
1529 
1530 	do
1531 	{
1532 		if (mixin (jansson_d.jansson.json_is_integer!("json"))) {
1533 			return cast(double)(.json_integer_value(json));
1534 		} else if (mixin (jansson_d.jansson.json_is_real!("json"))) {
1535 			return .json_real_value(json);
1536 		} else {
1537 			return 0.0;
1538 		}
1539 	}
1540 
1541 /* simple values */
1542 
1543 ///
1544 extern (C)
1545 nothrow @trusted @nogc @live
1546 public jansson_d.jansson.json_t* json_true()
1547 
1548 	do
1549 	{
1550 		static jansson_d.jansson.json_t the_true = {jansson_d.jansson.json_type.JSON_TRUE, size_t.max};
1551 
1552 		return &the_true;
1553 	}
1554 
1555 ///
1556 extern (C)
1557 nothrow @trusted @nogc @live
1558 public jansson_d.jansson.json_t* json_false()
1559 
1560 	do
1561 	{
1562 		static jansson_d.jansson.json_t the_false = {jansson_d.jansson.json_type.JSON_FALSE, size_t.max};
1563 
1564 		return &the_false;
1565 	}
1566 
1567 ///
1568 extern (C)
1569 nothrow @trusted @nogc @live
1570 public jansson_d.jansson.json_t* json_null()
1571 
1572 	do
1573 	{
1574 		static jansson_d.jansson.json_t the_null = {jansson_d.jansson.json_type.JSON_NULL, size_t.max};
1575 
1576 		return &the_null;
1577 	}
1578 
1579 /* deletion */
1580 
1581 ///
1582 extern (C)
1583 nothrow @trusted @nogc
1584 public void json_delete(scope jansson_d.jansson.json_t* json)
1585 
1586 	do
1587 	{
1588 		if (json == null) {
1589 			return;
1590 		}
1591 
1592 		switch (mixin (jansson_d.jansson.json_typeof!("json"))) {
1593 			case jansson_d.jansson.json_type.JSON_OBJECT:
1594 				.json_delete_object(mixin (jansson_d.jansson_private.json_to_object!("json")));
1595 
1596 				break;
1597 
1598 			case jansson_d.jansson.json_type.JSON_ARRAY:
1599 				.json_delete_array(mixin (jansson_d.jansson_private.json_to_array!("json")));
1600 
1601 				break;
1602 
1603 			case jansson_d.jansson.json_type.JSON_STRING:
1604 				.json_delete_string(mixin (jansson_d.jansson_private.json_to_string!("json")));
1605 
1606 				break;
1607 
1608 			case jansson_d.jansson.json_type.JSON_INTEGER:
1609 				.json_delete_integer(mixin (jansson_d.jansson_private.json_to_integer!("json")));
1610 
1611 				break;
1612 
1613 			case jansson_d.jansson.json_type.JSON_REAL:
1614 				.json_delete_real(mixin (jansson_d.jansson_private.json_to_real!("json")));
1615 
1616 				break;
1617 
1618 			default:
1619 				return;
1620 		}
1621 
1622 		/* json_delete is not called for true, false or null */
1623 	}
1624 
1625 /* equality */
1626 
1627 ///
1628 extern (C)
1629 nothrow @trusted @nogc @live
1630 public int json_equal(scope const jansson_d.jansson.json_t* json1, scope const jansson_d.jansson.json_t* json2)
1631 
1632 	do
1633 	{
1634 		if ((json1 == null) || (json2 == null)) {
1635 			return 0;
1636 		}
1637 
1638 		if (mixin (jansson_d.jansson.json_typeof!("json1")) != mixin (jansson_d.jansson.json_typeof!("json2"))) {
1639 			return 0;
1640 		}
1641 
1642 		/* this covers true, false and null as they are singletons */
1643 		if (json1 == json2) {
1644 			return 1;
1645 		}
1646 
1647 		switch (mixin (jansson_d.jansson.json_typeof!("json1"))) {
1648 			case jansson_d.jansson.json_type.JSON_OBJECT:
1649 				return .json_object_equal(json1, json2);
1650 
1651 			case jansson_d.jansson.json_type.JSON_ARRAY:
1652 				return .json_array_equal(json1, json2);
1653 
1654 			case jansson_d.jansson.json_type.JSON_STRING:
1655 				return .json_string_equal(json1, json2);
1656 
1657 			case jansson_d.jansson.json_type.JSON_INTEGER:
1658 				return .json_integer_equal(json1, json2);
1659 
1660 			case jansson_d.jansson.json_type.JSON_REAL:
1661 				return .json_real_equal(json1, json2);
1662 
1663 			default:
1664 				return 0;
1665 		}
1666 	}
1667 
1668 /* copying */
1669 
1670 ///
1671 extern (C)
1672 nothrow @trusted @nogc //ToDo: @nodiscard
1673 public jansson_d.jansson.json_t* json_copy(scope jansson_d.jansson.json_t* json)
1674 
1675 	do
1676 	{
1677 		if (json == null) {
1678 			return null;
1679 		}
1680 
1681 		switch (mixin (jansson_d.jansson.json_typeof!("json"))) {
1682 			case jansson_d.jansson.json_type.JSON_OBJECT:
1683 				return .json_object_copy(json);
1684 
1685 			case jansson_d.jansson.json_type.JSON_ARRAY:
1686 				return .json_array_copy(json);
1687 
1688 			case jansson_d.jansson.json_type.JSON_STRING:
1689 				return .json_string_copy(json);
1690 
1691 			case jansson_d.jansson.json_type.JSON_INTEGER:
1692 				return .json_integer_copy(json);
1693 
1694 			case jansson_d.jansson.json_type.JSON_REAL:
1695 				return .json_real_copy(json);
1696 
1697 			case jansson_d.jansson.json_type.JSON_TRUE:
1698 			case jansson_d.jansson.json_type.JSON_FALSE:
1699 			case jansson_d.jansson.json_type.JSON_NULL:
1700 				return json;
1701 
1702 			default:
1703 				return null;
1704 		}
1705 	}
1706 
1707 ///
1708 extern (C)
1709 nothrow @trusted @nogc //ToDo: @nodiscard
1710 public jansson_d.jansson.json_t* json_deep_copy(scope const jansson_d.jansson.json_t* json)
1711 
1712 	do
1713 	{
1714 		jansson_d.hashtable.hashtable_t parents_set = void;
1715 
1716 		if (jansson_d.hashtable.hashtable_init(&parents_set)) {
1717 			return null;
1718 		}
1719 
1720 		jansson_d.jansson.json_t* res = .do_deep_copy(json, &parents_set);
1721 		jansson_d.hashtable.hashtable_close(&parents_set);
1722 
1723 		return res;
1724 	}
1725 
1726 nothrow @trusted @nogc
1727 jansson_d.jansson.json_t* do_deep_copy(scope const jansson_d.jansson.json_t* json, scope jansson_d.hashtable.hashtable_t* parents)
1728 
1729 	do
1730 	{
1731 		if (json == null) {
1732 			return null;
1733 		}
1734 
1735 		switch (mixin (jansson_d.jansson.json_typeof!("json"))) {
1736 			case jansson_d.jansson.json_type.JSON_OBJECT:
1737 				return .json_object_deep_copy(json, parents);
1738 
1739 			case jansson_d.jansson.json_type.JSON_ARRAY:
1740 				return .json_array_deep_copy(json, parents);
1741 
1742 			/*
1743 			 * for the rest of the types, deep copying doesn't differ from
1744 			 * shallow copying
1745 			 */
1746 			case jansson_d.jansson.json_type.JSON_STRING:
1747 				return .json_string_copy(json);
1748 
1749 			case jansson_d.jansson.json_type.JSON_INTEGER:
1750 				return .json_integer_copy(json);
1751 
1752 			case jansson_d.jansson.json_type.JSON_REAL:
1753 				return .json_real_copy(json);
1754 
1755 			case jansson_d.jansson.json_type.JSON_TRUE:
1756 			case jansson_d.jansson.json_type.JSON_FALSE:
1757 			case jansson_d.jansson.json_type.JSON_NULL:
1758 				return cast(jansson_d.jansson.json_t*)(json);
1759 
1760 			default:
1761 				return null;
1762 		}
1763 	}