/****************************************************************************** * Read from the current position in the file to the first format line * containing a new sequence. Update the value of the current sequence. * * Returns TRUE if it was able to advance to the next sequence, FALSE if * EOF reached before the next sequence was found. Dies if other errors * encountered. *****************************************************************************/ BOOLEAN_T go_to_next_sequence_in_wiggle( WIGGLE_READER_T *reader ) { char *line = NULL; char *prev_chrom = NULL; BOOLEAN_T result = FALSE; while((result = read_wiggle_line(reader, &line)) == TRUE) { if (is_format_line(line) == TRUE) { // Parse format lines and move to next line if (reader->chrom) { prev_chrom = strdup(reader->chrom); } parse_wiggle_format_line(reader, line); int chrom_match = 1; if (prev_chrom) { chrom_match = strcmp(prev_chrom, reader->chrom); myfree(prev_chrom); } if (chrom_match != 0) { // We've reached a new sequence result = TRUE; break; } } myfree(line); } myfree(line); return result; }
/****************************************************************************** * Reads the next data block from the wiggle file * * Returns TRUE if it was able to read the block, FALSE if it reaches * a new sequence sequence or EOF. Dies if other errors encountered. *****************************************************************************/ BOOLEAN_T get_next_data_block_from_wiggle( WIGGLE_READER_T *reader, char **chrom, size_t *start, size_t *step, size_t *span, double *value ) { char *line = NULL; // Mark current position long save_pos = ftell(reader->wiggle_file); BOOLEAN_T result = read_wiggle_line(reader, &line); if (result == TRUE) { if (is_track_line(line) == TRUE) { // Skip track lines myfree(line); result = FALSE; } else if (is_format_line(line) == TRUE) { // We've reached a new sequence, back up one line // FIXME CEG add error handling fseek(reader->wiggle_file, save_pos, SEEK_SET); myfree(line); result = FALSE; } else { parse_wiggle_value_line(reader, line, start, value); *chrom = strdup(reader->chrom); *step = reader->step; *span = reader->span; myfree(line); result = TRUE; } } return result; }
/****************************************************************************** * Reads the next data line from the wiggle file * * Returns TRUE if it was able to read the line, FALSE if it reaches * a new sequence sequence or EOF. Dies if other errors encountered. *****************************************************************************/ BOOLEAN_T get_next_data_line_from_wiggle( WIGGLE_READER_T *reader, char **chrom, size_t *start, size_t *step, size_t *span, double *value ) { char *line = NULL; BOOLEAN_T done_looking = FALSE; BOOLEAN_T found_data = FALSE; // Save current reader state INPUT_FMT_T prev_format = reader->format; long prev_prev_line_position = reader->prev_line_position; size_t prev_start = reader->start; size_t prev_step = reader->step; size_t prev_span = reader->span; char *prev_chrom = NULL; if (reader->chrom) { prev_chrom = strdup(reader->chrom); } long save_pos = ftell(reader->wiggle_file); // Keep trying until we've read a data line or reached a new sequence while (done_looking == FALSE) { BOOLEAN_T read_line = read_wiggle_line(reader, &line); if (read_line != TRUE) { // We've reached EOF found_data = FALSE; done_looking = TRUE; break; } // A wiggle file line is either a track line, // a format line, or a data line. if (is_track_line(line) == TRUE) { // Skip track lines continue; } else if (is_format_line(line) == TRUE) { // A format line may indicate a new sequence // or simply be setting the start, span or step. // If it's a new sequence we should just back up // and return FALSE since no more data blocs are // available for this sequence. parse_wiggle_format_line(reader, line); // Check to see if we've reached a new sequence int chrom_match = -1; if (prev_chrom) { chrom_match = strcmp(prev_chrom, reader->chrom); } if (chrom_match != 0) { // We've reached a new sequence. Back up one and return FALSE errno = 0; int e = fseek(reader->wiggle_file, save_pos, SEEK_SET); if (e) { die( "Error when trying to get data line in wiggle file: %s.\nError message: %s.\n", reader->filename, strerror(errno) ); } // Restore reader values reader->format = prev_format; reader->prev_line_position = prev_prev_line_position; reader->start = prev_start; reader->step = prev_step; reader->span = prev_span; myfree(reader->chrom); reader->chrom = strdup(prev_chrom); found_data = FALSE; done_looking = TRUE; } } else { // We've reached a data line parse_wiggle_value_line(reader, line, start, value); if (*chrom) { myfree(*chrom); } *chrom = strdup(reader->chrom); *step = reader->step; *span = reader->span; reader->prev_line_position = save_pos; found_data = TRUE; done_looking = TRUE; } myfree(line); } myfree(prev_chrom); return found_data; }