3 #include "DataDesc/gs_private.h"
10 _gs_sequence_alloc(void) {
11 struct s_gs_sequence *p_sequence = NULL;
12 p_sequence = malloc(sizeof(struct s_gs_sequence));
17 struct s_gs_sequence *
18 _gs_sequence_new(void) {
19 struct s_gs_sequence *p_sequence = NULL;
21 p_sequence = _gs_sequence_alloc();
23 p_sequence->message = NULL;
24 p_sequence->code = -1;
25 p_sequence->next = NULL;
35 _gs_message_alloc(void) {
36 struct s_gs_message *p_message = NULL;
38 p_message = malloc(sizeof(struct s_gs_message));
44 gs_message_new(struct s_gs_type_bag *p_bag,
45 struct s_gs_connection *p_connection,
48 struct s_gs_type_bag_ops *bag_ops = p_bag->bag_ops;
49 struct s_gs_message *p_message = NULL;
51 p_message = _gs_message_alloc();
54 p_message->name = strdup(name);
56 p_message->first = NULL;
57 p_message->last = NULL;
59 bag_ops->store_message(p_bag, p_connection, p_message);
66 gs_message_append_new_sequence(struct s_gs_message *p_message,
67 struct s_gs_type *p_type) {
69 struct s_gs_sequence *p_sequence = NULL;
71 p_sequence = _gs_sequence_new();
73 p_sequence->message = p_message;
74 p_sequence->code = p_type->code;
75 p_sequence->next = NULL;
77 if (p_message->first) {
78 p_message->last ->next = p_sequence;
80 p_message->first = p_sequence;
83 p_message->last = p_sequence;
91 struct s_gs_message_instance *
92 _gs_message_instance_alloc(void) {
93 struct s_gs_message_instance *p_message_instance = NULL;
94 p_message_instance = malloc(sizeof (struct s_gs_message_instance));
95 return p_message_instance;
99 struct s_gs_message_instance *
100 _gs_message_instance_new(void) {
101 struct s_gs_message_instance *p_message_instance = NULL;
103 p_message_instance = _gs_message_instance_alloc();
105 p_message_instance->p_message = NULL;
106 p_message_instance->current = NULL;
107 p_message_instance->p_bag = NULL;
108 p_message_instance->p_connection = NULL;
110 return p_message_instance;
116 _gs_message_send_type(struct s_gs_type_bag *p_bag,
117 struct s_gs_connection *p_cnx,
119 gras_dict_t **p_refs,
120 struct s_gs_type *p_type,
125 _sg_message_send_get_type_by_code(struct s_gs_type_bag *p_bag,
126 struct s_gs_connection *p_cnx,
129 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
130 struct s_gs_type *p_type = NULL;
132 p_type = bops->get_type_by_code(p_bag, NULL, code);
134 if (!bops->check_type_mark(p_bag, p_cnx, p_type->name)) {
135 struct s_gs_type *p_type_type = NULL;
136 gras_dict_t *_refs = NULL;
138 p_type_type = bops->get_type_by_name(p_bag, NULL, "_s_gs_type");
140 GS_FAILURE("_s_gs_type default type missing");
142 bops->mark_type(p_bag, p_cnx, p_type->name);
144 fprintf(stderr, "sending type with code = %d\n", code);
146 _gs_message_send_type(p_bag, p_cnx, vars, &_refs, p_type_type, p_type);
148 fprintf(stderr, "type with code = %d, name = %s sent\n", code, p_type->name);
150 fprintf(stderr, "no need to send type with code = %d, name = %s\n", code, p_type->name);
158 _gs_message_send_type(struct s_gs_type_bag *p_bag,
159 struct s_gs_connection *p_cnx,
161 gras_dict_t **p_refs,
162 struct s_gs_type *p_type,
165 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
166 struct s_gs_connection_ops *cops = p_cnx->connection_ops;
169 gras_dict_new(p_refs);
171 if (p_type->category_code > 1)
172 fprintf(stderr, "\n");
173 fprintf(stderr, "sending a %s\n", p_type->name);
175 switch (p_type->category_code) {
177 case e_gs_type_cat_elemental:
179 if (p_type->before_callback) {
180 p_type->before_callback(vars, p_type, data);
183 cops->write (p_cnx, data, p_type->size);
187 case e_gs_type_cat_struct :
189 struct s_gs_cat_struct *p_struct = NULL;
191 if (p_type->before_callback) {
192 p_type->before_callback(vars, p_type, data);
195 p_struct = p_type->category.struct_data;
201 nb_fields = p_struct->nb_fields;
203 while (i < nb_fields) {
204 struct s_gs_cat_struct_field *p_field = NULL;
205 struct s_gs_type *p_field_type = NULL;
208 p_field = p_struct->field_array[i];
209 p_field_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, p_field->code);
210 ref = ((char *)data) + p_field->offset;
212 if (p_field->before_callback) {
213 p_field->before_callback(vars, p_field_type, ref);
216 _gs_message_send_type(p_bag,
223 if (p_field->after_callback) {
224 p_field->after_callback(vars, p_field_type, ref);
231 if (p_type->after_callback) {
232 p_type->after_callback(vars, p_type, data);
237 case e_gs_type_cat_union :
239 struct s_gs_cat_union *p_union = NULL;
241 p_union = p_type->category.union_data;
245 struct s_gs_cat_union_field *p_field = NULL;
246 struct s_gs_type *p_field_type = NULL;
248 field_num = p_union->callback(vars, p_type, data);
250 if ((field_num < 0) || (field_num >= p_union->nb_fields))
251 GS_FAILURE("invalid field index");
253 _gs_message_send_type(p_bag,
257 bops->get_type_by_name(p_bag, NULL, "signed int"),
260 p_field = p_union->field_array[field_num];
261 p_field_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, p_field->code);
263 if (p_field->before_callback) {
264 p_field->before_callback(vars, p_field_type, data);
267 _gs_message_send_type(p_bag,
274 if (p_field->after_callback) {
275 p_field->after_callback(vars, p_field_type, data);
279 if (p_type->after_callback) {
280 p_type->after_callback(vars, p_type, data);
285 case e_gs_type_cat_ref :
288 void **p_ref = (void **)data;
289 struct s_gs_cat_ref *p_ref_data = NULL;
292 p_ref_data = p_type->category.ref_data;
294 if (p_ref_data->callback) {
295 code = p_ref_data->callback(vars, p_type, data);
298 if (p_ref_data->code >= 0) {
299 code = p_ref_data->code;
301 _gs_message_send_type(p_bag,
305 bops->get_type_by_name(p_bag, NULL, "signed int"),
309 cops->write (p_cnx, data, p_type->size);
311 if (*p_ref && !(gras_dict_retrieve_ext(*p_refs, (char *)p_ref, sizeof(void *), &dummy), dummy)) {
312 struct s_gs_type *p_ref_type = NULL;
314 fprintf(stderr, "sending data referenced at %p\n", *p_ref);
315 gras_dict_insert_ext(*p_refs, (char *)p_ref, sizeof(void *), p_ref, NULL);
317 p_ref_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, code);
319 _gs_message_send_type(p_bag,
328 fprintf(stderr, "not sending data referenced at %p\n", *p_ref);
331 if (p_type->after_callback) {
332 p_type->after_callback(vars, p_type, data);
337 case e_gs_type_cat_array :
339 struct s_gs_cat_array *p_array = NULL;
341 struct s_gs_type *p_element_type = NULL;
342 long int element_size = 0;
345 p_array = p_type->category.array_data;
346 count = p_array->element_count;
349 count = p_array->callback(vars, p_type, data);
351 GS_FAILURE("invalid array element count");
352 } else if (p_array->callback) {
353 (void)p_array->callback(vars, p_type, data);
356 _gs_message_send_type(p_bag,
360 bops->get_type_by_name(p_bag, NULL, "signed long int"),
363 p_element_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, p_array->code);
364 element_size = p_element_type->aligned_size;
370 _gs_message_send_type(p_bag,
381 if (p_type->after_callback) {
382 p_type->after_callback(vars, p_type, data);
388 case e_gs_type_cat_ignored :
390 if (p_type->before_callback) {
391 p_type->before_callback(vars, p_type, data);
397 GS_FAILURE("invalid type");
401 struct s_gs_message_instance *
402 gs_message_init_send_by_ref(struct s_gs_type_bag *p_bag,
403 struct s_gs_connection *p_cnx,
404 struct s_gs_message *p_message) {
405 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
406 struct s_gs_message_instance *p_message_instance = NULL;
409 vars = gs_vars_alloc();
411 if (!bops->check_message_mark(p_bag, p_cnx, p_message->name)) {
412 struct s_gs_type *p_message_type = NULL;
413 gras_dict_t *_refs = NULL;
414 struct s_gs_type *signed_int = NULL;
416 signed_int = bops->get_type_by_name(p_bag, NULL, "signed int");
417 p_message_type = bops->get_type_by_name(p_bag, NULL, "_s_gs_message");
420 GS_FAILURE("_s_gs_message default type missing");
422 bops->mark_message(p_bag, p_cnx, p_message->name);
424 _gs_message_send_type(p_bag, p_cnx, vars, &_refs, signed_int, &p_message->code);
425 _gs_message_send_type(p_bag, p_cnx, vars, &_refs, p_message_type, p_message);
427 gras_dict_t *_refs = NULL;
428 struct s_gs_type *signed_int = NULL;
430 _gs_message_send_type(p_bag, p_cnx, vars, &_refs, signed_int, &p_message->code);
435 p_message_instance = _gs_message_instance_new();
437 p_message_instance->p_message = p_message;
438 p_message_instance->current = p_message->first;
439 p_message_instance->p_bag = p_bag;
440 p_message_instance->p_connection = p_cnx;
443 return p_message_instance;
446 struct s_gs_message_instance *
447 gs_message_init_send_by_name(struct s_gs_type_bag *p_bag,
448 struct s_gs_connection *p_connection,
450 struct s_gs_type_bag_ops *bag_ops = p_bag->bag_ops;
451 struct s_gs_message *p_message = NULL;
452 struct s_gs_message_instance *p_message_instance = NULL;
454 p_message = bag_ops->get_message_by_name(p_bag, NULL, name);
455 p_message_instance = gs_message_init_send_by_ref(p_bag, p_connection, p_message);
457 return p_message_instance;
460 struct s_gs_message_instance *
461 gs_message_init_send_by_code(struct s_gs_type_bag *p_bag,
462 struct s_gs_connection *p_connection,
464 struct s_gs_type_bag_ops *bag_ops = p_bag->bag_ops;
465 struct s_gs_message *p_message = NULL;
466 struct s_gs_message_instance *p_message_instance = NULL;
468 p_message = bag_ops->get_message_by_code(p_bag, NULL, code);
469 p_message_instance = gs_message_init_send_by_ref(p_bag, p_connection, p_message);
471 return p_message_instance;
475 gs_message_send_next_sequence_ext(void *vars,
476 struct s_gs_message_instance *p_message_instance,
478 struct s_gs_type_bag *p_bag = p_message_instance->p_bag;
479 struct s_gs_connection *p_cnx = p_message_instance->p_connection;
480 struct s_gs_sequence *p_sequence = NULL;
481 struct s_gs_type *p_type = NULL;
482 gras_dict_t *refs = NULL;
484 p_sequence = p_message_instance->current;
486 GS_FAILURE("message type has no more sequences");
488 p_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, p_sequence->code);
489 _gs_message_send_type(p_message_instance->p_bag,
490 p_message_instance->p_connection,
495 gras_dict_free(&refs);
496 p_message_instance->current = p_sequence->next;
500 gs_message_send_next_sequence(struct s_gs_message_instance *p_message_instance,
504 vars = gs_vars_alloc();
505 gs_message_send_next_sequence_ext(vars, p_message_instance, data);
514 * Note: here we suppose that the remote NULL is a sequence of 'length' bytes set to 0.
518 _gs_is_null(void **p_ptr,
522 for (i = 0; i < length; i++) {
523 if (((unsigned char *)p_ptr)[i]) {
534 _gs_alloc_ref(gras_dict_t **p_refs,
539 void *new_ref = NULL;
541 new_ref = malloc((size_t)size);
542 *p_new_ref = new_ref;
544 if (p_old_ref && !_gs_is_null(p_old_ref, length)) {
545 p_old_ref = gs_memdup(p_old_ref, (size_t)length);
546 p_new_ref = gs_memdup(&new_ref, sizeof(void *));
548 gras_dict_insert_ext(*p_refs,(char *) p_old_ref, length, p_new_ref, NULL);
554 _gs_convert_elemental(void *local,
555 struct s_gs_type *p_local_type,
557 struct s_gs_type *p_remote_type) {
558 struct s_gs_cat_elemental *p_local_elemental = p_local_type->category.elemental_data;
559 struct s_gs_cat_elemental *p_remote_elemental = p_remote_type->category.elemental_data;
564 if (p_local_elemental->encoding == p_remote_elemental->encoding) {
565 if (p_local_type->size != p_remote_type->size) {
566 GS_FAILURE("size conversion unimplemented");
569 GS_FAILURE("encoding conversion unimplemented");
575 _gs_message_receive_type(struct s_gs_type_bag *p_bag,
576 struct s_gs_connection *p_cnx,
577 gras_dict_t **p_refs,
578 struct s_gs_type *p_type,
580 long int old_data_length,
585 _sg_message_receive_get_type_by_code(struct s_gs_type_bag *p_bag,
586 struct s_gs_connection *p_cnx,
588 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
589 struct s_gs_type *p_type = NULL;
591 p_type = bops->get_type_by_code(p_bag, p_cnx, code);
594 struct s_gs_type *p_type_type = NULL;
595 gras_dict_t *_refs = NULL;
597 p_type_type = bops->get_type_by_name(p_bag, p_cnx, "_s_gs_type");
599 GS_FAILURE("_s_gs_type default type missing");
601 fprintf(stderr, "need type with code = %d\n", code);
602 _gs_message_receive_type(p_bag, p_cnx, &_refs, p_type_type, NULL, 0, (void **)&p_type);
603 fprintf(stderr, "got type with code = %d, name = %s\n", code, p_type->name);
605 bops->store_incoming_type(p_bag, p_cnx, p_type);
607 fprintf(stderr, "already seen type with code = %d, name = %s\n", code, p_type->name);
616 _gs_message_receive_type(struct s_gs_type_bag *p_bag,
617 struct s_gs_connection *p_cnx,
618 gras_dict_t **p_refs,
619 struct s_gs_type *p_remote_type,
621 long int old_ptr_length,
623 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
624 struct s_gs_connection_ops *cops = p_cnx->connection_ops;
625 struct s_gs_type *p_local_type = NULL;
626 void *new_data = *p_new_ptr;
629 gras_dict_new(p_refs);
631 p_local_type = bops->get_type_by_name(p_bag, NULL, p_remote_type->name);
632 if (p_local_type->category_code > 1)
633 fprintf(stderr, "\n");
634 fprintf(stderr, "receiving a %s\n", p_local_type->name);
636 switch (p_remote_type->category_code) {
638 case e_gs_type_cat_elemental:
641 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
642 new_data = *p_new_ptr;
645 if (p_remote_type->size <= p_local_type->size) {
646 cops->read (p_cnx, new_data, p_remote_type->size);
647 _gs_convert_elemental(new_data, p_local_type, new_data, p_remote_type);
651 ptr = malloc((size_t)p_remote_type->size);
652 cops->read (p_cnx, ptr, p_remote_type->size);
653 _gs_convert_elemental(new_data, p_local_type, ptr, p_remote_type);
659 case e_gs_type_cat_struct :
661 struct s_gs_cat_struct *p_struct = NULL;
663 p_struct = p_remote_type->category.struct_data;
666 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
667 new_data = *p_new_ptr;
674 nb_fields = p_struct->nb_fields;
676 while (i < nb_fields) {
677 struct s_gs_cat_struct_field *p_field = NULL;
678 struct s_gs_type *p_field_type = NULL;
681 p_field = p_struct->field_array[i];
682 p_field_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, p_field->code);
683 ref = ((char *)new_data) + p_field->offset;
685 _gs_message_receive_type(p_bag,
698 case e_gs_type_cat_union :
700 struct s_gs_cat_union *p_union = NULL;
702 p_union = p_remote_type->category.union_data;
705 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
706 new_data = *p_new_ptr;
711 struct s_gs_cat_union_field *p_field = NULL;
712 struct s_gs_type *p_field_type = NULL;
715 int *p_field_num = &field_num;
717 _gs_message_receive_type(p_bag,
720 bops->get_type_by_name(p_bag, p_cnx, "signed int"),
723 (void**)&p_field_num);
726 p_field = p_union->field_array[field_num];
727 p_field_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, p_field->code);
729 _gs_message_receive_type(p_bag,
740 case e_gs_type_cat_ref :
742 void **p_old_ref = NULL;
743 void **p_new_ref = NULL;
744 struct s_gs_cat_ref *p_ref_data = NULL;
747 p_ref_data = p_remote_type->category.ref_data;
748 code = p_ref_data->code;
753 _gs_message_receive_type(p_bag,
756 bops->get_type_by_name(p_bag, p_cnx, "signed int"),
762 p_old_ref = malloc((size_t)p_remote_type->size);
763 cops->read (p_cnx, p_old_ref, p_remote_type->size);
766 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
767 new_data = *p_new_ptr;
770 if (!_gs_is_null(p_old_ref, p_remote_type->size)) {
771 if (!(gras_dict_retrieve_ext(*p_refs, (char *)p_old_ref, p_remote_type->size, (void **)&p_new_ref), p_new_ref)) {
772 void *new_ref = NULL;
773 struct s_gs_type *p_ref_type = NULL;
775 fprintf(stderr, "receiving data referenced at %p\n", *(void **)p_old_ref);
776 p_ref_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, code);
778 _gs_message_receive_type(p_bag,
786 *(void **)new_data = new_ref;
788 fprintf(stderr, "not receiving data referenced at %p\n", *(void **)p_old_ref);
789 *(void **)new_data = *p_new_ref;
792 fprintf(stderr, "not receiving data referenced at %p\n", *(void **)p_old_ref);
793 *(void **)new_data = NULL;
798 case e_gs_type_cat_array :
800 struct s_gs_cat_array *p_array = NULL;
802 struct s_gs_type *p_element_type = NULL;
803 struct s_gs_type *p_local_element_type = NULL;
804 long int element_size = 0;
807 p_array = p_remote_type->category.array_data;
810 long int *p_count = &count;
812 _gs_message_receive_type(p_bag,
815 bops->get_type_by_name(p_bag, p_cnx, "signed long int"),
821 p_element_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, p_array->code);
822 p_local_element_type = bops->get_type_by_name(p_bag, NULL, p_element_type->name);
823 element_size = p_local_element_type->aligned_size;
826 _gs_alloc_ref(p_refs, count*element_size, p_old_ptr, old_ptr_length, p_new_ptr);
827 new_data = *p_new_ptr;
836 _gs_message_receive_type(p_bag,
849 case e_gs_type_cat_ignored:
851 struct s_gs_cat_ignored *p_ignored = NULL;
854 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
855 new_data = *p_new_ptr;
858 p_ignored = p_local_type->category.ignored_data;
860 if (p_ignored->default_value) {
861 memcpy(new_data, p_ignored->default_value, (size_t)p_local_type->size);
868 GS_FAILURE("invalid type");
872 struct s_gs_message_instance *
873 gs_message_init_receive(struct s_gs_type_bag *p_bag,
874 struct s_gs_connection *p_cnx) {
876 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
877 struct s_gs_message_instance *p_message_instance = NULL;
879 struct s_gs_message *p_message = NULL;
882 gras_dict_t *_refs = NULL;
883 struct s_gs_type *signed_int = NULL;
885 signed_int = bops->get_type_by_name(p_bag, p_cnx, "signed int");
886 _gs_message_receive_type(p_bag, p_cnx, &_refs, signed_int, NULL, 0, (void**)&p_code);
888 p_message = bops->get_message_by_code(p_bag, p_cnx, *p_code);
891 struct s_gs_type *p_message_type = NULL;
892 p_message_type = bops->get_type_by_name(p_bag, p_cnx, "_s_gs_message");
895 GS_FAILURE("_s_gs_message default type missing");
897 _gs_message_receive_type(p_bag, p_cnx, &_refs, p_message_type, NULL, 0, (void **)&p_message);
899 bops->store_incoming_message(p_bag, p_cnx, p_message);
903 p_message_instance = _gs_message_instance_new();
905 p_message_instance->p_message = p_message;
906 p_message_instance->current = p_message->first;
907 p_message_instance->p_bag = p_bag;
908 p_message_instance->p_connection = p_cnx;
910 return p_message_instance;
914 gs_message_receive_next_sequence(struct s_gs_message_instance *p_message_instance) {
915 struct s_gs_type_bag *p_bag = p_message_instance->p_bag;
916 struct s_gs_connection *p_cnx = p_message_instance->p_connection;
917 struct s_gs_sequence *p_sequence = NULL;
918 struct s_gs_type *p_remote_type = NULL;
919 gras_dict_t *refs = NULL;
922 p_sequence = p_message_instance->current;
924 GS_FAILURE("message type has no more sequences");
926 p_remote_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, p_sequence->code);
927 _gs_message_receive_type(p_bag,
935 gras_dict_free(&refs);
937 p_message_instance->current = p_sequence->next;