int main( int argc, char * argv [] ) { /* Message structures and byte array */ igtl_header header; void* bind_header; child_message_body child_body; igtl_bind_info bind_info; size_t bind_size; size_t child_body_size; int rh; /* Comparison result for header */ int rb; /* Comparison result for BIND header section*/ int rc; /* Comparison result for child body section */ int s; igtl_bind_init_info(&bind_info); /* Generate transform message */ generate_transform_body(&(child_body.transform)); /* Generate image message */ generate_image_body(&(child_body.image)); /* Generate sensor message */ generate_sensor_body(&(child_body.sensor)); /* Set up BIND info structure */ if (igtl_bind_alloc_info(&bind_info, 3) == 0) { return EXIT_FAILURE; } strncpy(bind_info.child_info_array[0].type, "TRANSFORM", IGTL_HEADER_TYPE_SIZE); strncpy(bind_info.child_info_array[0].name, "ChildTrans", IGTL_HEADER_NAME_SIZE); bind_info.child_info_array[0].size = sizeof(transform_message_body); bind_info.child_info_array[0].ptr = (void*)&child_body.transform; strncpy(bind_info.child_info_array[1].type, "IMAGE", IGTL_HEADER_TYPE_SIZE); strncpy(bind_info.child_info_array[1].name, "ChildImage", IGTL_HEADER_NAME_SIZE); bind_info.child_info_array[1].size = sizeof(image_message_body); bind_info.child_info_array[1].ptr = (void*)&child_body.image; strncpy(bind_info.child_info_array[2].type, "SENSOR", IGTL_HEADER_TYPE_SIZE); strncpy(bind_info.child_info_array[2].name, "ChildSensor", IGTL_HEADER_NAME_SIZE); bind_info.child_info_array[2].size = sizeof(sensor_message_body); bind_info.child_info_array[2].ptr = (void*)&child_body.sensor; bind_size = (size_t)igtl_bind_get_size(&bind_info, IGTL_TYPE_PREFIX_NONE); bind_header = malloc(bind_size); if (bind_header == NULL) { igtl_bind_free_info(&bind_info); return EXIT_FAILURE; } igtl_bind_pack(&bind_info, bind_header, IGTL_TYPE_PREFIX_NONE); /* Calculate the sum of child body size and paddings (0 in this test program) */ child_body_size = (size_t) (bind_info.child_info_array[0].size + bind_info.child_info_array[1].size + bind_info.child_info_array[2].size); /* Set header */ header.version = 1; strncpy( (char*)&(header.name), "BIND", 12 ); strncpy( (char*)&(header.device_name), "DeviceName", 20 ); header.timestamp = 1234567890; header.body_size = bind_size + sizeof(child_message_body); header.crc = igtl_bind_get_crc(&bind_info, IGTL_TYPE_PREFIX_NONE, bind_header); igtl_header_convert_byte_order( &(header) ); /* Dumping data -- for testing */ /* FILE *fp; fp = fopen("bind.bin", "w"); fwrite(&(header), IGTL_HEADER_SIZE, 1, fp); fwrite(bind_header, bind_size, 1, fp); fwrite(&(child_body), child_body_size, 1, fp); fclose(fp); */ /* Compare the serialized byte array with the gold standard */ rh = memcmp((const void*)&header, (const void*)test_bind_message_header, IGTL_HEADER_SIZE); rb = memcmp((const void*)bind_header, (const void*)test_bind_message_bind_header, bind_size); rc = memcmp((const void*)&child_body, (const void*)test_bind_message_bind_body, child_body_size); igtl_bind_free_info(&bind_info); free(bind_header); if (rh == 0 && rb == 0 && rc == 0) { return EXIT_SUCCESS; } else { /* Print first 256 bytes as HEX values in STDERR for debug */ s = IGTL_HEADER_SIZE+bind_size+child_body_size; if (s > 256) { s = 256; } fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s); igtl_message_dump_hex(stdout, (const void*)&header, s); return EXIT_FAILURE; } }
/* * Function to unpack BIND message */ int igtl_bind_unpack_normal(void * byte_array, igtl_bind_info * info) { igtl_uint16 i; igtl_uint16 ncmessages; igtl_uint16 nametable_size; size_t namelen; char * ptr; char * ptr2; igtl_uint64 tmp64; if (byte_array == NULL || info == NULL) { return 0; } /* Number of child messages */ ptr = (char *) byte_array; if (igtl_is_little_endian()) { ncmessages = BYTE_SWAP_INT16(*((igtl_uint16*)ptr)); } else { ncmessages = *((igtl_uint16*)ptr); } /* Allocate an array of bind_info, if neccessary */ if (ncmessages != info->ncmessages) { if (igtl_bind_alloc_info(info, ncmessages) == 0) { return 0; } } /* Pointer to the first element in the BIND header section */ ptr += sizeof(igtl_uint16); /* Extract types and body sizes from the BIND header section */ for (i = 0; i < ncmessages; i ++) { /* Type of child message */ strncpy(info->child_info_array[i].type, (char*)ptr, IGTL_HEADER_TYPE_SIZE); info->child_info_array[i].type[IGTL_HEADER_TYPE_SIZE] = '\0'; /* Body size of child message */ ptr += IGTL_HEADER_TYPE_SIZE; if (igtl_is_little_endian()) { memcpy(&tmp64, ptr, sizeof(igtl_uint64)); info->child_info_array[i].size = BYTE_SWAP_INT64(tmp64); } else { memcpy(&(info->child_info_array[i].size), ptr, sizeof(igtl_uint64)); } ptr += sizeof(igtl_uint64); } /* Name table size */ if (igtl_is_little_endian()) { nametable_size = BYTE_SWAP_INT16(*((igtl_uint16 *) ptr)); } else { nametable_size = *((igtl_uint16 *) ptr); } /* * Check if the name table field is aligned to WORD (The length of * the field must be even. */ if (nametable_size % 2 != 0) { return 0; } ptr += sizeof(igtl_uint16); ptr2 = ptr; /* Extract device names from the name table section */ if (nametable_size > 0) { for (i = 0; i < ncmessages; i ++) { strncpy(info->child_info_array[i].name, ptr, IGTL_HEADER_NAME_SIZE); info->child_info_array[i].name[IGTL_HEADER_NAME_SIZE] = '\0'; namelen = strlen(info->child_info_array[i].name); ptr += namelen + 1; } } ptr = ptr2 + nametable_size; /* Set pointers to the child message bodies */ for (i = 0; i < ncmessages; i ++) { info->child_info_array[i].ptr = ptr; /* Note: a padding byte is added, if the size of the child message body is odd. */ ptr += info->child_info_array[i].size + (info->child_info_array[i].size % 2); } /** TODO: check the total size of the message? **/ return 1; }