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 (d_out->json) {
222 e = plocation_write_data(d_out->json, location, json_integer(value));
223 } else {
224 e = dio_put_uint8_raw(&d_out->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 (d_out->json) {
240 e = plocation_write_data(d_out->json, location, json_integer(value));
241 } else {
242 e = dio_put_sint8_raw(&d_out->raw, value);
243 }
244
245 return e;
246}
247
248/**********************************************************************/
252 const struct plocation *location, int value)
253{
254 int e;
255
256 if (d_out->json) {
257 e = plocation_write_data(d_out->json, location, json_integer(value));
258 } else {
259 e = dio_put_uint16_raw(&d_out->raw, value);
260 }
261
262 return e;
263}
264
265/**********************************************************************/
269 const struct plocation *location, int value)
270{
271 int e;
272
273 if (d_out->json) {
274 e = plocation_write_data(d_out->json, location, json_integer(value));
275 } else {
276 e = dio_put_sint16_raw(&d_out->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 (d_out->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(d_out->json, location, obj);
316 } else {
317 e = dio_put_cm_parameter_raw(&d_out->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 (d_out->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(d_out->json, location, obj);
347 } else {
348 e = dio_put_unit_order_raw(&d_out->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 (d_out->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(d_out, 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(d_out->json, location, universal);
383 }
384
385 FC_FREE(location->sub_location);
386 } else {
387 e = dio_put_worklist_raw(&d_out->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 (d_out->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(d_out->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 (d_out->json) {
924 e |= plocation_write_data(d_out->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 (d_out->json) {
941 e = plocation_write_data(d_out->json, location, json_integer(value));
942 } else {
943 e = dio_put_uint32_raw(&d_out->raw, value);
944 }
945
946 return e;
947}
948
949/**********************************************************************/
953 const struct plocation *location, int value)
954{
955 int e;
956
957 if (d_out->json) {
958 e = plocation_write_data(d_out->json, location, json_integer(value));
959 } else {
960 e = dio_put_sint32_raw(&d_out->raw, value);
961 }
962
963 return e;
964}
965
966/**********************************************************************/
970 const struct plocation *location, bool value)
971{
972 int e;
973
974 if (d_out->json) {
975 e = plocation_write_data(d_out->json, location,
976 value ? json_true() : json_false());
977 } else {
978 e = dio_put_bool8_raw(&d_out->raw, value);
979 }
980
981 return e;
982}
983
984/**********************************************************************/
988 const struct plocation *location, bool value)
989{
990 int e;
991
992 if (d_out->json) {
993 e = plocation_write_data(d_out->json, location,
994 value ? json_true() : json_false());
995 } else {
996 e = dio_put_bool32_raw(&d_out->raw, value);
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 (d_out->json) {
1012 e = plocation_write_data(d_out->json, location, json_real(value));
1013 } else {
1014 e = dio_put_ufloat_raw(&d_out->raw, value, float_factor);
1015 }
1016
1017 return e;
1018}
1019
1020/**********************************************************************/
1024 const struct plocation *location,
1025 float value, int float_factor)
1026{
1027 int e;
1028
1029 if (d_out->json) {
1030 e = plocation_write_data(d_out->json, location, json_real(value));
1031 } else {
1032 e = dio_put_sfloat_raw(&d_out->raw, value, float_factor);
1033 }
1034
1035 return e;
1036}
1037
1038/**********************************************************************/
1043 const struct plocation *location, int size)
1044{
1045 int e;
1046
1047 if (d_out->json) {
1048 e = dio_put_farray_json(d_out, location, size);
1049 } else {
1050 e = dio_put_arraylen_raw(&d_out->raw, size);
1051 }
1052
1053 return e;
1054}
1055
1056/**********************************************************************/
1060 const struct plocation *location,
1061 int *values, int stop_value)
1062{
1063 int e;
1064
1065 if (d_out->json) {
1066 /* TODO: Implement. */
1067 log_error("Tried to send unimplemeted data type uint8_vec8.");
1068 e = -1;
1069 } else {
1070 e = dio_put_uint8_vec8_raw(&d_out->raw, values, stop_value);
1071 }
1072
1073 return e;
1074}
1075
1076/**********************************************************************/
1080 const struct plocation *location, int *values,
1081 int stop_value)
1082{
1083 int e;
1084
1085 if (d_out->json) {
1086 /* TODO: Implement. */
1087 log_error("Tried to send unimplemeted data type uint16_vec8.");
1088 e = -1;
1089 } else {
1090 e = dio_put_uint16_vec8_raw(&d_out->raw, values, stop_value);
1091 }
1092
1093 return e;
1094}
1095
1096/**********************************************************************/
1100 struct plocation *location,
1101 const void *value,
1102 size_t size)
1103{
1104 int e;
1105
1106 if (d_out->json) {
1107 int i;
1108
1109 e = dio_put_farray_json(d_out, location, size);
1110
1111 location->sub_location = plocation_elem_new(0);
1112
1113 for (i = 0; i < size; i++) {
1114 location->sub_location->number = i;
1115
1116 e |= dio_put_uint8_json(d_out, location,
1117 ((unsigned char *)value)[i]);
1118 }
1119
1120 FC_FREE(location->sub_location);
1121 } else {
1122 e = dio_put_memory_raw(&d_out->raw, value, size);
1123 }
1124
1125 return e;
1126}
1127
1128/**********************************************************************/
1132 const struct plocation *location,
1133 const char *value)
1134{
1135 int e;
1136
1137 if (d_out->json) {
1138 e = plocation_write_data(d_out->json, location, json_string(value));
1139 } else {
1140 e = dio_put_string_raw(&d_out->raw, value);
1141 }
1142
1143 return e;
1144}
1145
1146/**********************************************************************/
1150 const struct plocation *location,
1151 const char *value)
1152{
1153 int e;
1154
1155 if (d_out->json) {
1156 char *escaped_value;
1157
1158 /* Let CURL find the length itself by passing 0 */
1160
1161 /* Handle as a regular string from now on. */
1162 e = dio_put_string_json(d_out, location, escaped_value);
1163
1164 /* CURL's memory management wants to free this itself. */
1166 } else {
1167 e = dio_put_estring_raw(&d_out->raw, value);
1168 }
1169
1170 return e;
1171}
1172
1173/**********************************************************************/
1177 const struct plocation *location,
1178 const struct requirement *preq)
1179{
1180 int e = 0;
1181
1182 if (d_out->json) {
1183 int kind, range, value;
1184 bool survives, present, quiet;
1185
1186 /* Create the requirement object. */
1188
1189 /* Read the requirement values. */
1190 req_get_values(preq, &kind, &range, &survives, &present, &quiet, &value);
1191
1192 /* Write the requirement values to the fields of the requirement
1193 * object. */
1195 e |= json_object_set_new(requirement, "value", json_integer(value));
1196
1198
1199 e |= json_object_set_new(requirement, "survives", json_boolean(survives));
1200 e |= json_object_set_new(requirement, "present", json_boolean(present));
1201 e |= json_object_set_new(requirement, "quiet", json_boolean(quiet));
1202
1203 /* Put the requirement object in the packet. */
1204 e |= plocation_write_data(d_out->json, location, requirement);
1205 } else {
1207 }
1208
1209 return e;
1210}
1211
1212/**********************************************************************/
1216 const struct plocation *location,
1217 const struct act_prob *prob)
1218{
1219 int e = 0;
1220
1221 if (d_out->json) {
1222 /* Create the action probability object. */
1224
1225 /* Write the action probability values to the fields of the action
1226 * probability object. */
1229
1230 /* Put the action probability object in the packet. */
1231 e |= plocation_write_data(d_out->json, location, action_probability);
1232 } else {
1233 e = dio_put_action_probability_raw(&d_out->raw, prob);
1234 }
1235
1236 return e;
1237}
1238
1239/**********************************************************************/
1243 const struct plocation *location,
1244 bool *dest)
1245{
1247
1248 if (!pbool) {
1249 log_error("ERROR: Unable to get bool8 from location: %s", plocation_name(location));
1250 return FALSE;
1251 }
1252 *dest = json_is_true(pbool);
1253
1254 return TRUE;
1255}
1256
1257/**********************************************************************/
1260bool dio_get_bool8_json(struct connection *pc, struct data_in *din,
1261 const struct plocation *location, bool *dest)
1262{
1263 if (pc->json_mode) {
1264 return dio_get_bool8_json_internal(pc->json_packet, location, dest);
1265 } else {
1266 return dio_get_bool8_raw(din, dest);
1267 }
1268}
1269
1270/**********************************************************************/
1273bool dio_get_bool32_json(struct connection *pc, struct data_in *din,
1274 const struct plocation *location, bool *dest)
1275{
1276 if (pc->json_mode) {
1277 json_t *pbool = plocation_read_data(pc->json_packet, location);
1278
1279 if (!pbool) {
1280 log_error("ERROR: Unable to get bool32 from location: %s", plocation_name(location));
1281 return FALSE;
1282 }
1283 *dest = json_is_true(pbool);
1284 } else {
1285 return dio_get_bool32_raw(din, dest);
1286 }
1287
1288 return TRUE;
1289}
1290
1291/**********************************************************************/
1294bool dio_get_ufloat_json(struct connection *pc, struct data_in *din,
1295 const struct plocation *location,
1296 float *dest, int float_factor)
1297{
1298 if (pc->json_mode) {
1299 json_t *preal = plocation_read_data(pc->json_packet, location);
1300
1301 if (!preal) {
1302 log_error("ERROR: Unable to get real from location: %s", plocation_name(location));
1303 return FALSE;
1304 }
1305 *dest = json_real_value(preal);
1306 } else {
1307 return dio_get_ufloat_raw(din, dest, float_factor);
1308 }
1309
1310 return TRUE;
1311}
1312
1313/**********************************************************************/
1316bool dio_get_sfloat_json(struct connection *pc, struct data_in *din,
1317 const struct plocation *location,
1318 float *dest, int float_factor)
1319{
1320 if (pc->json_mode) {
1321 json_t *preal = plocation_read_data(pc->json_packet, location);
1322
1323 if (!preal) {
1324 log_error("ERROR: Unable to get real from location: %s", plocation_name(location));
1325 return FALSE;
1326 }
1327 *dest = json_real_value(preal);
1328 } else {
1329 return dio_get_sfloat_raw(din, dest, float_factor);
1330 }
1331
1332 return TRUE;
1333}
1334
1335/**********************************************************************/
1338bool dio_get_sint8_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 sint8 from location: %s", plocation_name(location));
1346 return FALSE;
1347 }
1348 *dest = json_integer_value(pint);
1349 } else {
1350 return dio_get_sint8_raw(din, dest);
1351 }
1352
1353 return TRUE;
1354}
1355
1356/**********************************************************************/
1359bool dio_get_sint16_json(struct connection *pc, struct data_in *din,
1360 const struct plocation *location, int *dest)
1361{
1362 if (pc->json_mode) {
1363 json_t *pint = plocation_read_data(pc->json_packet, location);
1364
1365 if (!pint) {
1366 log_error("ERROR: Unable to get sint16 from location: %s", plocation_name(location));
1367 return FALSE;
1368 }
1369 *dest = json_integer_value(pint);
1370 } else {
1371 return dio_get_sint16_raw(din, dest);
1372 }
1373
1374 return TRUE;
1375}
1376
1377/**********************************************************************/
1380bool dio_get_memory_json(struct connection *pc, struct data_in *din,
1381 struct plocation *location,
1382 void *dest, size_t dest_size)
1383{
1384 if (pc->json_mode) {
1385 int i;
1386
1387 location->sub_location = plocation_elem_new(0);
1388
1389 for (i = 0; i < dest_size; i++) {
1390 int val;
1391
1392 location->sub_location->number = i;
1393
1394 if (!dio_get_uint8_json_internal(pc->json_packet, location, &val)) {
1395 free(location->sub_location);
1396 return FALSE;
1397 }
1398 ((unsigned char *)dest)[i] = val;
1399 }
1400
1401 FC_FREE(location->sub_location);
1402 } else {
1403 return dio_get_memory_raw(din, dest, dest_size);
1404 }
1405
1406 return TRUE;
1407}
1408
1409/**********************************************************************/
1413 const struct plocation *location,
1414 char *dest, size_t max_dest_size)
1415{
1417 const char *result_str;
1418
1419 if (!pstring) {
1420 log_error("ERROR: Unable to get string from location: %s", plocation_name(location));
1421 return FALSE;
1422 }
1423
1425
1426 if (dest
1428 log_error("ERROR: Unable to get string from location: %s", plocation_name(location));
1429 return FALSE;
1430 }
1431
1432 return TRUE;
1433}
1434
1435/**********************************************************************/
1438bool dio_get_string_json(struct connection *pc, struct data_in *din,
1439 const struct plocation *location,
1440 char *dest, size_t max_dest_size)
1441{
1442 if (pc->json_mode) {
1443 return dio_get_string_json_internal(pc->json_packet, location,
1444 dest, max_dest_size);
1445 } else {
1446 return dio_get_string_raw(din, dest, max_dest_size);
1447 }
1448}
1449
1450/**********************************************************************/
1455bool dio_get_estring_json(struct connection *pc, struct data_in *din,
1456 const struct plocation *location,
1457 char *dest, size_t max_dest_size)
1458{
1459 if (pc->json_mode) {
1460 char *escaped_value;
1461 char *unescaped_value;
1462
1463 /* The encoded string has the same size limit as the decoded string. */
1465
1466 if (!dio_get_string_json_internal(pc->json_packet, location,
1468 /* dio_get_string_json() has logged this already. */
1469 return FALSE;
1470 }
1471
1472 /* Let CURL find the length itself by passing 0 */
1474 0, nullptr);
1475
1476 /* Done with the escaped value. */
1478
1479 /* Copy the unescaped value so CURL can free its own copy. */
1480 memcpy(dest, unescaped_value,
1481 /* Don't copy the memory following unescaped_value. */
1483
1484 /* CURL's memory management wants to free this itself. */
1486
1487 /* Make sure that the string is terminated. */
1488 dest[max_dest_size - 1] = '\0';
1489 } else {
1490 return dio_get_estring_raw(din, dest, max_dest_size);
1491 }
1492
1493 return TRUE;
1494}
1495
1496#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:77
int dio_put_worklist_json(struct json_data_out *d_out, struct plocation *location, const struct worklist *pwl)
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)))
int dio_put_uint16_vec8_json(struct json_data_out *d_out, const struct plocation *location, int *values, int stop_value)
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_farray_json(struct json_data_out *d_out, const struct plocation *location, int size)
int dio_put_sint16_json(struct json_data_out *d_out, const struct plocation *location, int 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)))
int dio_put_sfloat_json(struct json_data_out *d_out, const struct plocation *location, float value, int float_factor)
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_unit_order_json(struct json_data_out *d_out, struct plocation *location, const struct unit_order *order)
int dio_put_bool32_json(struct json_data_out *d_out, const struct plocation *location, bool value)
int dio_put_uint32_json(struct json_data_out *d_out, const struct plocation *location, int value)
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_ufloat_json(struct json_data_out *d_out, const struct plocation *location, float value, int float_factor)
int dio_put_uint8_vec8_json(struct json_data_out *d_out, 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)))
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_bool8_json(struct json_data_out *d_out, const struct plocation *location, bool value)
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_cm_parameter_json(struct json_data_out *d_out, struct plocation *location, const struct cm_parameter *order)
int dio_put_sint32_json(struct json_data_out *d_out, const struct plocation *location, int value)
int dio_put_object_json(struct json_data_out *d_out, const struct plocation *location)
int dio_put_arraylen_json(struct json_data_out *d_out, const struct plocation *location, int size)
int dio_put_action_probability_json(struct json_data_out *d_out, const struct plocation *location, const struct act_prob *prob)
int dio_put_estring_json(struct json_data_out *d_out, const struct plocation *location, const char *value)
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_memory_json(struct json_data_out *d_out, struct plocation *location, const void *value, size_t size)
bool dio_get_bool32_json(struct connection *pc, struct data_in *din, const struct plocation *location, bool *dest) fc__attribute((nonnull(4)))
int dio_put_sint8_json(struct json_data_out *d_out, const struct plocation *location, int value)
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)))
int dio_put_string_json(struct json_data_out *d_out, const struct plocation *location, const char *value)
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_uint16_json(struct json_data_out *d_out, const struct plocation *location, int value)
bool dio_get_sint16_json(struct connection *pc, struct data_in *din, const struct plocation *location, int *dest) fc__attribute((nonnull(4)))
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_uint8_json(struct json_data_out *d_out, const struct plocation *location, int value)
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)))
int dio_put_requirement_json(struct json_data_out *d_out, const struct plocation *location, const struct requirement *preq)
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:767
int dio_put_uint32_raw(struct raw_data_out *d_out, int value)
Definition dataio_raw.c:311
int dio_put_uint8_vec8_raw(struct raw_data_out *d_out, int *values, int stop_value)
Definition dataio_raw.c:452
int dio_put_bool32_raw(struct raw_data_out *d_out, bool value)
Definition dataio_raw.c:401
struct plocation * plocation_field_new(char *name)
bool dio_get_worklist_raw(struct data_in *din, struct worklist *pwl)
Definition dataio_raw.c:940
bool dio_get_action_probability_raw(struct data_in *din, struct act_prob *aprob)
int dio_put_cm_parameter_raw(struct raw_data_out *d_out, const struct cm_parameter *param)
Definition dataio_raw.c:541
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:752
bool dio_get_uint32_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:648
bool dio_get_sint16_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:785
bool dio_get_unit_order_raw(struct data_in *din, struct unit_order *order)
Definition dataio_raw.c:914
int dio_put_ufloat_raw(struct raw_data_out *d_out, float value, int float_factor)
Definition dataio_raw.c:415
bool dio_get_sint32_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:803
int dio_put_action_probability_raw(struct raw_data_out *d_out, const struct act_prob *aprob)
int dio_put_uint16_raw(struct raw_data_out *d_out, int value)
Definition dataio_raw.c:289
int dio_put_worklist_raw(struct raw_data_out *d_out, const struct worklist *pwl)
Definition dataio_raw.c:587
bool dio_get_cm_parameter_raw(struct data_in *din, struct cm_parameter *param)
Definition dataio_raw.c:876
int dio_put_memory_raw(struct raw_data_out *d_out, const void *value, size_t size)
Definition dataio_raw.c:506
bool dio_get_uint8_vec8_raw(struct data_in *din, int **values, int stop_value)
Definition dataio_raw.c:976
int dio_put_string_raw(struct raw_data_out *d_out, const char *value)
Definition dataio_raw.c:520
bool dio_get_uint16_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:627
bool dio_get_memory_raw(struct data_in *din, void *dest, size_t dest_size)
Definition dataio_raw.c:824
bool dio_get_bool32_raw(struct data_in *din, bool *dest)
Definition dataio_raw.c:715
int dio_put_bool8_raw(struct raw_data_out *d_out, bool value)
Definition dataio_raw.c:389
int dio_put_sfloat_raw(struct raw_data_out *d_out, float value, int float_factor)
Definition dataio_raw.c:433
bool dio_get_ufloat_raw(struct data_in *din, float *dest, int float_factor)
Definition dataio_raw.c:736
int dio_put_sint16_raw(struct raw_data_out *d_out, int value)
Definition dataio_raw.c:369
bool dio_get_uint8_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:606
bool dio_get_uint16_vec8_raw(struct data_in *din, int **values, int stop_value)
struct plocation * plocation_elem_new(int number)
bool dio_get_bool8_raw(struct data_in *din, bool *dest)
Definition dataio_raw.c:695
int dio_put_sint32_raw(struct raw_data_out *d_out, int value)
Definition dataio_raw.c:377
int dio_put_sint8_raw(struct raw_data_out *d_out, int value)
Definition dataio_raw.c:361
int dio_put_unit_order_raw(struct raw_data_out *d_out, const struct unit_order *order)
Definition dataio_raw.c:568
int dio_put_uint16_vec8_raw(struct raw_data_out *d_out, int *values, int stop_value)
Definition dataio_raw.c:480
bool dio_get_string_raw(struct data_in *din, char *dest, size_t max_dest_size)
Definition dataio_raw.c:839
const char * plocation_name(const struct plocation *loc)
int dio_put_requirement_raw(struct raw_data_out *d_out, const struct requirement *preq)
int dio_put_uint8_raw(struct raw_data_out *d_out, int value)
Definition dataio_raw.c:267
#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:103
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:937
int min
Definition fc_types.h:936
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:595
universals_u value
Definition fc_types.h:594
#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