aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/SPDataImport.m4
-rw-r--r--Source/SPExportFile.m2
-rw-r--r--Source/SPExporter.m2
-rw-r--r--Source/SPFileHandle.h21
-rw-r--r--Source/SPFileHandle.m209
5 files changed, 108 insertions, 130 deletions
diff --git a/Source/SPDataImport.m b/Source/SPDataImport.m
index 8ce41afc..64f314a9 100644
--- a/Source/SPDataImport.m
+++ b/Source/SPDataImport.m
@@ -389,7 +389,7 @@
[[NSFileManager defaultManager] removeItemAtPath:filename error:nil];
return;
}
- fileIsCompressed = [sqlFileHandle isCompressed];
+ fileIsCompressed = ([sqlFileHandle compressionFormat] != SPNoCompression);
// Grab the file length
fileTotalLength = (NSUInteger)[[[[NSFileManager defaultManager] attributesOfItemAtPath:filename error:NULL] objectForKey:NSFileSize] longLongValue];
@@ -752,7 +752,7 @@
// Grab the file length and status
fileTotalLength = (NSUInteger)[[[[NSFileManager defaultManager] attributesOfItemAtPath:filename error:NULL] objectForKey:NSFileSize] longLongValue];
if (!fileTotalLength) fileTotalLength = 1;
- fileIsCompressed = [csvFileHandle isCompressed];
+ fileIsCompressed = ([csvFileHandle compressionFormat] != SPNoCompression);
// If importing a bzipped file, use indeterminate progress bars as no progress is available
BOOL useIndeterminate = NO;
diff --git a/Source/SPExportFile.m b/Source/SPExportFile.m
index 132e1028..5d1c040d 100644
--- a/Source/SPExportFile.m
+++ b/Source/SPExportFile.m
@@ -191,7 +191,7 @@
return;
}
- [[self exportFileHandle] setShouldWriteWithCompressionFormat:fileCompressionFormat];
+ [[self exportFileHandle] setCompressionFormat:fileCompressionFormat];
}
#pragma mark -
diff --git a/Source/SPExporter.m b/Source/SPExporter.m
index 195d900d..db5cf809 100644
--- a/Source/SPExporter.m
+++ b/Source/SPExporter.m
@@ -95,7 +95,7 @@
exportOutputCompressFile = compress;
- [[[self exportOutputFile] exportFileHandle] setShouldWriteWithCompressionFormat:(compress) ? [self exportOutputCompressionFormat] : SPNoCompression];
+ [[[self exportOutputFile] exportFileHandle] setCompressionFormat:(compress) ? [self exportOutputCompressionFormat] : SPNoCompression];
}
/**
diff --git a/Source/SPFileHandle.h b/Source/SPFileHandle.h
index 23162385..5622b1b6 100644
--- a/Source/SPFileHandle.h
+++ b/Source/SPFileHandle.h
@@ -28,6 +28,7 @@
//
// More info at <https://github.com/sequelpro/sequelpro>
+union SPSomeFileHandle;
/**
* @class SPFileHandle SPFileHandle.h
*
@@ -39,7 +40,7 @@
*/
@interface SPFileHandle : NSObject
{
- void *wrappedFile;
+ union SPSomeFileHandle *wrappedFile;
char *wrappedFilePath;
NSMutableData *buffer;
@@ -53,7 +54,6 @@
BOOL dataWritten;
BOOL allDataWritten;
BOOL fileIsClosed;
- BOOL useCompression;
SPFileCompressionFormat compressionFormat;
}
@@ -69,7 +69,7 @@
#pragma mark Initialisation
// Returns a file handle initialised with a file
-- (id)initWithFile:(void *)theFile fromPath:(const char *)path mode:(int)mode;
+- (id)initWithFile:(FILE *)theFile fromPath:(const char *)path mode:(int)mode;
#pragma mark -
#pragma mark Data reading
@@ -87,7 +87,11 @@
#pragma mark Data writing
// Set whether data should be written in the supplied compression format (defaults to NO on a fresh object)
-- (void)setShouldWriteWithCompressionFormat:(SPFileCompressionFormat)useCompressionFormat;
+// This has no influence on reading data.
+- (void)setCompressionFormat:(SPFileCompressionFormat)useCompressionFormat;
+
+// Returns the compression format being used. Currently gzip or bzip2 only.
+- (SPFileCompressionFormat)compressionFormat;
// Write the provided data to the file
- (void)writeData:(NSData *)data;
@@ -98,13 +102,4 @@
// Prevents further access to the file
- (void)closeFile;
-#pragma mark -
-#pragma mark File information
-
-// Returns whether compression is enabled on the file
-- (BOOL)isCompressed;
-
-// Returns the compression format being used. Currently gzip or bzip2 only.
-- (SPFileCompressionFormat)compressionFormat;
-
@end
diff --git a/Source/SPFileHandle.m b/Source/SPFileHandle.m
index 3971e18b..3e0489a4 100644
--- a/Source/SPFileHandle.m
+++ b/Source/SPFileHandle.m
@@ -37,6 +37,12 @@
// waits until some has been written out. This can affect speed and memory usage.
#define SPFH_MAX_WRITE_BUFFER_SIZE 1048576
+union SPSomeFileHandle {
+ FILE *file;
+ BZFILE *bzfile;
+ gzFile *gzfile;
+};
+
@interface SPFileHandle ()
- (void)_writeBufferToData;
@@ -57,14 +63,14 @@
* theFile is a FILE when compression is disabled, a gzFile when gzip compression is enabled
* or a BZFILE when bzip2 compression is enabled.
*/
-- (id)initWithFile:(void *)theFile fromPath:(const char *)path mode:(int)mode
+- (id)initWithFile:(FILE *)theFile fromPath:(const char *)path mode:(int)mode
{
if ((self = [super init])) {
dataWritten = NO;
allDataWritten = YES;
fileIsClosed = NO;
- wrappedFile = theFile;
+ wrappedFile = malloc(sizeof(*wrappedFile)); //FIXME ivar can be moved to .m file with "modern objc", replacing the opaque struct pointer
wrappedFilePath = malloc(strlen(path) + 1);
strcpy(wrappedFilePath, path);
@@ -83,65 +89,62 @@
bufferPosition = 0;
endOfFile = NO;
- useCompression = NO;
compressionFormat = SPNoCompression;
+ processingThread = nil;
// If in read mode, set up the buffer
if (fileMode == O_RDONLY) {
-
- int i, c;
- char bzbuf[4];
- const char *charFileMode = fileMode == O_WRONLY ? "wb" : "rb";
-
- BZFILE *bzfile;
- gzFile *gzfile = gzopen(path, charFileMode);
-
- // Set gzip buffer
- gzbuffer(gzfile, 131072);
-
- // Get the first 4 bytes from the file
- for (i = 0; (c = getc(wrappedFile)) != EOF && i < 4; bzbuf[i++] = c);
-
- rewind(wrappedFile);
-
- // Test to see if the file is gzip compressed
- BOOL isGzip = !gzdirect(gzfile);
-
- // Test to see if the first 2 bytes extracted from the file match the Bzip2 signature/magic number
- // (BZ). The 3rd byte should be either 'h' (Huffman encoding) or 0 (Bzip1 - deprecated) to
- // indicate the Bzip version. Finally, the 4th byte should be a number between 1 and 9 that indicates
- // the block size used.
-
- BOOL isBzip2 = ((bzbuf[0] == 'B') && (bzbuf[1] == 'Z')) &&
- ((bzbuf[2] == 'h') || (bzbuf[2] == '0')) &&
- ((bzbuf[3] >= 0x31) && (bzbuf[3] <= 0x39));
-
- if (isBzip2) bzfile = BZ2_bzopen(path, charFileMode);
-
- useCompression = isGzip || isBzip2;
-
- if (useCompression) {
- if (isGzip) {
+ // Test for GZIP (by opening the file with gz and checking what happens)
+ {
+ gzFile *gzfile = gzopen(path, "rb");
+
+ // Set gzip buffer
+ gzbuffer(gzfile, 131072);
+
+ // Test to see if the file is gzip compressed
+ if(!gzdirect(gzfile)) {
compressionFormat = SPGzipCompression;
- wrappedFile = gzfile;
+ wrappedFile->gzfile = gzfile;
}
- else if (isBzip2) {
- compressionFormat = SPBzip2Compression;
- wrappedFile = bzfile;
+ else {
+ // ...not gzip
gzclose(gzfile);
}
+ }
+ // Test for BZ (by checking the file header)
+ if(compressionFormat == SPNoCompression) {
+ char bzbuf[4];
+ int i, c;
- fclose(theFile);
+ // Get the first 4 bytes from the file
+ for (i = 0; (c = getc(theFile)) != EOF && i < 4; bzbuf[i++] = c);
+
+ rewind(theFile);
+
+ // Test to see if the first 2 bytes extracted from the file match the Bzip2 signature/magic number
+ // (BZ). The 3rd byte should be either 'h' (Huffman encoding) or 0 (Bzip1 - deprecated) to
+ // indicate the Bzip version. Finally, the 4th byte should be a number between 1 and 9 that indicates
+ // the block size used.
+
+ BOOL isBzip2 = ((bzbuf[0] == 'B') && (bzbuf[1] == 'Z')) &&
+ ((bzbuf[2] == 'h') || (bzbuf[2] == '0')) &&
+ ((bzbuf[3] >= 0x31) && (bzbuf[3] <= 0x39));
+
+ if (isBzip2) {
+ compressionFormat = SPBzip2Compression;
+ wrappedFile->bzfile = BZ2_bzopen(path, "rb");
+ }
+ }
+ // Default to plain
+ if(compressionFormat == SPNoCompression) {
+ wrappedFile->file = theFile;
}
else {
- gzclose(gzfile);
+ fclose(theFile);
}
-
- processingThread = nil;
}
// In write mode, set up a thread to handle writing in the background
else if (fileMode == O_WRONLY) {
- useCompression = NO;
processingThread = [[NSThread alloc] initWithTarget:self selector:@selector(_writeBufferToData) object:nil];
[processingThread setName:@"SPFileHandle data writing thread"];
[processingThread start];
@@ -204,17 +207,15 @@
{
long dataLength = 0;
void *data = malloc(length);
-
- if (useCompression) {
- if (compressionFormat == SPGzipCompression) {
- dataLength = gzread(wrappedFile, data, (unsigned)length);
- }
- else if (compressionFormat == SPBzip2Compression) {
- dataLength = BZ2_bzread(wrappedFile, data, (int)length);
- }
+
+ if (compressionFormat == SPGzipCompression) {
+ dataLength = gzread(wrappedFile->gzfile, data, (unsigned)length);
+ }
+ else if (compressionFormat == SPBzip2Compression) {
+ dataLength = BZ2_bzread(wrappedFile->bzfile, data, (int)length);
}
else {
- dataLength = fread(data, 1, length, wrappedFile);
+ dataLength = fread(data, 1, length, wrappedFile->file);
}
return [NSMutableData dataWithBytesNoCopy:data length:dataLength freeWhenDone:YES];
@@ -235,13 +236,16 @@
*/
- (NSUInteger)realDataReadLength
{
- if ((fileMode == O_WRONLY) || (compressionFormat == SPBzip2Compression)) return 0;
+ if (fileMode == O_WRONLY) return 0;
- if (useCompression && (compressionFormat == SPGzipCompression)) {
- return gzoffset(wrappedFile);
+ if (compressionFormat == SPGzipCompression) {
+ return gzoffset(wrappedFile->gzfile);
+ }
+ else if(compressionFormat == SPBzip2Compression) {
+ return 0;
}
else {
- return ftell(wrappedFile);
+ return ftell(wrappedFile->file);
}
}
@@ -253,40 +257,34 @@
* to NO on a fresh object. If this is called after data has been
* written, an exception is thrown.
*/
-- (void)setShouldWriteWithCompressionFormat:(SPFileCompressionFormat)useCompressionFormat
+- (void)setCompressionFormat:(SPFileCompressionFormat)useCompressionFormat
{
if (compressionFormat == useCompressionFormat) return;
// Regardless of the supplied argument, close the current file according to how it was previously opened
- if (useCompression) {
- if (compressionFormat == SPGzipCompression) {
- gzclose(wrappedFile);
- }
- else if (compressionFormat == SPBzip2Compression) {
- BZ2_bzclose(wrappedFile);
- }
+ if (compressionFormat == SPGzipCompression) {
+ gzclose(wrappedFile->gzfile);
+ }
+ else if (compressionFormat == SPBzip2Compression) {
+ BZ2_bzclose(wrappedFile->bzfile);
}
else {
- fclose(wrappedFile);
+ fclose(wrappedFile->file);
}
if (dataWritten) [NSException raise:NSInternalInconsistencyException format:@"Cannot change compression settings when data has already been written."];
- useCompression = ((useCompressionFormat == SPGzipCompression) || (useCompressionFormat == SPBzip2Compression));
-
compressionFormat = useCompressionFormat;
- if (useCompression) {
- if (compressionFormat == SPGzipCompression) {
- wrappedFile = gzopen(wrappedFilePath, "wb");
- gzbuffer(wrappedFile, 131072);
- }
- else if (compressionFormat == SPBzip2Compression) {
- wrappedFile = BZ2_bzopen(wrappedFilePath, "wb");
- }
- }
+ if (compressionFormat == SPGzipCompression) {
+ wrappedFile->gzfile = gzopen(wrappedFilePath, "wb");
+ gzbuffer(wrappedFile->gzfile, 131072);
+ }
+ else if (compressionFormat == SPBzip2Compression) {
+ wrappedFile->bzfile = BZ2_bzopen(wrappedFilePath, "wb");
+ }
else {
- wrappedFile = fopen(wrappedFilePath, "wb");
+ wrappedFile->file = fopen(wrappedFilePath, "wb");
}
}
@@ -345,16 +343,14 @@
if (!fileIsClosed) {
[self synchronizeFile];
- if (useCompression) {
- if (compressionFormat == SPGzipCompression) {
- gzclose(wrappedFile);
- }
- else if (compressionFormat == SPBzip2Compression) {
- BZ2_bzclose(wrappedFile);
- }
- }
+ if (compressionFormat == SPGzipCompression) {
+ gzclose(wrappedFile->gzfile);
+ }
+ else if (compressionFormat == SPBzip2Compression) {
+ BZ2_bzclose(wrappedFile->bzfile);
+ }
else {
- fclose(wrappedFile);
+ fclose(wrappedFile->file);
}
if (processingThread) {
@@ -372,14 +368,6 @@
#pragma mark File information
/**
- * Returns whether compression is enabled on the file.
- */
-- (BOOL)isCompressed
-{
- return useCompression;
-}
-
-/**
* Returns the compression format being used. Currently gzip or bzip2 only.
*/
- (SPFileCompressionFormat)compressionFormat
@@ -418,22 +406,16 @@
// Write out the data
long bufferLengthWrittenOut = 0;
-
- if (useCompression) {
- switch (compressionFormat)
- {
- case SPGzipCompression:
- bufferLengthWrittenOut = gzwrite(wrappedFile, [dataToBeWritten bytes], (unsigned)[dataToBeWritten length]);
- break;
- case SPBzip2Compression:
- bufferLengthWrittenOut = BZ2_bzwrite(wrappedFile, (void *)[dataToBeWritten bytes], (int)[dataToBeWritten length]);
- break;
- default:
- break;
- }
- }
- else {
- bufferLengthWrittenOut = fwrite([dataToBeWritten bytes], 1, [dataToBeWritten length], wrappedFile);
+
+ switch (compressionFormat) {
+ case SPGzipCompression:
+ bufferLengthWrittenOut = gzwrite(wrappedFile->gzfile, [dataToBeWritten bytes], (unsigned)[dataToBeWritten length]);
+ break;
+ case SPBzip2Compression:
+ bufferLengthWrittenOut = BZ2_bzwrite(wrappedFile->bzfile, (void *)[dataToBeWritten bytes], (int)[dataToBeWritten length]);
+ break;
+ default:
+ bufferLengthWrittenOut = fwrite([dataToBeWritten bytes], 1, [dataToBeWritten length], wrappedFile->file);
}
// Restore data to the buffer if it wasn't written out
@@ -470,6 +452,7 @@
if (processingThread) SPClear(processingThread);
+ free(wrappedFile);
free(wrappedFilePath);
SPClear(buffer);