]> git.donarmstrong.com Git - samtools.git/blob - razip.c
Create trunk copy
[samtools.git] / razip.c
1 #include <stdio.h>
2 #include <fcntl.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include "razf.h"
6
7 #define WINDOW_SIZE 4096
8
9 static int razf_main_usage()
10 {
11         printf("\n");
12         printf("Usage:   razip [options] [file] ...\n\n");
13         printf("Options: -c      write on standard output, keep original files unchanged\n");
14         printf("         -d      decompress\n");
15         printf("         -l      list compressed file contents\n");
16         printf("         -b INT  decompress at INT position in the uncompressed file\n");
17         printf("         -s INT  decompress INT bytes in the uncompressed file\n");
18         printf("         -h      give this help\n");
19         printf("\n");
20         return 0;
21 }
22
23 static int write_open(const char *fn, int is_forced)
24 {
25         int fd = -1;
26         char c;
27         if (!is_forced) {
28                 if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644)) < 0 && errno == EEXIST) {
29                         printf("razip: %s already exists; do you wish to overwrite (y or n)? ", fn);
30                         scanf("%c", &c);
31                         if (c != 'Y' && c != 'y') {
32                                 printf("razip: not overwritten\n");
33                                 exit(1);
34                         }
35                 }
36         }
37         if (fd < 0) {
38                 if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
39                         fprintf(stderr, "razip: %s: Fail to write\n", fn);
40                         exit(1);
41                 }
42         }
43         return fd;
44 }
45
46 int main(int argc, char **argv)
47 {
48         int c, compress, pstdout, is_forced;
49         RAZF *rz;
50         void *buffer;
51         long start, end, size;
52
53         compress = 1; pstdout = 0; start = 0; size = -1; end = -1; is_forced = 0;
54         while((c  = getopt(argc, argv, "cdlhfb:s:")) >= 0){
55                 switch(c){
56                 case 'h': return razf_main_usage();
57                 case 'd': compress = 0; break;
58                 case 'c': pstdout = 1; break;
59                 case 'l': compress = 2; break;
60                 case 'b': start = atol(optarg); break;
61                 case 's': size = atol(optarg); break;
62                 case 'f': is_forced = 1; break;
63                 }
64         }
65         if (size >= 0) end = start + size;
66         if(end >= 0 && end < start){
67                 fprintf(stderr, " -- Illegal region: [%ld, %ld] --\n", start, end);
68                 return 1;
69         }
70         if(compress == 1){
71                 int f_src, f_dst = -1;
72                 if(argc > optind){
73                         if((f_src = open(argv[optind], O_RDONLY)) < 0){
74                                 fprintf(stderr, " -- Cannot open file: %s --\n", argv[optind]);
75                                 return 1;
76                         }
77                         if(pstdout){
78                                 f_dst = fileno(stdout);
79                         } else {
80                                 char *name = malloc(sizeof(strlen(argv[optind]) + 5));
81                                 strcpy(name, argv[optind]);
82                                 strcat(name, ".rz");
83                                 f_dst = write_open(name, is_forced);
84                                 if (f_dst < 0) return 1;
85                                 free(name);
86                         }
87                 } else if(pstdout){ 
88                         f_src = fileno(stdin);
89                         f_dst = fileno(stdout);
90                 } else return razf_main_usage();
91                 rz = razf_dopen(f_dst, "w");
92                 buffer = malloc(WINDOW_SIZE);
93                 while((c = read(f_src, buffer, WINDOW_SIZE)) > 0) razf_write(rz, buffer, c);
94                 razf_close(rz); // f_dst will be closed here
95                 if (argc > optind) unlink(argv[optind]);
96                 free(buffer);
97                 close(f_src);
98                 return 0;
99         } else {
100                 if(argc <= optind) return razf_main_usage();
101                 if(compress == 2){
102                         rz = razf_open(argv[optind], "r");
103                         if(rz->file_type == FILE_TYPE_RZ) {
104                                                         printf("%20s%20s%7s %s\n", "compressed", "uncompressed", "ratio", "name");
105                                 printf("%20lld%20lld%6.1f%% %s\n", (long long)rz->end, (long long)rz->src_end, rz->end * 100.0f / rz->src_end,
106                                            argv[optind]);
107                         } else fprintf(stdout, "%s is not a regular rz file\n", argv[optind]);
108                 } else {
109                         int f_dst;
110                         if (argc > optind && !pstdout) {
111                                 char *name;
112                                 if (strstr(argv[optind], ".rz") - argv[optind] != strlen(argv[optind]) - 3) {
113                                         printf("razip: %s: unknown suffix -- ignored\n", argv[optind]);
114                                         return 1;
115                                 }
116                                 name = strdup(argv[optind]);
117                                 name[strlen(name) - 3] = '\0';
118                                 f_dst = write_open(name, is_forced);
119                                 free(name);
120                         } else f_dst = fileno(stdout);
121                         rz = razf_open(argv[optind], "r");
122                         buffer = malloc(WINDOW_SIZE);
123                         razf_seek(rz, start, SEEK_SET);
124                         while(1){
125                                 if(end < 0) c = razf_read(rz, buffer, WINDOW_SIZE);
126                                 else c = razf_read(rz, buffer, (end - start > WINDOW_SIZE)? WINDOW_SIZE:(end - start));
127                                 if(c <= 0) break;
128                                 start += c;
129                                 write(f_dst, buffer, c);
130                                 if(end >= 0 && start >= end) break;
131                         }
132                         free(buffer);
133                         if (!pstdout) unlink(argv[optind]);
134                 }
135                 razf_close(rz);
136                 return 0;
137         }
138 }
139