1 static char rcsid[] = "$Id: bzip2.c 219867 2019-08-09 20:06:43Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5
6 #include "bzip2.h"
7
8 #include <stddef.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include "mem.h"
12
13
14 #ifdef HAVE_BZLIB
15 #include <bzlib.h>
16 #endif
17
18 #define BUFFER_SIZE 131072
19
20 #define T Bzip2_T
21 struct T {
22 FILE *fp;
23 #ifdef HAVE_BZLIB
24 BZFILE *bzfile;
25 #endif
26
27 bool eofp;
28
29 char *buffer;
30 int navail;
31 int bufferi;
32 };
33
34
35 T
Bzip2_new(char * filename)36 Bzip2_new (char *filename) {
37 T new = (T) MALLOC(sizeof(*new));
38 int error;
39 FILE *fp;
40
41 #ifndef HAVE_BZLIB
42 fprintf(stderr,"Bzip2_new called when BZLIB is unavailable\n");
43 exit(9);
44
45 #else
46 fp = fopen(filename,"r");
47 if (fp == NULL) {
48 fprintf(stderr,"Unable to open bzip2 file %s\n",filename);
49 exit(9);
50 } else {
51 new->fp = fp;
52 }
53
54 new->bzfile = BZ2_bzReadOpen(&error,fp,/*small*/0,/*verbosity*/0,/*unused*/NULL,/*nunused*/0);
55 if (error != BZ_OK) {
56 fprintf(stderr,"BZ2_bzReadOpen gave error %d\n",error);
57 exit(9);
58 }
59 #endif
60
61 new->eofp = false;
62 new->buffer = (char *) CALLOC(BUFFER_SIZE,sizeof(char));
63 new->navail = 0;
64 new->bufferi = 0;
65
66 return new;
67 }
68
69 void
Bzip2_free(T * old)70 Bzip2_free (T *old) {
71 #ifdef HAVE_BZLIB
72 int error;
73
74 BZ2_bzReadClose(&error,(*old)->bzfile);
75 if (error != BZ_OK) {
76 fprintf(stderr,"BZ2_bzReadClose gave error %d\n",error);
77 exit(9);
78 }
79 fclose((*old)->fp);
80 #endif
81
82 FREE((*old)->buffer);
83 FREE(*old);
84 return;
85 }
86
87
88 int
bzgetc(T this)89 bzgetc (T this) {
90 #ifdef HAVE_BZLIB
91 int error;
92 #endif
93
94 if (this->navail > 0) {
95 this->navail -= 1;
96 return this->buffer[this->bufferi++];
97
98 } else if (this->eofp == true) {
99 return EOF;
100
101 } else {
102 #ifdef HAVE_BZLIB
103 this->navail = BZ2_bzRead(&error,this->bzfile,this->buffer,BUFFER_SIZE);
104 if (error == BZ_STREAM_END) {
105 this->eofp = true;
106 } else if (error != BZ_OK) {
107 fprintf(stderr,"BZ2_bzRead gave error %d\n",error);
108 exit(9);
109 }
110 #endif
111 this->bufferi = 1;
112 this->navail -= 1;
113 return this->buffer[0];
114 }
115 }
116
117
118 bool
bzeof(T this)119 bzeof (T this) {
120 if (this->navail > 0) {
121 return false;
122 } else {
123 return this->eofp;
124 }
125 }
126
127 char *
bzgets(T this,char * buffer,int maxlength)128 bzgets (T this, char *buffer, int maxlength) {
129 int n = 0;
130 int c = '\0';
131
132 if (this->navail == 0 && this->eofp == true) {
133 return (char *) NULL;
134 } else {
135 while (c != '\n' && n < maxlength - 1 && (c = bzgetc(this)) != EOF) {
136 buffer[n++] = c;
137 }
138 buffer[n] = '\0';
139 return buffer;
140 }
141 }
142
143
144 #if 0
145 int
146 main (int argc, char *argv[]) {
147 char *filename;
148 T bzip2;
149 char string[100];
150
151 filename = argv[1];
152 bzip2 = Bzip2_new(filename);
153 while (bzeof(bzip2) == false) {
154 bzgets(bzip2,string,100);
155 printf("%s",string);
156 }
157 Bzip2_free(&bzip2);
158 return 0;
159 }
160 #endif
161
162