OSX 10.15 file offset methods

This commit is contained in:
rfm 2024-11-08 15:19:40 +00:00
parent 4b3315111b
commit fe5efb6aa2
4 changed files with 113 additions and 32 deletions

View file

@ -3,7 +3,7 @@
* Headers/Foundation/NSFileHandle.h:
* Source/GSFileHandle.m:
* Source/NSFileHandle.m:
Add -truncateAtOffset:error: method (issue 325)
Add OSX 12.15 file offset methods (issue 325, pull 446 and more)
2024-11-03 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -100,6 +100,12 @@ GS_EXPORT_CLASS
- (void) truncateFileAtOffset: (unsigned long long)pos;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_15, GS_API_LATEST)
- (BOOL) getOffset: (out unsigned long long *)offsetInFile
error: (out NSError **)error;
- (BOOL) seekToEndReturningOffset: (out unsigned long long *)offsetInFile
error: (out NSError **)error;
- (BOOL) seekToOffset: (unsigned long long)offset
error: (out NSError **)error;
- (BOOL) truncateAtOffset: (unsigned long long)offset
error: (out NSError **)error;
#endif

View file

@ -1521,7 +1521,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
// Seeking within a file
- (unsigned long long) offsetInFile
- (BOOL) getOffset: (out unsigned long long *)offsetInFile
error: (out NSError **)error;
{
off_t result = -1;
@ -1545,14 +1546,47 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
}
if (result < 0)
{
[NSException raise: NSFileHandleOperationException
format: @"failed to move to offset in file - %@",
[NSError _last]];
if (error)
{
*error = [NSError _last];
}
return NO;
}
return (unsigned long long)result;
if (offsetInFile)
{
*offsetInFile = (unsigned long long)result;
}
return YES;
}
- (unsigned long long) offsetInFile
{
unsigned long long result;
NSError *error;
if ([self getOffset: &result error: &error] == NO)
{
[NSException raise: NSFileHandleOperationException
format: @"failed to move to offset in file - %@", error];
}
return result;
}
- (unsigned long long) seekToEndOfFile
{
unsigned long long result;
NSError *error;
if ([self seekToEndReturningOffset: &result error: &error] == NO)
{
[NSException raise: NSFileHandleOperationException
format: @"failed to move to offset in file - %@", error];
}
return result;
}
- (BOOL) seekToEndReturningOffset: (out unsigned long long *)offsetInFile
error: (out NSError **)error
{
off_t result = -1;
@ -1576,21 +1610,39 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
}
if (result < 0)
{
[NSException raise: NSFileHandleOperationException
format: @"failed to move to offset in file - %@",
[NSError _last]];
if (error)
{
*error = [NSError _last];
}
return NO;
}
return (unsigned long long)result;
if (offsetInFile)
{
*offsetInFile = (unsigned long long)result;
}
return YES;
}
- (void) seekToFileOffset: (unsigned long long)pos
{
NSError *error;
if ([self seekToOffset: pos error: &error] == NO)
{
[NSException raise: NSFileHandleOperationException
format: @"failed to move to offset in file - %@", error];
}
}
- (BOOL) seekToOffset: (unsigned long long)offset
error: (out NSError **)error
{
off_t result = -1;
#ifdef __ANDROID__
if (asset)
{
result = AAsset_seek(asset, (off_t)pos, SEEK_SET);
result = AAsset_seek(asset, (off_t)offset, SEEK_SET);
}
else
#endif
@ -1599,21 +1651,23 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
#if USE_ZLIB
if (gzDescriptor != 0)
{
result = gzseek(gzDescriptor, (off_t)pos, SEEK_SET);
result = gzseek(gzDescriptor, (off_t)offset, SEEK_SET);
}
else
#endif
result = lseek(descriptor, (off_t)pos, SEEK_SET);
result = lseek(descriptor, (off_t)offset, SEEK_SET);
}
if (result < 0)
{
[NSException raise: NSFileHandleOperationException
format: @"failed to move to offset in file - %@",
[NSError _last]];
if (error)
{
*error = [NSError _last];
}
return NO;
}
return YES;
}
// Operations on file
- (void) closeFile
@ -1716,21 +1770,6 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
}
}
- (void) truncateFileAtOffset: (unsigned long long)pos
{
if (!(isStandardFile && descriptor >= 0))
{
[NSException raise: NSFileHandleOperationException
format: @"attempt to truncate invalid file"];
}
if (ftruncate(descriptor, pos) < 0)
{
[NSException raise: NSFileHandleOperationException
format: @"truncation failed"];
}
[self seekToFileOffset: pos];
}
- (BOOL) truncateAtOffset: (unsigned long long)offset
error: (out NSError **)error
{
@ -1746,6 +1785,21 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
return YES;
}
- (void) truncateFileAtOffset: (unsigned long long)pos
{
if (!(isStandardFile && descriptor >= 0))
{
[NSException raise: NSFileHandleOperationException
format: @"attempt to truncate invalid file"];
}
if (ftruncate(descriptor, pos) < 0)
{
[NSException raise: NSFileHandleOperationException
format: @"truncation failed"];
}
[self seekToFileOffset: pos];
}
- (void) writeInBackgroundAndNotify: (NSData*)item forModes: (NSArray*)modes
{
NSMutableDictionary* info;

View file

@ -409,6 +409,13 @@ static Class NSFileHandle_ssl_class = nil;
// Seeking within a file
- (BOOL) getOffset: (out unsigned long long *)offsetInFile
error: (out NSError **)error
{
[self subclassResponsibility: _cmd];
return NO;
}
/**
* Return current position in file, or raises exception if instance does
* not represent a regular file.
@ -429,6 +436,20 @@ static Class NSFileHandle_ssl_class = nil;
return 0;
}
- (BOOL) seekToEndReturningOffset: (out unsigned long long *)offsetInFile
error: (out NSError **)error
{
[self subclassResponsibility: _cmd];
return NO;
}
- (BOOL) seekToOffset: (unsigned long long)offset
error: (out NSError **)error
{
[self subclassResponsibility: _cmd];
return NO;
}
/**
* Position file pointer at pos, raising exception if instance does
* not represent a regular file.