37
37
// waits until some has been written out. This can affect speed and memory usage.
38
38
#define SPFH_MAX_WRITE_BUFFER_SIZE 1048576
39
39
40
- union SPSomeFileHandle {
40
+ struct SPRawFileHandles {
41
41
FILE *file;
42
42
BZFILE *bzfile;
43
43
gzFile *gzfile;
46
46
@interface SPFileHandle ()
47
47
48
48
- (void )_writeBufferToData ;
49
+ - (void )_closeFileHandles ;
49
50
50
51
@end
51
52
@@ -132,11 +133,11 @@ - (id)initWithFile:(FILE *)theFile fromPath:(const char *)path mode:(int)mode
132
133
133
134
if (isBzip2) {
134
135
compressionFormat = SPBzip2Compression;
135
- wrappedFile->bzfile = BZ2_bzopen (path, " rb " );
136
+ wrappedFile->bzfile = BZ2_bzReadOpen ( NULL , theFile, 0 , 0 , NULL , 0 );
136
137
}
137
138
}
138
- // Default to plain
139
- if (compressionFormat == SPNoCompression) {
139
+ // We need to save the file handle both in plain and BZ2 format
140
+ if (compressionFormat == SPNoCompression || compressionFormat == SPBzip2Compression ) {
140
141
wrappedFile->file = theFile;
141
142
}
142
143
else {
@@ -231,7 +232,7 @@ - (NSMutableData *)readDataToEndOfFile
231
232
}
232
233
233
234
/* *
234
- * Returns the on-disk (raw/uncompressed ) length of data read so far.
235
+ * Returns the on-disk (raw/compressed ) length of data read so far.
235
236
* This includes any compression headers within the data, and can be used
236
237
* for progress bars when processing files.
237
238
*/
@@ -243,7 +244,7 @@ - (NSUInteger)realDataReadLength
243
244
return gzoffset (wrappedFile->gzfile );
244
245
}
245
246
else if (compressionFormat == SPBzip2Compression) {
246
- return 0 ;
247
+ return ftell (wrappedFile-> file ) ;
247
248
}
248
249
else {
249
250
return ftell (wrappedFile->file );
@@ -263,15 +264,7 @@ - (void)setCompressionFormat:(SPFileCompressionFormat)useCompressionFormat
263
264
if (compressionFormat == useCompressionFormat) return ;
264
265
265
266
// Regardless of the supplied argument, close the current file according to how it was previously opened
266
- if (compressionFormat == SPGzipCompression) {
267
- gzclose (wrappedFile->gzfile );
268
- }
269
- else if (compressionFormat == SPBzip2Compression) {
270
- BZ2_bzclose (wrappedFile->bzfile );
271
- }
272
- else {
273
- fclose (wrappedFile->file );
274
- }
267
+ [self _closeFileHandles ];
275
268
276
269
if (dataWritten) [NSException raise :NSInternalInconsistencyException format: @" Cannot change compression settings when data has already been written." ];
277
270
@@ -282,7 +275,8 @@ - (void)setCompressionFormat:(SPFileCompressionFormat)useCompressionFormat
282
275
gzbuffer (wrappedFile->gzfile , 131072 );
283
276
}
284
277
else if (compressionFormat == SPBzip2Compression) {
285
- wrappedFile->bzfile = BZ2_bzopen (wrappedFilePath, " wb" );
278
+ wrappedFile->file = fopen (wrappedFilePath, " wb" );
279
+ wrappedFile->bzfile = BZ2_bzWriteOpen (NULL , wrappedFile->file , 9 , 0 , 0 );
286
280
}
287
281
else {
288
282
wrappedFile->file = fopen (wrappedFilePath, " wb" );
@@ -343,16 +337,7 @@ - (void)closeFile
343
337
{
344
338
if (!fileIsClosed) {
345
339
[self synchronizeFile ];
346
-
347
- if (compressionFormat == SPGzipCompression) {
348
- gzclose (wrappedFile->gzfile );
349
- }
350
- else if (compressionFormat == SPBzip2Compression) {
351
- BZ2_bzclose (wrappedFile->bzfile );
352
- }
353
- else {
354
- fclose (wrappedFile->file );
355
- }
340
+ [self _closeFileHandles ];
356
341
357
342
if (processingThread) {
358
343
if ([processingThread isExecuting ]) {
@@ -442,6 +427,35 @@ - (void)_writeBufferToData
442
427
[writePool drain ];
443
428
}
444
429
430
+ /* *
431
+ * Close any open file handles
432
+ */
433
+ - (void )_closeFileHandles
434
+ {
435
+ if (compressionFormat == SPGzipCompression) {
436
+ gzclose (wrappedFile->gzfile );
437
+ wrappedFile->gzfile = NULL ;
438
+ }
439
+ else if (compressionFormat == SPBzip2Compression) {
440
+ if (fileMode == O_RDONLY) {
441
+ BZ2_bzReadClose (NULL , wrappedFile->bzfile );
442
+ }
443
+ else if (fileMode == O_WRONLY) {
444
+ BZ2_bzWriteClose (NULL , wrappedFile->bzfile , 0 , NULL , NULL );
445
+ }
446
+ else {
447
+ [NSException raise :NSInvalidArgumentException format: @" SPFileHandle only supports read-only and write-only file modes" ];
448
+ }
449
+ fclose (wrappedFile->file );
450
+ wrappedFile->bzfile = NULL ;
451
+ wrappedFile->file = NULL ;
452
+ }
453
+ else {
454
+ fclose (wrappedFile->file );
455
+ wrappedFile->file = NULL ;
456
+ }
457
+ }
458
+
445
459
#pragma mark -
446
460
447
461
/* *
0 commit comments