/* * This function gets called inside the function read or by the return loan, * it frees the dynamic array of dynamic data, when we return the loan, * or when we have some errors, after allocating memory for the sample * list */ void RTI_RoutingServiceFileStreamReader_freeDynamicDataArray( struct DDS_DynamicData ** samples, int count) { int i = 0; for (i = 0; i < count; i++) { if (samples[i] != NULL) { DDS_DynamicData_delete(samples[i]); samples[i] = NULL; } } free(samples); samples = NULL; }
/* * The read function gets called every time the routing service * gets notified of data available by the function on_data_available * of every stream reader's listener */ void RTI_RoutingServiceFileStreamReader_read( RTI_RoutingServiceStreamReader stream_reader, RTI_RoutingServiceSample ** sample_list, RTI_RoutingServiceSampleInfo ** info_list, int * count, RTI_RoutingServiceEnvironment * env) { int i = 0, sample_counter = 0; struct DDS_DynamicData * sample = NULL; struct DDS_DynamicDataProperty_t dynamic_data_props = DDS_DynamicDataProperty_t_INITIALIZER; struct RTI_RoutingServiceFileStreamReader * self = (struct RTI_RoutingServiceFileStreamReader *) stream_reader; /* * We don't provide sample info in this adapter, which * is an optional feature */ *info_list = NULL; /* * if the function read it is called because we have discovery data, * the pointer or the stream reader that calls the */ if ((self->connection->input_discovery_reader == self)) { int new_discovered_samples = 0; fprintf(stdout,"DiscoveryReader: called function read " "for input discovery\n"); /* * we keep track in the checking thread of the number of file names * inside the discovery_data array, every new discovered file, we * increase this counter (discovery_data_counter), and we keep track * of the files we have already read, and created the relative streams, * with the discovery_data_counter_read, subtracting one to another, we * know how many new discovered files we have */ new_discovered_samples = self->discovery_data_counter - self->discovery_data_counter_read; /* * we receive as a parameter the pointer to an array, and we need to * allocate memory for it, first for the array, then for the single * elements we put in it. */ *sample_list = calloc( new_discovered_samples, sizeof(struct RTI_RoutingServiceStreamInfo *)); if (*sample_list == NULL) { RTI_RoutingServiceEnvironment_set_error( env, "Failure creating dynamic data sample in read " "function for discovery"); return; } /* * inside this loop we create the sample info structures, * to describe the new stream to be created */ for (i = 0; i < new_discovered_samples; i++) { struct RTI_RoutingServiceStreamInfo *streaminfo; /* * here we create the stream info type, passing as string name * the name of the file taken from the discovery_data array * filled by the checking thread. */ streaminfo = RTI_RoutingServiceStreamInfo_new_discovered( self->discovery_data[self->discovery_data_counter_read], "TextLine",/*typename*/ RTI_ROUTING_SERVICE_TYPE_REPRESENTATION_DYNAMIC_TYPE, self->type_code); if (streaminfo == NULL) { continue; } (*sample_list)[*count] = streaminfo; /* * we increment the count of the sample info generated and returned * inside the sampli_list dynamic array. */ (*count)++; /* * we increment the index as we have already read that * position of the array */ self->discovery_data_counter_read++; } } else { fprintf(stdout,"StreamReader: called function read for data\n"); *sample_list = calloc(self->samples_per_read,sizeof(DDS_DynamicData *)); if (*sample_list == NULL) { RTI_RoutingServiceEnvironment_set_error( env,"Failure creating dynamic data " "sample list in read function"); return; } /* * Read as many times as samples_per_read * (or less if we encounter the end of file) */ for (i = 0; i < self->samples_per_read && !feof(self->file); i++) { /* * Create a dynamic data sample for every buffer we read. We use * the type we received when the stream reader was created */ sample = DDS_DynamicData_new(self->type_code, &dynamic_data_props); if (sample == NULL) { RTI_RoutingServiceEnvironment_set_error( env, "Failure creating dynamic data sample in read function"); RTI_RoutingServiceFileStreamReader_freeDynamicDataArray( (struct DDS_DynamicData **) *sample_list, sample_counter); *sample_list = NULL; return; } /* * Fill the dynamic data sample fields * with the buffer read from the file. */ if ( !RTI_RoutingServiceFileAdapter_read_sample( sample, self->file, env)) { /* No sample read */ DDS_DynamicData_delete(sample); continue; } (*sample_list)[sample_counter++] = sample; } /* Set the count to the actual number of samples we have generated */ *count = sample_counter; } /* * If there are no samples to read we free the memory allocated straight * away as the routing service wouldn't call return_loan */ if (*count == 0) { /* If we report zero samples we have to free the array now */ free(*sample_list); *sample_list = NULL; } }
int main() { struct DDS_TypeCode *inner_tc = NULL; struct DDS_TypeCode *outer_tc = NULL; struct DDS_TypeCodeFactory *factory = NULL; DDS_ExceptionCode_t err; DDS_ReturnCode_t retcode; int ret = -1; DDS_DynamicData *outer_data = NULL; DDS_DynamicData *inner_data = NULL; DDS_DynamicData *bounded_data = NULL; /* Getting a reference to the type code factory */ factory = DDS_TypeCodeFactory_get_instance(); if (factory == NULL) { fprintf(stderr, "! Unable to get type code factory singleton\n"); goto fail; } /* Creating the typeCode of the inner_struct */ inner_tc = inner_struct_get_typecode(factory); if (inner_tc == NULL) { fprintf(stderr, "! Unable to create typeCode\n"); goto fail; } /* Creating the typeCode of the outer_struct that contains an inner_struct */ outer_tc = outer_struct_get_typecode(factory); if (inner_tc == NULL) { fprintf(stderr, "! Unable to create typeCode\n"); goto fail; } printf(" Connext Dynamic Data Nested Struct Example \n" "--------------------------------------------\n"); printf(" Data Types\n" "------------------\n"); DDS_TypeCode_print_IDL(inner_tc, 0, &err); DDS_TypeCode_print_IDL(outer_tc, 0, &err); /* Now, we create a dynamicData instance for each type */ outer_data = DDS_DynamicData_new(outer_tc, &DDS_DYNAMIC_DATA_PROPERTY_DEFAULT); if (outer_data == NULL) { fprintf(stderr, "! Unable to create outer dynamicData\n"); goto fail; } inner_data = DDS_DynamicData_new(inner_tc, &DDS_DYNAMIC_DATA_PROPERTY_DEFAULT); if (outer_data == NULL) { fprintf(stderr, "! Unable to create inner dynamicData\n"); goto fail; } /* Setting the inner data */ retcode = DDS_DynamicData_set_double(inner_data, "x", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, 3.14159); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to set value 'x' in the inner struct \n"); goto fail; } retcode = DDS_DynamicData_set_double(inner_data, "y", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, 2.71828); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to set value 'y' in the inner struct\n"); goto fail; } printf("\n\n get/set_complex_member API\n" "----------------------------\n"); /* Using set_complex_member, we copy inner_data values in inner_struct of * outer_data */ printf("Setting initial values of outer_data with " "set_complex_member()\n"); retcode = DDS_DynamicData_set_complex_member(outer_data, "inner", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, inner_data); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to set complex struct value " "(member inner in the outer struct)\n"); goto fail; } DDS_DynamicData_print(outer_data, stdout, 1); retcode = DDS_DynamicData_clear_all_members(inner_data); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to clear all member in the inner data\n"); goto fail; } printf("\n + get_complex_member() called\n"); retcode = DDS_DynamicData_get_complex_member(outer_data, inner_data, "inner", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to get complex struct value " "(member inner in the outer struct)\n"); goto fail; } printf("\n + inner_data value\n"); DDS_DynamicData_print(inner_data, stdout, 1); /* get_complex_member made a copy of the inner_struct. If we modify * inner_data values, outer_data inner_struct WILL NOT be modified. */ printf("\n + setting new values to inner_data\n"); retcode = DDS_DynamicData_set_double(inner_data, "x", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, 1.00000); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to set value 'x' in the inner struct \n"); goto fail; } retcode = DDS_DynamicData_set_double(inner_data, "y", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, 0.00001); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to set value 'y' in the inner struct \n"); goto fail; } DDS_DynamicData_print(inner_data, stdout, 1); /* Current value of outer_data * outer_data: * inner: * x: 3.141590 * y: 2.718280 * * inner_data: * x: 1.000000 * y: 0.000010 */ printf("\n + current outer_data value \n"); DDS_DynamicData_print(outer_data, stdout, 1); /* Bind/Unbind member API */ printf("\n\n bind/unbind API\n" "------------------\n"); printf("Creating a new dynamic data called bounded_data\n"); bounded_data = DDS_DynamicData_new(NULL, &DDS_DYNAMIC_DATA_PROPERTY_DEFAULT); if (bounded_data == NULL) { fprintf(stderr, "! Unable to create new dynamic data\n"); goto fail; } printf("\n + binding bounded_data to outer_data's inner_struct\n"); /* Using bind_complex_member, we do not copy inner_struct, but bind it. * So, if we modify bounded_data, the inner member inside outer_data WILL * also be modified */ retcode = DDS_DynamicData_bind_complex_member(outer_data, bounded_data, "inner", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to bind the structs\n"); goto fail; } DDS_DynamicData_print(bounded_data, stdout, 1); printf("\n + setting new values to bounded_data\n"); retcode = DDS_DynamicData_set_double(bounded_data, "x", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, 1.00000); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to set value to 'x' with the bounded data\n"); goto fail; } retcode = DDS_DynamicData_set_double(bounded_data, "y", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, 0.00001); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to set value to 'x' with the bounded data\n"); goto fail; } /* Current value of outer data * outer: * inner: * x: 1.000000 * y: 0.000010 */ DDS_DynamicData_print(bounded_data, stdout, 1); retcode = DDS_DynamicData_unbind_complex_member(outer_data, bounded_data); if (retcode != DDS_RETCODE_OK) { fprintf(stderr, "! Unable to unbind the data\n"); goto fail; } printf("\n + current outer_data value \n"); DDS_DynamicData_print(outer_data, stdout, 1); ret = 1; fail: if (inner_tc != NULL) { DDS_TypeCodeFactory_delete_tc(factory, inner_tc, NULL); } if (outer_tc != NULL) { DDS_TypeCodeFactory_delete_tc(factory, outer_tc, NULL); } if (inner_data != NULL) { DDS_DynamicData_delete(inner_data); } if (outer_data != NULL) { DDS_DynamicData_delete(outer_data); } if (bounded_data != NULL) { DDS_DynamicData_delete(bounded_data); } return ret; }