1 #include <string.h>
2 #include <assert.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <errno.h>
6 #include "mmpriv.h"
7 
mm_split_init(const char * prefix,const mm_idx_t * mi)8 FILE *mm_split_init(const char *prefix, const mm_idx_t *mi)
9 {
10 	char *fn;
11 	FILE *fp;
12 	uint32_t i, k = mi->k;
13 	fn = (char*)calloc(strlen(prefix) + 10, 1);
14 	sprintf(fn, "%s.%.4d.tmp", prefix, mi->index);
15 	if ((fp = fopen(fn, "wb")) == NULL) {
16 		if (mm_verbose >= 1)
17 			fprintf(stderr, "[ERROR]\033[1;31m failed to write to temporary file '%s'\033[0m: %s\n", fn, strerror(errno));
18 		exit(1);
19 	}
20 	mm_err_fwrite(&k, 4, 1, fp);
21 	mm_err_fwrite(&mi->n_seq, 4, 1, fp);
22 	for (i = 0; i < mi->n_seq; ++i) {
23 		uint32_t l;
24 		l = strlen(mi->seq[i].name);
25 		mm_err_fwrite(&l, 1, 4, fp);
26 		mm_err_fwrite(mi->seq[i].name, 1, l, fp);
27 		mm_err_fwrite(&mi->seq[i].len, 4, 1, fp);
28 	}
29 	free(fn);
30 	return fp;
31 }
32 
mm_split_merge_prep(const char * prefix,int n_splits,FILE ** fp,uint32_t * n_seq_part)33 mm_idx_t *mm_split_merge_prep(const char *prefix, int n_splits, FILE **fp, uint32_t *n_seq_part)
34 {
35 	mm_idx_t *mi = 0;
36 	char *fn;
37 	int i, j;
38 
39 	if (n_splits < 1) return 0;
40 	fn = CALLOC(char, strlen(prefix) + 10);
41 	for (i = 0; i < n_splits; ++i) {
42 		sprintf(fn, "%s.%.4d.tmp", prefix, i);
43 		if ((fp[i] = fopen(fn, "rb")) == 0) {
44 			if (mm_verbose >= 1)
45 				fprintf(stderr, "ERROR: failed to open temporary file '%s': %s\n", fn, strerror(errno));
46 			for (j = 0; j < i; ++j)
47 				fclose(fp[j]);
48 			free(fn);
49 			return 0;
50 		}
51 	}
52 	free(fn);
53 
54 	mi = CALLOC(mm_idx_t, 1);
55 	for (i = 0; i < n_splits; ++i) {
56 		mm_err_fread(&mi->k, 4, 1, fp[i]); // TODO: check if k is all the same
57 		mm_err_fread(&n_seq_part[i], 4, 1, fp[i]);
58 		mi->n_seq += n_seq_part[i];
59 	}
60 	mi->seq = CALLOC(mm_idx_seq_t, mi->n_seq);
61 	for (i = j = 0; i < n_splits; ++i) {
62 		uint32_t k;
63 		for (k = 0; k < n_seq_part[i]; ++k, ++j) {
64 			uint32_t l;
65 			mm_err_fread(&l, 1, 4, fp[i]);
66 			mi->seq[j].name = (char*)calloc(l + 1, 1);
67 			mm_err_fread(mi->seq[j].name, 1, l, fp[i]);
68 			mm_err_fread(&mi->seq[j].len, 4, 1, fp[i]);
69 		}
70 	}
71 	return mi;
72 }
73 
mm_split_rm_tmp(const char * prefix,int n_splits)74 void mm_split_rm_tmp(const char *prefix, int n_splits)
75 {
76 	int i;
77 	char *fn;
78 	fn = CALLOC(char, strlen(prefix) + 10);
79 	for (i = 0; i < n_splits; ++i) {
80 		sprintf(fn, "%s.%.4d.tmp", prefix, i);
81 		remove(fn);
82 	}
83 	free(fn);
84 }
85