Freeciv-3.4
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 = nullptr;
73
74 if (curl_easy_handle == nullptr) {
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 == nullptr) {
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 == nullptr) {
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 == nullptr) {
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 == nullptr) {
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
208 return nullptr;
209 }
210}
211
212/**********************************************************************/
216 const struct plocation *location,
217 int value)
218{
219 int e;
220
221 if (dout->json) {
222 e = plocation_write_data(dout->json, location, json_integer(value));
223 } else {
224 e = dio_put_uint8_raw(&dout->raw, value);
225 }
226
227 return e;
228}
229
230/**********************************************************************/
234 const struct plocation *location,
235 int value)
236{
237 int e;
238
239 if (dout->json) {
240 e = plocation_write_data(dout->json, location, json_integer(value));
241 } else {
242 e = dio_put_sint8_raw(&dout->raw, value);
243 }
244
245 return e;
246}
247
248/**********************************************************************/
252 const struct plocation *location, int value)
253{
254 int e;
255
256 if (dout->json) {
257 e = plocation_write_data(dout->json, location, json_integer(value));
258 } else {
259 e = dio_put_uint16_raw(&dout->raw, value);
260 }
261
262 return e;
263}
264
265/**********************************************************************/
269 const struct plocation *location, int value)
270{
271 int e;
272
273 if (dout->json) {
274 e = plocation_write_data(dout->json, location, json_integer(value));
275 } else {
276 e = dio_put_sint16_raw(&dout->raw, value);
277 }
278
279 return e;
280}
281
282/**********************************************************************/
286 struct plocation *location,
287 const struct cm_parameter *param)
288{
289 int e = 0;
290
291 if (dout->json) {
294 json_t *factor = json_array();
295 int i;
296
297 for (i = 0; i < O_LAST; i++) {
300 e |= json_array_append_new(factor,
301 json_integer(param->factor[i]));
302 }
303
304 e |= json_object_set_new(obj, "minimal_surplus", min_surplus);
305 e |= json_object_set_new(obj, "factor", factor);
306 e |= json_object_set_new(obj, "max_growth", json_boolean(param->max_growth));
307 e |= json_object_set_new(obj, "require_happy",
309 e |= json_object_set_new(obj, "allow_disorder",
311 e |= json_object_set_new(obj, "allow_specialists",
313 e |= json_object_set_new(obj, "happy_factor",
314 json_integer(param->happy_factor));
315 e |= plocation_write_data(dout->json, location, obj);
316 } else {
317 e = dio_put_cm_parameter_raw(&dout->raw, param);
318 }
319
320 return e;
321}
322
323/**********************************************************************/
327 struct plocation *location,
328 const struct unit_order *order)
329{
330 int e = 0;
331
332 if (dout->json) {
334
335 e |= json_object_set_new(obj, "order", json_integer(order->order));
336 e |= json_object_set_new(obj, "activity", json_integer(order->activity));
337 e |= json_object_set_new(obj, "target", json_integer(order->target));
338 e |= json_object_set_new(obj, "sub_target", json_integer(order->sub_target));
339 e |= json_object_set_new(obj, "action", json_integer(order->action));
340 if (order->dir == -1) {
341 /* Avoid integer underflow */
342 e |= json_object_set_new(obj, "dir", json_integer(-1));
343 } else {
344 e |= json_object_set_new(obj, "dir", json_integer(order->dir));
345 }
346 e |= plocation_write_data(dout->json, location, obj);
347 } else {
348 e = dio_put_unit_order_raw(&dout->raw, order);
349 }
350
351 return e;
352}
353
354/**********************************************************************/
358 struct plocation *location,
359 const struct worklist *pwl)
360{
361 int e = 0;
362
363 if (dout->json) {
364 int i;
365 const int size = worklist_length(pwl);
366
367 /* Must create the array before insertion. */
368 e |= dio_put_farray_json(dout, location, size);
369
370 location->sub_location = plocation_elem_new(0);
371
372 for (i = 0; i < size; i++) {
373 const struct universal *pcp = &(pwl->entries[i]);
375
376 location->sub_location->number = i;
377
378 e |= json_object_set_new(universal, "kind", json_integer(pcp->kind));
379 e |= json_object_set_new(universal, "value",
381
382 e |= plocation_write_data(dout->json, location, universal);
383 }
384
385 FC_FREE(location->sub_location);
386 } else {
387 e = dio_put_worklist_raw(&dout->raw, pwl);
388 }
389
390 return e;
391}
392
393/**********************************************************************/
397 const struct plocation *location,
398 int *dest)
399{
401
402 if (!pint) {
403 log_error("ERROR: Unable to get uint8 from location: %s", plocation_name(location));
404 return FALSE;
405 }
406 *dest = json_integer_value(pint);
407
408 return TRUE;
409}
410
411/**********************************************************************/
414bool dio_get_uint8_json(struct connection *pc, struct data_in *din,
415 const struct plocation *location, int *dest)
416{
417 if (pc->json_mode) {
418 return dio_get_uint8_json_internal(pc->json_packet, location, dest);
419 } else {
420 return dio_get_uint8_raw(din, dest);
421 }
422}
423
424/**********************************************************************/
427bool dio_get_uint16_json(struct connection *pc, struct data_in *din,
428 const struct plocation *location, int *dest)
429{
430 if (pc->json_mode) {
431 json_t *pint = plocation_read_data(pc->json_packet, location);
432
433 if (!pint) {
434 log_error("ERROR: Unable to get uint16 from location: %s", plocation_name(location));
435 return FALSE;
436 }
437 *dest = json_integer_value(pint);
438 } else {
439 return dio_get_uint16_raw(din, dest);
440 }
441
442 return TRUE;
443}
444
445/**********************************************************************/
449 const struct plocation *location,
450 int *dest)
451{
453
454 if (!pint) {
455 log_error("ERROR: Unable to get uint32 from location: %s", plocation_name(location));
456 return FALSE;
457 }
458 *dest = json_integer_value(pint);
459
460 return TRUE;
461}
462
463/**********************************************************************/
466bool dio_get_uint32_json(struct connection *pc, struct data_in *din,
467 const struct plocation *location, int *dest)
468{
469 if (pc->json_mode) {
470 return dio_get_uint32_json_internal(pc->json_packet, location, dest);
471 } else {
472 return dio_get_uint32_raw(din, dest);
473 }
474}
475
476/**********************************************************************/
479bool dio_get_sint32_json(struct connection *pc, struct data_in *din,
480 const struct plocation *location, int *dest)
481{
482 if (pc->json_mode) {
483 return dio_get_uint32_json_internal(pc->json_packet, location, dest);
484 } else {
485 return dio_get_sint32_raw(din, dest);
486 }
487}
488
489/**********************************************************************/
493 struct plocation *location,
494 struct cm_parameter *param)
495{
496 if (pc->json_mode) {
497 int i;
498
499 cm_init_parameter(param);
500
501 location->sub_location = plocation_field_new("max_growth");
502 if (!dio_get_bool8_json(pc, din, location, &param->max_growth)) {
503 log_packet("Corrupt cm_parameter.max_growth");
504 FC_FREE(location->sub_location);
505 return FALSE;
506 }
507
508 location->sub_location->name = "require_happy";
509 if (!dio_get_bool8_json(pc, din, location, &param->require_happy)) {
510 log_packet("Corrupt cm_parameter.require_happy");
511 FC_FREE(location->sub_location);
512 return FALSE;
513 }
514
515 location->sub_location->name = "allow_disorder";
516 if (!dio_get_bool8_json(pc, din, location, &param->allow_disorder)) {
517 log_packet("Corrupt cm_parameter.allow_disorder");
518 FC_FREE(location->sub_location);
519 return FALSE;
520 }
521
522 location->sub_location->name = "allow_specialists";
523 if (!dio_get_bool8_json(pc, din, location, &param->allow_specialists)) {
524 log_packet("Corrupt cm_parameter.allow_specialists");
525 FC_FREE(location->sub_location);
526 FC_FREE(location->sub_location);
527 return FALSE;
528 }
529
530 location->sub_location->name = "happy_factor";
531 if (!dio_get_uint16_json(pc, din, location, &param->happy_factor)) {
532 log_packet("Corrupt cm_parameter.happy_factor");
533 FC_FREE(location->sub_location);
534 return FALSE;
535 }
536
537 location->sub_location->name = "factor";
539 for (i = 0; i < O_LAST; i++) {
540 location->sub_location->sub_location->number = i;
541 if (!dio_get_uint16_json(pc, din, location, &param->factor[i])) {
542 log_packet("Corrupt cm_parameter.factor");
544 FC_FREE(location->sub_location);
545 return FALSE;
546 }
547 }
548
549 location->sub_location->name = "minimal_surplus";
550 for (i = 0; i < O_LAST; i++) {
551 location->sub_location->sub_location->number = i;
552 if (!dio_get_sint16_json(pc, din, location,
553 &param->minimal_surplus[i])) {
554 log_packet("Corrupt cm_parameter.minimal_surplus");
556 FC_FREE(location->sub_location);
557 return FALSE;
558 }
559 }
560
562 FC_FREE(location->sub_location);
563 } else {
564 return dio_get_cm_parameter_raw(din, param);
565 }
566
567 return TRUE;
568}
569
570/**********************************************************************/
573bool dio_get_unit_order_json(struct connection *pc, struct data_in *din,
574 struct plocation *location,
575 struct unit_order *order)
576{
577 if (pc->json_mode) {
578 struct plocation *loc;
579 int iorder, iactivity, idir; /* These fields are enums */
580
581 /* Orders may be located in a nested field (as items in an array) */
582 loc = location;
583 while (loc->sub_location) {
584 loc = loc->sub_location;
585 }
586
587 loc->sub_location = plocation_field_new("order");
588 if (!dio_get_uint8_json(pc, din, location, &iorder)) {
589 log_packet("Corrupt order.order");
590 FC_FREE(loc->sub_location);
591 return FALSE;
592 }
593
594 loc->sub_location->name = "activity";
595 if (!dio_get_uint8_json(pc, din, location, &iactivity)) {
596 log_packet("Corrupt order.activity");
597 FC_FREE(loc->sub_location);
598 return FALSE;
599 }
600
601 loc->sub_location->name = "target";
602 if (!dio_get_sint32_json(pc, din, location, &order->target)) {
603 log_packet("Corrupt order.target");
604 FC_FREE(loc->sub_location);
605 return FALSE;
606 }
607
608 loc->sub_location->name = "sub_target";
609 if (!dio_get_sint16_json(pc, din, location, &order->sub_target)) {
610 log_packet("Corrupt order.sub_target");
611 FC_FREE(loc->sub_location);
612 return FALSE;
613 }
614
615 loc->sub_location->name = "action";
616 if (!dio_get_uint8_json(pc, din, location, &order->action)) {
617 log_packet("Corrupt order.action");
618 FC_FREE(loc->sub_location);
619 return FALSE;
620 }
621
622 loc->sub_location->name = "dir";
623 if (!dio_get_uint8_json(pc, din, location, &idir)) {
624 log_packet("Corrupt order.dir");
625 FC_FREE(loc->sub_location);
626 return FALSE;
627 }
628
629 /*
630 * FIXME: The values should be checked!
631 */
632 order->order = iorder;
633 order->activity = iactivity;
634 order->dir = idir;
635
636 FC_FREE(loc->sub_location);
637 } else {
638 return dio_get_unit_order_raw(din, order);
639 }
640
641 return TRUE;
642}
643
644/**********************************************************************/
647bool dio_get_worklist_json(struct connection *pc, struct data_in *din,
648 struct plocation *location,
649 struct worklist *pwl)
650{
651 if (pc->json_mode) {
652 int i, length;
653
654 const json_t *wlist = plocation_read_data(pc->json_packet, location);
655
657
658 if (!json_is_array(wlist)) {
659 log_packet("Not a worklist");
660 return FALSE;
661 }
662
663 /* Safe. Checked that it was an array above. */
664 length = json_array_size(wlist);
665
666 /* A worklist is an array... */
667 location->sub_location = plocation_elem_new(0);
668
669 /* ... of universal objects. */
670 location->sub_location->sub_location = plocation_field_new("kind");
671
672 for (i = 0; i < length; i++) {
673 int value;
674 int kind;
675 struct universal univ;
676
677 location->sub_location->number = i;
678
679 location->sub_location->sub_location->name = "kind";
680 if (!dio_get_uint8_json_internal(pc->json_packet, location, &kind)) {
681 log_packet("Corrupt worklist element kind");
683 FC_FREE(location->sub_location);
684 return FALSE;
685 }
686
687 location->sub_location->sub_location->name = "value";
688 if (!dio_get_uint8_json_internal(pc->json_packet, location, &value)) {
689 log_packet("Corrupt worklist element value");
691 FC_FREE(location->sub_location);
692 return FALSE;
693 }
694
695 /*
696 * FIXME: the value returned by universal_by_number() should be checked!
697 */
699 worklist_append(pwl, &univ);
700 }
701
703 FC_FREE(location->sub_location);
704 } else {
706 }
707
708 return TRUE;
709}
710
711/**********************************************************************/
715bool dio_get_arraylen_json(struct connection *pc, struct data_in *din,
716 const struct plocation *location, int *dest)
717{
718 if (pc->json_mode) {
719 const json_t *arr = plocation_read_data(pc->json_packet, location);
720
721 if (!json_is_array(arr)) {
722 log_packet("Not an array");
723 return FALSE;
724 }
725
726 *dest = json_array_size(arr);
727 } else {
728 return dio_get_arraylen_raw(din, dest);
729 }
730
731 return TRUE;
732}
733
734/**********************************************************************/
737bool dio_get_uint8_vec8_json(struct connection *pc, struct data_in *din,
738 const struct plocation *location,
739 int **values, int stop_value)
740{
741 if (pc->json_mode) {
742 /* TODO: implement */
743 log_warn("Received unimplemeted data type uint8_vec8.");
744 } else {
745 return dio_get_uint8_vec8_raw(din, values, stop_value);
746 }
747
748 return TRUE;
749}
750
751/**********************************************************************/
754bool dio_get_uint16_vec8_json(struct connection *pc, struct data_in *din,
755 const struct plocation *location,
756 int **values,
757 int stop_value)
758{
759 if (pc->json_mode) {
760 /* TODO: implement */
761 log_warn("Received unimplemeted data type uint16_vec8.");
762 } else {
763 return dio_get_uint16_vec8_raw(din, values, stop_value);
764 }
765
766 return TRUE;
767}
768
769/**********************************************************************/
772bool dio_get_requirement_json(struct connection *pc, struct data_in *din,
773 const struct plocation *location,
774 struct requirement *preq)
775{
776 if (pc->json_mode) {
777 int kind, range, value;
778 bool survives, present, quiet;
779
780 struct plocation *req_field;
781
782 /* Find the requirement object. */
783 json_t *requirement = plocation_read_data(pc->json_packet, location);
784
785 if (!requirement) {
786 log_error("ERROR: Unable to get requirement from location: %s", plocation_name(location));
787 return FALSE;
788 }
789
790 /* Find the requirement object fields and translate their values. */
793 log_error("ERROR: Unable to get part of requirement from location: %s",
794 plocation_name(location));
795 return FALSE;
796 }
797
798 req_field->name = "value";
800 log_error("ERROR: Unable to get part of requirement from location: %s",
801 plocation_name(location));
802 return FALSE;
803 }
804
805 req_field->name = "range";
807 log_error("ERROR: Unable to get part of requirement from location: %s",
808 plocation_name(location));
809 return FALSE;
810 }
811
812 req_field->name = "survives";
814 log_error("ERROR: Unable to get part of requirement from location: %s",
815 plocation_name(location));
816 return FALSE;
817 }
818
819 req_field->name = "present";
821 log_error("ERROR: Unable to get part of requirement from location: %s",
822 plocation_name(location));
823 return FALSE;
824 }
825
826 req_field->name = "quiet";
828 log_error("ERROR: Unable to get part of requirement from location: %s",
829 plocation_name(location));
830 return FALSE;
831 }
832
834
835 /* Create a requirement with the values sent over the network. */
836 *preq = req_from_values(kind, range, survives, present, quiet, value);
837 } else {
839 }
840
841 return TRUE;
842}
843
844/**********************************************************************/
848 const struct plocation *location,
849 struct act_prob *prob)
850{
851 if (pc->json_mode) {
852 struct plocation *ap_field;
853
854 /* Find the action probability object. */
855 json_t *action_probability = plocation_read_data(pc->json_packet, location);
856
857 if (!action_probability) {
858 log_error("ERROR: Unable to get action probability from location: %s",
859 plocation_name(location));
860 return FALSE;
861 }
862
863 /* Find the action probability object fields and translate their
864 * values. */
867 log_error("ERROR: Unable to get part of action probability "
868 "from location: %s",
869 plocation_name(location));
870 return FALSE;
871 }
872
873 ap_field->name = "max";
875 log_error("ERROR: Unable to get part of action probability "
876 "from location: %s",
877 plocation_name(location));
878 return FALSE;
879 }
880
882 } else {
884 }
885
886 return TRUE;
887}
888
889/**********************************************************************/
893 const struct plocation *location, int size)
894{
895 int e = 0;
896
897 if (dout->json) {
898 int i;
900
901 /* Jansson's json_array_set_new() refuses to create array elements so
902 * they must be created with the array. */
903 for (i = 0; i < size; i++) {
905 }
906
907 e |= plocation_write_data(dout->json, location, farray);
908 } else {
909 /* No caller needs this */
910 }
911
912 return e;
913}
914
915/**********************************************************************/
919 const struct plocation *location)
920{
921 int e = 0;
922
923 if (dout->json) {
924 e |= plocation_write_data(dout->json, location, json_object());
925 } else {
926 /* No caller needs this */
927 }
928
929 return e;
930}
931
932/**********************************************************************/
936 const struct plocation *location, int value)
937{
938 int e;
939
940 if (dout->json) {
941 e = plocation_write_data(dout->json, location, json_integer(value));
942 } else {
943 e = dio_put_uint32_raw(&dout->raw, value);
944 }
945
946 return e;
947}
948
949/**********************************************************************/
953 const struct plocation *location, int value)
954{
955 int e;
956
957 if (dout->json) {
958 e = plocation_write_data(dout->json, location, json_integer(value));
959 } else {
960 e = dio_put_sint32_raw(&dout->raw, value);
961 }
962
963 return e;
964}
965
966/**********************************************************************/
970 const struct plocation *location, bool value)
971{
972 int e;
973
974 if (dout->json) {
975 e = plocation_write_data(dout->json, location, value ? json_true() : json_false());
976 } else {
977 e = dio_put_bool8_raw(&dout->raw, value);
978 }
979
980 return e;
981}
982
983/**********************************************************************/
987 const struct plocation *location, bool value)
988{
989 int e;
990
991 if (dout->json) {
992 e = plocation_write_data(dout->json, location, value ? json_true() : json_false());
993 } else {
994 e = dio_put_bool32_raw(&dout->raw, value);
995 }
996
997 return e;
998}
999
1000/**********************************************************************/
1004 const struct plocation *location,
1005 float value, int float_factor)
1006{
1007 int e;
1008
1009 if (dout->json) {
1010 e = plocation_write_data(dout->json, location, json_real(value));
1011 } else {
1012 e = dio_put_ufloat_raw(&dout->raw, value, float_factor);
1013 }
1014
1015 return e;
1016}
1017
1018/**********************************************************************/
1022 const struct plocation *location,
1023 float value, int float_factor)
1024{
1025 int e;
1026
1027 if (dout->json) {
1028 e = plocation_write_data(dout->json, location, json_real(value));
1029 } else {
1030 e = dio_put_sfloat_raw(&dout->raw, value, float_factor);
1031 }
1032
1033 return e;
1034}
1035
1036/**********************************************************************/
1041 const struct plocation *location, int size)
1042{
1043 int e;
1044
1045 if (dout->json) {
1046 e = dio_put_farray_json(dout, location, size);
1047 } else {
1048 e = dio_put_arraylen_raw(&dout->raw, size);
1049 }
1050
1051 return e;
1052}
1053
1054/**********************************************************************/
1058 const struct plocation *location,
1059 int *values, int stop_value)
1060{
1061 int e;
1062
1063 if (dout->json) {
1064 /* TODO: implement. */
1065 log_error("Tried to send unimplemeted data type uint8_vec8.");
1066 e = -1;
1067 } else {
1068 e = dio_put_uint8_vec8_raw(&dout->raw, values, stop_value);
1069 }
1070
1071 return e;
1072}
1073
1074/**********************************************************************/
1078 const struct plocation *location, int *values,
1079 int stop_value)
1080{
1081 int e;
1082
1083 if (dout->json) {
1084 /* TODO: implement. */
1085 log_error("Tried to send unimplemeted data type uint16_vec8.");
1086 e = -1;
1087 } else {
1088 e = dio_put_uint16_vec8_raw(&dout->raw, values, stop_value);
1089 }
1090
1091 return e;
1092}
1093
1094/**********************************************************************/
1098 struct plocation *location,
1099 const void *value,
1100 size_t size)
1101{
1102 int e;
1103
1104 if (dout->json) {
1105 int i;
1106
1107 e = dio_put_farray_json(dout, location, size);
1108
1109 location->sub_location = plocation_elem_new(0);
1110
1111 for (i = 0; i < size; i++) {
1112 location->sub_location->number = i;
1113
1114 e |= dio_put_uint8_json(dout, location,
1115 ((unsigned char *)value)[i]);
1116 }
1117
1118 FC_FREE(location->sub_location);
1119 } else {
1120 e = dio_put_memory_raw(&dout->raw, value, size);
1121 }
1122
1123 return e;
1124}
1125
1126/**********************************************************************/
1130 const struct plocation *location,
1131 const char *value)
1132{
1133 int e;
1134
1135 if (dout->json) {
1136 e = plocation_write_data(dout->json, location, json_string(value));
1137 } else {
1138 e = dio_put_string_raw(&dout->raw, value);
1139 }
1140
1141 return e;
1142}
1143
1144/**********************************************************************/
1148 const struct plocation *location,
1149 const char *value)
1150{
1151 int e;
1152
1153 if (dout->json) {
1154 char *escaped_value;
1155
1156 /* Let CURL find the length itself by passing 0 */
1158
1159 /* Handle as a regular string from now on. */
1160 e = dio_put_string_json(dout, location, escaped_value);
1161
1162 /* CURL's memory management wants to free this itself. */
1164 } else {
1165 e = dio_put_estring_raw(&dout->raw, value);
1166 }
1167
1168 return e;
1169}
1170
1171/**********************************************************************/
1175 const struct plocation *location,
1176 const struct requirement *preq)
1177{
1178 int e = 0;
1179
1180 if (dout->json) {
1181 int kind, range, value;
1182 bool survives, present, quiet;
1183
1184 /* Create the requirement object. */
1186
1187 /* Read the requirement values. */
1188 req_get_values(preq, &kind, &range, &survives, &present, &quiet, &value);
1189
1190 /* Write the requirement values to the fields of the requirement
1191 * object. */
1193 e |= json_object_set_new(requirement, "value", json_integer(value));
1194
1196
1197 e |= json_object_set_new(requirement, "survives", json_boolean(survives));
1198 e |= json_object_set_new(requirement, "present", json_boolean(present));
1199 e |= json_object_set_new(requirement, "quiet", json_boolean(quiet));
1200
1201 /* Put the requirement object in the packet. */
1202 e |= plocation_write_data(dout->json, location, requirement);
1203 } else {
1204 e = dio_put_requirement_raw(&dout->raw, preq);
1205 }
1206
1207 return e;
1208}
1209
1210/**********************************************************************/
1214 const struct plocation *location,
1215 const struct act_prob *prob)
1216{
1217 int e = 0;
1218
1219 if (dout->json) {
1220 /* Create the action probability object. */
1222
1223 /* Write the action probability values to the fields of the action
1224 * probability object. */
1227
1228 /* Put the action probability object in the packet. */
1229 e |= plocation_write_data(dout->json, location, action_probability);
1230 } else {
1231 e = dio_put_action_probability_raw(&dout->raw, prob);
1232 }
1233
1234 return e;
1235}
1236
1237/**********************************************************************/
1241 const struct plocation *location,
1242 bool *dest)
1243{
1245
1246 if (!pbool) {
1247 log_error("ERROR: Unable to get bool8 from location: %s", plocation_name(location));
1248 return FALSE;
1249 }
1250 *dest = json_is_true(pbool);
1251
1252 return TRUE;
1253}
1254
1255/**********************************************************************/
1258bool dio_get_bool8_json(struct connection *pc, struct data_in *din,
1259 const struct plocation *location, bool *dest)
1260{
1261 if (pc->json_mode) {
1262 return dio_get_bool8_json_internal(pc->json_packet, location, dest);
1263 } else {
1264 return dio_get_bool8_raw(din, dest);
1265 }
1266}
1267
1268/**********************************************************************/
1271bool dio_get_bool32_json(struct connection *pc, struct data_in *din,
1272 const struct plocation *location, bool *dest)
1273{
1274 if (pc->json_mode) {
1275 json_t *pbool = plocation_read_data(pc->json_packet, location);
1276
1277 if (!pbool) {
1278 log_error("ERROR: Unable to get bool32 from location: %s", plocation_name(location));
1279 return FALSE;
1280 }
1281 *dest = json_is_true(pbool);
1282 } else {
1283 return dio_get_bool32_raw(din, dest);
1284 }
1285
1286 return TRUE;
1287}
1288
1289/**********************************************************************/
1292bool dio_get_ufloat_json(struct connection *pc, struct data_in *din,
1293 const struct plocation *location,
1294 float *dest, int float_factor)
1295{
1296 if (pc->json_mode) {
1297 json_t *preal = plocation_read_data(pc->json_packet, location);
1298
1299 if (!preal) {
1300 log_error("ERROR: Unable to get real from location: %s", plocation_name(location));
1301 return FALSE;
1302 }
1303 *dest = json_real_value(preal);
1304 } else {
1305 return dio_get_ufloat_raw(din, dest, float_factor);
1306 }
1307
1308 return TRUE;
1309}
1310
1311/**********************************************************************/
1314bool dio_get_sfloat_json(struct connection *pc, struct data_in *din,
1315 const struct plocation *location,
1316 float *dest, int float_factor)
1317{
1318 if (pc->json_mode) {
1319 json_t *preal = plocation_read_data(pc->json_packet, location);
1320
1321 if (!preal) {
1322 log_error("ERROR: Unable to get real from location: %s", plocation_name(location));
1323 return FALSE;
1324 }
1325 *dest = json_real_value(preal);
1326 } else {
1327 return dio_get_sfloat_raw(din, dest, float_factor);
1328 }
1329
1330 return TRUE;
1331}
1332
1333/**********************************************************************/
1336bool dio_get_sint8_json(struct connection *pc, struct data_in *din,
1337 const struct plocation *location, int *dest)
1338{
1339 if (pc->json_mode) {
1340 json_t *pint = plocation_read_data(pc->json_packet, location);
1341
1342 if (!pint) {
1343 log_error("ERROR: Unable to get sint8 from location: %s", plocation_name(location));
1344 return FALSE;
1345 }
1346 *dest = json_integer_value(pint);
1347 } else {
1348 return dio_get_sint8_raw(din, dest);
1349 }
1350
1351 return TRUE;
1352}
1353
1354/**********************************************************************/
1357bool dio_get_sint16_json(struct connection *pc, struct data_in *din,
1358 const struct plocation *location, int *dest)
1359{
1360 if (pc->json_mode) {
1361 json_t *pint = plocation_read_data(pc->json_packet, location);
1362
1363 if (!pint) {
1364 log_error("ERROR: Unable to get sint16 from location: %s", plocation_name(location));
1365 return FALSE;
1366 }
1367 *dest = json_integer_value(pint);
1368 } else {
1369 return dio_get_sint16_raw(din, dest);
1370 }
1371
1372 return TRUE;
1373}
1374
1375/**********************************************************************/
1378bool dio_get_memory_json(struct connection *pc, struct data_in *din,
1379 struct plocation *location,
1380 void *dest, size_t dest_size)
1381{
1382 if (pc->json_mode) {
1383 int i;
1384
1385 location->sub_location = plocation_elem_new(0);
1386
1387 for (i = 0; i < dest_size; i++) {
1388 int val;
1389
1390 location->sub_location->number = i;
1391
1392 if (!dio_get_uint8_json_internal(pc->json_packet, location, &val)) {
1393 free(location->sub_location);
1394 return FALSE;
1395 }
1396 ((unsigned char *)dest)[i] = val;
1397 }
1398
1399 FC_FREE(location->sub_location);
1400 } else {
1401 return dio_get_memory_raw(din, dest, dest_size);
1402 }
1403
1404 return TRUE;
1405}
1406
1407/**********************************************************************/
1411 const struct plocation *location,
1412 char *dest, size_t max_dest_size)
1413{
1415 const char *result_str;
1416
1417 if (!pstring) {
1418 log_error("ERROR: Unable to get string from location: %s", plocation_name(location));
1419 return FALSE;
1420 }
1421
1423
1424 if (dest
1426 log_error("ERROR: Unable to get string from location: %s", plocation_name(location));
1427 return FALSE;
1428 }
1429
1430 return TRUE;
1431}
1432
1433/**********************************************************************/
1436bool dio_get_string_json(struct connection *pc, struct data_in *din,
1437 const struct plocation *location,
1438 char *dest, size_t max_dest_size)
1439{
1440 if (pc->json_mode) {
1441 return dio_get_string_json_internal(pc->json_packet, location,
1442 dest, max_dest_size);
1443 } else {
1444 return dio_get_string_raw(din, dest, max_dest_size);
1445 }
1446}
1447
1448/**********************************************************************/
1453bool dio_get_estring_json(struct connection *pc, struct data_in *din,
1454 const struct plocation *location,
1455 char *dest, size_t max_dest_size)
1456{
1457 if (pc->json_mode) {
1458 char *escaped_value;
1459 char *unescaped_value;
1460
1461 /* The encoded string has the same size limit as the decoded string. */
1463
1464 if (!dio_get_string_json_internal(pc->json_packet, location,
1466 /* dio_get_string_json() has logged this already. */
1467 return FALSE;
1468 }
1469
1470 /* Let CURL find the length itself by passing 0 */
1472 0, nullptr);
1473
1474 /* Done with the escaped value. */
1476
1477 /* Copy the unescaped value so CURL can free its own copy. */
1478 memcpy(dest, unescaped_value,
1479 /* Don't copy the memory following unescaped_value. */
1481
1482 /* CURL's memory management wants to free this itself. */
1484
1485 /* Make sure that the string is terminated. */
1486 dest[max_dest_size - 1] = '\0';
1487 } else {
1488 return dio_get_estring_raw(din, dest, max_dest_size);
1489 }
1490
1491 return TRUE;
1492}
1493
1494#endif /* FREECIV_JSON_CONNECTION */
#define n
Definition astring.c:77
void cm_init_parameter(struct cm_parameter *dest)
Definition cm.c:2185
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:102
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:935
int min
Definition fc_types.h:934
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:593
universals_u value
Definition fc_types.h:592
#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