3 #include "gs/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;
168 if (p_type->category_code > 1)
169 fprintf(stderr, "\n");
170 fprintf(stderr, "sending a %s\n", p_type->name);
172 switch (p_type->category_code) {
174 case e_gs_type_cat_elemental:
176 if (p_type->before_callback) {
177 p_type->before_callback(vars, p_type, data);
180 cops->write (p_cnx, data, p_type->size);
184 case e_gs_type_cat_struct :
186 struct s_gs_cat_struct *p_struct = NULL;
188 if (p_type->before_callback) {
189 p_type->before_callback(vars, p_type, data);
192 p_struct = p_type->category.struct_data;
198 nb_fields = p_struct->nb_fields;
200 while (i < nb_fields) {
201 struct s_gs_cat_struct_field *p_field = NULL;
202 struct s_gs_type *p_field_type = NULL;
205 p_field = p_struct->field_array[i];
206 p_field_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, p_field->code);
207 ref = ((char *)data) + p_field->offset;
209 if (p_field->before_callback) {
210 p_field->before_callback(vars, p_field_type, ref);
213 _gs_message_send_type(p_bag,
220 if (p_field->after_callback) {
221 p_field->after_callback(vars, p_field_type, ref);
228 if (p_type->after_callback) {
229 p_type->after_callback(vars, p_type, data);
234 case e_gs_type_cat_union :
236 struct s_gs_cat_union *p_union = NULL;
238 p_union = p_type->category.union_data;
242 struct s_gs_cat_union_field *p_field = NULL;
243 struct s_gs_type *p_field_type = NULL;
245 field_num = p_union->callback(vars, p_type, data);
247 if ((field_num < 0) || (field_num >= p_union->nb_fields))
248 GS_FAILURE("invalid field index");
250 _gs_message_send_type(p_bag,
254 bops->get_type_by_name(p_bag, NULL, "signed int"),
257 p_field = p_union->field_array[field_num];
258 p_field_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, p_field->code);
260 if (p_field->before_callback) {
261 p_field->before_callback(vars, p_field_type, data);
264 _gs_message_send_type(p_bag,
271 if (p_field->after_callback) {
272 p_field->after_callback(vars, p_field_type, data);
276 if (p_type->after_callback) {
277 p_type->after_callback(vars, p_type, data);
282 case e_gs_type_cat_ref :
285 void **p_ref = (void **)data;
286 struct s_gs_cat_ref *p_ref_data = NULL;
289 p_ref_data = p_type->category.ref_data;
291 if (p_ref_data->callback) {
292 code = p_ref_data->callback(vars, p_type, data);
295 if (p_ref_data->code >= 0) {
296 code = p_ref_data->code;
298 _gs_message_send_type(p_bag,
302 bops->get_type_by_name(p_bag, NULL, "signed int"),
306 cops->write (p_cnx, data, p_type->size);
308 if (*p_ref && !(gras_dict_retrieve_ext(*p_refs, (char *)p_ref, sizeof(void *), &dummy), dummy)) {
309 struct s_gs_type *p_ref_type = NULL;
311 fprintf(stderr, "sending data referenced at %p\n", *p_ref);
312 gras_dict_insert_ext(*p_refs, (char *)p_ref, sizeof(void *), p_ref, NULL);
314 p_ref_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, code);
316 _gs_message_send_type(p_bag,
325 fprintf(stderr, "not sending data referenced at %p\n", *p_ref);
328 if (p_type->after_callback) {
329 p_type->after_callback(vars, p_type, data);
334 case e_gs_type_cat_array :
336 struct s_gs_cat_array *p_array = NULL;
338 struct s_gs_type *p_element_type = NULL;
339 long int element_size = 0;
342 p_array = p_type->category.array_data;
343 count = p_array->element_count;
346 count = p_array->callback(vars, p_type, data);
348 GS_FAILURE("invalid array element count");
349 } else if (p_array->callback) {
350 (void)p_array->callback(vars, p_type, data);
353 _gs_message_send_type(p_bag,
357 bops->get_type_by_name(p_bag, NULL, "signed long int"),
360 p_element_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, p_array->code);
361 element_size = p_element_type->aligned_size;
367 _gs_message_send_type(p_bag,
378 if (p_type->after_callback) {
379 p_type->after_callback(vars, p_type, data);
385 case e_gs_type_cat_ignored :
387 if (p_type->before_callback) {
388 p_type->before_callback(vars, p_type, data);
394 GS_FAILURE("invalid type");
398 struct s_gs_message_instance *
399 gs_message_init_send_by_ref(struct s_gs_type_bag *p_bag,
400 struct s_gs_connection *p_cnx,
401 struct s_gs_message *p_message) {
402 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
403 struct s_gs_message_instance *p_message_instance = NULL;
406 vars = gs_vars_alloc();
408 if (!bops->check_message_mark(p_bag, p_cnx, p_message->name)) {
409 struct s_gs_type *p_message_type = NULL;
410 gras_dict_t *_refs = NULL;
411 struct s_gs_type *signed_int = NULL;
413 signed_int = bops->get_type_by_name(p_bag, NULL, "signed int");
414 p_message_type = bops->get_type_by_name(p_bag, NULL, "_s_gs_message");
417 GS_FAILURE("_s_gs_message default type missing");
419 bops->mark_message(p_bag, p_cnx, p_message->name);
421 _gs_message_send_type(p_bag, p_cnx, vars, &_refs, signed_int, &p_message->code);
422 _gs_message_send_type(p_bag, p_cnx, vars, &_refs, p_message_type, p_message);
424 gras_dict_t *_refs = NULL;
425 struct s_gs_type *signed_int = NULL;
427 _gs_message_send_type(p_bag, p_cnx, vars, &_refs, signed_int, &p_message->code);
432 p_message_instance = _gs_message_instance_new();
434 p_message_instance->p_message = p_message;
435 p_message_instance->current = p_message->first;
436 p_message_instance->p_bag = p_bag;
437 p_message_instance->p_connection = p_cnx;
440 return p_message_instance;
443 struct s_gs_message_instance *
444 gs_message_init_send_by_name(struct s_gs_type_bag *p_bag,
445 struct s_gs_connection *p_connection,
447 struct s_gs_type_bag_ops *bag_ops = p_bag->bag_ops;
448 struct s_gs_message *p_message = NULL;
449 struct s_gs_message_instance *p_message_instance = NULL;
451 p_message = bag_ops->get_message_by_name(p_bag, NULL, name);
452 p_message_instance = gs_message_init_send_by_ref(p_bag, p_connection, p_message);
454 return p_message_instance;
457 struct s_gs_message_instance *
458 gs_message_init_send_by_code(struct s_gs_type_bag *p_bag,
459 struct s_gs_connection *p_connection,
461 struct s_gs_type_bag_ops *bag_ops = p_bag->bag_ops;
462 struct s_gs_message *p_message = NULL;
463 struct s_gs_message_instance *p_message_instance = NULL;
465 p_message = bag_ops->get_message_by_code(p_bag, NULL, code);
466 p_message_instance = gs_message_init_send_by_ref(p_bag, p_connection, p_message);
468 return p_message_instance;
472 gs_message_send_next_sequence_ext(void *vars,
473 struct s_gs_message_instance *p_message_instance,
475 struct s_gs_type_bag *p_bag = p_message_instance->p_bag;
476 struct s_gs_connection *p_cnx = p_message_instance->p_connection;
477 struct s_gs_sequence *p_sequence = NULL;
478 struct s_gs_type *p_type = NULL;
479 gras_dict_t *refs = NULL;
481 p_sequence = p_message_instance->current;
483 GS_FAILURE("message type has no more sequences");
485 p_type = _sg_message_send_get_type_by_code(p_bag, p_cnx, vars, p_sequence->code);
486 _gs_message_send_type(p_message_instance->p_bag,
487 p_message_instance->p_connection,
492 gras_dict_free(&refs);
493 p_message_instance->current = p_sequence->next;
497 gs_message_send_next_sequence(struct s_gs_message_instance *p_message_instance,
501 vars = gs_vars_alloc();
502 gs_message_send_next_sequence_ext(vars, p_message_instance, data);
511 * Note: here we suppose that the remote NULL is a sequence of 'length' bytes set to 0.
515 _gs_is_null(void **p_ptr,
519 for (i = 0; i < length; i++) {
520 if (((unsigned char *)p_ptr)[i]) {
531 _gs_alloc_ref(gras_dict_t **p_refs,
536 void *new_ref = NULL;
538 new_ref = malloc((size_t)size);
539 *p_new_ref = new_ref;
541 if (p_old_ref && !_gs_is_null(p_old_ref, length)) {
542 p_old_ref = gs_memdup(p_old_ref, (size_t)length);
543 p_new_ref = gs_memdup(&new_ref, sizeof(void *));
545 gras_dict_insert_ext(*p_refs,(char *) p_old_ref, length, p_new_ref, NULL);
551 _gs_convert_elemental(void *local,
552 struct s_gs_type *p_local_type,
554 struct s_gs_type *p_remote_type) {
555 struct s_gs_cat_elemental *p_local_elemental = p_local_type->category.elemental_data;
556 struct s_gs_cat_elemental *p_remote_elemental = p_remote_type->category.elemental_data;
561 if (p_local_elemental->encoding == p_remote_elemental->encoding) {
562 if (p_local_type->size != p_remote_type->size) {
563 GS_FAILURE("size conversion unimplemented");
566 GS_FAILURE("encoding conversion unimplemented");
572 _gs_message_receive_type(struct s_gs_type_bag *p_bag,
573 struct s_gs_connection *p_cnx,
574 gras_dict_t **p_refs,
575 struct s_gs_type *p_type,
577 long int old_data_length,
582 _sg_message_receive_get_type_by_code(struct s_gs_type_bag *p_bag,
583 struct s_gs_connection *p_cnx,
585 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
586 struct s_gs_type *p_type = NULL;
588 p_type = bops->get_type_by_code(p_bag, p_cnx, code);
591 struct s_gs_type *p_type_type = NULL;
592 gras_dict_t *_refs = NULL;
594 p_type_type = bops->get_type_by_name(p_bag, p_cnx, "_s_gs_type");
596 GS_FAILURE("_s_gs_type default type missing");
598 fprintf(stderr, "need type with code = %d\n", code);
599 _gs_message_receive_type(p_bag, p_cnx, &_refs, p_type_type, NULL, 0, (void **)&p_type);
600 fprintf(stderr, "got type with code = %d, name = %s\n", code, p_type->name);
602 bops->store_incoming_type(p_bag, p_cnx, p_type);
604 fprintf(stderr, "already seen type with code = %d, name = %s\n", code, p_type->name);
613 _gs_message_receive_type(struct s_gs_type_bag *p_bag,
614 struct s_gs_connection *p_cnx,
615 gras_dict_t **p_refs,
616 struct s_gs_type *p_remote_type,
618 long int old_ptr_length,
620 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
621 struct s_gs_connection_ops *cops = p_cnx->connection_ops;
622 struct s_gs_type *p_local_type = NULL;
623 void *new_data = *p_new_ptr;
625 p_local_type = bops->get_type_by_name(p_bag, NULL, p_remote_type->name);
626 if (p_local_type->category_code > 1)
627 fprintf(stderr, "\n");
628 fprintf(stderr, "receiving a %s\n", p_local_type->name);
630 switch (p_remote_type->category_code) {
632 case e_gs_type_cat_elemental:
635 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
636 new_data = *p_new_ptr;
639 if (p_remote_type->size <= p_local_type->size) {
640 cops->read (p_cnx, new_data, p_remote_type->size);
641 _gs_convert_elemental(new_data, p_local_type, new_data, p_remote_type);
645 ptr = malloc((size_t)p_remote_type->size);
646 cops->read (p_cnx, ptr, p_remote_type->size);
647 _gs_convert_elemental(new_data, p_local_type, ptr, p_remote_type);
653 case e_gs_type_cat_struct :
655 struct s_gs_cat_struct *p_struct = NULL;
657 p_struct = p_remote_type->category.struct_data;
660 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
661 new_data = *p_new_ptr;
668 nb_fields = p_struct->nb_fields;
670 while (i < nb_fields) {
671 struct s_gs_cat_struct_field *p_field = NULL;
672 struct s_gs_type *p_field_type = NULL;
675 p_field = p_struct->field_array[i];
676 p_field_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, p_field->code);
677 ref = ((char *)new_data) + p_field->offset;
679 _gs_message_receive_type(p_bag,
692 case e_gs_type_cat_union :
694 struct s_gs_cat_union *p_union = NULL;
696 p_union = p_remote_type->category.union_data;
699 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
700 new_data = *p_new_ptr;
705 struct s_gs_cat_union_field *p_field = NULL;
706 struct s_gs_type *p_field_type = NULL;
709 int *p_field_num = &field_num;
711 _gs_message_receive_type(p_bag,
714 bops->get_type_by_name(p_bag, p_cnx, "signed int"),
717 (void**)&p_field_num);
720 p_field = p_union->field_array[field_num];
721 p_field_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, p_field->code);
723 _gs_message_receive_type(p_bag,
734 case e_gs_type_cat_ref :
736 void **p_old_ref = NULL;
737 void **p_new_ref = NULL;
738 struct s_gs_cat_ref *p_ref_data = NULL;
741 p_ref_data = p_remote_type->category.ref_data;
742 code = p_ref_data->code;
747 _gs_message_receive_type(p_bag,
750 bops->get_type_by_name(p_bag, p_cnx, "signed int"),
756 p_old_ref = malloc((size_t)p_remote_type->size);
757 cops->read (p_cnx, p_old_ref, p_remote_type->size);
760 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
761 new_data = *p_new_ptr;
764 if (!_gs_is_null(p_old_ref, p_remote_type->size)) {
765 if (!(gras_dict_retrieve_ext(*p_refs, (char *)p_old_ref, p_remote_type->size, (void **)&p_new_ref), p_new_ref)) {
766 void *new_ref = NULL;
767 struct s_gs_type *p_ref_type = NULL;
769 fprintf(stderr, "receiving data referenced at %p\n", *(void **)p_old_ref);
770 p_ref_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, code);
772 _gs_message_receive_type(p_bag,
780 *(void **)new_data = new_ref;
782 fprintf(stderr, "not receiving data referenced at %p\n", *(void **)p_old_ref);
783 *(void **)new_data = *p_new_ref;
786 fprintf(stderr, "not receiving data referenced at %p\n", *(void **)p_old_ref);
787 *(void **)new_data = NULL;
792 case e_gs_type_cat_array :
794 struct s_gs_cat_array *p_array = NULL;
796 struct s_gs_type *p_element_type = NULL;
797 struct s_gs_type *p_local_element_type = NULL;
798 long int element_size = 0;
801 p_array = p_remote_type->category.array_data;
804 long int *p_count = &count;
806 _gs_message_receive_type(p_bag,
809 bops->get_type_by_name(p_bag, p_cnx, "signed long int"),
815 p_element_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, p_array->code);
816 p_local_element_type = bops->get_type_by_name(p_bag, NULL, p_element_type->name);
817 element_size = p_local_element_type->aligned_size;
820 _gs_alloc_ref(p_refs, count*element_size, p_old_ptr, old_ptr_length, p_new_ptr);
821 new_data = *p_new_ptr;
830 _gs_message_receive_type(p_bag,
843 case e_gs_type_cat_ignored:
845 struct s_gs_cat_ignored *p_ignored = NULL;
848 _gs_alloc_ref(p_refs, p_local_type->size, p_old_ptr, old_ptr_length, p_new_ptr);
849 new_data = *p_new_ptr;
852 p_ignored = p_local_type->category.ignored_data;
854 if (p_ignored->default_value) {
855 memcpy(new_data, p_ignored->default_value, (size_t)p_local_type->size);
862 GS_FAILURE("invalid type");
866 struct s_gs_message_instance *
867 gs_message_init_receive(struct s_gs_type_bag *p_bag,
868 struct s_gs_connection *p_cnx) {
870 struct s_gs_type_bag_ops *bops = p_bag->bag_ops;
871 struct s_gs_message_instance *p_message_instance = NULL;
873 struct s_gs_message *p_message = NULL;
876 gras_dict_t *_refs = NULL;
877 struct s_gs_type *signed_int = NULL;
879 signed_int = bops->get_type_by_name(p_bag, p_cnx, "signed int");
880 _gs_message_receive_type(p_bag, p_cnx, &_refs, signed_int, NULL, 0, (void**)&p_code);
882 p_message = bops->get_message_by_code(p_bag, p_cnx, *p_code);
885 struct s_gs_type *p_message_type = NULL;
886 p_message_type = bops->get_type_by_name(p_bag, p_cnx, "_s_gs_message");
889 GS_FAILURE("_s_gs_message default type missing");
891 _gs_message_receive_type(p_bag, p_cnx, &_refs, p_message_type, NULL, 0, (void **)&p_message);
893 bops->store_incoming_message(p_bag, p_cnx, p_message);
897 p_message_instance = _gs_message_instance_new();
899 p_message_instance->p_message = p_message;
900 p_message_instance->current = p_message->first;
901 p_message_instance->p_bag = p_bag;
902 p_message_instance->p_connection = p_cnx;
904 return p_message_instance;
908 gs_message_receive_next_sequence(struct s_gs_message_instance *p_message_instance) {
909 struct s_gs_type_bag *p_bag = p_message_instance->p_bag;
910 struct s_gs_connection *p_cnx = p_message_instance->p_connection;
911 struct s_gs_sequence *p_sequence = NULL;
912 struct s_gs_type *p_remote_type = NULL;
913 gras_dict_t *refs = NULL;
916 p_sequence = p_message_instance->current;
918 GS_FAILURE("message type has no more sequences");
920 p_remote_type = _sg_message_receive_get_type_by_code(p_bag, p_cnx, p_sequence->code);
921 _gs_message_receive_type(p_bag,
929 gras_dict_free(&refs);
931 p_message_instance->current = p_sequence->next;