/* ----------------------------- MNI Header ----------------------------------- @NAME : acr_read_one_element @INPUT : afp - Acr_File pointer from which to read @OUTPUT : group_id - ACR-NEMA group id element_id - ACR-NEMA element id data_length - length of data to follow data_pointer - pointer to data. Space is allocated by this routine. One additional byte is allocated and set to zero so that the data can be treated as a string. @RETURNS : Status. @DESCRIPTION: Routine to read in one ACR-NEMA element. @METHOD : @GLOBALS : @CALLS : @CREATED : November 10, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ Acr_Status acr_read_one_element(Acr_File *afp, int *group_id, int *element_id, long *data_length, char **data_pointer) { int ch, i, buflen; unsigned char buffer[2*ACR_SIZEOF_SHORT+ACR_SIZEOF_LONG]; unsigned short grpid, elid; size_t size_allocated; buflen = sizeof(buffer)/sizeof(buffer[0]); /* Read in group id, element id and length of data */ for (i=0; i < buflen; i++) { ch = acr_getc(afp); if (ch == EOF) { if (i == 0) return ACR_END_OF_INPUT; else return ACR_PROTOCOL_ERROR; } buffer[i] = ch; } acr_get_short(1, &buffer[0], &grpid); *group_id = grpid; acr_get_short(1, &buffer[2], &elid); *element_id = elid; acr_get_long(1, &buffer[4], data_length); /* Allocate space for the data and null-terminate it */ size_allocated = *data_length + 1; *data_pointer = MALLOC(size_allocated); if (*data_pointer == NULL) { *data_length = 0; size_allocated = *data_length + 1; *data_pointer = MALLOC(size_allocated); } (*data_pointer)[*data_length] = '\0'; /* Read in the data */ for (i=0; i < *data_length; i++) { ch = acr_getc(afp); if (ch == EOF) { FREE(*data_pointer); return ACR_PROTOCOL_ERROR; } (*data_pointer)[i] = ch; } return ACR_OK; }
/* ----------------------------- MNI Header ----------------------------------- @NAME : acr_read_buffer @INPUT : afp nbytes_to_read @OUTPUT : buffer nbytes_read - if NULL, then this value is ignored, otherwise the number of bytes actually read in is returned. @RETURNS : Input status. If an error occurs on the first byte, then ACR_END_OF_INPUT is returned, if an error occurs elsewhere, then ACR_ABNORMAL_END_OF_INPUT is returned, otherwise ACR_OK is returned. @DESCRIPTION: Reads in a buffer of data and optionally returns the number of bytes read @METHOD : @GLOBALS : @CALLS : @CREATED : February 12, 1997 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ Acr_Status acr_read_buffer(Acr_File *afp, unsigned char buffer[], long nbytes_to_read, long *nbytes_read) { long i; int ch; for (i=0; i < nbytes_to_read; i++) { ch = acr_getc(afp); if (ch == EOF) { break; } buffer[i] = (unsigned char) ch; } /* Save the number of bytes read */ if (nbytes_read != NULL) { *nbytes_read = i; } /* Return the status */ if (i >= nbytes_to_read) { return ACR_OK; } else if (acr_get_io_watchpoint(afp) <= 0) { return ACR_REACHED_WATCHPOINT; } else if (i == 0) { return ACR_END_OF_INPUT; } else { return ACR_ABNORMAL_END_OF_INPUT; } }
/* ----------------------------- MNI Header ----------------------------------- @NAME : acr_skip_input_data @INPUT : afp nbytes_to_skip @OUTPUT : (none) @RETURNS : Input status. If an error occurs on the first byte, then ACR_END_OF_INPUT is returned, if an error occurs elsewhere, then ACR_ABNORMAL_END_OF_INPUT is returned, otherwise ACR_OK is returned. @DESCRIPTION: Skips over input data. @METHOD : @GLOBALS : @CALLS : @CREATED : February 12, 1997 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ Acr_Status acr_skip_input_data(Acr_File *afp, long nbytes_to_skip) { long i; int ch; for (i=0; i < nbytes_to_skip; i++) { ch = acr_getc(afp); if (ch == EOF) { break; } } /* Return the status */ if (i >= nbytes_to_skip) { return ACR_OK; } else if (acr_get_io_watchpoint(afp) <= 0) { return ACR_REACHED_WATCHPOINT; } else if (i == 0) { return ACR_END_OF_INPUT; } else { return ACR_ABNORMAL_END_OF_INPUT; } }
/* ----------------------------- MNI Header ----------------------------------- @NAME : acr_test_byte_ordering @INPUT : afp @OUTPUT : (none) @RETURNS : status. @DESCRIPTION: Tests input for byte ordering to use. @METHOD : @GLOBALS : @CALLS : @CREATED : November 10, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ Acr_Status acr_test_byte_ordering(Acr_File *afp) { int ch, i, buflen; unsigned char buffer[2*ACR_SIZEOF_SHORT+ACR_SIZEOF_LONG]; long data_length; buflen = sizeof(buffer)/sizeof(buffer[0]); /* Read in group id, element id and length of data, get length of data */ for (i=0; i < buflen; i++) { ch = acr_getc(afp); if (ch == EOF) { if (i == 0) return ACR_END_OF_INPUT; else return ACR_PROTOCOL_ERROR; } buffer[i] = ch; } /* Test data length (the first element should be a group length). Try non-vax ordering first. */ (void) acr_set_vax_byte_ordering(FALSE); acr_get_long(1, &buffer[4], &data_length); /* If that doesn't work, set it to vax ordering. */ if (data_length != ACR_SIZEOF_LONG) { (void) acr_set_vax_byte_ordering(TRUE); acr_get_long(1, &buffer[4], &data_length); } /* Put the characters back */ for (i=buflen-1; i >=0; i--) { if (acr_ungetc((int) buffer[i],afp) == EOF) { return ACR_PROTOCOL_ERROR; } } if (data_length != ACR_SIZEOF_LONG) { return ACR_PROTOCOL_ERROR; } else { return ACR_OK; } }