Freeciv-3.3
Loading...
Searching...
No Matches
dataio_json.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#ifdef FREECIV_JSON_CONNECTION
19
20#include "fc_prehdrs.h"
21
22#include <curl/curl.h>
23
24#include <limits.h>
25#include <math.h>
26#include <stdint.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31#ifdef FREECIV_HAVE_SYS_TYPES_H
32#include <sys/types.h>
33#endif
34#ifdef HAVE_SYS_SOCKET_H
35#include <sys/socket.h>
36#endif
37#ifdef HAVE_NETINET_IN_H
38#include <netinet/in.h>
39#endif
40#ifdef HAVE_ARPA_INET_H
41#include <arpa/inet.h>
42#endif
43
44/* utility */
45#include "bitvector.h"
46#include "capability.h"
47#include "log.h"
48#include "mem.h"
49#include "support.h"
50
51/* common */
52#include "events.h"
53#include "player.h"
54#include "requirements.h"
55#include "tech.h"
56#include "worklist.h"
57
58/* common/aicore */
59#include "cm.h"
60
61#include "dataio.h"
62
64 const struct plocation *location,
65 bool *dest);
66
67/**********************************************************************/
70static CURL *get_curl(void)
71{
72 static CURL *curl_easy_handle = NULL;
73
74 if (curl_easy_handle == NULL) {
76 } else {
77 /* Reuse the existing CURL easy handle */
79 }
80
81 return curl_easy_handle;
82}
83
85 const struct plocation *location,
86 json_t *data);
87
88/**********************************************************************/
92 const struct plocation *location,
93 json_t *data)
94{
95 int e = -1;
96
97 if (location->sub_location == NULL) {
98 e = json_object_set_new(item, location->name, data);
99 } else {
101 location->sub_location, data);
102 }
103
104 return e;
105}
106
107/**********************************************************************/
111 const struct plocation *location,
112 json_t *data)
113{
114 int e = -1;
115
116 if (location->sub_location == NULL) {
117 if (location->number == -1) {
118 e = json_array_append_new(item, data);
119 } else {
120 e = json_array_set_new(item, location->number, data);
121 }
122 } else {
123 size_t n = (location->number == -1)
124 ? (json_array_size(item) - 1)
125 : location->number;
126
128 location->sub_location, data);
129 }
130
131 return e;
132}
133
134/**********************************************************************/
139 const struct plocation *location,
140 json_t *data)
141{
142 int e = -1;
143
144 switch (location->kind) {
145 case PADR_FIELD:
146 e = plocation_write_field(item, location, data);
147 break;
148 case PADR_ELEMENT:
149 e = plocation_write_elem(item, location, data);
150 break;
151 default:
152 log_error("Unknown packet part location kind.");
153 break;
154 }
155
156 return e;
157}
158
160 const struct plocation *location);
161
162/**********************************************************************/
166 const struct plocation *location)
167{
168 if (location->sub_location == NULL) {
169 return json_object_get(item, location->name);
170 } else {
171 return plocation_read_data(json_object_get(item, location->name),
172 location->sub_location);
173 }
174}
175
176/**********************************************************************/
180 const struct plocation *location)
181{
182 if (location->sub_location == NULL) {
183 return json_array_get(item, location->number);
184 } else {
186 location->sub_location);
187 }
188}
189
190/**********************************************************************/
194 const struct plocation *location)
195{
196 if (json_is_null(item)) { // PTZ200719 sanity checks stops the massacre
197 return item;
198 }
199
200 switch (location->kind) {
201 case PADR_FIELD:
202 return plocation_read_field(item, location);
203 case PADR_ELEMENT:
204 return plocation_read_elem(item, location);
205 default:
206 log_error("Unknown packet part location kind.");
207 return NULL;
208 }
209}
210
211/**********************************************************************/
215 const struct plocation *location,
216 int value)
217{
218 int e;
219
220 if (dout->json) {
221 e = plocation_write_data(dout->json, location, json_integer(value));
222 } else {
223 e = dio_put_uint8_raw(&dout->raw, value);
224 }
225
226 return e;
227}
228
229/**********************************************************************/
233 const struct plocation *location,
234 int value)
235{
236 int e;
237
238 if (dout->json) {
239 e = plocation_write_data(dout->json, location, json_integer(value));
240 } else {
241 e = dio_put_sint8_raw(&dout->raw, value);
242 }
243
244 return e;
245}
246
247/**********************************************************************/
251 const struct plocation *location, int value)
252{
253 int e;
254
255 if (dout->json) {
256 e = plocation_write_data(dout->json, location, json_integer(value));
257 } else {
258 e = dio_put_uint16_raw(&dout->raw, value);
259 }
260
261 return e;
262}
263
264/**********************************************************************/
268 const struct plocation *location, int value)
269{
270 int e;
271
272 if (dout->json) {
273 e = plocation_write_data(dout->json, location, json_integer(value));
274 } else {
275 e = dio_put_sint16_raw(&dout->raw, value);
276 }
277
278 return e;
279}
280
281/**********************************************************************/
285 struct plocation *location,
286 const struct cm_parameter *param)
287{
288 int e = 0;
289
290 if (dout->json) {
293 json_t *factor = json_array();
294 int i;
295
296 for (i = 0; i < O_LAST; i++) {
299 e |= json_array_append_new(factor,
300 json_integer(param->factor[i]));
301 }
302
303 e |= json_object_set_new(obj, "minimal_surplus", min_surplus);
304 e |= json_object_set_new(obj, "factor", factor);
305 e |= json_object_set_new(obj, "max_growth", json_boolean(param->max_growth));
306 e |= json_object_set_new(obj, "require_happy",
308 e |= json_object_set_new(obj, "allow_disorder",
310 e |= json_object_set_new(obj, "allow_specialists",
312 e |= json_object_set_new(obj, "happy_factor",
313 json_integer(param->happy_factor));
314 e |= plocation_write_data(dout->json, location, obj);
315 } else {
316 e = dio_put_cm_parameter_raw(&dout->raw, param);
317 }
318
319 return e;
320}
321
322/**********************************************************************/
326 struct plocation *location,
327 const struct unit_order *order)
328{
329 int e = 0;
330
331 if (dout->json) {
333
334 e |= json_object_set_new(obj, "order", json_integer(order->order));
335 e |= json_object_set_new(obj, "activity", json_integer(order->activity));
336 e |= json_object_set_new(obj, "target", json_integer(order->target));
337 e |= json_object_set_new(obj, "sub_target", json_integer(order->sub_target));
338 e |= json_object_set_new(obj, "action", json_integer(order->action));
339 if (order->dir == -1) {
340 /* Avoid integer underflow */
341 e |= json_object_set_new(obj, "dir", json_integer(-1));
342 } else {
343 e |= json_object_set_new(obj, "dir", json_integer(order->dir));
344 }
345 e |= plocation_write_data(dout->json, location, obj);
346 } else {
347 e = dio_put_unit_order_raw(&dout->raw, order);
348 }
349
350 return e;
351}
352
353/**********************************************************************/
357 struct plocation *location,
358 const struct worklist *pwl)
359{
360 int e = 0;
361
362 if (dout->json) {
363 int i;
364 const int size = worklist_length(pwl);
365
366 /* Must create the array before insertion. */
367 e |= dio_put_farray_json(dout, location, size);
368
369 location->sub_location = plocation_elem_new(0);
370
371 for (i = 0; i < size; i++) {
372 const struct universal *pcp = &(pwl->entries[i]);
374
375 location->sub_location->number = i;
376
377 e |= json_object_set_new(universal, "kind", json_integer(pcp->kind));
378 e |= json_object_set_new(universal, "value",
380
381 e |= plocation_write_data(dout->json, location, universal);
382 }
383
384 FC_FREE(location->sub_location);
385 } else {
386 e = dio_put_worklist_raw(&dout->raw, pwl);
387 }
388
389 return e;
390}
391
392/**********************************************************************/
396 const struct plocation *location,
397 int *dest)
398{
400
401 if (!pint) {
402 log_error("ERROR: Unable to get uint8 from location: %s", plocation_name(location));
403 return FALSE;
404 }
405 *dest = json_integer_value(pint);
406
407 return TRUE;
408}
409
410/**********************************************************************/
413bool dio_get_uint8_json(struct connection *pc, struct data_in *din,
414 const struct plocation *location, int *dest)
415{
416 if (pc->json_mode) {
417 return dio_get_uint8_json_internal(pc->json_packet, location, dest);
418 } else {
419 return dio_get_uint8_raw(din, dest);
420 }
421}
422
423/**********************************************************************/
426bool dio_get_uint16_json(struct connection *pc, struct data_in *din,
427 const struct plocation *location, int *dest)
428{
429 if (pc->json_mode) {
430 json_t *pint = plocation_read_data(pc->json_packet, location);
431
432 if (!pint) {
433 log_error("ERROR: Unable to get uint16 from location: %s", plocation_name(location));
434 return FALSE;
435 }
436 *dest = json_integer_value(pint);
437 } else {
438 return dio_get_uint16_raw(din, dest);
439 }
440
441 return TRUE;
442}
443
444/**********************************************************************/
448 const struct plocation *location,
449 int *dest)
450{
452
453 if (!pint) {
454 log_error("ERROR: Unable to get uint32 from location: %s", plocation_name(location));
455 return FALSE;
456 }
457 *dest = json_integer_value(pint);
458
459 return TRUE;
460}
461
462/**********************************************************************/
465bool dio_get_uint32_json(struct connection *pc, struct data_in *din,
466 const struct plocation *location, int *dest)
467{
468 if (pc->json_mode) {
469 return dio_get_uint32_json_internal(pc->json_packet, location, dest);
470 } else {
471 return dio_get_uint32_raw(din, dest);
472 }
473}
474
475/**********************************************************************/
478bool dio_get_sint32_json(struct connection *pc, struct data_in *din,
479 const struct plocation *location, int *dest)
480{
481 if (pc->json_mode) {
482 return dio_get_uint32_json_internal(pc->json_packet, location, dest);
483 } else {
484 return dio_get_sint32_raw(din, dest);
485 }
486}
487
488/**********************************************************************/
492 struct plocation *location,
493 struct cm_parameter *param)
494{
495 if (pc->json_mode) {
496 int i;
497
498 cm_init_parameter(param);
499
500 location->sub_location = plocation_field_new("max_growth");
501 if (!dio_get_bool8_json(pc, din, location, &param->max_growth)) {
502 log_packet("Corrupt cm_parameter.max_growth");
503 FC_FREE(location->sub_location);
504 return FALSE;
505 }
506
507 location->sub_location->name = "require_happy";
508 if (!dio_get_bool8_json(pc, din, location, &param->require_happy)) {
509 log_packet("Corrupt cm_parameter.require_happy");
510 FC_FREE(location->sub_location);
511 return FALSE;
512 }
513
514 location->sub_location->name = "allow_disorder";
515 if (!dio_get_bool8_json(pc, din, location, &param->allow_disorder)) {
516 log_packet("Corrupt cm_parameter.allow_disorder");
517 FC_FREE(location->sub_location);
518 return FALSE;
519 }
520
521 location->sub_location->name = "allow_specialists";
522 if (!dio_get_bool8_json(pc, din, location, &param->allow_specialists)) {
523 log_packet("Corrupt cm_parameter.allow_specialists");
524 FC_FREE(location->sub_location);
525 FC_FREE(location->sub_location);
526 return FALSE;
527 }
528
529 location->sub_location->name = "happy_factor";
530 if (!dio_get_uint16_json(pc, din, location, &param->happy_factor)) {
531 log_packet("Corrupt cm_parameter.happy_factor");
532 FC_FREE(location->sub_location);
533 return FALSE;
534 }
535
536 location->sub_location->name = "factor";
538 for (i = 0; i < O_LAST; i++) {
539 location->sub_location->sub_location->number = i;
540 if (!dio_get_uint16_json(pc, din, location, &param->factor[i])) {
541 log_packet("Corrupt cm_parameter.factor");
543 FC_FREE(location->sub_location);
544 return FALSE;
545 }
546 }
547
548 location->sub_location->name = "minimal_surplus";
549 for (i = 0; i < O_LAST; i++) {
550 location->sub_location->sub_location->number = i;
551 if (!dio_get_sint16_json(pc, din, location,
552 &param->minimal_surplus[i])) {
553 log_packet("Corrupt cm_parameter.minimal_surplus");
555 FC_FREE(location->sub_location);
556 return FALSE;
557 }
558 }
559
561 FC_FREE(location->sub_location);
562 } else {
563 return dio_get_cm_parameter_raw(din, param);
564 }
565
566 return TRUE;
567}
568
569/**********************************************************************/
572bool dio_get_unit_order_json(struct connection *pc, struct data_in *din,
573 struct plocation *location,
574 struct unit_order *order)
575{
576 if (pc->json_mode) {
577 struct plocation *loc;
578 int iorder, iactivity, idir; /* These fields are enums */
579
580 /* Orders may be located in a nested field (as items in an array) */
581 loc = location;
582 while (loc->sub_location) {
583 loc = loc->sub_location;
584 }
585
586 loc->sub_location = plocation_field_new("order");
587 if (!dio_get_uint8_json(pc, din, location, &iorder)) {
588 log_packet("Corrupt order.order");
589 FC_FREE(loc->sub_location);
590 return FALSE;
591 }
592
593 loc->sub_location->name = "activity";
594 if (!dio_get_uint8_json(pc, din, location, &iactivity)) {
595 log_packet("Corrupt order.activity");
596 FC_FREE(loc->sub_location);
597 return FALSE;
598 }
599
600 loc->sub_location->name = "target";
601 if (!dio_get_sint32_json(pc, din, location, &order->target)) {
602 log_packet("Corrupt order.target");
603 FC_FREE(loc->sub_location);
604 return FALSE;
605 }
606
607 loc->sub_location->name = "sub_target";
608 if (!dio_get_sint16_json(pc, din, location, &order->sub_target)) {
609 log_packet("Corrupt order.sub_target");
610 FC_FREE(loc->sub_location);
611 return FALSE;
612 }
613
614 loc->sub_location->name = "action";
615 if (!dio_get_uint8_json(pc, din, location, &order->action)) {
616 log_packet("Corrupt order.action");
617 FC_FREE(loc->sub_location);
618 return FALSE;
619 }
620
621 loc->sub_location->name = "dir";
622 if (!dio_get_uint8_json(pc, din, location, &idir)) {
623 log_packet("Corrupt order.dir");
624 FC_FREE(loc->sub_location);
625 return FALSE;
626 }
627
628 /*
629 * FIXME: The values should be checked!
630 */
631 order->order = iorder;
632 order->activity = iactivity;
633 order->dir = idir;
634
635 FC_FREE(loc->sub_location);
636 } else {
637 return dio_get_unit_order_raw(din, order);
638 }
639
640 return TRUE;
641}
642
643/**********************************************************************/
646bool dio_get_worklist_json(struct connection *pc, struct data_in *din,
647 struct plocation *location,
648 struct worklist *pwl)
649{
650 if (pc->json_mode) {
651 int i, length;
652
653 const json_t *wlist = plocation_read_data(pc->json_packet, location);
654
656
657 if (!json_is_array(wlist)) {
658 log_packet("Not a worklist");
659 return FALSE;
660 }
661
662 /* Safe. Checked that it was an array above. */
663 length = json_array_size(wlist);
664
665 /* A worklist is an array... */
666 location->sub_location = plocation_elem_new(0);
667
668 /* ... of universal objects. */
669 location->sub_location->sub_location = plocation_field_new("kind");
670
671 for (i = 0; i < length; i++) {
672 int value;
673 int kind;
674 struct universal univ;
675
676 location->sub_location->number = i;
677
678 location->sub_location->sub_location->name = "kind";
679 if (!dio_get_uint8_json_internal(pc->json_packet, location, &kind)) {
680 log_packet("Corrupt worklist element kind");
682 FC_FREE(location->sub_location);
683 return FALSE;
684 }
685
686 location->sub_location->sub_location->name = "value";
687 if (!dio_get_uint8_json_internal(pc->json_packet, location, &value)) {
688 log_packet("Corrupt worklist element value");
690 FC_FREE(location->sub_location);
691 return FALSE;
692 }
693
694 /*
695 * FIXME: the value returned by universal_by_number() should be checked!
696 */
698 worklist_append(pwl, &univ);
699 }
700
702 FC_FREE(location->sub_location);
703 } else {
705 }
706
707 return TRUE;
708}
709
710/**********************************************************************/
714bool dio_get_arraylen_json(struct connection *pc, struct data_in *din,
715 const struct plocation *location, int *dest)
716{
717 if (pc->json_mode) {
718 const json_t *arr = plocation_read_data(pc->json_packet, location);
719
720 if (!json_is_array(arr)) {
721 log_packet("Not an array");
722 return FALSE;
723 }
724
725 *dest = json_array_size(arr);
726 } else {
727 return dio_get_arraylen_raw(din, dest);
728 }
729
730 return TRUE;
731}
732
733/**********************************************************************/
736bool dio_get_uint8_vec8_json(struct connection *pc, struct data_in *din,
737 const struct plocation *location,
738 int **values, int stop_value)
739{
740 if (pc->json_mode) {
741 /* TODO: implement */
742 log_warn("Received unimplemeted data type uint8_vec8.");
743 } else {
744 return dio_get_uint8_vec8_raw(din, values, stop_value);
745 }
746
747 return TRUE;
748}
749
750/**********************************************************************/
753bool dio_get_uint16_vec8_json(struct connection *pc, struct data_in *din,
754 const struct plocation *location,
755 int **values,
756 int stop_value)
757{
758 if (pc->json_mode) {
759 /* TODO: implement */
760 log_warn("Received unimplemeted data type uint16_vec8.");
761 } else {
762 return dio_get_uint16_vec8_raw(din, values, stop_value);
763 }
764
765 return TRUE;
766}
767
768/**********************************************************************/
771bool dio_get_requirement_json(struct connection *pc, struct data_in *din,
772 const struct plocation *location,
773 struct requirement *preq)
774{
775 if (pc->json_mode) {
776 int kind, range, value;
777 bool survives, present, quiet;
778
779 struct plocation *req_field;
780
781 /* Find the requirement object. */
782 json_t *requirement = plocation_read_data(pc->json_packet, location);
783
784 if (!requirement) {
785 log_error("ERROR: Unable to get requirement from location: %s", plocation_name(location));
786 return FALSE;
787 }
788
789 /* Find the requirement object fields and translate their values. */
792 log_error("ERROR: Unable to get part of requirement from location: %s",
793 plocation_name(location));
794 return FALSE;
795 }
796
797 req_field->name = "value";
799 log_error("ERROR: Unable to get part of requirement from location: %s",
800 plocation_name(location));
801 return FALSE;
802 }
803
804 req_field->name = "range";
806 log_error("ERROR: Unable to get part of requirement from location: %s",
807 plocation_name(location));
808 return FALSE;
809 }
810
811 req_field->name = "survives";
813 log_error("ERROR: Unable to get part of requirement from location: %s",
814 plocation_name(location));
815 return FALSE;
816 }
817
818 req_field->name = "present";
820 log_error("ERROR: Unable to get part of requirement from location: %s",
821 plocation_name(location));
822 return FALSE;
823 }
824
825 req_field->name = "quiet";
827 log_error("ERROR: Unable to get part of requirement from location: %s",
828 plocation_name(location));
829 return FALSE;
830 }
831
833
834 /* Create a requirement with the values sent over the network. */
835 *preq = req_from_values(kind, range, survives, present, quiet, value);
836 } else {
838 }
839
840 return TRUE;
841}
842
843/**********************************************************************/
847 const struct plocation *location,
848 struct act_prob *prob)
849{
850 if (pc->json_mode) {
851 struct plocation *ap_field;
852
853 /* Find the action probability object. */
854 json_t *action_probability = plocation_read_data(pc->json_packet, location);
855
856 if (!action_probability) {
857 log_error("ERROR: Unable to get action probability from location: %s",
858 plocation_name(location));
859 return FALSE;
860 }
861
862 /* Find the action probability object fields and translate their
863 * values. */
866 log_error("ERROR: Unable to get part of action probability "
867 "from location: %s",
868 plocation_name(location));
869 return FALSE;
870 }
871
872 ap_field->name = "max";
874 log_error("ERROR: Unable to get part of action probability "
875 "from location: %s",
876 plocation_name(location));
877 return FALSE;
878 }
879
881 } else {
883 }
884
885 return TRUE;
886}
887
888/**********************************************************************/
892 const struct plocation *location, int size)
893{
894 int e = 0;
895
896 if (dout->json) {
897 int i;
899
900 /* Jansson's json_array_set_new() refuses to create array elements so
901 * they must be created with the array. */
902 for (i = 0; i < size; i++) {
904 }
905
906 e |= plocation_write_data(dout->json, location, farray);
907 } else {
908 /* No caller needs this */
909 }
910
911 return e;
912}
913
914/**********************************************************************/
918 const struct plocation *location)
919{
920 int e = 0;
921
922 if (dout->json) {
923 e |= plocation_write_data(dout->json, location, json_object());
924 } else {
925 /* No caller needs this */
926 }
927
928 return e;
929}
930
931/**********************************************************************/
935 const struct plocation *location, int value)
936{
937 int e;
938
939 if (dout->json) {
940 e = plocation_write_data(dout->json, location, json_integer(value));
941 } else {
942 e = dio_put_uint32_raw(&dout->raw, value);
943 }
944
945 return e;
946}
947
948/**********************************************************************/
952 const struct plocation *location, int value)
953{
954 int e;
955
956 if (dout->json) {
957 e = plocation_write_data(dout->json, location, json_integer(value));
958 } else {
959 e = dio_put_sint32_raw(&dout->raw, value);
960 }
961
962 return e;
963}
964
965/**********************************************************************/
969 const struct plocation *location, bool value)
970{
971 int e;
972
973 if (dout->json) {
974 e = plocation_write_data(dout->json, location, value ? json_true() : json_false());
975 } else {
976 e = dio_put_bool8_raw(&dout->raw, value);
977 }
978
979 return e;
980}
981
982/**********************************************************************/
986 const struct plocation *location, bool value)
987{
988 int e;
989
990 if (dout->json) {
991 e = plocation_write_data(dout->json, location, value ? json_true() : json_false());
992 } else {
993 e = dio_put_bool32_raw(&dout->raw, value);
994 }
995
996 return e;
997}
998
999/**********************************************************************/
1003 const struct plocation *location,
1004 float value, int float_factor)
1005{
1006 int e;
1007
1008 if (dout->json) {
1009 e = plocation_write_data(dout->json, location, json_real(value));
1010 } else {
1011 e = dio_put_ufloat_raw(&dout->raw, value, float_factor);
1012 }
1013
1014 return e;
1015}
1016
1017/**********************************************************************/
1021 const struct plocation *location,
1022 float value, int float_factor)
1023{
1024 int e;
1025
1026 if (dout->json) {
1027 e = plocation_write_data(dout->json, location, json_real(value));
1028 } else {
1029 e = dio_put_sfloat_raw(&dout->raw, value, float_factor);
1030 }
1031
1032 return e;
1033}
1034
1035/**********************************************************************/
1040 const struct plocation *location, int size)
1041{
1042 int e;
1043
1044 if (dout->json) {
1045 e = dio_put_farray_json(dout, location, size);
1046 } else {
1047 e = dio_put_arraylen_raw(&dout->raw, size);
1048 }
1049
1050 return e;
1051}
1052
1053/**********************************************************************/
1057 const struct plocation *location,
1058 int *values, int stop_value)
1059{
1060 int e;
1061
1062 if (dout->json) {
1063 /* TODO: implement. */
1064 log_error("Tried to send unimplemeted data type uint8_vec8.");
1065 e = -1;
1066 } else {
1067 e = dio_put_uint8_vec8_raw(&dout->raw, values, stop_value);
1068 }
1069
1070 return e;
1071}
1072
1073/**********************************************************************/
1077 const struct plocation *location, int *values,
1078 int stop_value)
1079{
1080 int e;
1081
1082 if (dout->json) {
1083 /* TODO: implement. */
1084 log_error("Tried to send unimplemeted data type uint16_vec8.");
1085 e = -1;
1086 } else {
1087 e = dio_put_uint16_vec8_raw(&dout->raw, values, stop_value);
1088 }
1089
1090 return e;
1091}
1092
1093/**********************************************************************/
1097 struct plocation *location,
1098 const void *value,
1099 size_t size)
1100{
1101 int e;
1102
1103 if (dout->json) {
1104 int i;
1105
1106 e = dio_put_farray_json(dout, location, size);
1107
1108 location->sub_location = plocation_elem_new(0);
1109
1110 for (i = 0; i < size; i++) {
1111 location->sub_location->number = i;
1112
1113 e |= dio_put_uint8_json(dout, location,
1114 ((unsigned char *)value)[i]);
1115 }
1116
1117 FC_FREE(location->sub_location);
1118 } else {
1119 e = dio_put_memory_raw(&dout->raw, value, size);
1120 }
1121
1122 return e;
1123}
1124
1125/**********************************************************************/
1129 const struct plocation *location,
1130 const char *value)
1131{
1132 int e;
1133
1134 if (dout->json) {
1135 e = plocation_write_data(dout->json, location, json_string(value));
1136 } else {
1137 e = dio_put_string_raw(&dout->raw, value);
1138 }
1139
1140 return e;
1141}
1142
1143/**********************************************************************/
1147 const struct plocation *location,
1148 const char *value)
1149{
1150 int e;
1151
1152 if (dout->json) {
1153 char *escaped_value;
1154
1155 /* Let CURL find the length it self by passing 0 */
1157
1158 /* Handle as a regular string from now on. */
1159 e = dio_put_string_json(dout, location, escaped_value);
1160
1161 /* CURL's memory management wants to free this it self. */
1163 } else {
1164 e = dio_put_estring_raw(&dout->raw, value);
1165 }
1166
1167 return e;
1168}
1169
1170/**********************************************************************/
1174 const struct plocation *location,
1175 const struct requirement *preq)
1176{
1177 int e = 0;
1178
1179 if (dout->json) {
1180 int kind, range, value;
1181 bool survives, present, quiet;
1182
1183 /* Create the requirement object. */
1185
1186 /* Read the requirement values. */
1187 req_get_values(preq, &kind, &range, &survives, &present, &quiet, &value);
1188
1189 /* Write the requirement values to the fields of the requirement
1190 * object. */
1192 e |= json_object_set_new(requirement, "value", json_integer(value));
1193
1195
1196 e |= json_object_set_new(requirement, "survives", json_boolean(survives));
1197 e |= json_object_set_new(requirement, "present", json_boolean(present));
1198 e |= json_object_set_new(requirement, "quiet", json_boolean(quiet));
1199
1200 /* Put the requirement object in the packet. */
1201 e |= plocation_write_data(dout->json, location, requirement);
1202 } else {
1203 e = dio_put_requirement_raw(&dout->raw, preq);
1204 }
1205
1206 return e;
1207}
1208
1209/**********************************************************************/
1213 const struct plocation *location,
1214 const struct act_prob *prob)
1215{
1216 int e = 0;
1217
1218 if (dout->json) {
1219 /* Create the action probability object. */
1221
1222 /* Write the action probability values to the fields of the action
1223 * probability object. */
1226
1227 /* Put the action probability object in the packet. */
1228 e |= plocation_write_data(dout->json, location, action_probability);
1229 } else {
1230 e = dio_put_action_probability_raw(&dout->raw, prob);
1231 }
1232
1233 return e;
1234}
1235
1236/**********************************************************************/
1240 const struct plocation *location,
1241 bool *dest)
1242{
1244
1245 if (!pbool) {
1246 log_error("ERROR: Unable to get bool8 from location: %s", plocation_name(location));
1247 return FALSE;
1248 }
1249 *dest = json_is_true(pbool);
1250
1251 return TRUE;
1252}
1253
1254/**********************************************************************/
1257bool dio_get_bool8_json(struct connection *pc, struct data_in *din,
1258 const struct plocation *location, bool *dest)
1259{
1260 if (pc->json_mode) {
1261 return dio_get_bool8_json_internal(pc->json_packet, location, dest);
1262 } else {
1263 return dio_get_bool8_raw(din, dest);
1264 }
1265}
1266
1267/**********************************************************************/
1270bool dio_get_bool32_json(struct connection *pc, struct data_in *din,
1271 const struct plocation *location, bool *dest)
1272{
1273 if (pc->json_mode) {
1274 json_t *pbool = plocation_read_data(pc->json_packet, location);
1275
1276 if (!pbool) {
1277 log_error("ERROR: Unable to get bool32 from location: %s", plocation_name(location));
1278 return FALSE;
1279 }
1280 *dest = json_is_true(pbool);
1281 } else {
1282 return dio_get_bool32_raw(din, dest);
1283 }
1284
1285 return TRUE;
1286}
1287
1288/**********************************************************************/
1291bool dio_get_ufloat_json(struct connection *pc, struct data_in *din,
1292 const struct plocation *location,
1293 float *dest, int float_factor)
1294{
1295 if (pc->json_mode) {
1296 json_t *preal = plocation_read_data(pc->json_packet, location);
1297
1298 if (!preal) {
1299 log_error("ERROR: Unable to get real from location: %s", plocation_name(location));
1300 return FALSE;
1301 }
1302 *dest = json_real_value(preal);
1303 } else {
1304 return dio_get_ufloat_raw(din, dest, float_factor);
1305 }
1306
1307 return TRUE;
1308}
1309
1310/**********************************************************************/
1313bool dio_get_sfloat_json(struct connection *pc, struct data_in *din,
1314 const struct plocation *location,
1315 float *dest, int float_factor)
1316{
1317 if (pc->json_mode) {
1318 json_t *preal = plocation_read_data(pc->json_packet, location);
1319
1320 if (!preal) {
1321 log_error("ERROR: Unable to get real from location: %s", plocation_name(location));
1322 return FALSE;
1323 }
1324 *dest = json_real_value(preal);
1325 } else {
1326 return dio_get_sfloat_raw(din, dest, float_factor);
1327 }
1328
1329 return TRUE;
1330}
1331
1332/**********************************************************************/
1335bool dio_get_sint8_json(struct connection *pc, struct data_in *din,
1336 const struct plocation *location, int *dest)
1337{
1338 if (pc->json_mode) {
1339 json_t *pint = plocation_read_data(pc->json_packet, location);
1340
1341 if (!pint) {
1342 log_error("ERROR: Unable to get sint8 from location: %s", plocation_name(location));
1343 return FALSE;
1344 }
1345 *dest = json_integer_value(pint);
1346 } else {
1347 return dio_get_sint8_raw(din, dest);
1348 }
1349
1350 return TRUE;
1351}
1352
1353/**********************************************************************/
1356bool dio_get_sint16_json(struct connection *pc, struct data_in *din,
1357 const struct plocation *location, int *dest)
1358{
1359 if (pc->json_mode) {
1360 json_t *pint = plocation_read_data(pc->json_packet, location);
1361
1362 if (!pint) {
1363 log_error("ERROR: Unable to get sint16 from location: %s", plocation_name(location));
1364 return FALSE;
1365 }
1366 *dest = json_integer_value(pint);
1367 } else {
1368 return dio_get_sint16_raw(din, dest);
1369 }
1370
1371 return TRUE;
1372}
1373
1374/**********************************************************************/
1377bool dio_get_memory_json(struct connection *pc, struct data_in *din,
1378 struct plocation *location,
1379 void *dest, size_t dest_size)
1380{
1381 if (pc->json_mode) {
1382 int i;
1383
1384 location->sub_location = plocation_elem_new(0);
1385
1386 for (i = 0; i < dest_size; i++) {
1387 int val;
1388
1389 location->sub_location->number = i;
1390
1391 if (!dio_get_uint8_json_internal(pc->json_packet, location, &val)) {
1392 free(location->sub_location);
1393 return FALSE;
1394 }
1395 ((unsigned char *)dest)[i] = val;
1396 }
1397
1398 FC_FREE(location->sub_location);
1399 } else {
1400 return dio_get_memory_raw(din, dest, dest_size);
1401 }
1402
1403 return TRUE;
1404}
1405
1406/**********************************************************************/
1410 const struct plocation *location,
1411 char *dest, size_t max_dest_size)
1412{
1414 const char *result_str;
1415
1416 if (!pstring) {
1417 log_error("ERROR: Unable to get string from location: %s", plocation_name(location));
1418 return FALSE;
1419 }
1420
1422
1423 if (dest
1425 log_error("ERROR: Unable to get string from location: %s", plocation_name(location));
1426 return FALSE;
1427 }
1428
1429 return TRUE;
1430}
1431
1432/**********************************************************************/
1435bool dio_get_string_json(struct connection *pc, struct data_in *din,
1436 const struct plocation *location,
1437 char *dest, size_t max_dest_size)
1438{
1439 if (pc->json_mode) {
1440 return dio_get_string_json_internal(pc->json_packet, location,
1441 dest, max_dest_size);
1442 } else {
1443 return dio_get_string_raw(din, dest, max_dest_size);
1444 }
1445}
1446
1447/**********************************************************************/
1452bool dio_get_estring_json(struct connection *pc, struct data_in *din,
1453 const struct plocation *location,
1454 char *dest, size_t max_dest_size)
1455{
1456 if (pc->json_mode) {
1457 char *escaped_value;
1458 char *unescaped_value;
1459
1460 /* The encoded string has the same size limit as the decoded string. */
1462
1463 if (!dio_get_string_json_internal(pc->json_packet, location,
1465 /* dio_get_string_json() has logged this already. */
1466 return FALSE;
1467 }
1468
1469 /* Let CURL find the length it self by passing 0 */
1471
1472 /* Done with the escaped value. */
1474
1475 /* Copy the unescaped value so CURL can free its own copy. */
1476 memcpy(dest, unescaped_value,
1477 /* Don't copy the memory following unescaped_value. */
1479
1480 /* CURL's memory management wants to free this it self. */
1482
1483 /* Make sure that the string is terminated. */
1484 dest[max_dest_size - 1] = '\0';
1485 } else {
1486 return dio_get_estring_raw(din, dest, max_dest_size);
1487 }
1488
1489 return TRUE;
1490}
1491
1492#endif /* FREECIV_JSON_CONNECTION */
#define n
Definition astring.c:77
void cm_init_parameter(struct cm_parameter *dest)
Definition cm.c:2183
char * incite_cost
Definition comments.c:76
int dio_put_unit_order_json(struct json_data_out *dout, struct plocation *location, const struct unit_order *order)
bool dio_get_uint8_vec8_json(struct connection *pc, struct data_in *din, const struct plocation *location, int **values, int stop_value) fc__attribute((nonnull(4)))
bool dio_get_uint8_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest) fc__attribute((nonnull(4)))
int dio_put_uint8_vec8_json(struct json_data_out *dout, const struct plocation *location, int *values, int stop_value)
bool dio_get_cm_parameter_json(struct connection *pc, struct data_in *din, struct plocation *location, struct cm_parameter *param) fc__attribute((nonnull(4)))
bool dio_get_requirement_json(struct connection *pc, struct data_in *din, const struct plocation *location, struct requirement *preq) fc__attribute((nonnull(4)))
int dio_put_worklist_json(struct json_data_out *dout, struct plocation *location, const struct worklist *pwl)
int dio_put_uint32_json(struct json_data_out *dout, const struct plocation *location, int value)
int dio_put_object_json(struct json_data_out *dout, const struct plocation *location)
bool dio_get_estring_json(struct connection *pc, struct data_in *din, const struct plocation *location, char *dest, size_t max_dest_size) fc__attribute((nonnull(4)))
int dio_put_uint16_vec8_json(struct json_data_out *dout, const struct plocation *location, int *values, int stop_value)
bool dio_get_uint32_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest) fc__attribute((nonnull(4)))
bool dio_get_memory_json(struct connection *pc, struct data_in *din, struct plocation *location, void *dest, size_t dest_size) fc__attribute((nonnull(4)))
bool dio_get_uint16_vec8_json(struct connection *pc, struct data_in *din, const struct plocation *location, int **values, int stop_value) fc__attribute((nonnull(4)))
int dio_put_uint16_json(struct json_data_out *dout, const struct plocation *location, int value)
bool dio_get_sint8_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest) fc__attribute((nonnull(4)))
int dio_put_memory_json(struct json_data_out *dout, struct plocation *location, const void *value, size_t size)
bool dio_get_sint32_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest) fc__attribute((nonnull(4)))
int dio_put_arraylen_json(struct json_data_out *dout, const struct plocation *location, int size)
int dio_put_uint8_json(struct json_data_out *dout, const struct plocation *location, int value)
int dio_put_farray_json(struct json_data_out *dout, const struct plocation *location, int size)
int dio_put_bool8_json(struct json_data_out *dout, const struct plocation *location, bool value)
int dio_put_sint32_json(struct json_data_out *dout, const struct plocation *location, int value)
int dio_put_estring_json(struct json_data_out *dout, const struct plocation *location, const char *value)
int dio_put_action_probability_json(struct json_data_out *dout, const struct plocation *location, const struct act_prob *prob)
bool dio_get_arraylen_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest) fc__attribute((nonnull(4)))
bool dio_get_worklist_json(struct connection *pc, struct data_in *din, struct plocation *location, struct worklist *pwl) fc__attribute((nonnull(4)))
bool dio_get_sfloat_json(struct connection *pc, struct data_in *din, const struct plocation *location, float *dest, int float_factor) fc__attribute((nonnull(4)))
int dio_put_bool32_json(struct json_data_out *dout, const struct plocation *location, bool value)
bool dio_get_bool32_json(struct connection *pc, struct data_in *din, const struct plocation *location, bool *dest) fc__attribute((nonnull(4)))
bool dio_get_ufloat_json(struct connection *pc, struct data_in *din, const struct plocation *location, float *dest, int float_factor) fc__attribute((nonnull(4)))
bool dio_get_bool8_json(struct connection *pc, struct data_in *din, const struct plocation *location, bool *dest) fc__attribute((nonnull(4)))
bool dio_get_unit_order_json(struct connection *pc, struct data_in *din, struct plocation *location, struct unit_order *order) fc__attribute((nonnull(4)))
int dio_put_sfloat_json(struct json_data_out *dout, const struct plocation *location, float value, int float_factor)
int dio_put_requirement_json(struct json_data_out *dout, const struct plocation *location, const struct requirement *preq)
int dio_put_sint8_json(struct json_data_out *dout, const struct plocation *location, int value)
int dio_put_sint16_json(struct json_data_out *dout, const struct plocation *location, int value)
int dio_put_ufloat_json(struct json_data_out *dout, const struct plocation *location, float value, int float_factor)
bool dio_get_sint16_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest) fc__attribute((nonnull(4)))
int dio_put_string_json(struct json_data_out *dout, const struct plocation *location, const char *value)
bool dio_get_action_probability_json(struct connection *pc, struct data_in *din, const struct plocation *location, struct act_prob *prob) fc__attribute((nonnull(4)))
bool dio_get_uint16_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest) fc__attribute((nonnull(4)))
int dio_put_cm_parameter_json(struct json_data_out *dout, struct plocation *location, const struct cm_parameter *order)
bool dio_get_string_json(struct connection *pc, struct data_in *din, const struct plocation *location, char *dest, size_t max_dest_size) fc__attribute((nonnull(4)))
bool dio_get_requirement_raw(struct data_in *din, struct requirement *preq)
bool dio_get_sint8_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:759
int dio_put_uint8_vec8_raw(struct raw_data_out *dout, int *values, int stop_value)
Definition dataio_raw.c:447
int dio_put_cm_parameter_raw(struct raw_data_out *dout, const struct cm_parameter *param)
Definition dataio_raw.c:533
int dio_put_action_probability_raw(struct raw_data_out *dout, const struct act_prob *aprob)
int dio_put_uint8_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:265
struct plocation * plocation_field_new(char *name)
bool dio_get_worklist_raw(struct data_in *din, struct worklist *pwl)
Definition dataio_raw.c:932
bool dio_get_action_probability_raw(struct data_in *din, struct act_prob *aprob)
int dio_put_uint32_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:309
bool dataio_get_conv_callback(char *dst, size_t ndst, const char *src, size_t nsrc)
Definition dataio_raw.c:139
bool dio_get_sfloat_raw(struct data_in *din, float *dest, int float_factor)
Definition dataio_raw.c:744
bool dio_get_uint32_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:640
int dio_put_string_raw(struct raw_data_out *dout, const char *value)
Definition dataio_raw.c:512
bool dio_get_sint16_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:777
bool dio_get_unit_order_raw(struct data_in *din, struct unit_order *order)
Definition dataio_raw.c:906
bool dio_get_sint32_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:795
int dio_put_bool8_raw(struct raw_data_out *dout, bool value)
Definition dataio_raw.c:386
bool dio_get_cm_parameter_raw(struct data_in *din, struct cm_parameter *param)
Definition dataio_raw.c:868
int dio_put_sint8_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:358
int dio_put_requirement_raw(struct raw_data_out *dout, const struct requirement *preq)
bool dio_get_uint8_vec8_raw(struct data_in *din, int **values, int stop_value)
Definition dataio_raw.c:968
bool dio_get_uint16_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:619
int dio_put_sint32_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:374
bool dio_get_memory_raw(struct data_in *din, void *dest, size_t dest_size)
Definition dataio_raw.c:816
int dio_put_memory_raw(struct raw_data_out *dout, const void *value, size_t size)
Definition dataio_raw.c:499
bool dio_get_bool32_raw(struct data_in *din, bool *dest)
Definition dataio_raw.c:707
bool dio_get_ufloat_raw(struct data_in *din, float *dest, int float_factor)
Definition dataio_raw.c:728
int dio_put_bool32_raw(struct raw_data_out *dout, bool value)
Definition dataio_raw.c:398
bool dio_get_uint8_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:598
int dio_put_uint16_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:287
bool dio_get_uint16_vec8_raw(struct data_in *din, int **values, int stop_value)
Definition dataio_raw.c:993
struct plocation * plocation_elem_new(int number)
bool dio_get_bool8_raw(struct data_in *din, bool *dest)
Definition dataio_raw.c:687
int dio_put_unit_order_raw(struct raw_data_out *dout, const struct unit_order *order)
Definition dataio_raw.c:560
int dio_put_ufloat_raw(struct raw_data_out *dout, float value, int float_factor)
Definition dataio_raw.c:412
int dio_put_uint16_vec8_raw(struct raw_data_out *dout, int *values, int stop_value)
Definition dataio_raw.c:474
int dio_put_sfloat_raw(struct raw_data_out *dout, float value, int float_factor)
Definition dataio_raw.c:429
int dio_put_sint16_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:366
bool dio_get_string_raw(struct data_in *din, char *dest, size_t max_dest_size)
Definition dataio_raw.c:831
const char * plocation_name(const struct plocation *loc)
int dio_put_worklist_raw(struct raw_data_out *dout, const struct worklist *pwl)
Definition dataio_raw.c:579
#define dio_put_arraylen_raw
Definition dataio_raw.h:167
@ PADR_FIELD
Definition dataio_raw.h:57
@ PADR_ELEMENT
Definition dataio_raw.h:59
#define dio_get_arraylen_raw
Definition dataio_raw.h:166
#define dio_get_estring_raw
Definition dataio_raw.h:162
#define dio_put_estring_raw
Definition dataio_raw.h:163
@ O_LAST
Definition fc_types.h:101
struct tile * loc
Definition citydlg.c:227
#define log_packet
Definition log.h:138
#define log_warn(message,...)
Definition log.h:106
#define log_error(message,...)
Definition log.h:104
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_malloc(sz)
Definition mem.h:34
void req_get_values(const struct requirement *req, int *type, int *range, bool *survives, bool *present, bool *quiet, int *value)
struct requirement req_from_values(int type, int range, bool survives, bool present, bool quiet, int value)
struct universal universal_by_number(const enum universals_n kind, const int value)
int universal_number(const struct universal *source)
#define MIN(x, y)
Definition shared.h:55
size_t size
Definition specvec.h:72
int max
Definition fc_types.h:950
int min
Definition fc_types.h:949
bool allow_disorder
Definition cm.h:44
int factor[O_LAST]
Definition cm.h:47
bool max_growth
Definition cm.h:42
bool allow_specialists
Definition cm.h:45
bool require_happy
Definition cm.h:43
int minimal_surplus[O_LAST]
Definition cm.h:41
int happy_factor
Definition cm.h:48
Definition climisc.h:82
enum plocation_kind kind
Definition dataio_raw.h:65
size_t number
Definition dataio_raw.h:70
struct plocation * sub_location
Definition dataio_raw.h:79
char * name
Definition dataio_raw.h:73
enum unit_activity activity
Definition unit.h:95
enum unit_orders order
Definition unit.h:94
int action
Definition unit.h:102
enum direction8 dir
Definition unit.h:104
int target
Definition unit.h:98
int sub_target
Definition unit.h:99
enum universals_n kind
Definition fc_types.h:608
universals_u value
Definition fc_types.h:607
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
void worklist_init(struct worklist *pwl)
Definition worklist.c:38
bool worklist_append(struct worklist *pwl, const struct universal *prod)
Definition worklist.c:147
int worklist_length(const struct worklist *pwl)
Definition worklist.c:57