Freeciv-3.2
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 // PTZ200718 handles last element get case...
124 // better here than all around put_array-diff algo ?
125 size_t n = (location->number == -1)
126 ? (json_array_size(item) - 1)
127 : location->number;
128
130
131 if (json_is_array(sub_item)) {
133 location->sub_location, data);
134 } else {
135 log_error("ERROR:plocation_write_elem:array not found for sub location:"
136 "%s @[" SIZE_T_PRINTF "]",
138 }
139 }
140
141 return e;
142}
143
144/**********************************************************************/
149 const struct plocation *location,
150 json_t *data)
151{
152 int e = -1;
153
154 switch (location->kind) {
155 case PADR_FIELD:
156 e = plocation_write_field(item, location, data);
157 break;
158 case PADR_ELEMENT:
159 e = plocation_write_elem(item, location, data);
160 break;
161 default:
162 log_error("Unknown packet part location kind.");
163 break;
164 }
165
166 return e;
167}
168
170 const struct plocation *location);
171
172/**********************************************************************/
176 const struct plocation *location)
177{
178 if (location->sub_location == NULL) {
179 return json_object_get(item, location->name);
180 } else {
181 return plocation_read_data(json_object_get(item, location->name),
182 location->sub_location);
183 }
184}
185
186/**********************************************************************/
190 const struct plocation *location)
191{
192 if (location->sub_location == NULL) {
193 return json_array_get(item, location->number);
194 } else {
196 location->sub_location);
197 }
198}
199
200/**********************************************************************/
204 const struct plocation *location)
205{
206 if (json_is_null(item)) { // PTZ200719 sanity checks stops the massacre
207 return item;
208 }
209
210 switch (location->kind) {
211 case PADR_FIELD:
212 return plocation_read_field(item, location);
213 case PADR_ELEMENT:
214 return plocation_read_elem(item, location);
215 default:
216 log_error("Unknown packet part location kind.");
217 return NULL;
218 }
219}
220
221/**********************************************************************/
225 const struct plocation *location,
226 int value)
227{
228 int e;
229
230 if (dout->json) {
231 e = plocation_write_data(dout->json, location, json_integer(value));
232 } else {
233 e = dio_put_uint8_raw(&dout->raw, value);
234 }
235
236 return e;
237}
238
239/**********************************************************************/
243 const struct plocation *location,
244 int value)
245{
246 int e;
247
248 if (dout->json) {
249 e = plocation_write_data(dout->json, location, json_integer(value));
250 } else {
251 e = dio_put_sint8_raw(&dout->raw, value);
252 }
253
254 return e;
255}
256
257/**********************************************************************/
261 const struct plocation *location, int value)
262{
263 int e;
264
265 if (dout->json) {
266 e = plocation_write_data(dout->json, location, json_integer(value));
267 } else {
268 e = dio_put_uint16_raw(&dout->raw, value);
269 }
270
271 return e;
272}
273
274/**********************************************************************/
278 const struct plocation *location, int value)
279{
280 int e;
281
282 if (dout->json) {
283 e = plocation_write_data(dout->json, location, json_integer(value));
284 } else {
285 e = dio_put_sint16_raw(&dout->raw, value);
286 }
287
288 return e;
289}
290
291/**********************************************************************/
295 struct plocation *location,
296 const struct cm_parameter *param)
297{
298 int e = 0;
299
300 if (dout->json) {
303 json_t *factor = json_array();
304 int i;
305
306 for (i = 0; i < O_LAST; i++) {
309 e |= json_array_append_new(factor,
310 json_integer(param->factor[i]));
311 }
312
313 e |= json_object_set_new(obj, "minimal_surplus", min_surplus);
314 e |= json_object_set_new(obj, "factor", factor);
315 e |= json_object_set_new(obj, "max_growth", json_boolean(param->max_growth));
316 e |= json_object_set_new(obj, "require_happy",
318 e |= json_object_set_new(obj, "allow_disorder",
320 e |= json_object_set_new(obj, "allow_specialists",
322 e |= json_object_set_new(obj, "happy_factor",
323 json_integer(param->happy_factor));
324 e |= plocation_write_data(dout->json, location, obj);
325 } else {
326 e = dio_put_cm_parameter_raw(&dout->raw, param);
327 }
328
329 return e;
330}
331
332/**********************************************************************/
336 struct plocation *location,
337 const struct unit_order *order)
338{
339 int e = 0;
340
341 if (dout->json) {
343
344 e |= json_object_set_new(obj, "order", json_integer(order->order));
345 e |= json_object_set_new(obj, "activity", json_integer(order->activity));
346 e |= json_object_set_new(obj, "target", json_integer(order->target));
347 e |= json_object_set_new(obj, "sub_target", json_integer(order->sub_target));
348 e |= json_object_set_new(obj, "action", json_integer(order->action));
349 if (order->dir == -1) {
350 /* Avoid integer underflow */
351 e |= json_object_set_new(obj, "dir", json_integer(-1));
352 } else {
353 e |= json_object_set_new(obj, "dir", json_integer(order->dir));
354 }
355 e |= plocation_write_data(dout->json, location, obj);
356 } else {
357 e = dio_put_unit_order_raw(&dout->raw, order);
358 }
359
360 return e;
361}
362
363/**********************************************************************/
367 struct plocation *location,
368 const struct worklist *pwl)
369{
370 int e = 0;
371
372 if (dout->json) {
373 int i;
374 const int size = worklist_length(pwl);
375
376 /* Must create the array before insertion. */
377 e |= dio_put_farray_json(dout, location, size);
378
379 location->sub_location = plocation_elem_new(0);
380
381 for (i = 0; i < size; i++) {
382 const struct universal *pcp = &(pwl->entries[i]);
384
385 location->sub_location->number = i;
386
387 e |= json_object_set_new(universal, "kind", json_integer(pcp->kind));
388 e |= json_object_set_new(universal, "value",
390
391 e |= plocation_write_data(dout->json, location, universal);
392 }
393
394 FC_FREE(location->sub_location);
395 } else {
396 e = dio_put_worklist_raw(&dout->raw, pwl);
397 }
398
399 return e;
400}
401
402/**********************************************************************/
406 const struct plocation *location,
407 int *dest)
408{
410
411 if (!pint) {
412 log_error("ERROR: Unable to get uint8 from location: %s", plocation_name(location));
413 return FALSE;
414 }
415 *dest = json_integer_value(pint);
416
417 if (!dest) {
418 log_error("ERROR: Unable to get unit8 from location: %s", plocation_name(location));
419 return FALSE;
420 }
421
422 return TRUE;
423}
424
425/**********************************************************************/
428bool dio_get_uint8_json(struct connection *pc, struct data_in *din,
429 const struct plocation *location, int *dest)
430{
431 if (pc->json_mode) {
432 return dio_get_uint8_json_internal(pc->json_packet, location, dest);
433 } else {
434 return dio_get_uint8_raw(din, dest);
435 }
436}
437
438/**********************************************************************/
441bool dio_get_uint16_json(struct connection *pc, struct data_in *din,
442 const struct plocation *location, int *dest)
443{
444 if (pc->json_mode) {
445 json_t *pint = plocation_read_data(pc->json_packet, location);
446
447 if (!pint) {
448 log_error("ERROR: Unable to get uint16 from location: %s", plocation_name(location));
449 return FALSE;
450 }
451 *dest = json_integer_value(pint);
452
453 if (!dest) {
454 log_error("ERROR: Unable to get unit16 from location: %s", plocation_name(location));
455 return FALSE;
456 }
457 } else {
458 return dio_get_uint16_raw(din, dest);
459 }
460
461 return TRUE;
462}
463
464/**********************************************************************/
468 const struct plocation *location,
469 int *dest)
470{
472
473 if (!pint) {
474 log_error("ERROR: Unable to get uint32 from location: %s", plocation_name(location));
475 return FALSE;
476 }
477 *dest = json_integer_value(pint);
478
479 if (!dest) {
480 log_error("ERROR: Unable to get unit32 from location: %s", plocation_name(location));
481 return FALSE;
482 }
483
484 return TRUE;
485}
486
487/**********************************************************************/
490bool dio_get_uint32_json(struct connection *pc, struct data_in *din,
491 const struct plocation *location, int *dest)
492{
493 if (pc->json_mode) {
494 return dio_get_uint32_json_internal(pc->json_packet, location, dest);
495 } else {
496 return dio_get_uint32_raw(din, dest);
497 }
498}
499
500/**********************************************************************/
503bool dio_get_sint32_json(struct connection *pc, struct data_in *din,
504 const struct plocation *location, int *dest)
505{
506 if (pc->json_mode) {
507 return dio_get_uint32_json_internal(pc->json_packet, location, dest);
508 } else {
509 return dio_get_sint32_raw(din, dest);
510 }
511}
512
513/**********************************************************************/
517 struct plocation *location,
518 struct cm_parameter *param)
519{
520 if (pc->json_mode) {
521 int i;
522
523 cm_init_parameter(param);
524
525 location->sub_location = plocation_field_new("max_growth");
526 if (!dio_get_bool8_json(pc, din, location, &param->max_growth)) {
527 log_packet("Corrupt cm_parameter.max_growth");
528 FC_FREE(location->sub_location);
529 return FALSE;
530 }
531
532 location->sub_location->name = "require_happy";
533 if (!dio_get_bool8_json(pc, din, location, &param->require_happy)) {
534 log_packet("Corrupt cm_parameter.require_happy");
535 FC_FREE(location->sub_location);
536 return FALSE;
537 }
538
539 location->sub_location->name = "allow_disorder";
540 if (!dio_get_bool8_json(pc, din, location, &param->allow_disorder)) {
541 log_packet("Corrupt cm_parameter.allow_disorder");
542 FC_FREE(location->sub_location);
543 return FALSE;
544 }
545
546 location->sub_location->name = "allow_specialists";
547 if (!dio_get_bool8_json(pc, din, location, &param->allow_specialists)) {
548 log_packet("Corrupt cm_parameter.allow_specialists");
549 FC_FREE(location->sub_location);
550 FC_FREE(location->sub_location);
551 return FALSE;
552 }
553
554 location->sub_location->name = "happy_factor";
555 if (!dio_get_uint16_json(pc, din, location, &param->happy_factor)) {
556 log_packet("Corrupt cm_parameter.happy_factor");
557 FC_FREE(location->sub_location);
558 return FALSE;
559 }
560
561 location->sub_location->name = "factor";
563 for (i = 0; i < O_LAST; i++) {
564 location->sub_location->sub_location->number = i;
565 if (!dio_get_uint16_json(pc, din, location, &param->factor[i])) {
566 log_packet("Corrupt cm_parameter.factor");
568 FC_FREE(location->sub_location);
569 return FALSE;
570 }
571 }
572
573 location->sub_location->name = "minimal_surplus";
574 for (i = 0; i < O_LAST; i++) {
575 location->sub_location->sub_location->number = i;
576 if (!dio_get_sint16_json(pc, din, location,
577 &param->minimal_surplus[i])) {
578 log_packet("Corrupt cm_parameter.minimal_surplus");
580 FC_FREE(location->sub_location);
581 return FALSE;
582 }
583 }
584
586 FC_FREE(location->sub_location);
587 } else {
588 return dio_get_cm_parameter_raw(din, param);
589 }
590
591 return TRUE;
592}
593
594/**********************************************************************/
597bool dio_get_unit_order_json(struct connection *pc, struct data_in *din,
598 struct plocation *location,
599 struct unit_order *order)
600{
601 if (pc->json_mode) {
602 struct plocation *loc;
603 int iorder, iactivity, idir; /* These fields are enums */
604
605 /* Orders may be located in a nested field (as items in an array) */
606 loc = location;
607 while (loc->sub_location) {
608 loc = loc->sub_location;
609 }
610
611 loc->sub_location = plocation_field_new("order");
612 if (!dio_get_uint8_json(pc, din, location, &iorder)) {
613 log_packet("Corrupt order.order");
614 FC_FREE(loc->sub_location);
615 return FALSE;
616 }
617
618 loc->sub_location->name = "activity";
619 if (!dio_get_uint8_json(pc, din, location, &iactivity)) {
620 log_packet("Corrupt order.activity");
621 FC_FREE(loc->sub_location);
622 return FALSE;
623 }
624
625 loc->sub_location->name = "target";
626 if (!dio_get_sint32_json(pc, din, location, &order->target)) {
627 log_packet("Corrupt order.target");
628 FC_FREE(loc->sub_location);
629 return FALSE;
630 }
631
632 loc->sub_location->name = "sub_target";
633 if (!dio_get_sint16_json(pc, din, location, &order->sub_target)) {
634 log_packet("Corrupt order.sub_target");
635 FC_FREE(loc->sub_location);
636 return FALSE;
637 }
638
639 loc->sub_location->name = "action";
640 if (!dio_get_uint8_json(pc, din, location, &order->action)) {
641 log_packet("Corrupt order.action");
642 FC_FREE(loc->sub_location);
643 return FALSE;
644 }
645
646 loc->sub_location->name = "dir";
647 if (!dio_get_uint8_json(pc, din, location, &idir)) {
648 log_packet("Corrupt order.dir");
649 FC_FREE(loc->sub_location);
650 return FALSE;
651 }
652
653 /*
654 * FIXME: The values should be checked!
655 */
656 order->order = iorder;
657 order->activity = iactivity;
658 order->dir = idir;
659
660 FC_FREE(loc->sub_location);
661 } else {
662 return dio_get_unit_order_raw(din, order);
663 }
664
665 return TRUE;
666}
667
668/**********************************************************************/
671bool dio_get_worklist_json(struct connection *pc, struct data_in *din,
672 struct plocation *location,
673 struct worklist *pwl)
674{
675 if (pc->json_mode) {
676 int i, length;
677
678 const json_t *wlist = plocation_read_data(pc->json_packet, location);
679
681
682 if (!json_is_array(wlist)) {
683 log_packet("Not a worklist");
684 return FALSE;
685 }
686
687 /* Safe. Checked that it was an array above. */
688 length = json_array_size(wlist);
689
690 /* A worklist is an array... */
691 location->sub_location = plocation_elem_new(0);
692
693 /* ... of universal objects. */
694 location->sub_location->sub_location = plocation_field_new("kind");
695
696 for (i = 0; i < length; i++) {
697 int value;
698 int kind;
699 struct universal univ;
700
701 location->sub_location->number = i;
702
703 location->sub_location->sub_location->name = "kind";
704 if (!dio_get_uint8_json_internal(pc->json_packet, location, &kind)) {
705 log_packet("Corrupt worklist element kind");
707 FC_FREE(location->sub_location);
708 return FALSE;
709 }
710
711 location->sub_location->sub_location->name = "value";
712 if (!dio_get_uint8_json_internal(pc->json_packet, location, &value)) {
713 log_packet("Corrupt worklist element value");
715 FC_FREE(location->sub_location);
716 return FALSE;
717 }
718
719 /*
720 * FIXME: the value returned by universal_by_number() should be checked!
721 */
723 worklist_append(pwl, &univ);
724 }
725
727 FC_FREE(location->sub_location);
728 } else {
730 }
731
732 return TRUE;
733}
734
735/**********************************************************************/
738bool dio_get_uint8_vec8_json(struct connection *pc, struct data_in *din,
739 const struct plocation *location,
740 int **values, int stop_value)
741{
742 if (pc->json_mode) {
743 /* TODO: implement */
744 log_warn("Received unimplemeted data type uint8_vec8.");
745 } else {
746 return dio_get_uint8_vec8_raw(din, values, stop_value);
747 }
748
749 return TRUE;
750}
751
752/**********************************************************************/
755bool dio_get_uint16_vec8_json(struct connection *pc, struct data_in *din,
756 const struct plocation *location,
757 int **values,
758 int stop_value)
759{
760 if (pc->json_mode) {
761 /* TODO: implement */
762 log_warn("Received unimplemeted data type uint16_vec8.");
763 } else {
764 return dio_get_uint16_vec8_raw(din, values, stop_value);
765 }
766
767 return TRUE;
768}
769
770/**********************************************************************/
773bool dio_get_requirement_json(struct connection *pc, struct data_in *din,
774 const struct plocation *location,
775 struct requirement *preq)
776{
777 if (pc->json_mode) {
778 int kind, range, value;
779 bool survives, present, quiet;
780
781 struct plocation *req_field;
782
783 /* Find the requirement object. */
784 json_t *requirement = plocation_read_data(pc->json_packet, location);
785
786 if (!requirement) {
787 log_error("ERROR: Unable to get requirement from location: %s", plocation_name(location));
788 return FALSE;
789 }
790
791 /* Find the requirement object fields and translate their values. */
794 log_error("ERROR: Unable to get part of requirement from location: %s",
795 plocation_name(location));
796 return FALSE;
797 }
798
799 req_field->name = "value";
801 log_error("ERROR: Unable to get part of requirement from location: %s",
802 plocation_name(location));
803 return FALSE;
804 }
805
806 req_field->name = "range";
808 log_error("ERROR: Unable to get part of requirement from location: %s",
809 plocation_name(location));
810 return FALSE;
811 }
812
813 req_field->name = "survives";
815 log_error("ERROR: Unable to get part of requirement from location: %s",
816 plocation_name(location));
817 return FALSE;
818 }
819
820 req_field->name = "present";
822 log_error("ERROR: Unable to get part of requirement from location: %s",
823 plocation_name(location));
824 return FALSE;
825 }
826
827 req_field->name = "quiet";
829 log_error("ERROR: Unable to get part of requirement from location: %s",
830 plocation_name(location));
831 return FALSE;
832 }
833
835
836 /* Create a requirement with the values sent over the network. */
837 *preq = req_from_values(kind, range, survives, present, quiet, value);
838 } else {
840 }
841
842 return TRUE;
843}
844
845/**********************************************************************/
849 const struct plocation *location,
850 struct act_prob *prob)
851{
852 if (pc->json_mode) {
853 struct plocation *ap_field;
854
855 /* Find the action probability object. */
856 json_t *action_probability = plocation_read_data(pc->json_packet, location);
857
858 if (!action_probability) {
859 log_error("ERROR: Unable to get action probability from location: %s",
860 plocation_name(location));
861 return FALSE;
862 }
863
864 /* Find the action probability object fields and translate their
865 * values. */
868 log_error("ERROR: Unable to get part of action probability "
869 "from location: %s",
870 plocation_name(location));
871 return FALSE;
872 }
873
874 ap_field->name = "max";
876 log_error("ERROR: Unable to get part of action probability "
877 "from location: %s",
878 plocation_name(location));
879 return FALSE;
880 }
881
883 } else {
885 }
886
887 return TRUE;
888}
889
890/**********************************************************************/
894 const struct plocation *location, int size)
895{
896 int e = 0;
897
898 if (dout->json) {
899 int i;
901
902 /* Jansson's json_array_set_new() refuses to create array elements so
903 * they must be created with the array. */
904 for (i = 0; i < size; i++) {
906 }
907
908 e |= plocation_write_data(dout->json, location, farray);
909 } else {
910 /* No caller needs this */
911 }
912
913 return e;
914}
915
916/**********************************************************************/
920 const struct plocation *location, int value)
921{
922 int e;
923
924 if (dout->json) {
925 e = plocation_write_data(dout->json, location, json_integer(value));
926 } else {
927 e = dio_put_uint32_raw(&dout->raw, value);
928 }
929
930 return e;
931}
932
933/**********************************************************************/
937 const struct plocation *location, int value)
938{
939 int e;
940
941 if (dout->json) {
942 e = plocation_write_data(dout->json, location, json_integer(value));
943 } else {
944 e = dio_put_sint32_raw(&dout->raw, value);
945 }
946
947 return e;
948}
949
950/**********************************************************************/
954 const struct plocation *location, bool value)
955{
956 int e;
957
958 if (dout->json) {
959 e = plocation_write_data(dout->json, location, value ? json_true() : json_false());
960 } else {
961 e = dio_put_bool8_raw(&dout->raw, value);
962 }
963
964 return e;
965}
966
967/**********************************************************************/
971 const struct plocation *location, bool value)
972{
973 int e;
974
975 if (dout->json) {
976 e = plocation_write_data(dout->json, location, value ? json_true() : json_false());
977 } else {
978 e = dio_put_bool32_raw(&dout->raw, value);
979 }
980
981 return e;
982}
983
984/**********************************************************************/
988 const struct plocation *location,
989 float value, int float_factor)
990{
991 int e;
992
993 if (dout->json) {
994 e = plocation_write_data(dout->json, location, json_real(value));
995 } else {
996 e = dio_put_ufloat_raw(&dout->raw, value, float_factor);
997 }
998
999 return e;
1000}
1001
1002/**********************************************************************/
1006 const struct plocation *location,
1007 float value, int float_factor)
1008{
1009 int e;
1010
1011 if (dout->json) {
1012 e = plocation_write_data(dout->json, location, json_real(value));
1013 } else {
1014 e = dio_put_sfloat_raw(&dout->raw, value, float_factor);
1015 }
1016
1017 return e;
1018}
1019
1020/**********************************************************************/
1024 const struct plocation *location,
1025 int *values, int stop_value)
1026{
1027 int e;
1028
1029 if (dout->json) {
1030 /* TODO: implement. */
1031 log_error("Tried to send unimplemeted data type uint8_vec8.");
1032 e = -1;
1033 } else {
1034 e = dio_put_uint8_vec8_raw(&dout->raw, values, stop_value);
1035 }
1036
1037 return e;
1038}
1039
1040/**********************************************************************/
1044 const struct plocation *location, int *values,
1045 int stop_value)
1046{
1047 int e;
1048
1049 if (dout->json) {
1050 /* TODO: implement. */
1051 log_error("Tried to send unimplemeted data type uint16_vec8.");
1052 e = -1;
1053 } else {
1054 e = dio_put_uint16_vec8_raw(&dout->raw, values, stop_value);
1055 }
1056
1057 return e;
1058}
1059
1060/**********************************************************************/
1064 struct plocation *location,
1065 const void *value,
1066 size_t size)
1067{
1068 int e;
1069
1070 if (dout->json) {
1071 int i;
1072
1073 e = dio_put_farray_json(dout, location, size);
1074
1075 location->sub_location = plocation_elem_new(0);
1076
1077 for (i = 0; i < size; i++) {
1078 location->sub_location->number = i;
1079
1080 e |= dio_put_uint8_json(dout, location,
1081 ((unsigned char *)value)[i]);
1082 }
1083
1084 FC_FREE(location->sub_location);
1085 } else {
1086 e = dio_put_memory_raw(&dout->raw, value, size);
1087 }
1088
1089 return e;
1090}
1091
1092/**********************************************************************/
1096 const struct plocation *location,
1097 const char *value)
1098{
1099 int e;
1100
1101 if (dout->json) {
1102 e = plocation_write_data(dout->json, location, json_string(value));
1103 } else {
1104 e = dio_put_string_raw(&dout->raw, value);
1105 }
1106
1107 return e;
1108}
1109
1110/**********************************************************************/
1114 const struct plocation *location,
1115 const char *value)
1116{
1117 int e;
1118
1119 if (dout->json) {
1120 char *escaped_value;
1121
1122 /* Let CURL find the length it self by passing 0 */
1124
1125 /* Handle as a regular string from now on. */
1126 e = dio_put_string_json(dout, location, escaped_value);
1127
1128 /* CURL's memory management wants to free this it self. */
1130 } else {
1131 e = dio_put_estring_raw(&dout->raw, value);
1132 }
1133
1134 return e;
1135}
1136
1137/**********************************************************************/
1141 const struct plocation *location,
1142 const struct requirement *preq)
1143{
1144 int e = 0;
1145
1146 if (dout->json) {
1147 int kind, range, value;
1148 bool survives, present, quiet;
1149
1150 /* Create the requirement object. */
1152
1153 /* Read the requirement values. */
1154 req_get_values(preq, &kind, &range, &survives, &present, &quiet, &value);
1155
1156 /* Write the requirement values to the fields of the requirement
1157 * object. */
1159 e |= json_object_set_new(requirement, "value", json_integer(value));
1160
1162
1163 e |= json_object_set_new(requirement, "survives", json_boolean(survives));
1164 e |= json_object_set_new(requirement, "present", json_boolean(present));
1165 e |= json_object_set_new(requirement, "quiet", json_boolean(quiet));
1166
1167 /* Put the requirement object in the packet. */
1168 e |= plocation_write_data(dout->json, location, requirement);
1169 } else {
1170 e = dio_put_requirement_raw(&dout->raw, preq);
1171 }
1172
1173 return e;
1174}
1175
1176/**********************************************************************/
1180 const struct plocation *location,
1181 const struct act_prob *prob)
1182{
1183 int e = 0;
1184
1185 if (dout->json) {
1186 /* Create the action probability object. */
1188
1189 /* Write the action probability values to the fields of the action
1190 * probability object. */
1193
1194 /* Put the action probability object in the packet. */
1195 e |= plocation_write_data(dout->json, location, action_probability);
1196 } else {
1197 e = dio_put_action_probability_raw(&dout->raw, prob);
1198 }
1199
1200 return e;
1201}
1202
1203/**********************************************************************/
1207 const struct plocation *location,
1208 bool *dest)
1209{
1211
1212 if (!pbool) {
1213 log_error("ERROR: Unable to get bool8 from location: %s", plocation_name(location));
1214 return FALSE;
1215 }
1216 *dest = json_is_true(pbool);
1217
1218 if (!dest) {
1219 log_error("ERROR: Unable to get bool from location: %s", plocation_name(location));
1220 return FALSE;
1221 }
1222
1223 return TRUE;
1224}
1225
1226/**********************************************************************/
1229bool dio_get_bool8_json(struct connection *pc, struct data_in *din,
1230 const struct plocation *location, bool *dest)
1231{
1232 if (pc->json_mode) {
1233 return dio_get_bool8_json_internal(pc->json_packet, location, dest);
1234 } else {
1235 return dio_get_bool8_raw(din, dest);
1236 }
1237}
1238
1239/**********************************************************************/
1242bool dio_get_bool32_json(struct connection *pc, struct data_in *din,
1243 const struct plocation *location, bool *dest)
1244{
1245 if (pc->json_mode) {
1246 json_t *pbool = plocation_read_data(pc->json_packet, location);
1247
1248 if (!pbool) {
1249 log_error("ERROR: Unable to get bool32 from location: %s", plocation_name(location));
1250 return FALSE;
1251 }
1252 *dest = json_is_true(pbool);
1253
1254 if (!dest) {
1255 log_error("ERROR: Unable to get bool32 from location: %s", plocation_name(location));
1256 return FALSE;
1257 }
1258 } else {
1259 return dio_get_bool32_raw(din, dest);
1260 }
1261
1262 return TRUE;
1263}
1264
1265/**********************************************************************/
1268bool dio_get_ufloat_json(struct connection *pc, struct data_in *din,
1269 const struct plocation *location,
1270 float *dest, int float_factor)
1271{
1272 if (pc->json_mode) {
1273 json_t *preal = plocation_read_data(pc->json_packet, location);
1274
1275 if (!preal) {
1276 log_error("ERROR: Unable to get real from location: %s", plocation_name(location));
1277 return FALSE;
1278 }
1279 *dest = json_real_value(preal);
1280 } else {
1281 return dio_get_ufloat_raw(din, dest, float_factor);
1282 }
1283
1284 return TRUE;
1285}
1286
1287/**********************************************************************/
1290bool dio_get_sfloat_json(struct connection *pc, struct data_in *din,
1291 const struct plocation *location,
1292 float *dest, int float_factor)
1293{
1294 if (pc->json_mode) {
1295 json_t *preal = plocation_read_data(pc->json_packet, location);
1296
1297 if (!preal) {
1298 log_error("ERROR: Unable to get real from location: %s", plocation_name(location));
1299 return FALSE;
1300 }
1301 *dest = json_real_value(preal);
1302 } else {
1303 return dio_get_sfloat_raw(din, dest, float_factor);
1304 }
1305
1306 return TRUE;
1307}
1308
1309/**********************************************************************/
1312bool dio_get_sint8_json(struct connection *pc, struct data_in *din,
1313 const struct plocation *location, int *dest)
1314{
1315 if (pc->json_mode) {
1316 json_t *pint = plocation_read_data(pc->json_packet, location);
1317
1318 if (!pint) {
1319 log_error("ERROR: Unable to get sint8 from location: %s", plocation_name(location));
1320 return FALSE;
1321 }
1322 *dest = json_integer_value(pint);
1323
1324 if (!dest) {
1325 log_error("ERROR: Unable to get sint8 from location: %s", plocation_name(location));
1326 return FALSE;
1327 }
1328 } else {
1329 return dio_get_sint8_raw(din, dest);
1330 }
1331
1332 return TRUE;
1333}
1334
1335/**********************************************************************/
1338bool dio_get_sint16_json(struct connection *pc, struct data_in *din,
1339 const struct plocation *location, int *dest)
1340{
1341 if (pc->json_mode) {
1342 json_t *pint = plocation_read_data(pc->json_packet, location);
1343
1344 if (!pint) {
1345 log_error("ERROR: Unable to get sint16 from location: %s", plocation_name(location));
1346 return FALSE;
1347 }
1348 *dest = json_integer_value(pint);
1349
1350 if (!dest) {
1351 log_error("ERROR: Unable to get sint16 from location: %s", plocation_name(location));
1352 return FALSE;
1353 }
1354 } else {
1355 return dio_get_sint16_raw(din, dest);
1356 }
1357
1358 return TRUE;
1359}
1360
1361/**********************************************************************/
1364bool dio_get_memory_json(struct connection *pc, struct data_in *din,
1365 struct plocation *location,
1366 void *dest, size_t dest_size)
1367{
1368 if (pc->json_mode) {
1369 int i;
1370
1371 location->sub_location = plocation_elem_new(0);
1372
1373 for (i = 0; i < dest_size; i++) {
1374 int val;
1375
1376 location->sub_location->number = i;
1377
1378 if (!dio_get_uint8_json_internal(pc->json_packet, location, &val)) {
1379 free(location->sub_location);
1380 return FALSE;
1381 }
1382 ((unsigned char *)dest)[i] = val;
1383 }
1384
1385 FC_FREE(location->sub_location);
1386 } else {
1387 return dio_get_memory_raw(din, dest, dest_size);
1388 }
1389
1390 return TRUE;
1391}
1392
1393/**********************************************************************/
1397 const struct plocation *location,
1398 char *dest, size_t max_dest_size)
1399{
1401 const char *result_str;
1402
1403 if (!pstring) {
1404 log_error("ERROR: Unable to get string from location: %s", plocation_name(location));
1405 return FALSE;
1406 }
1407
1409
1410 if (dest
1412 log_error("ERROR: Unable to get string from location: %s", plocation_name(location));
1413 return FALSE;
1414 }
1415
1416 return TRUE;
1417}
1418
1419/**********************************************************************/
1422bool dio_get_string_json(struct connection *pc, struct data_in *din,
1423 const struct plocation *location,
1424 char *dest, size_t max_dest_size)
1425{
1426 if (pc->json_mode) {
1427 return dio_get_string_json_internal(pc->json_packet, location,
1428 dest, max_dest_size);
1429 } else {
1430 return dio_get_string_raw(din, dest, max_dest_size);
1431 }
1432}
1433
1434/**********************************************************************/
1439bool dio_get_estring_json(struct connection *pc, struct data_in *din,
1440 const struct plocation *location,
1441 char *dest, size_t max_dest_size)
1442{
1443 if (pc->json_mode) {
1444 char *escaped_value;
1445 char *unescaped_value;
1446
1447 /* The encoded string has the same size limit as the decoded string. */
1449
1450 if (!dio_get_string_json_internal(pc->json_packet, location,
1452 /* dio_get_string_json() has logged this already. */
1453 return FALSE;
1454 }
1455
1456 /* Let CURL find the length it self by passing 0 */
1458
1459 /* Done with the escaped value. */
1461
1462 /* Copy the unescaped value so CURL can free its own copy. */
1463 memcpy(dest, unescaped_value,
1464 /* Don't copy the memory following unescaped_value. */
1466
1467 /* CURL's memory management wants to free this it self. */
1469
1470 /* Make sure that the string is terminated. */
1471 dest[max_dest_size - 1] = '\0';
1472 } else {
1473 return dio_get_estring_raw(din, dest, max_dest_size);
1474 }
1475
1476 return TRUE;
1477}
1478
1479#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:75
int dio_put_unit_order_json(struct json_data_out *dout, struct plocation *location, const struct unit_order *order)
int dio_put_uint8_vec8_json(struct json_data_out *dout, const struct plocation *location, int *values, int stop_value)
bool dio_get_uint16_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest)
bool dio_get_estring_json(struct connection *pc, struct data_in *din, const struct plocation *location, char *dest, size_t max_dest_size)
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)
bool dio_get_worklist_json(struct connection *pc, struct data_in *din, struct plocation *location, struct worklist *pwl)
int dio_put_uint16_vec8_json(struct json_data_out *dout, const struct plocation *location, int *values, int stop_value)
bool dio_get_sint16_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest)
bool dio_get_sint32_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest)
bool dio_get_sint8_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest)
int dio_put_uint16_json(struct json_data_out *dout, const struct plocation *location, int value)
bool dio_get_bool32_json(struct connection *pc, struct data_in *din, const struct plocation *location, bool *dest)
int dio_put_memory_json(struct json_data_out *dout, struct plocation *location, const void *value, size_t size)
bool dio_get_uint32_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest)
bool dio_get_string_json(struct connection *pc, struct data_in *din, const struct plocation *location, char *dest, size_t max_dest_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)
bool dio_get_requirement_json(struct connection *pc, struct data_in *din, const struct plocation *location, struct requirement *preq)
int dio_put_bool8_json(struct json_data_out *dout, const struct plocation *location, bool value)
bool dio_get_uint8_vec8_json(struct connection *pc, struct data_in *din, 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)
bool dio_get_sfloat_json(struct connection *pc, struct data_in *din, const struct plocation *location, float *dest, int float_factor)
bool dio_get_uint8_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest)
int dio_put_sint32_json(struct json_data_out *dout, const struct plocation *location, int value)
bool dio_get_memory_json(struct connection *pc, struct data_in *din, struct plocation *location, void *dest, size_t dest_size)
bool dio_get_unit_order_json(struct connection *pc, struct data_in *din, struct plocation *location, struct unit_order *order)
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_ufloat_json(struct connection *pc, struct data_in *din, const struct plocation *location, float *dest, int float_factor)
int dio_put_bool32_json(struct json_data_out *dout, const struct plocation *location, bool value)
bool dio_get_action_probability_json(struct connection *pc, struct data_in *din, const struct plocation *location, struct act_prob *prob)
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_bool8_json(struct connection *pc, struct data_in *din, const struct plocation *location, bool *dest)
int dio_put_string_json(struct json_data_out *dout, const struct plocation *location, const char *value)
int dio_put_cm_parameter_json(struct json_data_out *dout, struct plocation *location, const struct cm_parameter *order)
bool dio_get_uint16_vec8_json(struct connection *pc, struct data_in *din, const struct plocation *location, int **values, int stop_value)
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
@ PADR_FIELD
Definition dataio_raw.h:57
@ PADR_ELEMENT
Definition dataio_raw.h:59
#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:137
#define log_warn(message,...)
Definition log.h:105
#define log_error(message,...)
Definition log.h:103
#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
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:94
enum unit_orders order
Definition unit.h:93
int action
Definition unit.h:100
enum direction8 dir
Definition unit.h:102
int target
Definition unit.h:97
int sub_target
Definition unit.h:98
enum universals_n kind
Definition fc_types.h:902
universals_u value
Definition fc_types.h:901
#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