]> git.donarmstrong.com Git - samtools.git/blob - glf.c
* Merge from branches/dev/
[samtools.git] / glf.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include "glf.h"
4
5 #ifdef _NO_BGZF
6 // then alias bgzf_*() functions
7 #endif
8
9 static inline int bam_is_big_endian()
10 {
11         long one= 1;
12         return !(*((char *)(&one)));
13 }
14
15 glf_header_t *glf_header_init()
16 {
17         return (glf_header_t*)calloc(1, sizeof(glf_header_t));
18 }
19
20 glf_header_t *glf_header_read(glfFile fp)
21 {
22         glf_header_t *h;
23         char magic[4];
24         if (bam_is_big_endian()) {
25                 fprintf(stderr, "[glf_header_read] Big endian is detected. Abort.\n");
26                 exit(1);
27         }
28         h = (glf_header_t*)calloc(1, sizeof(glf_header_t));
29         bgzf_read(fp, magic, 4);
30         if (strncmp(magic, "GLF\2", 4)) {
31                 fprintf(stderr, "[glf_header_read] invalid magic. Abort.\n");
32                 exit(1);
33         }
34         bgzf_read(fp, &h->l_text, 4);
35         if (h->l_text) {
36                 h->text = (uint8_t*)calloc(h->l_text + 1, 1);
37                 bgzf_read(fp, h->text, h->l_text);
38         }
39         return h;
40 }
41
42 void glf_header_write(glfFile fp, const glf_header_t *h)
43 {
44         bgzf_write(fp, "GLF\2", 4);
45         bgzf_write(fp, &h->l_text, 4);
46         if (h->l_text) bgzf_write(fp, h->text, h->l_text);
47 }
48
49 void glf_header_destroy(glf_header_t *h)
50 {
51         free(h->text);
52         free(h);
53 }
54
55 char *glf_ref_read(glfFile fp)
56 {
57         int32_t n;
58         char *str;
59         if (bgzf_read(fp, &n, 4) != 4) return 0;
60         if (n < 0) {
61                 fprintf(stderr, "[glf_ref_read] invalid reference name length: %d.\n", n);
62                 return 0;
63         }
64         str = (char*)calloc(n + 1, 1); // not necesarily n+1 in fact
65         bgzf_read(fp, str, n);
66         return str;
67 }
68
69 void glf_ref_write(glfFile fp, const char *str)
70 {
71         int32_t n = strlen(str);
72         ++n;
73         bgzf_write(fp, &n, 4);
74         bgzf_write(fp, str, n);
75 }
76
77 void glf_view_normal(const char *ref_name, glf2_t *g1)
78 {
79         int j;
80         printf("%s\t%d\t%c\t%d\t%d\t%d", ref_name, g1->pos + 1, "XACMGRSVTWYHKDBN"[g1->ref_base],
81                    g1->depth, g1->max_mapQ, g1->min_lk);
82         for (j = 0; j != 10; ++j) printf("\t%d", g1->lk[j]);
83         printf("\n");
84 }
85
86 static char *glf_read_indel(glfFile fp, char *str, int *max, int16_t indel)
87 {
88         int l = indel > 0? indel : -indel;
89         if (l + 1 > *max) {
90                 *max = l + 1;
91                 str = (char*)realloc(str, *max);
92         }
93         bgzf_read(fp, str, l);
94         str[l] = 0;
95         return str;
96 }
97
98 void glf_view(glfFile fp)
99 {
100         glf_header_t *h;
101         char *name, *str;
102         glf2_t g2;
103         int max;
104         
105         h = glf_header_read(fp);
106         str = 0; max = 0;
107         while ((name = glf_ref_read(fp)) != 0) {
108                 while (bgzf_read(fp, &g2, sizeof(glf2_t))) {
109                         if (g2.type == GLF_TYPE_END) break;
110                         else if (g2.type == GLF_TYPE_NORMAL) glf_view_normal(name, &g2);
111                         else if (g2.type == GLF_TYPE_INDEL) {
112                                 int16_t indel1, indel2;
113                                 printf("%s\t%d\t*\t%d\t%d\t%d\t", name, g2.pos + 1, g2.depth, g2.max_mapQ, g2.min_lk);
114                                 printf("%d\t%d\t%d\t", g2.lk[0], g2.lk[1], g2.lk[2]);
115                                 indel1 = *(int16_t*)(g2.lk + 3);
116                                 indel2 = *(int16_t*)(g2.lk + 5);
117                                 printf("%d\t%d\t", indel1, indel2);
118                                 if (indel1) {
119                                         str = glf_read_indel(fp, str, &max, indel1);
120                                         printf("%c%d%s\t", indel1>0? '+':'-', indel1>0?indel1:-indel1, str);
121                                 } else printf("*\t");
122                                 if (indel2) {
123                                         str = glf_read_indel(fp, str, &max, indel2);
124                                         printf("%c%d%s\n", indel2>0? '+':'-', indel2>0?indel2:-indel2, str);
125                                 } else printf("*\n");
126                         }
127                 }
128                 free(name);
129         }
130         glf_header_destroy(h);
131         free(str);
132 }
133
134 int glf_view_main(int argc, char *argv[])
135 {
136         glfFile fp;
137         if (argc == 1) {
138                 fprintf(stderr, "Usage: glfview <in.glf>\n");
139                 return 1;
140         }
141         fp = (strcmp(argv[1], "-") == 0)? bgzf_fdopen(fileno(stdin), "r") : bgzf_open(argv[1], "r");
142         if (fp == 0) {
143                 fprintf(stderr, "Fail to open file '%s'\n", argv[1]);
144                 return 1;
145         }
146         glf_view(fp);
147         bgzf_close(fp);
148         return 0;
149 }
150
151 #ifdef GLFVIEW_MAIN
152 int main(int argc, char *argv[])
153 {
154         return glf_view_main(argc, argv);
155 }
156 #endif