diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 4d3770d04..714a08c44 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -972,6 +972,7 @@ 4BC6236E26F4235400F83DFE /* Copper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC6236C26F4235400F83DFE /* Copper.cpp */; }; 4BC6236F26F426B400F83DFE /* FAT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B477709268FBE4D005C2340 /* FAT.cpp */; }; 4BC6237226F94BCB00F83DFE /* MintermTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BC6237126F94BCB00F83DFE /* MintermTests.mm */; }; + 4BC62FF228A149300036AE59 /* NSData+dataWithContentsOfGZippedFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC62FF128A149300036AE59 /* NSData+dataWithContentsOfGZippedFile.m */; }; 4BC751B21D157E61006C31D9 /* 6522Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC751B11D157E61006C31D9 /* 6522Tests.swift */; }; 4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; }; 4BC890D3230F86020025A55A /* DirectAccessDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC890D1230F86020025A55A /* DirectAccessDevice.cpp */; }; @@ -2056,6 +2057,8 @@ 4BC6236C26F4235400F83DFE /* Copper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Copper.cpp; sourceTree = ""; }; 4BC6237026F94A5B00F83DFE /* Minterms.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Minterms.hpp; sourceTree = ""; }; 4BC6237126F94BCB00F83DFE /* MintermTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MintermTests.mm; sourceTree = ""; }; + 4BC62FF028A149300036AE59 /* NSData+dataWithContentsOfGZippedFile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSData+dataWithContentsOfGZippedFile.h"; sourceTree = ""; }; + 4BC62FF128A149300036AE59 /* NSData+dataWithContentsOfGZippedFile.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSData+dataWithContentsOfGZippedFile.m"; sourceTree = ""; }; 4BC751B11D157E61006C31D9 /* 6522Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6522Tests.swift; sourceTree = ""; }; 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FIRFilter.cpp; sourceTree = ""; }; 4BC76E681C98E31700E6EF73 /* FIRFilter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FIRFilter.hpp; sourceTree = ""; }; @@ -4290,6 +4293,8 @@ 4BFCA12A1ECBE7C400AC40C1 /* ZexallTests.swift */, 4B3BA0C41D318B44005DD7A7 /* Bridges */, 4B1414631B588A1100E04248 /* Test Binaries */, + 4BC62FF028A149300036AE59 /* NSData+dataWithContentsOfGZippedFile.h */, + 4BC62FF128A149300036AE59 /* NSData+dataWithContentsOfGZippedFile.m */, ); path = "Clock SignalTests"; sourceTree = ""; @@ -6132,6 +6137,7 @@ 4B778F4F23A5F21C0000D260 /* StaticAnalyser.cpp in Sources */, 4B8DD3682633B2D400B3C866 /* SpectrumVideoContentionTests.mm in Sources */, 4B7752A928217E200073E2C5 /* 65816Storage.cpp in Sources */, + 4BC62FF228A149300036AE59 /* NSData+dataWithContentsOfGZippedFile.m in Sources */, 4B7752AC28217E6E0073E2C5 /* StaticAnalyser.cpp in Sources */, 4B778F1223A5EC720000D260 /* CRT.cpp in Sources */, 4B778EF423A5DB3A0000D260 /* C1540.cpp in Sources */, diff --git a/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm b/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm index 5b9d71f46..64ad5e40c 100644 --- a/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm +++ b/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm @@ -9,10 +9,10 @@ #import #include "Blitter.hpp" +#include "NSData+dataWithContentsOfGZippedFile.h" #include #include -#include namespace Amiga { /// An empty stub to satisfy Amiga::Blitter's inheritance from Amiga::DMADevice; @@ -38,32 +38,9 @@ struct Chipset { Amiga::Chipset nonChipset; Amiga::Blitter blitter(nonChipset, ram, 256 * 1024); - NSURL *const traceURL = [[NSBundle bundleForClass:[self class]] - URLForResource:name withExtension:@"json.gz" subdirectory:@"Amiga Blitter Tests"]; - - // Use gzopen/etc to decompress to a temporary file, then read that back - // into memory to provide to the JSON deserialiser. This avoids having to wade - // too deeply into ZLib's slightly circuitous handling of decompression when - // the destination size is unkoinw. - NSString *const tempDir = NSTemporaryDirectory(); - NSString *const tempFile = [tempDir stringByAppendingPathComponent:@"temp.json"]; - - const gzFile compressedFile = gzopen([traceURL fileSystemRepresentation], "rb"); - FILE *const uncompressedFile = fopen([tempFile UTF8String], "wb"); - - uint8_t buffer[64 * 1024]; - while(true) { - const auto length = gzread(compressedFile, buffer, sizeof(buffer)); - if(!length) break; - fwrite(buffer, 1, length, uncompressedFile); - if(length != sizeof(buffer)) break; - } - - fclose(uncompressedFile); - gzclose(compressedFile); - - // Open and parse. - NSData *const traceData = [NSData dataWithContentsOfFile:tempFile]; + NSString *const tracePath = [[NSBundle bundleForClass:[self class]] + pathForResource:name ofType:@"json.gz" inDirectory:@"Amiga Blitter Tests"]; + NSData *const traceData = [NSData dataWithContentsOfGZippedFile:tracePath]; NSArray *const trace = [NSJSONSerialization JSONObjectWithData:traceData options:0 error:nil]; XCTAssertNotNil(trace); diff --git a/OSBindings/Mac/Clock SignalTests/NSData+dataWithContentsOfGZippedFile.h b/OSBindings/Mac/Clock SignalTests/NSData+dataWithContentsOfGZippedFile.h new file mode 100644 index 000000000..49ee06dde --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/NSData+dataWithContentsOfGZippedFile.h @@ -0,0 +1,19 @@ +// +// NSData+dataWithContentsOfGZippedFile.h +// Clock SignalTests +// +// Created by Thomas Harte on 08/08/2022. +// Copyright © 2022 Thomas Harte. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSData (dataWithContentsOfGZippedFile) + ++ (instancetype)dataWithContentsOfGZippedFile:(NSString *)path; + +@end + +NS_ASSUME_NONNULL_END diff --git a/OSBindings/Mac/Clock SignalTests/NSData+dataWithContentsOfGZippedFile.m b/OSBindings/Mac/Clock SignalTests/NSData+dataWithContentsOfGZippedFile.m new file mode 100644 index 000000000..2f3d7baa6 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/NSData+dataWithContentsOfGZippedFile.m @@ -0,0 +1,35 @@ +// +// NSData+dataWithContentsOfGZippedFile.m +// Clock SignalTests +// +// Created by Thomas Harte on 08/08/2022. +// Copyright © 2022 Thomas Harte. All rights reserved. +// + +#import "NSData+dataWithContentsOfGZippedFile.h" + +#include + +@implementation NSData (dataWithContentsOfGZippedFile) + ++ (instancetype)dataWithContentsOfGZippedFile:(NSString *)path { + gzFile compressedFile = gzopen([path UTF8String], "rb"); + if(!compressedFile) { + return nil; + } + + NSMutableData *data = [[NSMutableData alloc] init]; + + uint8_t buffer[64 * 1024]; + while(true) { + int length = gzread(compressedFile, buffer, sizeof(buffer)); + if(!length) break; + [data appendBytes:buffer length:length]; + if(length != sizeof(buffer)) break; + } + + gzclose(compressedFile); + return data; +} + +@end