@@ -33,8 +33,73 @@ typedef struct GzipCompressorState
33
33
} GzipCompressorState ;
34
34
35
35
/* Private routines that support gzip compressed data I/O */
36
+ static void DeflateCompressorInit (CompressorState * cs );
37
+ static void DeflateCompressorEnd (ArchiveHandle * AH , CompressorState * cs );
38
+ static void DeflateCompressorCommon (ArchiveHandle * AH , CompressorState * cs ,
39
+ bool flush );
40
+ static void EndCompressorGzip (ArchiveHandle * AH , CompressorState * cs );
41
+ static void WriteDataToArchiveGzip (ArchiveHandle * AH , CompressorState * cs ,
42
+ const void * data , size_t dLen );
43
+ static void ReadDataFromArchiveGzip (ArchiveHandle * AH , CompressorState * cs );
44
+
45
+ static void
46
+ DeflateCompressorInit (CompressorState * cs )
47
+ {
48
+ GzipCompressorState * gzipcs ;
49
+ z_streamp zp ;
50
+
51
+ gzipcs = (GzipCompressorState * ) pg_malloc0 (sizeof (GzipCompressorState ));
52
+ zp = gzipcs -> zp = (z_streamp ) pg_malloc (sizeof (z_stream ));
53
+ zp -> zalloc = Z_NULL ;
54
+ zp -> zfree = Z_NULL ;
55
+ zp -> opaque = Z_NULL ;
56
+
57
+ /*
58
+ * outsize is the buffer size we tell zlib it can output to. We actually
59
+ * allocate one extra byte because some routines want to append a trailing
60
+ * zero byte to the zlib output.
61
+ */
62
+ gzipcs -> outsize = DEFAULT_IO_BUFFER_SIZE ;
63
+ gzipcs -> outbuf = pg_malloc (gzipcs -> outsize + 1 );
64
+
65
+ /* -Z 0 uses the "None" compressor -- not zlib with no compression */
66
+ Assert (cs -> compression_spec .level != 0 );
67
+
68
+ if (deflateInit (zp , cs -> compression_spec .level ) != Z_OK )
69
+ pg_fatal ("could not initialize compression library: %s" , zp -> msg );
70
+
71
+ /* Just be paranoid - maybe End is called after Start, with no Write */
72
+ zp -> next_out = gzipcs -> outbuf ;
73
+ zp -> avail_out = gzipcs -> outsize ;
74
+
75
+ /* Keep track of gzipcs */
76
+ cs -> private_data = gzipcs ;
77
+ }
78
+
79
+ static void
80
+ DeflateCompressorEnd (ArchiveHandle * AH , CompressorState * cs )
81
+ {
82
+ GzipCompressorState * gzipcs = (GzipCompressorState * ) cs -> private_data ;
83
+ z_streamp zp ;
84
+
85
+ zp = gzipcs -> zp ;
86
+ zp -> next_in = NULL ;
87
+ zp -> avail_in = 0 ;
88
+
89
+ /* Flush any remaining data from zlib buffer */
90
+ DeflateCompressorCommon (AH , cs , true);
91
+
92
+ if (deflateEnd (zp ) != Z_OK )
93
+ pg_fatal ("could not close compression stream: %s" , zp -> msg );
94
+
95
+ pg_free (gzipcs -> outbuf );
96
+ pg_free (gzipcs -> zp );
97
+ pg_free (gzipcs );
98
+ cs -> private_data = NULL ;
99
+ }
100
+
36
101
static void
37
- DeflateCompressorGzip (ArchiveHandle * AH , CompressorState * cs , bool flush )
102
+ DeflateCompressorCommon (ArchiveHandle * AH , CompressorState * cs , bool flush )
38
103
{
39
104
GzipCompressorState * gzipcs = (GzipCompressorState * ) cs -> private_data ;
40
105
z_streamp zp = gzipcs -> zp ;
@@ -78,69 +143,20 @@ DeflateCompressorGzip(ArchiveHandle *AH, CompressorState *cs, bool flush)
78
143
static void
79
144
EndCompressorGzip (ArchiveHandle * AH , CompressorState * cs )
80
145
{
81
- GzipCompressorState * gzipcs = (GzipCompressorState * ) cs -> private_data ;
82
- z_streamp zp ;
83
-
84
- if (gzipcs -> zp )
85
- {
86
- zp = gzipcs -> zp ;
87
- zp -> next_in = NULL ;
88
- zp -> avail_in = 0 ;
89
-
90
- /* Flush any remaining data from zlib buffer */
91
- DeflateCompressorGzip (AH , cs , true);
92
-
93
- if (deflateEnd (zp ) != Z_OK )
94
- pg_fatal ("could not close compression stream: %s" , zp -> msg );
95
-
96
- pg_free (gzipcs -> outbuf );
97
- pg_free (gzipcs -> zp );
98
- }
99
-
100
- pg_free (gzipcs );
101
- cs -> private_data = NULL ;
146
+ /* If deflation was initialized, finalize it */
147
+ if (cs -> private_data )
148
+ DeflateCompressorEnd (AH , cs );
102
149
}
103
150
104
151
static void
105
152
WriteDataToArchiveGzip (ArchiveHandle * AH , CompressorState * cs ,
106
153
const void * data , size_t dLen )
107
154
{
108
155
GzipCompressorState * gzipcs = (GzipCompressorState * ) cs -> private_data ;
109
- z_streamp zp ;
110
-
111
- if (!gzipcs -> zp )
112
- {
113
- zp = gzipcs -> zp = (z_streamp ) pg_malloc (sizeof (z_stream ));
114
- zp -> zalloc = Z_NULL ;
115
- zp -> zfree = Z_NULL ;
116
- zp -> opaque = Z_NULL ;
117
-
118
- /*
119
- * outsize is the buffer size we tell zlib it can output to. We
120
- * actually allocate one extra byte because some routines want to
121
- * append a trailing zero byte to the zlib output.
122
- */
123
- gzipcs -> outsize = DEFAULT_IO_BUFFER_SIZE ;
124
- gzipcs -> outbuf = pg_malloc (gzipcs -> outsize + 1 );
125
-
126
- /*
127
- * A level of zero simply copies the input one block at the time. This
128
- * is probably not what the user wanted when calling this interface.
129
- */
130
- if (cs -> compression_spec .level == 0 )
131
- pg_fatal ("requested to compress the archive yet no level was specified" );
132
-
133
- if (deflateInit (zp , cs -> compression_spec .level ) != Z_OK )
134
- pg_fatal ("could not initialize compression library: %s" , zp -> msg );
135
-
136
- /* Just be paranoid - maybe End is called after Start, with no Write */
137
- zp -> next_out = gzipcs -> outbuf ;
138
- zp -> avail_out = gzipcs -> outsize ;
139
- }
140
156
141
157
gzipcs -> zp -> next_in = (void * ) unconstify (void * , data );
142
158
gzipcs -> zp -> avail_in = dLen ;
143
- DeflateCompressorGzip (AH , cs , false);
159
+ DeflateCompressorCommon (AH , cs , false);
144
160
}
145
161
146
162
static void
@@ -214,17 +230,19 @@ void
214
230
InitCompressorGzip (CompressorState * cs ,
215
231
const pg_compress_specification compression_spec )
216
232
{
217
- GzipCompressorState * gzipcs ;
218
-
219
233
cs -> readData = ReadDataFromArchiveGzip ;
220
234
cs -> writeData = WriteDataToArchiveGzip ;
221
235
cs -> end = EndCompressorGzip ;
222
236
223
237
cs -> compression_spec = compression_spec ;
224
238
225
- gzipcs = (GzipCompressorState * ) pg_malloc0 (sizeof (GzipCompressorState ));
226
-
227
- cs -> private_data = gzipcs ;
239
+ /*
240
+ * If the caller has defined a write function, prepare the necessary
241
+ * state. Note that if the data is empty, End may be called immediately
242
+ * after Init, without ever calling Write.
243
+ */
244
+ if (cs -> writeF )
245
+ DeflateCompressorInit (cs );
228
246
}
229
247
230
248
0 commit comments