Example #1
0
/*
 * Given the archive name (ar_name), the chunk types to output (chunk_mode),
 * and some other parameters such as the read filter, open one file and dumps
 * text formatted output to that file.  The number of reads is updated in the
 * \"num_reads\" parameter.
 *
 * Returns 0 on success.
 */
int process_srf_to_text_files(char *ar_name, char chunk_mode, int num_reads_only_mode, int filter_mode, read_filter_t *read_filter, long *num_reads) {
    srf_t *srf;
    char name[1024], dir2[1024];
    ztr_t *ztr;
    int last_lane = 0, last_tile = 0;
    /*               dump */
    FILE *files[] = {NULL};

    if (NULL == (srf = srf_open(ar_name, "rb"))) {
	perror(ar_name);
	return 1;
    }

    char *cp = strrchr(ar_name, '.');
    if (cp) *cp = 0;
    sprintf(dir2, "%s.run", ar_name);
    mkdir(dir2, 0777);

    while (NULL != (ztr = srf_next_ztr(srf, name, 0))) {
	int lane, tile, x, y;

	parse_name(name, &lane, &tile, &x, &y);

	if (last_lane != lane || last_tile != tile) {
	    fprintf(stderr, "New tile: %d/%d\n", lane, tile);
	    last_lane = lane;
	    last_tile = tile;

	    if (files[0]) { fclose(files[0]); files[0] = NULL; }

	    if (chunk_mode) {
		files[0] = fopen_text(dir2, lane, tile);
	    }
	}

	if(!num_reads_only_mode) {
	    if(!filter_mode || (filter_mode && check_read_name(read_filter, name))) {
		dump_text(ztr, name, chunk_mode, files);
		++(*num_reads);
	    }
	} else {
	    ++(*num_reads);
	}

	delete_ztr(ztr);
    }

    if (files[0]) fclose(files[0]);

    srf_destroy(srf, 1);
    return 0;
}
Example #2
0
int main(int argc, char **argv) {
    ztr_t *ztr;
    mFILE *fp;
    int i;

    if (argc >= 2) {
	if (NULL == (fp = mfopen(argv[1], "rb"))) {
	    perror(argv[1]);
	    return 1;
	}
    } else {
	fp = mstdin();
    }

    if (NULL == (ztr = mfread_ztr(fp))) {
	perror("fread_ztr");
	return 1;
    }

    printf("Nchunks = %d\n", ztr->nchunks);
    for (i = 0; i < ztr->nchunks; i++) {
	char str[5];
	int complen;
	int rawlen;
	char *val;

	(void)ZTR_BE2STR(ztr->chunk[i].type, str);
	complen = ztr->chunk[i].dlength;
	val = ztr_lookup_mdata_value(ztr, &ztr->chunk[i], "TYPE");
	if (val)
	    printf("-- %s (%s) --\n", str, val);
	else
	    printf("-- %s --\n", str);
	explode_chunk(ztr, &ztr->chunk[i]);
	rawlen = ztr->chunk[i].dlength;
	printf("SUMMARY %s  mlen %3d, dlen %6d, rawlen %6d, ratio %f\n",
	       str, ztr->chunk[i].mdlength,
	       complen, rawlen, (double)complen/rawlen);
#if 0
	fflush(stdout);
	puts("\n========================================");
	write(1, ztr->chunk[i].data, ztr->chunk[i].dlength);
	puts("\n========================================");
#endif
    }

    delete_ztr(ztr);
    
    return 0;
}
Example #3
0
/*
 * fread_ztr
 *
 * Reads a ZTR file from 'fp'. This checks for the correct magic number and
 * major version number, but not minor version number.
 *
 * FIXME: Add automatic uncompression?
 *
 * Arguments:
 *	fp		A readable FILE pointer
 *
 * Returns:
 *	Success: Pointer to a ztr_t structure (malloced)
 *	Failure: NULL
 */
ztr_t *fread_ztr(FILE *fp) {
    ztr_t *ztr;
    ztr_chunk_t *chunk;
    int sections = read_sections(0);
    
    /* Allocate */
    if (NULL == (ztr = new_ztr()))
	return NULL;

    /* Read the header */
    if (-1 == ztr_read_header(fp, &ztr->header))
	return NULL;

    /* Check magic number and version */
    if (memcmp(ztr->header.magic, ZTR_MAGIC, 8) != 0)
	return NULL;

    if (ztr->header.version_major != ZTR_VERSION_MAJOR)
	return NULL;

    /* Load chunks */
    while ((chunk = ztr_read_chunk_hdr(fp))) {
	/*
	char str[5];

	fprintf(stderr, "Read chunk %.4s %08x length %d\n",
		ZTR_BE2STR(chunk->type, str), chunk->type, chunk->dlength);
	*/
	switch(chunk->type) {
	case ZTR_TYPE_HEADER:
	    /* End of file */
	    return ztr;

	case ZTR_TYPE_SAMP:
	case ZTR_TYPE_SMP4:
	    if (! (sections & READ_SAMPLES)) {
		fseek(fp, chunk->dlength, SEEK_CUR);
		xfree(chunk);
		continue;
	    }
	    break;

          
	case ZTR_TYPE_BASE:
	case ZTR_TYPE_BPOS:
	case ZTR_TYPE_CNF4:
	case ZTR_TYPE_CNF1:
	case ZTR_TYPE_CSID:
	    if (! (sections & READ_BASES)) {
		fseek(fp, chunk->dlength, SEEK_CUR);
		xfree(chunk);
		continue;
	    }
	    break;

	case ZTR_TYPE_TEXT:
	    if (! (sections & READ_COMMENTS)) {
		fseek(fp, chunk->dlength, SEEK_CUR);
		xfree(chunk);
		continue;
	    }
	    break;

	case ZTR_TYPE_CLIP:
	case ZTR_TYPE_FLWO:
	case ZTR_TYPE_FLWC:
	    break;

	    /*
	default:
	    fprintf(stderr, "Unknown chunk type '%s': skipping\n",
		    ZTR_BE2STR(chunk->type,str));
	    fseek(fp, chunk->dlength, SEEK_CUR);
	    xfree(chunk);
	    continue;
	    */
	}

	chunk->ztr_owns = 1;
	chunk->data = (char *)xmalloc(chunk->dlength);
	if (chunk->dlength != fread(chunk->data, 1, chunk->dlength, fp)) {
	    delete_ztr(ztr);
	    return NULL;
	}
            
	ztr->nchunks++;
	ztr->chunk = (ztr_chunk_t *)xrealloc(ztr->chunk, ztr->nchunks *
					     sizeof(ztr_chunk_t));
	memcpy(&ztr->chunk[ztr->nchunks-1], chunk, sizeof(*chunk));
	xfree(chunk);
    }

    return ztr;
}
Example #4
0
/*
 * Write a sequence to a FILE *fp of format "format". If "format" is 0,
 * we choose our favourite - SCF.
 *
 * Returns:
 *   0 for success
 *  -1 for failure
 */
int mfwrite_reading(mFILE *fp, Read *read, int format) {
    int r = -1;
    int no_compress = 0;

#ifdef _WIN32
    /*
     * jkb 09/06/00 comment below
     *
     * On windows "prog > file.scf" will work wrongly (compared to
     * "prog file.scf") because windows is rather stupid. It treats ascii
     * and binary streams differently, it considers stdout to be ascii unless
     * told otherwise, and it can only be told otherwise by using non-ansi
     * windows-specific function calls.
     */
    if (format != TT_EXP && format != TT_PLN && fp->fp)
	_setmode(_fileno(fp->fp), _O_BINARY);
#endif

    switch (format) {
    default:
	/* Defaults to ZTR type */

#ifdef IOLIB_ZTR
    case TT_ZTR:
    case TT_ZTR2: {
        ztr_t *ztr;
	ztr = read2ztr(read);
	compress_ztr(ztr, 2);
	r = mfwrite_ztr(fp, ztr); 
	delete_ztr(ztr);
	no_compress = 1;
	break;
    }
    case TT_ZTR1: {
        ztr_t *ztr;
	ztr = read2ztr(read);
	compress_ztr(ztr, 1);
	r = mfwrite_ztr(fp, ztr); 
	delete_ztr(ztr);
	break;
    }
    case TT_ZTR3: {
        ztr_t *ztr;
	ztr = read2ztr(read);
	compress_ztr(ztr, 3);
	r = mfwrite_ztr(fp, ztr); 
	delete_ztr(ztr);
	no_compress = 1;
	break;
    }
#endif

#ifdef IOLIB_SCF
    case TT_SCF: {
        Scf *scf;
	scf = read2scf(read);
	r = mfwrite_scf(scf, fp);
	scf_deallocate(scf);
	break;
    }
#endif

#ifdef IOLIB_CTF
    case TT_CTF:
	r = mfwrite_ctf(fp, read); 
	break;
#endif

#ifdef IOLIB_ABI
    case TT_ABI:
	/*return mfwrite_abi(fp, read); */
	break;
#endif

#ifdef IOLIB_ALF
    case TT_ALF:
	/* return mfwrite_alf(fp, read); */
	break;
#endif

#ifdef IOLIB_EXP
    case TT_EXP: {
	Exp_info *e = read2exp(read, read->ident ? read->ident : "unknown");
	
	if (NULL == e) {
	    fprintf(stderr, "Failed to create experiment file.\n");
	    r = -1;
	} else {
	    exp_print_mfile(fp, e);
	    exp_destroy_info(e);
	    r = 0;
	}
	break;
    }
#endif

#ifdef IOLIB_PLN
    case TT_PLN:
	r = mfwrite_pln(fp, read);
	break;
#endif
    }

    mftruncate(fp, -1);
    if (r == 0 && !no_compress) {
	fcompress_file(fp);
    }
    mfflush(fp);

    return r;
}
Example #5
0
/*
 * Read a sequence from a FILE *fp of format "format". If "format" is 0
 * (ANY_FORMAT), we automatically determine the correct format.
 * We still pass a filename 'fn' although this isn't used other than for
 * filling in the read->trace_name field.
 *
 * NB this function should NOT be used when Biolims support is required
 * (as biolims readings are not stored in a file)
 *
 * Returns:
 *   Read *   for success
 *   NULLRead for failure
 */
Read *mfread_reading(mFILE *fp, char *fn, int format) {
    Read *read;
    mFILE *newfp;

    if (!fn)
	fn = "(unknown)";

    newfp = freopen_compressed(fp, NULL);
    if (newfp != fp) {
	fp = newfp;
    } else {
	newfp = NULL;
    }

#ifdef _WIN32
    /*
     * jkb 16/05/00 comment below
     *
     * On windows "prog < file.abi" will work wrongly (compared to
     * "prog file.abi") because windows is rather stupid. It treats ascii
     * and binary streams differently, it considers stdin to be ascii unless
     * told otherwise, and it can only be told otherwise by using non-ansi
     * windows-specific function calls.
     */
    if (format != TT_EXP && format != TT_PLN && fp->fp)
	_setmode(_fileno(fp->fp), _O_BINARY);
#endif

    if (format == TT_ANY) {
	format = fdetermine_trace_type(fp);
	mrewind(fp);
    }

    switch (format) {
    case TT_UNK:
    case TT_ERR:
	errout("File '%s' has unknown trace type\n", fn);
	read = NULLRead;
	break;

#ifdef IOLIB_SCF
    case TT_SCF: {
        Scf *scf;
	scf = mfread_scf(fp);

	if (scf) {
	    read = scf2read(scf);
	    scf_deallocate(scf);
	} else
	    read = NULLRead;

	break;
    }
#endif

#ifdef IOLIB_CTF
    case TT_CTF:
	read = mfread_ctf(fp);
	break;
#endif

#ifdef IOLIB_ZTR
    case TT_ZTR:
    case TT_ZTR1:
    case TT_ZTR2:
    case TT_ZTR3: {
        ztr_t *ztr;

	if ((ztr = mfread_ztr(fp))) {
	    uncompress_ztr(ztr);
	    read = ztr2read(ztr);
	    delete_ztr(ztr);
	} else {
	    read = NULLRead;
	}
	break;
    }
#endif

#ifdef IOLIB_ABI
    case TT_ABI:
	read = mfread_abi(fp);
	break;
#endif

#ifdef IOLIB_ALF
    case TT_ALF:
	read = mfread_alf(fp);
	break;
#endif

#ifdef IOLIB_EXP
    case TT_EXP: {
	/* FIXME: we shouldn't redirect like this */
	Exp_info *e = exp_mfread_info(fp);
	
	read = e ? exp2read(e,fn) : NULLRead;
	break;
    }
#endif

#ifdef IOLIB_PLN
    case TT_PLN:
	read = mfread_pln(fp);
	break;
#endif

    default:
	errout("Unknown format %d specified to read_reading()\n", format);
	read = NULLRead;
    }

    if (read != NULLRead && (read->trace_name = (char *)xmalloc(strlen(fn)+1)))
	strcpy(read->trace_name, fn);

    if (newfp) mfclose(newfp);

    return read;
}
Example #6
0
int check_trace_body(Settings *opts, Trace_reader *trc, srf_t *srf) {
  char         name[512];
  Spot_info    spot = { NULL, 0, 0, 0, 0, 0, 0 };
  ztr_t       *ztr = NULL;
  ztr_chunk_t *chunk;
  int          start_chunk = 0;
  int          i;

  if (-1 == construct_trace_name(srf->th.id_prefix,
				 (unsigned char *)srf->tb.read_id,
				 srf->tb.read_id_length,
				 name, sizeof(name))) {
    printf("Couldn't construct read name\n");
    return -1;
  }

  if (0 != decode_name(name, &spot)) {
    printf("Couldn't decode read name.\n");
    return -1;
  }

  if (opts->verbosity > 0) {
    printf("%s\n", name);
  }

  if (0 != read_trace_data(opts, trc, &spot)) {
    printf("Couldn't get trace data for %s\n", name);
    return -1;
  }

  mfseek(srf->mf, srf->mf_end, SEEK_SET);
  if (srf->tb.trace_size) {
    mfwrite(srf->tb.trace, 1, srf->tb.trace_size, srf->mf);
    free(srf->tb.trace);
    srf->tb.trace = NULL;
  }
  mftruncate(srf->mf, mftell(srf->mf));
  mfseek(srf->mf, srf->mf_pos, SEEK_SET);
  
  if (srf->ztr) {
    start_chunk = srf->ztr->nchunks;
    ztr = ztr_dup(srf->ztr);
  }

  if (NULL == partial_decode_ztr(srf, srf->mf, ztr)) {
    printf("Couldn't decode ZTR data for %s\n", name);
    return -1;
  }

  for (i = start_chunk; i < ztr->nchunks; i++) {
    chunk = &ztr->chunk[i];
    if (opts->verbosity > 1) {
      printf(" Chunk %d type %.4s\n", i,
	      (char *) &chunk->type);
    }
    switch (chunk->type) {
    case ZTR_TYPE_BASE:
      if (0 != uncompress_chunk(ztr, chunk)) {
	printf("Couldn't uncompress BASE chunk\n");
	return -1;
      }
      if (trc->seq_len + 1 != chunk->dlength
	  || 0 != memcmp(trc->seq, chunk->data + 1, trc->seq_len)) {
	printf("Sequence differs for %s\n", name);
	return -1;
      }
      break;
    case ZTR_TYPE_CNF1:
      if (0 != uncompress_chunk(ztr, chunk)) {
	printf("Couldn't uncompress CNF1 chunk\n");
	return -1;
      }
      if (trc->seq_len + 1 != chunk->dlength
	  || 0 != memcmp(trc->qual, chunk->data + 1, trc->seq_len)) {
	printf("CNF1 confidence values differ for %s\n", name);
	return -1;
      }
      break;
    case ZTR_TYPE_CNF4:
      if (0 != uncompress_chunk(ztr, chunk)) {
	printf("Couldn't uncompress CNF4 chunk\n");
	return -1;
      }
      if (0 != check_cnf4(ztr, chunk, trc)) {
	printf("CNF4 confidence values differ for %s\n", name);
	return -1;
      }
      break;
    case ZTR_TYPE_SMP4:
      if (0 != uncompress_chunk(ztr, chunk)) {
	printf("Couldn't uncompress SMP4 chunk\n");
	return -1;
      }
      if (0 != check_trace(ztr, chunk, trc)) {
	printf("Trace doesn't match for %s\n", name);
	return -1;
      }
      break;
    default:
      printf("Found unexpected chunk type in trace body for %s\n",
	      name);
      return -1;
    }
  }

  delete_ztr(ztr);

  return 0;
}
Example #7
0
int check_trace_header(Settings *opts, srf_t *srf, Previous_data *seen) {
  int i;
  int j;
  int n;
  uint8_t  *data;
  uint32_t  val;
  ztr_chunk_t *chunk;

  if (NULL != srf->mf) {
    mfrecreate(srf->mf, NULL, 0);
  } else {
    srf->mf = mfcreate(NULL, 0);
  }
  if (NULL == srf->mf) die("%s\n", strerror(errno));

  if (srf->th.trace_hdr_size) {
    if (1 != mfwrite(srf->th.trace_hdr, srf->th.trace_hdr_size, 1, srf->mf)) {
      die("mfwrite failed: %s\n", strerror(errno));
    }
  }

  if (srf->ztr) delete_ztr(srf->ztr);

  mrewind(srf->mf);

  if (NULL != (srf->ztr = partial_decode_ztr(srf, srf->mf, NULL))) {
    srf->mf_pos = mftell(srf->mf);
  } else {
    /* We expect this to work for srfs made by illumina2srf */
    printf("partial_decode_ztr failed for trace header\n");
    srf->mf_pos = 0;
    return -1;
  }

  mfseek(srf->mf, 0, SEEK_END);
  srf->mf_end = mftell(srf->mf);

  /* Go through chunks */
  for (i = 0; i < srf->ztr->nchunks; i++) {
    chunk = &srf->ztr->chunk[i];
    if (opts->verbosity > 1) {
      printf(" Chunk %d type %.4s\n", i,
	      (char *) &chunk->type);
    }
    switch (chunk->type) {
    case ZTR_TYPE_HUFF:
      break;
    case ZTR_TYPE_BPOS:
      if (0 != uncompress_chunk(srf->ztr, chunk)) {
	printf("Couldn't uncompress BPOS chunk\n");
	return -1;
      }
      n = (chunk->dlength - 4) / 4;
      for (j = 0; j < n; j++) {
	data = (uint8_t *) &chunk->data[j * 4 + 4];
	val = (  ((uint32_t) data[0]) << 24
	       | ((uint32_t) data[1]) << 16
	       | ((uint32_t) data[2]) <<  8
	       | ((uint32_t) data[3]));
	if (val != j) {
	  printf("BPOS data misses cycles\n");
	  return -1;
	}
      }
      break;
    case ZTR_TYPE_REGN:
      if (0 != uncompress_chunk(srf->ztr, chunk)) {
	printf("Couldn't uncompress REGN chunk\n");
	return -1;
      }
      if (NULL == seen->regn) {
	/* Copy REGN chunk */
	seen->regn_meta_sz = chunk->mdlength;
	seen->regn_meta = smalloc(seen->regn_meta_sz);
	memcpy(seen->regn_meta, chunk->mdata, seen->regn_meta_sz);
	seen->regn_sz = chunk->dlength;
	seen->regn = smalloc(seen->regn_sz);
	memcpy(seen->regn, chunk->data, seen->regn_sz);
      } else {
	/* Compare with last copy */
	if (seen->regn_meta_sz != chunk->mdlength
	    || seen->regn_sz != chunk->dlength
	    || 0 != memcmp(seen->regn_meta, chunk->mdata, seen->regn_meta_sz)
	    || 0 != memcmp(seen->regn, chunk->data, seen->regn_sz)) {
	  printf("REGN chunk changed between header blocks\n");
	  return -1;
	}
      }
      break;
    case ZTR_TYPE_TEXT:
      if (0 != uncompress_chunk(srf->ztr, chunk)) {
	printf("Couldn't uncompress REGN chunk\n");
	return -1;
      }
      if (NULL == seen->text) {
	seen->text_sz = chunk->dlength;
	seen->text = smalloc(seen->text_sz);
	memcpy(seen->text, chunk->data, seen->text_sz);
	
	if (0 != check_text(opts, seen)) return -1;
      } else {
	if (seen->text_sz != chunk->dlength
	    || 0 != memcmp(seen->text, chunk->data, seen->text_sz)) {
	  printf("New TEXT chunk found\n");
	  seen->text_sz = chunk->dlength;
	  seen->text = srealloc(seen->text, seen->text_sz);
	  memcpy(seen->text, chunk->data, seen->text_sz);
	  
	  if (0 != check_text(opts, seen)) return -1;
	}
      }
      break;
    default:
      printf("Found unexpected chunk type in header block\n");
      return -1;
    }
  }

  return 0;
}
Example #8
0
/*
 * Given the archive name and the level_mode
 * generate information about the archive
 *
 * Note the generated srf file is NOT indexed
 *
 * Returns 0 on success.
 */
int srf_info(char *input, int level_mode, long *read_count, long *chunk_count,
	     uint64_t *chunk_size, long key_count[NCHUNKS][NKEYS],
	     long type_count[NCHUNKS][NTYPES], HashTable *regn_hash,
	     uint64_t *base_count) {
    srf_t *srf;
    off_t pos;
    int type;
    int count = 0;
    long trace_body_count = 0;
    char name[1024];

    if (NULL == (srf = srf_open(input, "rb"))) {
	perror(input);
	return 1;
    }

    while ((type = srf_next_block_type(srf)) >= 0) {

      switch (type) {
	case SRFB_CONTAINER:
	    if( trace_body_count ){
		if( level_mode & LEVEL_NAME )
		    printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count);
		trace_body_count = 0;
	    }
	    if (0 != srf_read_cont_hdr(srf, &srf->ch)) {
		fprintf(stderr, "Error reading container header.\nExiting.\n");
		exit(1);
	    }
	    break;

        case SRFB_XML:
	    if( trace_body_count ){
		if( level_mode & LEVEL_NAME )
		    printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count);
		trace_body_count = 0;
	    }
	    if (0 != srf_read_xml(srf, &srf->xml)) {
		fprintf(stderr, "Error reading XML.\nExiting.\n");
		exit(1);
	    }
	    break;

	case SRFB_TRACE_HEADER:
	    if( trace_body_count ){
		if( level_mode & LEVEL_NAME )
		    printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count);
		trace_body_count = 0;
	    }
	    if (0 != srf_read_trace_hdr(srf, &srf->th)) {
		fprintf(stderr, "Error reading trace header.\nExiting.\n");
		exit(1);
	    }

	    if( 0 == (level_mode & (LEVEL_CHUNK | LEVEL_BASE)) )
		break;

	    /* Decode ZTR chunks in the header */
	    if (srf->mf)
		mfdestroy(srf->mf);

	    srf->mf = mfcreate(NULL, 0);
	    if (srf->th.trace_hdr_size)
		mfwrite(srf->th.trace_hdr, 1, srf->th.trace_hdr_size, srf->mf);
	    if (srf->ztr)
		delete_ztr(srf->ztr);
	    mrewind(srf->mf);

	    if (NULL != (srf->ztr = partial_decode_ztr(srf, srf->mf, NULL))) {
		srf->mf_pos = mftell(srf->mf);
	    } else {
		/* Maybe not enough to decode or no headerBlob. */
		/* So delay until decoding the body. */
		srf->mf_pos = 0;
	    }
	    mfseek(srf->mf, 0, SEEK_END);
	    srf->mf_end = mftell(srf->mf);

	    break;

	case SRFB_TRACE_BODY: {
	    srf_trace_body_t old_tb;
	    ztr_t *ztr_tmp;
            int no_trace = (level_mode & (LEVEL_CHUNK | LEVEL_BASE) ? 0 : 1);

	    if (0 != srf_read_trace_body(srf, &old_tb, no_trace)) {
		fprintf(stderr, "Error reading trace body.\nExiting.\n");
		exit(1);
	    }

	    if (-1 == construct_trace_name(srf->th.id_prefix,
					   (unsigned char *)old_tb.read_id,
					   old_tb.read_id_length,
					   name, 512)) {
		fprintf(stderr, "Error constructing trace name.\nExiting.\n");
		exit(1);
	    }

	    trace_body_count++;
	    if( 1 == trace_body_count ){
		if( level_mode & LEVEL_NAME )
		    printf( "trace_name: %s + %s", srf->th.id_prefix, name+strlen(srf->th.id_prefix));
	    }
          
	    read_count[READ_TOTAL]++;

	    if (old_tb.flags & SRF_READ_FLAG_BAD_MASK ){
		read_count[READ_BAD]++;
	    } else {
		read_count[READ_GOOD]++;
	    }
          
	    if( 0 == (level_mode & (LEVEL_CHUNK | LEVEL_BASE)) )
		break;

	    if (!srf->mf) {
		fprintf(stderr, "Error reading trace body.\nExiting.\n");
		exit(1);
	    }

	    mfseek(srf->mf, srf->mf_end, SEEK_SET);
	    if (old_tb.trace_size) {
		mfwrite(old_tb.trace, 1, old_tb.trace_size, srf->mf);
		free(old_tb.trace);
		old_tb.trace = NULL;
	    }
          
	    mftruncate(srf->mf, mftell(srf->mf));
	    mfseek(srf->mf, srf->mf_pos, SEEK_SET);

	    if (srf->ztr)
		ztr_tmp = ztr_dup(srf->ztr); /* inefficient, but simple */
	    else
		ztr_tmp = NULL;

	    if ((ztr_tmp = partial_decode_ztr(srf, srf->mf, ztr_tmp))) {
		int i;
		for (i=0; i<ztr_tmp->nchunks; i++) {
		    int ichunk = -1;

		    switch (ztr_tmp->chunk[i].type) {
		    case ZTR_TYPE_BASE:
			ichunk = CHUNK_BASE;
			chunk_size[ichunk] += ztr_tmp->chunk[i].dlength;
			if( parse_base(ztr_tmp, &ztr_tmp->chunk[i], base_count) ){
			    delete_ztr(ztr_tmp);
			    return 1;
			}
			break;
		    case ZTR_TYPE_CNF1:
			ichunk = CHUNK_CNF1;
			chunk_size[ichunk] += ztr_tmp->chunk[i].dlength;
			break;
		    case ZTR_TYPE_CNF4:
			ichunk = CHUNK_CNF4;
			chunk_size[ichunk] += ztr_tmp->chunk[i].dlength;
			break;
		    case ZTR_TYPE_SAMP:
			ichunk = CHUNK_SAMP;
			chunk_size[ichunk] += ztr_tmp->chunk[i].dlength;
			break;
		    case ZTR_TYPE_SMP4:
			ichunk = CHUNK_SMP4;
			chunk_size[ichunk] += ztr_tmp->chunk[i].dlength;
			break;
		    case ZTR_TYPE_REGN:
			ichunk = CHUNK_REGN;
			chunk_size[ichunk] += ztr_tmp->chunk[i].dlength;
			if( NULL == parse_regn(ztr_tmp, &ztr_tmp->chunk[i], regn_hash) ){
			    delete_ztr(ztr_tmp);
			    return 1;
			}
			break;
		    default:
			break;
		    }

		    if( ichunk > -1 ) {
			chunk_count[ichunk]++;
			count_mdata_keys(ztr_tmp, &ztr_tmp->chunk[i], ichunk, key_count, type_count);
		    }
		}

	    }

	    if( ztr_tmp )
		delete_ztr(ztr_tmp);

	    count++;
	    if( (level_mode == LEVEL_CHECK) && (count == 10) ){
		printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count);
		srf_destroy(srf, 1);
		return 0;
	    }
          
	    break;
        }

	case SRFB_INDEX: {
            off_t pos = ftell(srf->fp);
	    if( trace_body_count ){
		if( level_mode & LEVEL_NAME )
		    printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count);
		trace_body_count = 0;
	    }
            printf( "Reading srf index block\n");
	    if (0 != srf_read_index_hdr(srf, &srf->hdr, 1)) {
		srf_destroy(srf, 1);
		fprintf(stderr, "Error reading srf index block header.\nExiting.\n");
		exit(1);
	    }
            /* Skip the index body */
	    fseeko(srf->fp, pos + srf->hdr.size, SEEK_SET);

            break;
        }
        
	case SRFB_NULL_INDEX: {
            uint64_t ilen;
	    if( trace_body_count ){
		if( level_mode & LEVEL_NAME )
		    printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count);
		trace_body_count = 0;
	    }
            printf( "Reading srf null index block\n");
	    /*
	     * Maybe the last 8 bytes of a the file (or previously was
	     * last 8 bytes prior to concatenating SRF files together).
	     * If so it's the index length and should always be 8 zeros.
	     */
            if (1 != fread(&ilen, 8, 1, srf->fp)) {
		srf_destroy(srf, 1);
		fprintf(stderr, "Error reading srf null index block.\nExiting.\n");
		exit(1);
            }
            if (ilen != 0) {
		srf_destroy(srf, 1);
		fprintf(stderr, "Invalid srf null index block.\nExiting.\n");
		exit(1);
            }

            break;
        }
        
        default:
            srf_destroy(srf, 1);
	    fprintf(stderr, "Block of unknown type '%c'\nExiting.\n", type);
	    exit(1);
	}

    }

    if( trace_body_count ){
        if( level_mode & LEVEL_NAME )
            printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count);
        trace_body_count = 0;
    }

    /* the type should be -1 (EOF) */
    if( type != -1 ) {
        fprintf(stderr, "Block of unknown type '%c'\nExiting.\n", type);
	exit(1);
    }

    /* are we really at the end of the srf file */
    pos = ftell(srf->fp);
    fseek(srf->fp, 0, SEEK_END);
    if( pos != ftell(srf->fp) ){
        fprintf(stderr, "srf file is corrupt\n");
	exit(1);
    }
    
    srf_destroy(srf, 1);
    return 0;
}
Example #9
0
/*
 * As per partial_decode_ztr in srf.c, but without uncompress_ztr.
 */
ztr_t *partial_decode_ztr2(srf_t *srf, mFILE *mf, ztr_t *z) {
    ztr_t *ztr;
    ztr_chunk_t *chunk;
    long pos = 0;

    if (z) {
	/* Use existing ZTR object => already loaded header */
	ztr = z;

    } else {
	/* Allocate or use existing ztr */
	if (NULL == (ztr = new_ztr()))
	    return NULL;

	/* Read the header */
	if (-1 == ztr_read_header(mf, &ztr->header)) {
	    if (!z)
		delete_ztr(ztr);
	    mrewind(mf);
	    return NULL;
	}

	/* Check magic number and version */
	if (memcmp(ztr->header.magic, ZTR_MAGIC, 8) != 0) {
	    if (!z)
		delete_ztr(ztr);
	    mrewind(mf);
	    return NULL;
	}

	if (ztr->header.version_major != ZTR_VERSION_MAJOR) {
	    if (!z)
		delete_ztr(ztr);
	    mrewind(mf);
	    return NULL;
	}
    }

    /* Load chunks */
    pos = mftell(mf);
    while ((chunk = ztr_read_chunk_hdr(mf))) {
	chunk->data = (char *)xmalloc(chunk->dlength);
	if (chunk->dlength != mfread(chunk->data, 1, chunk->dlength, mf))
	    break;

	ztr->nchunks++;
	ztr->chunk = (ztr_chunk_t *)xrealloc(ztr->chunk, ztr->nchunks *
					     sizeof(ztr_chunk_t));
	memcpy(&ztr->chunk[ztr->nchunks-1], chunk, sizeof(*chunk));
	xfree(chunk);
	pos = mftell(mf);
    }

    /*
     * At this stage we're 'pos' into the mFILE mf with any remainder being
     * a partial block.
     */
    if (0 == ztr->nchunks) {
	if (!z)
	    delete_ztr(ztr);
	mrewind(mf);
	return NULL;
    }

    /* Ensure we exit at the start of a ztr CHUNK */
    mfseek(mf, pos, SEEK_SET);

    /* If this is the header part, ensure we uncompress and init. data */
    if (!z) {
	/* Force caching of huffman code_sets */
	ztr_find_hcode(ztr, CODE_USER);

	/* And uncompress the rest */
	uncompress_ztr(ztr);
    }

    return ztr;
}
Example #10
0
/*
 * Main method.
 */
int main(int argc, char **argv) {
    int i;
    long num_reads = 0;
    int num_reads_mode = 0;
    int num_reads_only_mode = 0;
    int filter_mode = 0;
    char *ar_name = NULL;
    srf_t *srf = NULL;
    char name[512];
    ztr_t *ztr = NULL;
    read_filter_t *read_filter = NULL;
    char *filter_value = NULL;

    int c;
    int errflg = 0;
    extern char *optarg;
    extern int optind, optopt;

    char chunk_mode = ALL;
    char type_mode = TEXT;
    char destination_mode = CONSOLE_DEST;
    FILE **files = NULL;
    int verbose = 0;

    if (argc < 2) {
	fprintf(stderr, "Please specify an archive name.\n");
	usage(1);
    }

    while ((c = getopt(argc, argv, ":c:d:f:not:v")) != -1) {
        switch (c) {
        case 'c':
	    chunk_mode = 0;
	    if(get_chunk_types(optarg, &chunk_mode) || !chunk_mode) {
                fprintf(stderr,
			"Invalid value \"%s\" given to option -%c.\n", optarg, c);
		errflg++;
	    }
	    break;
        case 'd':
	    destination_mode = 0;
	    if(get_destination_types(optarg, &destination_mode) || !destination_mode) {
                fprintf(stderr,
			"Invalid value \"%s\" given to option -%c.\n", optarg, c);
		errflg++;
	    }
	    break;
        case 'f':
	    if (num_reads_only_mode) {
		fprintf(stderr,
			"Option -%c is exclusing with option -o.\n", c);
                errflg++;
	    } else {
		filter_mode++;
		filter_value = optarg;
	    }
            break;
        case 'n':
	    if (num_reads_only_mode) {
		fprintf(stderr,
			"Option -%c is exclusing with option -o.\n", c);
                errflg++;
	    }
            else
                num_reads_mode++;
            break;
        case 'o':
	    if (num_reads_mode) {
		fprintf(stderr,
			"Option -%c is exclusing with option -n.\n", c);
                errflg++;
	    } else if (filter_mode) {
		fprintf(stderr,
			"Option -%c is exclusing with option -f.\n", c);
                errflg++;
	    } else
                num_reads_only_mode++;
            break;
        case 't':
	    type_mode=0;
	    if(get_type_of_output(optarg, &type_mode) || !type_mode) {
                fprintf(stderr,
			"Invalid value \"%s\" given to option -%c.\n", optarg, c);
		errflg++;
	    }
	    break;
        case 'v':
	    verbose++;
            break;
        case ':':       /* -? without operand */
            fprintf(stderr,
                    "Option -%c requires an operand\n", optopt);
            errflg++;
            break;
        case '?':
            fprintf(stderr,
                    "Unrecognised option: -%c\n", optopt);
            errflg++;
        }
    }

    if (errflg) {
	usage(1);
    }

    if(optind + 1 != argc) {
        fprintf(stderr, "The archive name must be the last argument.\n");
        usage(1);
    } else {
        ar_name = argv[optind];
    }
    
    if(filter_mode) {
	read_filter = get_read_filter(filter_value);
	if(verbose) {
	    dump_read_filter(read_filter);
	}
    }

    if(chunk_mode && verbose) {
	dump_chunk_mode(chunk_mode);
    }

    if(type_mode && verbose) {
	dump_type_mode(type_mode);
    }

    if(destination_mode && verbose) {
	dump_destination_mode(destination_mode);
    }

    if (!access(ar_name, R_OK)) {
	if(verbose) {
	    printf("Dumping from archive %s.\n", ar_name);
	}
    } else {
        fprintf(stderr, "Archive %s not found.\n", ar_name);
    }

    if(destination_mode & NONE_DEST) {
	if (NULL == (srf = srf_open(ar_name, "rb"))) {
	    perror(ar_name);
	    return 1;
	}

	while (NULL != (ztr = srf_next_ztr(srf, name, 0))) {
	    if(!num_reads_only_mode) {
		if(!filter_mode || (filter_mode && check_read_name(read_filter, name))) {
		    ++num_reads;
		}
	    } else {
		++num_reads;
	    }
	    delete_ztr(ztr);
	}
    }

    if(destination_mode & CONSOLE_DEST) {
	/* Cosole means stdout. */
	files = malloc((sizeof(FILE *))*5);
	for(i = 0; i < 5; i++) {
	    files[i] = stdout;
	}

	if (NULL == (srf = srf_open(ar_name, "rb"))) {
	    perror(ar_name);
	    return 1;
	}

	while (NULL != (ztr = srf_next_ztr(srf, name, 0))) {
	    if(!num_reads_only_mode) {
		if(!filter_mode || (filter_mode && check_read_name(read_filter, name))) {
		    if(type_mode & SOLEXA) {
			dump_solexa(ztr, name, chunk_mode, files);
		    } else if(type_mode & TEXT) {
			dump_text(ztr, name, chunk_mode, files);
		    } else {
			fprintf(stderr, "Assertion error on type_mode (%c).\nExiting.\n", type_mode);
			exit(1);
		    }
		    ++num_reads;
		}
	    } else {
		++num_reads;
	    }
	    delete_ztr(ztr);
	}
    }

    if(destination_mode & FILE_DEST) {
	if(type_mode & SOLEXA) {
	    process_srf_to_solexa_files(ar_name, chunk_mode, num_reads_only_mode, filter_mode, read_filter, &num_reads);
	} else if(type_mode & TEXT) {
	    process_srf_to_text_files(ar_name, chunk_mode, num_reads_only_mode, filter_mode, read_filter, &num_reads);
	} else {
	    fprintf(stderr, "Assertion error on type_mode (%c).\nExiting.\n", type_mode);
	    exit(1);
	}
    }

    if(num_reads_mode || num_reads_only_mode) {
	printf("\nReads: %ld\n", num_reads);
    }

    srf_destroy(srf, 1);

    return 0;
}