char * uproc_io_gets(char *s, int size, uproc_io_stream *stream) { char *res; switch (stream->type) { case UPROC_IO_GZIP: #if HAVE_ZLIB_H res = gzgets(stream->s.gz, s, size); if (!res) { int num; const char *msg = gzerror(stream->s.gz, &num); if (num != Z_OK && num != Z_STREAM_END) { uproc_error_msg(UPROC_EIO, "failed to read from gz stream: %d %s", num, msg); } } break; #endif case UPROC_IO_STDIO: res = fgets(s, size, stream->s.fp); if (!res && ferror(stream->s.fp)) { uproc_error_msg(UPROC_EIO, "failed to read from stream"); } break; default: uproc_error_msg(UPROC_EINVAL, "invalid stream"); return NULL; } return res; }
int uproc_io_seek(uproc_io_stream *stream, long offset, enum uproc_io_seek_whence whence) { int w; switch (whence) { case UPROC_IO_SEEK_SET: w = SEEK_SET; break; case UPROC_IO_SEEK_CUR: w = SEEK_CUR; break; } switch (stream->type) { case UPROC_IO_GZIP: #if HAVE_ZLIB_H return gzseek(stream->s.gz, offset, w) >= 0 ? 0 : -1; #endif case UPROC_IO_STDIO: return fseek(stream->s.fp, offset, w); } uproc_error_msg(UPROC_EINVAL, "invalid stream"); return -1; }
uproc_io_stream * uproc_io_stdstream_gz(FILE *stream) { if (stream == stdin) { return uproc_io_stdstream(stdin); } uproc_error_msg(UPROC_ENOTSUP, "gzip compression not available"); return NULL; }
int uproc_list_add(uproc_list *list, const uproc_list *src) { if (list->value_size != src->value_size) { return uproc_error_msg(UPROC_EINVAL, "can't add lists with different value sizes"); } return uproc_list_extend(list, src->data, src->size); }
int uproc_list_extend(uproc_list *list, const void *values, long n) { int res; if (n < 0) { return uproc_error_msg(UPROC_EINVAL, "negative number of items"); } if (n > (LONG_MAX - list->size)) { return uproc_error_msg(UPROC_EINVAL, "list too big"); } res = list_grow(list, n); if (res) { return res; } memcpy(list->data + list->size * list->value_size, values, n * list->value_size); list->size += n; return 0; }
int uproc_list_check_value_size(const uproc_list *list, size_t value_size) { if (value_size && value_size != list->value_size) { return uproc_error_msg(UPROC_EINVAL, "list value size %lu (possibly) doesn't match " "size of passed object %lu", (unsigned long)list->value_size, (unsigned long)value_size); } return 0; }
int uproc_list_pop(uproc_list *list, void *value) { if (list->size < 1) { return uproc_error_msg(UPROC_EINVAL, "pop from empty list"); } uproc_list_get(list, list->size - 1, value); list->size--; if (list->size > list->capacity / 4) { return 0; } return list_realloc(list, list->capacity / 2); }
int uproc_io_close(uproc_io_stream *stream) { int res = 1; if (!stream) { return 0; } switch (stream->type) { case UPROC_IO_GZIP: #if HAVE_ZLIB_H if (stream->s.gz) { res = gzclose(stream->s.gz); stream->s.gz = NULL; if (res == Z_OK) { res = 0; } else { res = uproc_error_msg(UPROC_ERRNO, "error closing gz stream"); } } break; #endif case UPROC_IO_STDIO: if (stream->s.fp) { res = fclose(stream->s.fp); if (res) { res = -1; } stream->s.fp = NULL; } break; default: return uproc_error_msg(UPROC_EINVAL, "invalid stream"); } if (!stream->stdstream) { free(stream); } return res; }
int uproc_list_set(uproc_list *list, long index, const void *value) { long idx = index; if (idx < 0) { idx += list->size; } if (idx < 0 || idx >= list->size) { return uproc_error_msg(UPROC_EINVAL, "list index %ld out of range", index); } memcpy(list->data + idx * list->value_size, value, list->value_size); return 0; }
int uproc_io_eof(uproc_io_stream *stream) { switch (stream->type) { case UPROC_IO_GZIP: #if HAVE_ZLIB_H return gzeof(stream->s.gz); #endif case UPROC_IO_STDIO: return feof(stream->s.fp); } uproc_error_msg(UPROC_EINVAL, "invalid stream"); return 0; }
int database_load(struct database *db, const char *path, int prot_thresh_level, enum uproc_ecurve_format format) { db->fwd = db->rev = NULL; db->idmap = NULL; db->prot_thresh = NULL; switch (prot_thresh_level) { case 2: case 3: db->prot_thresh = uproc_matrix_load( UPROC_IO_GZIP, "%s/prot_thresh_e%d", path, prot_thresh_level); if (!db->prot_thresh) { goto error; } break; case 0: break; default: uproc_error_msg( UPROC_EINVAL, "protein threshold level must be 0, 2, or 3"); goto error; } db->idmap = uproc_idmap_load(UPROC_IO_GZIP, "%s/idmap", path); if (!db->idmap) { goto error; } db->fwd = uproc_ecurve_load(format, UPROC_IO_GZIP, "%s/fwd.ecurve", path); if (!db->fwd) { goto error; } db->rev = uproc_ecurve_load(format, UPROC_IO_GZIP, "%s/rev.ecurve", path); if (!db->rev) { goto error; } return 0; error: database_free(db); return -1; }
int model_load(struct model *m, const char *path, int orf_thresh_level) { m->substmat = NULL; m->codon_scores = m->orf_thresh = NULL; m->substmat = uproc_substmat_load(UPROC_IO_GZIP, "%s/substmat", path); if (!m->substmat) { goto error; } m->codon_scores = uproc_matrix_load(UPROC_IO_GZIP, "%s/codon_scores", path); if (!m->codon_scores) { goto error; } switch (orf_thresh_level) { case 1: case 2: m->orf_thresh = uproc_matrix_load(UPROC_IO_GZIP, "%s/orf_thresh_e%d", path, orf_thresh_level); if (!m->orf_thresh) { goto error; } break; case 0: break; default: uproc_error_msg( UPROC_EINVAL, "ORF threshold level must be 0, 1, or 2"); goto error; } return 0; error: model_free(m); return -1; }
int uproc_io_printf(uproc_io_stream *stream, const char *fmt, ...) { int res = -1; va_list ap; va_start(ap, fmt); switch (stream->type) { case UPROC_IO_GZIP: #if HAVE_ZLIB_H res = gzvprintf(stream->s.gz, fmt, ap); break; #endif case UPROC_IO_STDIO: res = vfprintf(stream->s.fp, fmt, ap); break; default: res = uproc_error_msg(UPROC_EINVAL, "invalid stream"); } va_end(ap); return res; }
static uproc_io_stream * io_open(const char *path, const char *mode, enum uproc_io_type type) { uproc_io_stream *stream = malloc(sizeof *stream); if (!stream) { uproc_error(UPROC_ENOMEM); return NULL; } stream->type = type; stream->stdstream = false; switch (stream->type) { case UPROC_IO_GZIP: #if HAVE_ZLIB_H if (!(stream->s.gz = gzopen(path, mode))) { /* gzopen sets errno to 0 if memory allocation failed */ if (!errno) { uproc_error(UPROC_ENOMEM); goto error; } goto error_errno; } (void) gzbuffer(stream->s.gz, GZIP_BUFSZ); break; #endif case UPROC_IO_STDIO: if (!(stream->s.fp = fopen(path, mode))) { goto error_errno; } break; default: goto error; } return stream; error_errno: uproc_error_msg(UPROC_ERRNO, "can't open \"%s\" with mode \"%s\"", path, mode); error: free(stream); return NULL; }
uproc_list *uproc_list_create(size_t value_size) { struct uproc_list_s *list; if (!value_size) { uproc_error_msg(UPROC_EINVAL, "value size must be non-zero"); return NULL; } list = malloc(sizeof *list); if (!list) { uproc_error(UPROC_ENOMEM); return NULL; } list->size = list->capacity = 0; list->value_size = value_size; list->data = NULL; if (list_realloc(list, 0)) { free(list); return NULL; } return list; }
size_t uproc_io_read(void *ptr, size_t size, size_t nmemb, uproc_io_stream *stream) { switch (stream->type) { case UPROC_IO_GZIP: #if HAVE_ZLIB_H { size_t i, n; for (i = 0; i < nmemb; i++) { n = gzread(stream->s.gz, (char*)ptr + i * size, size); if (n != size) { break; } } return i; } #endif case UPROC_IO_STDIO: return fread(ptr, size, nmemb, stream->s.fp); } uproc_error_msg(UPROC_EINVAL, "invalid stream"); return 0; }
/* Doubles the capacity of a list. If (value_size * capacity) would exceed * MAX_SIZE, use (MAX_SIZE / value_size) instead of doubling. * Fails if the size is already (MAX_SIZE / value_size). */ static int list_grow(struct uproc_list_s *list, long n) { long cap_req, cap_new, cap_max; cap_req = list->size + n; if (cap_req < list->capacity) { return 0; } cap_max = MAX_SIZE / list->value_size; if (list->capacity == cap_max || cap_req > cap_max) { return uproc_error_msg(UPROC_EINVAL, "list too big"); } if (cap_max / 2 > list->capacity) { cap_new = list->capacity * 2; } else { cap_new = cap_max; } if (cap_new < cap_req) { cap_new = cap_req; } return list_realloc(list, cap_new); }