Freeciv-3.1
Loading...
Searching...
No Matches
dataio_raw.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/*
15 * The DataIO module provides a system independent (endianess and
16 * sizeof(int) independent) way to write and read data. It supports
17 * multiple datas which are collected in a buffer. It provides
18 * recognition of error cases like "not enough space" or "not enough
19 * data".
20 */
21
22#ifdef HAVE_CONFIG_H
23#include <fc_config.h>
24#endif
25
26#include "fc_prehdrs.h"
27
28#include <limits.h>
29#include <math.h>
30#include <stdint.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34
35#ifdef FREECIV_HAVE_SYS_TYPES_H
36#include <sys/types.h>
37#endif
38#ifdef HAVE_SYS_SOCKET_H
39#include <sys/socket.h>
40#endif
41#ifdef HAVE_NETINET_IN_H
42#include <netinet/in.h>
43#endif
44#ifdef HAVE_ARPA_INET_H
45#include <arpa/inet.h>
46#endif
47
48/* utility */
49#include "bitvector.h"
50#include "capability.h"
51#include "log.h"
52#include "mem.h"
53#include "support.h"
54
55/* common */
56#include "events.h"
57#include "player.h"
58#include "requirements.h"
59#include "tech.h"
60#include "worklist.h"
61
62/* common/aicore */
63#include "cm.h"
64
65#include "dataio.h"
66
67static bool get_conv(char *dst, size_t ndst, const char *src,
68 size_t nsrc);
69
72
73/* Uncomment to make field range tests to asserts, fatal with -F */
74/* #define FIELD_RANGE_ASSERT */
75
76#if defined(FREECIV_TESTMATIC) && !defined(FIELD_RANGE_ASSERT)
77#define FIELD_RANGE_ASSERT
78#endif
79
80#ifdef FIELD_RANGE_ASSERT
81/* Do log_error() first, so we get its output even if
82 * fc_assert() is fatal.
83 * fc_assert() before the _action_ might fix
84 * what we should find out to fail. */
85#define FIELD_RANGE_TEST(_test_, _action_, _format_, ...) \
86 if (_test_) { \
87 log_error(_format_, ## __VA_ARGS__); \
88 fc_assert(!(_test_)); \
89 _action_ \
90 }
91#else /* FIELD_RANGE_ASSERT */
92#define FIELD_RANGE_TEST(_test_, _action_, _format_, ...) \
93 if (_test_) { \
94 log_error(_format_, ## __VA_ARGS__); \
95 _action_ \
96 }
97#endif /* FIELD_RANGE_ASSERT */
98
99/**********************************************************************/
106
107/**********************************************************************/
111static bool get_conv(char *dst, size_t ndst, const char *src,
112 size_t nsrc)
113{
114 size_t len = nsrc; /* length to copy, not including null */
115 bool ret = TRUE;
116
117 if (ndst > 0 && len >= ndst) {
118 ret = FALSE;
119 len = ndst - 1;
120 }
121
122 memcpy(dst, src, len);
123 dst[len] = '\0';
124
125 return ret;
126}
127
128/**********************************************************************/
135
136/**********************************************************************/
139bool dataio_get_conv_callback(char *dst, size_t ndst, const char *src,
140 size_t nsrc)
141{
142 return get_conv_callback(dst, ndst, src, nsrc);
143}
144
145/**********************************************************************/
148static bool enough_space(struct raw_data_out *dout, size_t size)
149{
150 if (dout->current + size > dout->dest_size) {
151 dout->too_short = TRUE;
152 return FALSE;
153 } else {
154 dout->used = MAX(dout->used, dout->current + size);
155 return TRUE;
156 }
157}
158
159/**********************************************************************/
162static bool enough_data(struct data_in *din, size_t size)
163{
164 return dio_input_remaining(din) >= size;
165}
166
167/**********************************************************************/
171void dio_output_init(struct raw_data_out *dout, void *destination,
172 size_t dest_size)
173{
174 dout->dest = destination;
175 dout->dest_size = dest_size;
176 dout->current = 0;
177 dout->used = 0;
178 dout->too_short = FALSE;
179}
180
181/**********************************************************************/
184size_t dio_output_used(struct raw_data_out *dout)
185{
186 return dout->used;
187}
188
189/**********************************************************************/
194{
195 dout->current = 0;
196}
197
198/**********************************************************************/
202void dio_input_init(struct data_in *din, const void *src, size_t src_size)
203{
204 din->src = src;
205 din->src_size = src_size;
206 din->current = 0;
207}
208
209/**********************************************************************/
213void dio_input_rewind(struct data_in *din)
214{
215 din->current = 0;
216}
217
218/**********************************************************************/
221size_t dio_input_remaining(struct data_in *din)
222{
223 return din->src_size - din->current;
224}
225
226/**********************************************************************/
230{
231 switch (type) {
232 case DIOT_UINT8:
233 case DIOT_SINT8:
234 return 1;
235 case DIOT_UINT16:
236 case DIOT_SINT16:
237 return 2;
238 case DIOT_UINT32:
239 case DIOT_SINT32:
240 return 4;
241 case DIOT_LAST:
242 break;
243 }
244
245 fc_assert_msg(FALSE, "data_type %d not handled.", type);
246 return 0;
247}
248
249/**********************************************************************/
252bool dio_input_skip(struct data_in *din, size_t size)
253{
254 if (enough_data(din, size)) {
255 din->current += size;
256 return TRUE;
257 } else {
258 return FALSE;
259 }
260}
261
262/**********************************************************************/
265void dio_put_uint8_raw(struct raw_data_out *dout, int value)
266{
267 uint8_t x = value;
268 FC_STATIC_ASSERT(sizeof(x) == 1, uint8_not_1_byte);
269
270 FIELD_RANGE_TEST((int) x != value, ,
271 "Trying to put %d into 8 bits; "
272 "it will result %d at receiving side.",
273 value, (int) x);
274
275 if (enough_space(dout, 1)) {
276 memcpy(ADD_TO_POINTER(dout->dest, dout->current), &x, 1);
277 dout->current++;
278 }
279}
280
281/**********************************************************************/
284void dio_put_uint16_raw(struct raw_data_out *dout, int value)
285{
286 uint16_t x = htons(value);
287 FC_STATIC_ASSERT(sizeof(x) == 2, uint16_not_2_bytes);
288
289 FIELD_RANGE_TEST((int) ntohs(x) != value, ,
290 "Trying to put %d into 16 bits; "
291 "it will result %d at receiving side.",
292 value, (int) ntohs(x));
293
294 if (enough_space(dout, 2)) {
295 memcpy(ADD_TO_POINTER(dout->dest, dout->current), &x, 2);
296 dout->current += 2;
297 }
298}
299
300/**********************************************************************/
303void dio_put_uint32_raw(struct raw_data_out *dout, int value)
304{
305 uint32_t x = htonl(value);
306 FC_STATIC_ASSERT(sizeof(x) == 4, uint32_not_4_bytes);
307
308 FIELD_RANGE_TEST((int) ntohl(x) != value, ,
309 "Trying to put %d into 32 bits; "
310 "it will result %d at receiving side.",
311 value, (int) ntohl(x));
312
313 if (enough_space(dout, 4)) {
314 memcpy(ADD_TO_POINTER(dout->dest, dout->current), &x, 4);
315 dout->current += 4;
316 }
317}
318
319/**********************************************************************/
322void dio_put_type_raw(struct raw_data_out *dout, enum data_type type, int value)
323{
324 switch (type) {
325 case DIOT_UINT8:
326 dio_put_uint8_raw(dout, value);
327 return;
328 case DIOT_UINT16:
329 dio_put_uint16_raw(dout, value);
330 return;
331 case DIOT_UINT32:
332 dio_put_uint32_raw(dout, value);
333 return;
334 case DIOT_SINT8:
335 dio_put_sint8_raw(dout, value);
336 return;
337 case DIOT_SINT16:
338 dio_put_sint16_raw(dout, value);
339 return;
340 case DIOT_SINT32:
341 dio_put_sint32_raw(dout, value);
342 return;
343 case DIOT_LAST:
344 break;
345 }
346
347 fc_assert_msg(FALSE, "data_type %d not handled.", type);
348}
349
350/**********************************************************************/
353void dio_put_sint8_raw(struct raw_data_out *dout, int value)
354{
355 dio_put_uint8_raw(dout, 0 <= value ? value : value + 0x100);
356}
357
358/**********************************************************************/
361void dio_put_sint16_raw(struct raw_data_out *dout, int value)
362{
363 dio_put_uint16_raw(dout, 0 <= value ? value : value + 0x10000);
364}
365
366/**********************************************************************/
369void dio_put_sint32_raw(struct raw_data_out *dout, int value)
370{
371#if SIZEOF_INT == 4
372 dio_put_uint32_raw(dout, value);
373#else
374 dio_put_uint32_raw(dout, (0 <= value ? value : value + 0x100000000));
375#endif
376}
377
378/**********************************************************************/
381void dio_put_bool8_raw(struct raw_data_out *dout, bool value)
382{
383 FIELD_RANGE_TEST(value != TRUE && value != FALSE,
384 value = (value != FALSE);,
385 "Trying to put a non-boolean: %d", (int) value);
386
387 dio_put_uint8_raw(dout, value ? 1 : 0);
388}
389
390/**********************************************************************/
393void dio_put_bool32_raw(struct raw_data_out *dout, bool value)
394{
395 FIELD_RANGE_TEST(value != TRUE && value != FALSE,
396 value = (value != FALSE);,
397 "Trying to put a non-boolean: %d",
398 (int) value);
399
400 dio_put_uint32_raw(dout, value ? 1 : 0);
401}
402
403/**********************************************************************/
407void dio_put_ufloat_raw(struct raw_data_out *dout, float value, int float_factor)
408{
409 uint32_t v = value * float_factor;
410
411 FIELD_RANGE_TEST(fabsf((float) v / float_factor - value) > 1.1 / float_factor, ,
412 "Trying to put %f with factor %d in 32 bits; "
413 "it will result %f at receiving side, having error of %f units.",
414 value, float_factor, (float) v / float_factor,
415 fabsf((float) v / float_factor - value) * float_factor);
416
417 dio_put_uint32_raw(dout, v);
418}
419
420/**********************************************************************/
424void dio_put_sfloat_raw(struct raw_data_out *dout, float value, int float_factor)
425{
426 int32_t v = value * float_factor;
427
428 FIELD_RANGE_TEST(fabsf((float) v / float_factor - value) > 1.1 / float_factor, ,
429 "Trying to put %f with factor %d in 32 bits; "
430 "it will result %f at receiving side, having error of %f units.",
431 value, float_factor, (float) v / float_factor,
432 fabsf((float) v / float_factor - value) * float_factor);
433
434 dio_put_sint32_raw(dout, v);
435}
436
437/**********************************************************************/
442void dio_put_uint8_vec8_raw(struct raw_data_out *dout, int *values, int stop_value)
443{
444 size_t count;
445
446 for (count = 0; values[count] != stop_value; count++) {
447 /* nothing */
448 }
449
450 if (enough_space(dout, 1 + count)) {
451 size_t i;
452
453 dio_put_uint8_raw(dout, count);
454
455 for (i = 0; i < count; i++) {
456 dio_put_uint8_raw(dout, values[i]);
457 }
458 }
459}
460
461/**********************************************************************/
466void dio_put_uint16_vec8_raw(struct raw_data_out *dout, int *values, int stop_value)
467{
468 size_t count;
469
470 for (count = 0; values[count] != stop_value; count++) {
471 /* nothing */
472 }
473
474 if (enough_space(dout, 1 + 2 * count)) {
475 size_t i;
476
477 dio_put_uint8_raw(dout, count);
478
479 for (i = 0; i < count; i++) {
480 dio_put_uint16_raw(dout, values[i]);
481 }
482 }
483}
484
485/**********************************************************************/
488void dio_put_memory_raw(struct raw_data_out *dout, const void *value, size_t size)
489{
490 if (enough_space(dout, size)) {
491 memcpy(ADD_TO_POINTER(dout->dest, dout->current), value, size);
492 dout->current += size;
493 }
494}
495
496/**********************************************************************/
499void dio_put_string_raw(struct raw_data_out *dout, const char *value)
500{
501 if (put_conv_callback) {
502 size_t length;
503 char *buffer;
504
505 if ((buffer = (*put_conv_callback) (value, &length))) {
506 dio_put_memory_raw(dout, buffer, length + 1);
507 free(buffer);
508 }
509 } else {
510 dio_put_memory_raw(dout, value, strlen(value) + 1);
511 }
512}
513
514/**********************************************************************/
518 const struct cm_parameter *param)
519{
520 int i;
521
522 for (i = 0; i < O_LAST; i++) {
523 dio_put_sint16_raw(dout, param->minimal_surplus[i]);
524 }
525
526 dio_put_bool8_raw(dout, param->max_growth);
527 dio_put_bool8_raw(dout, param->require_happy);
528 dio_put_bool8_raw(dout, param->allow_disorder);
530
531 for (i = 0; i < O_LAST; i++) {
532 dio_put_uint16_raw(dout, param->factor[i]);
533 }
534
535 dio_put_uint16_raw(dout, param->happy_factor);
536}
537
538/**********************************************************************/
542 const struct unit_order *order)
543{
544 dio_put_uint8_raw(dout, order->order);
545 dio_put_uint8_raw(dout, order->activity);
546 dio_put_sint32_raw(dout, order->target);
547 dio_put_sint16_raw(dout, order->sub_target);
548 dio_put_uint8_raw(dout, order->action);
549 dio_put_sint8_raw(dout, order->dir);
550}
551
552/**********************************************************************/
556void dio_put_worklist_raw(struct raw_data_out *dout, const struct worklist *pwl)
557{
558 int i, length = worklist_length(pwl);
559
560 dio_put_uint8_raw(dout, length);
561 for (i = 0; i < length; i++) {
562 const struct universal *pcp = &(pwl->entries[i]);
563
564 dio_put_uint8_raw(dout, pcp->kind);
566 }
567}
568
569/**********************************************************************/
572bool dio_get_uint8_raw(struct data_in *din, int *dest)
573{
574 uint8_t x;
575
576 FC_STATIC_ASSERT(sizeof(x) == 1, uint8_not_byte);
577
578 if (!enough_data(din, 1)) {
579 log_packet("Packet too short to read 1 byte");
580
581 return FALSE;
582 }
583
584 memcpy(&x, ADD_TO_POINTER(din->src, din->current), 1);
585 *dest = x;
586 din->current++;
587 return TRUE;
588}
589
590/**********************************************************************/
593bool dio_get_uint16_raw(struct data_in *din, int *dest)
594{
595 uint16_t x;
596
597 FC_STATIC_ASSERT(sizeof(x) == 2, uint16_not_2_bytes);
598
599 if (!enough_data(din, 2)) {
600 log_packet("Packet too short to read 2 bytes");
601
602 return FALSE;
603 }
604
605 memcpy(&x, ADD_TO_POINTER(din->src, din->current), 2);
606 *dest = ntohs(x);
607 din->current += 2;
608 return TRUE;
609}
610
611/**********************************************************************/
614bool dio_get_uint32_raw(struct data_in *din, int *dest)
615{
616 uint32_t x;
617
618 FC_STATIC_ASSERT(sizeof(x) == 4, uint32_not_4_bytes);
619
620 if (!enough_data(din, 4)) {
621 log_packet("Packet too short to read 4 bytes");
622
623 return FALSE;
624 }
625
626 memcpy(&x, ADD_TO_POINTER(din->src, din->current), 4);
627 *dest = ntohl(x);
628 din->current += 4;
629 return TRUE;
630}
631
632/**********************************************************************/
635bool dio_get_type_raw(struct data_in *din, enum data_type type, int *dest)
636{
637 switch (type) {
638 case DIOT_UINT8:
639 return dio_get_uint8_raw(din, dest);
640 case DIOT_UINT16:
641 return dio_get_uint16_raw(din, dest);
642 case DIOT_UINT32:
643 return dio_get_uint32_raw(din, dest);
644 case DIOT_SINT8:
645 return dio_get_sint8_raw(din, dest);
646 case DIOT_SINT16:
647 return dio_get_sint16_raw(din, dest);
648 case DIOT_SINT32:
649 return dio_get_sint32_raw(din, dest);
650 case DIOT_LAST:
651 break;
652 }
653
654 fc_assert_msg(FALSE, "data_type %d not handled.", type);
655 return FALSE;
656}
657
658/**********************************************************************/
661bool dio_get_bool8_raw(struct data_in *din, bool *dest)
662{
663 int ival;
664
665 if (!dio_get_uint8_raw(din, &ival)) {
666 return FALSE;
667 }
668
669 if (ival != 0 && ival != 1) {
670 log_packet("Got a bad boolean: %d", ival);
671 return FALSE;
672 }
673
674 *dest = (ival != 0);
675 return TRUE;
676}
677
678/**********************************************************************/
681bool dio_get_bool32_raw(struct data_in *din, bool * dest)
682{
683 int ival;
684
685 if (!dio_get_uint32_raw(din, &ival)) {
686 return FALSE;
687 }
688
689 if (ival != 0 && ival != 1) {
690 log_packet("Got a bad boolean: %d", ival);
691 return FALSE;
692 }
693
694 *dest = (ival != 0);
695 return TRUE;
696}
697
698/**********************************************************************/
702bool dio_get_ufloat_raw(struct data_in *din, float *dest, int float_factor)
703{
704 int ival;
705
706 if (!dio_get_uint32_raw(din, &ival)) {
707 return FALSE;
708 }
709
710 *dest = (float) ival / float_factor;
711 return TRUE;
712}
713
714/**********************************************************************/
718bool dio_get_sfloat_raw(struct data_in *din, float *dest, int float_factor)
719{
720 int ival;
721
722 if (!dio_get_sint32_raw(din, &ival)) {
723 return FALSE;
724 }
725
726 *dest = (float) ival / float_factor;
727 return TRUE;
728}
729
730/**********************************************************************/
733bool dio_get_sint8_raw(struct data_in *din, int *dest)
734{
735 int tmp;
736
737 if (!dio_get_uint8_raw(din, &tmp)) {
738 return FALSE;
739 }
740
741 if (tmp > 0x7f) {
742 tmp -= 0x100;
743 }
744 *dest = tmp;
745 return TRUE;
746}
747
748/**********************************************************************/
751bool dio_get_sint16_raw(struct data_in *din, int *dest)
752{
753 int tmp;
754
755 if (!dio_get_uint16_raw(din, &tmp)) {
756 return FALSE;
757 }
758
759 if (tmp > 0x7fff) {
760 tmp -= 0x10000;
761 }
762 *dest = tmp;
763 return TRUE;
764}
765
766/**********************************************************************/
769bool dio_get_sint32_raw(struct data_in *din, int *dest)
770{
771 int tmp;
772
773 if (!dio_get_uint32_raw(din, &tmp)) {
774 return FALSE;
775 }
776
777#if SIZEOF_INT != 4
778 if (tmp > 0x7fffffff) {
779 tmp -= 0x100000000;
780 }
781#endif
782
783 *dest = tmp;
784 return TRUE;
785}
786
787/**********************************************************************/
790bool dio_get_memory_raw(struct data_in *din, void *dest, size_t dest_size)
791{
792 if (!enough_data(din, dest_size)) {
793 log_packet("Got too short memory");
794 return FALSE;
795 }
796
797 memcpy(dest, ADD_TO_POINTER(din->src, din->current), dest_size);
798 din->current += dest_size;
799 return TRUE;
800}
801
802/**********************************************************************/
805bool dio_get_string_raw(struct data_in *din, char *dest, size_t max_dest_size)
806{
807 char *c;
808 size_t offset, remaining;
809
810 fc_assert(max_dest_size > 0);
811
812 if (!enough_data(din, 1)) {
813 log_packet("Got a bad string");
814 return FALSE;
815 }
816
817 remaining = dio_input_remaining(din);
818 c = ADD_TO_POINTER(din->src, din->current);
819
820 /* avoid using strlen (or strcpy) on an (unsigned char*) --dwp */
821 for (offset = 0; offset < remaining && c[offset] != '\0'; offset++) {
822 /* nothing */
823 }
824
825 if (offset >= remaining) {
826 log_packet("Got a too short string");
827 return FALSE;
828 }
829
830 if (!(*get_conv_callback) (dest, max_dest_size, c, offset)) {
831 log_packet("Got a bad encoded string");
832 return FALSE;
833 }
834
835 din->current += offset + 1;
836 return TRUE;
837}
838
839/**********************************************************************/
843 struct cm_parameter *param)
844{
845 int i;
846
847 for (i = 0; i < O_LAST; i++) {
848 if (!dio_get_sint16_raw(din, &param->minimal_surplus[i])) {
849 log_packet("Got a bad cm_parameter");
850 return FALSE;
851 }
852 }
853
854 if (!dio_get_bool8_raw(din, &param->max_growth)
855 || !dio_get_bool8_raw(din, &param->require_happy)
856 || !dio_get_bool8_raw(din, &param->allow_disorder)
857 || !dio_get_bool8_raw(din, &param->allow_specialists)) {
858 log_packet("Got a bad cm_parameter");
859 return FALSE;
860 }
861
862 for (i = 0; i < O_LAST; i++) {
863 if (!dio_get_uint16_raw(din, &param->factor[i])) {
864 log_packet("Got a bad cm_parameter");
865 return FALSE;
866 }
867 }
868
869 if (!dio_get_uint16_raw(din, &param->happy_factor)) {
870 log_packet("Got a bad cm_parameter");
871 return FALSE;
872 }
873
874 return TRUE;
875}
876
877/**********************************************************************/
880bool dio_get_unit_order_raw(struct data_in *din, struct unit_order *order)
881{
882 /* These fields are enums */
883 int iorder, iactivity, idir;
884
885 if (!dio_get_uint8_raw(din, &iorder)
886 || !dio_get_uint8_raw(din, &iactivity)
887 || !dio_get_sint32_raw(din, &order->target)
888 || !dio_get_sint16_raw(din, &order->sub_target)
889 || !dio_get_uint8_raw(din, &order->action)
890 || !dio_get_sint8_raw(din, &idir)) {
891 log_packet("Got a bad unit_order");
892 return FALSE;
893 }
894
895 order->order = iorder;
896 order->activity = iactivity;
897 order->dir = idir;
898
899 return TRUE;
900}
901
902/**********************************************************************/
906bool dio_get_worklist_raw(struct data_in *din, struct worklist *pwl)
907{
908 int i, length;
909
910 worklist_init(pwl);
911
912 if (!dio_get_uint8_raw(din, &length)) {
913 log_packet("Got a bad worklist");
914 return FALSE;
915 }
916
917 for (i = 0; i < length; i++) {
918 int identifier;
919 int kind;
920 struct universal univ;
921
922 if (!dio_get_uint8_raw(din, &kind)
923 || !dio_get_uint8_raw(din, &identifier)) {
924 log_packet("Got a too short worklist");
925 return FALSE;
926 }
927
928 /*
929 * FIXME: the value returned by universal_by_number() should be checked!
930 */
931 univ = universal_by_number(kind, identifier);
932 worklist_append(pwl, &univ);
933 }
934
935 return TRUE;
936}
937
938/**********************************************************************/
942bool dio_get_uint8_vec8_raw(struct data_in *din, int **values, int stop_value)
943{
944 int count, inx;
945 int *vec;
946
947 if (!dio_get_uint8_raw(din, &count)) {
948 return FALSE;
949 }
950
951 vec = fc_calloc(count + 1, sizeof(*vec));
952 for (inx = 0; inx < count; inx++) {
953 if (!dio_get_uint8_raw(din, vec + inx)) {
954 free (vec);
955 return FALSE;
956 }
957 }
958 vec[inx] = stop_value;
959 *values = vec;
960
961 return TRUE;
962}
963
964/**********************************************************************/
967bool dio_get_uint16_vec8_raw(struct data_in *din, int **values, int stop_value)
968{
969 int count, inx;
970 int *vec;
971
972 if (!dio_get_uint8_raw(din, &count)) {
973 return FALSE;
974 }
975
976 vec = fc_calloc(count + 1, sizeof(*vec));
977 for (inx = 0; inx < count; inx++) {
978 if (!dio_get_uint16_raw(din, vec + inx)) {
979 free (vec);
980 return FALSE;
981 }
982 }
983 vec[inx] = stop_value;
984 *values = vec;
985
986 return TRUE;
987}
988
989/**********************************************************************/
993 struct act_prob *aprob)
994{
995 int min, max;
996
997 if (!dio_get_uint8_raw(din, &min)
998 || !dio_get_uint8_raw(din, &max)) {
999 log_packet("Got a bad action probability");
1000 return FALSE;
1001 }
1002
1003 aprob->min = min;
1004 aprob->max = max;
1005
1006 return TRUE;
1007}
1008
1009/**********************************************************************/
1013 const struct act_prob *aprob)
1014{
1015 dio_put_uint8_raw(dout, aprob->min);
1016 dio_put_uint8_raw(dout, aprob->max);
1017}
1018
1019/**********************************************************************/
1022bool dio_get_requirement_raw(struct data_in *din, struct requirement *preq)
1023{
1024 int type, range, value;
1025 bool survives, present, quiet;
1026
1027 if (!dio_get_uint8_raw(din, &type)
1028 || !dio_get_sint32_raw(din, &value)
1029 || !dio_get_uint8_raw(din, &range)
1030 || !dio_get_bool8_raw(din, &survives)
1031 || !dio_get_bool8_raw(din, &present)
1032 || !dio_get_bool8_raw(din, &quiet)) {
1033 log_packet("Got a bad requirement");
1034 return FALSE;
1035 }
1036
1037 /*
1038 * FIXME: the value returned by req_from_values() should be checked!
1039 */
1040 *preq = req_from_values(type, range, survives, present, quiet, value);
1041
1042 return TRUE;
1043}
1044
1045/**********************************************************************/
1049 const struct requirement *preq)
1050{
1051 int type, range, value;
1052 bool survives, present, quiet;
1053
1054 req_get_values(preq, &type, &range, &survives, &present, &quiet, &value);
1055
1056 dio_put_uint8_raw(dout, type);
1058 dio_put_uint8_raw(dout, range);
1059 dio_put_bool8_raw(dout, survives);
1060 dio_put_bool8_raw(dout, present);
1061 dio_put_bool8_raw(dout, quiet);
1062}
1063
1064/**********************************************************************/
1068{
1069 struct plocation *out = fc_malloc(sizeof(*out));
1070
1071 out->kind = PADR_FIELD;
1072 out->name = name;
1073 out->sub_location = NULL;
1074
1075 return out;
1076}
1077
1078/**********************************************************************/
1082{
1083 struct plocation *out = fc_malloc(sizeof(*out));
1084
1085 out->kind = PADR_ELEMENT;
1086 out->number = number;
1087 out->sub_location = NULL;
1088
1089 return out;
1090}
1091
1092/**********************************************************************/
1097const char *plocation_name(const struct plocation *loc)
1098{
1099 static char locname[10];
1100
1101 if (loc == NULL) {
1102 return "No location";
1103 }
1104
1105 switch (loc->kind) {
1106 case PADR_FIELD:
1107 return loc->name;
1108 case PADR_ELEMENT:
1109 fc_snprintf(locname, sizeof(locname), "%d", loc->number);
1110 return locname;
1111 }
1112
1113 return "Illegal location";
1114}
void dio_put_cm_parameter_raw(struct raw_data_out *dout, const struct cm_parameter *param)
Definition dataio_raw.c:517
void dio_put_action_probability_raw(struct raw_data_out *dout, const struct act_prob *aprob)
void dio_put_unit_order_raw(struct raw_data_out *dout, const struct unit_order *order)
Definition dataio_raw.c:541
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:733
static bool enough_space(struct raw_data_out *dout, size_t size)
Definition dataio_raw.c:148
void dio_put_ufloat_raw(struct raw_data_out *dout, float value, int float_factor)
Definition dataio_raw.c:407
struct plocation * plocation_field_new(char *name)
bool dio_get_worklist_raw(struct data_in *din, struct worklist *pwl)
Definition dataio_raw.c:906
bool dio_get_action_probability_raw(struct data_in *din, struct act_prob *aprob)
Definition dataio_raw.c:992
void dio_put_bool8_raw(struct raw_data_out *dout, bool value)
Definition dataio_raw.c:381
void dio_output_init(struct raw_data_out *dout, void *destination, size_t dest_size)
Definition dataio_raw.c:171
void dio_put_uint16_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:284
void dio_put_sfloat_raw(struct raw_data_out *dout, float value, int float_factor)
Definition dataio_raw.c:424
void dio_set_get_conv_callback(DIO_GET_CONV_FUN fun)
Definition dataio_raw.c:131
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:718
size_t dio_input_remaining(struct data_in *din)
Definition dataio_raw.c:221
void dio_put_uint8_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:265
void dio_put_sint16_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:361
bool dio_get_uint32_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:614
bool dio_get_sint16_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:751
bool dio_get_unit_order_raw(struct data_in *din, struct unit_order *order)
Definition dataio_raw.c:880
bool dio_get_sint32_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:769
void dio_put_sint32_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:369
bool dio_get_cm_parameter_raw(struct data_in *din, struct cm_parameter *param)
Definition dataio_raw.c:842
void dio_input_rewind(struct data_in *din)
Definition dataio_raw.c:213
bool dio_get_uint8_vec8_raw(struct data_in *din, int **values, int stop_value)
Definition dataio_raw.c:942
void dio_put_uint32_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:303
bool dio_get_uint16_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:593
bool dio_get_memory_raw(struct data_in *din, void *dest, size_t dest_size)
Definition dataio_raw.c:790
void dio_put_memory_raw(struct raw_data_out *dout, const void *value, size_t size)
Definition dataio_raw.c:488
static bool get_conv(char *dst, size_t ndst, const char *src, size_t nsrc)
Definition dataio_raw.c:111
bool dio_get_type_raw(struct data_in *din, enum data_type type, int *dest)
Definition dataio_raw.c:635
void dio_put_uint16_vec8_raw(struct raw_data_out *dout, int *values, int stop_value)
Definition dataio_raw.c:466
bool dio_get_bool32_raw(struct data_in *din, bool *dest)
Definition dataio_raw.c:681
bool dio_get_ufloat_raw(struct data_in *din, float *dest, int float_factor)
Definition dataio_raw.c:702
void dio_put_worklist_raw(struct raw_data_out *dout, const struct worklist *pwl)
Definition dataio_raw.c:556
void dio_put_requirement_raw(struct raw_data_out *dout, const struct requirement *preq)
bool dio_get_uint8_raw(struct data_in *din, int *dest)
Definition dataio_raw.c:572
static bool enough_data(struct data_in *din, size_t size)
Definition dataio_raw.c:162
static DIO_GET_CONV_FUN get_conv_callback
Definition dataio_raw.c:71
bool dio_input_skip(struct data_in *din, size_t size)
Definition dataio_raw.c:252
bool dio_get_uint16_vec8_raw(struct data_in *din, int **values, int stop_value)
Definition dataio_raw.c:967
size_t data_type_size(enum data_type type)
Definition dataio_raw.c:229
void dio_put_uint8_vec8_raw(struct raw_data_out *dout, int *values, int stop_value)
Definition dataio_raw.c:442
void dio_put_type_raw(struct raw_data_out *dout, enum data_type type, int value)
Definition dataio_raw.c:322
struct plocation * plocation_elem_new(int number)
bool dio_get_bool8_raw(struct data_in *din, bool *dest)
Definition dataio_raw.c:661
void dio_put_string_raw(struct raw_data_out *dout, const char *value)
Definition dataio_raw.c:499
size_t dio_output_used(struct raw_data_out *dout)
Definition dataio_raw.c:184
void dio_input_init(struct data_in *din, const void *src, size_t src_size)
Definition dataio_raw.c:202
#define FIELD_RANGE_TEST(_test_, _action_, _format_,...)
Definition dataio_raw.c:92
static DIO_PUT_CONV_FUN put_conv_callback
Definition dataio_raw.c:70
void dio_set_put_conv_callback(DIO_PUT_CONV_FUN fun)
Definition dataio_raw.c:102
bool dio_get_string_raw(struct data_in *din, char *dest, size_t max_dest_size)
Definition dataio_raw.c:805
const char * plocation_name(const struct plocation *loc)
void dio_put_bool32_raw(struct raw_data_out *dout, bool value)
Definition dataio_raw.c:393
void dio_output_rewind(struct raw_data_out *dout)
Definition dataio_raw.c:193
void dio_put_sint8_raw(struct raw_data_out *dout, int value)
Definition dataio_raw.c:353
char *(* DIO_PUT_CONV_FUN)(const char *src, size_t *length)
Definition dataio_raw.h:90
@ PADR_FIELD
Definition dataio_raw.h:57
@ PADR_ELEMENT
Definition dataio_raw.h:59
bool(* DIO_GET_CONV_FUN)(char *dst, size_t ndst, const char *src, size_t nsrc)
Definition dataio_raw.h:93
data_type
Definition dataio_raw.h:43
@ DIOT_UINT8
Definition dataio_raw.h:44
@ DIOT_UINT32
Definition dataio_raw.h:46
@ DIOT_UINT16
Definition dataio_raw.h:45
@ DIOT_LAST
Definition dataio_raw.h:51
@ DIOT_SINT32
Definition dataio_raw.h:49
@ DIOT_SINT8
Definition dataio_raw.h:47
@ DIOT_SINT16
Definition dataio_raw.h:48
@ O_LAST
Definition fc_types.h:91
struct tile * loc
Definition citydlg.c:220
GType type
Definition repodlgs.c:1312
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define log_packet
Definition log.h:137
#define fc_assert(condition)
Definition log.h:176
#define FC_STATIC_ASSERT(cond, tag)
Definition log.h:235
#define fc_calloc(n, esz)
Definition mem.h:38
#define fc_malloc(sz)
Definition mem.h:34
int len
Definition packhand.c:125
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 ADD_TO_POINTER(p, n)
Definition shared.h:86
#define MAX(x, y)
Definition shared.h:54
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
const void * src
Definition dataio_raw.h:31
size_t src_size
Definition dataio_raw.h:32
size_t current
Definition dataio_raw.h:32
enum plocation_kind kind
Definition dataio_raw.h:65
struct plocation * sub_location
Definition dataio_raw.h:78
char * name
Definition dataio_raw.h:72
void * dest
Definition dataio_raw.h:36
size_t used
Definition dataio_raw.h:37
size_t dest_size
Definition dataio_raw.h:37
size_t current
Definition dataio_raw.h:37
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:758
universals_u value
Definition fc_types.h:757
struct universal entries[MAX_LEN_WORKLIST]
Definition worklist.h:30
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
#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