52 #include "io_lib_config.h"
61 #include <sys/types.h>
72 static void dump_index_(
cram_index *e,
int level) {
74 n = printf(
"%*s%d / %d .. %d, ", level*4,
"", e->
refid, e->
start, e->
end);
76 for (i = 0; i < e->
nslice; i++) {
77 dump_index_(&e->
e[i], level+1);
81 static void dump_index(
cram_fd *fd) {
84 dump_index_(&fd->
index[i], 0);
103 int idx_stack_alloc = 0, idx_stack_ptr = 0;
116 idx->
start = INT_MIN;
119 idx_stack = calloc(++idx_stack_alloc,
sizeof(*idx_stack));
120 idx_stack[idx_stack_ptr] = idx;
122 sprintf(fn2,
"%s.crai", fn);
123 if (!(fp =
hopen(fn2,
"r"))) {
130 while ((len =
hread(fp, buf, 65536)) > 0)
131 kputsn(buf, len, &kstr);
132 if (len < 0 || kstr.
l < 2) {
148 if (kstr.
s[0] == 31 && (uc)kstr.
s[1] == 139) {
164 char *line = &kstr.
s[pos];
167 if (sscanf(line,
"%d\t%d\t%d\t%"PRId64"\t%d\t%d%n",
186 fprintf(stderr,
"Malformed index file, refid %d\n", e.refid);
190 if (e.refid != idx->
refid) {
196 memset(((
char *)fd->
index) + index_end, 0,
199 idx = &fd->
index[e.refid+1];
200 idx->
refid = e.refid;
201 idx->
start = INT_MIN;
205 idx_stack[(idx_stack_ptr = 0)] = idx;
208 while (!(e.start >= idx->
start && e.end <= idx->
end)) {
209 idx = idx_stack[--idx_stack_ptr];
215 idx->
e = realloc(idx->
e, idx->
nalloc *
sizeof(*idx->
e));
218 e.nalloc = e.nslice = 0; e.e = NULL;
219 *(ep = &idx->
e[idx->
nslice++]) = e;
222 if (++idx_stack_ptr >= idx_stack_alloc) {
223 idx_stack_alloc *= 2;
224 idx_stack = realloc(idx_stack, idx_stack_alloc*
sizeof(*idx_stack));
226 idx_stack[idx_stack_ptr] = idx;
229 while (pos < kstr.
l && kstr.
s[pos] !=
'\n')
232 }
while (pos < kstr.
l);
242 static void cram_index_free_recurse(
cram_index *e) {
245 for (i = 0; i < e->
nslice; i++) {
246 cram_index_free_recurse(&e->
e[i]);
258 for (i = 0; i < fd->
index_sz; i++) {
259 cram_index_free_recurse(&fd->
index[i]);
285 if (refid+1 < 0 || refid+1 >= fd->
index_sz)
291 from = &fd->
index[refid+1];
293 for (k = j/2; k != i; k = (j-i)/2 + i) {
294 if (from->
e[k].
refid > refid) {
299 if (from->
e[k].
refid < refid) {
304 if (from->
e[k].
start >= pos) {
309 if (from->
e[k].
start < pos) {
316 while (i > 0 && from->
e[i-1].
end >= pos)
321 from->
e[i+1].
start == pos &&
322 from->
e[i+1].
refid == refid)
353 fprintf(stderr,
"Unknown reference ID. Missing from index?\n");
374 static int cram_index_build_multiref(
cram_fd *fd,
381 int i, ref = -2, ref_start = 0, ref_end;
390 if (ref_end < s->crecs[i].aend)
396 sprintf(buf,
"%d\t%d\t%d\t%"PRId64"\t%d\t%d\n",
397 ref, ref_start, ref_end - ref_start + 1,
408 sprintf(buf,
"%d\t%d\t%d\t%"PRId64"\t%d\t%d\n",
409 ref, ref_start, ref_end - ref_start + 1,
429 off_t cpos, spos, hpos;
436 sprintf(fn_idx,
"%s.crai", fn_base);
437 if (!(fp =
zfopen(fn_idx,
"wz"))) {
442 cpos = htell(fd->
fp);
447 perror(
"Cram container read");
451 hpos = htell(fd->
fp);
467 spos = htell(fd->
fp);
475 sz = (int)(htell(fd->
fp) - spos);
478 cram_index_build_multiref(fd, c, s, fp,
481 sprintf(buf,
"%d\t%d\t%d\t%"PRId64"\t%d\t%d\n",
491 cpos = htell(fd->
fp);
492 assert(cpos == hpos + c->
length);