seanxiaoxiao
seanxiaoxiao

Reputation: 1302

Converting C-types to Objective-C objects

I have two questions.

  1. How to create a NSFileHandle object with the FILE* instance?

  2. How to create a NSData object with the void* instance?

I am sorry there's little information without context.

Just refer to my recent question. Weird behavior of fopen on ios I cannot use the native fopen function to create or to write the content into a file.

As a result, I just want to use the api in the ios framework and wrap the code of fopen and fwrite and such staff. So I should convert the FILE* object into NSFileHandle or something that can manipulate the file. Also the content which is handled with void* should be converted to the data format that can be accepted in the ios framework. And I think NSData should be the choice.

Upvotes: 1

Views: 334

Answers (2)

CodaFi
CodaFi

Reputation: 43330

As for FILE* to NSFileHandle, I found this mailing list question that perfectly matches what you need. Relevant code:

FILE *fp;
NSFileHandle *p;

fp = fopen( "foo", "r");
p = [[[NSFileHandle alloc] initWithFileDescriptor:fileno( fp)
closeOnDealloc:YES] autorelease];

And it comes with a lovely warning from the answerer:

Be careful not to read from fp, because stdio caches.

EDIT: As for void* to NSData, I think you want NSData's -initWithBytesNoCopy:Length:freeWhenDone:. See this related question on how to use it.

Upvotes: 3

Jody Hagins
Jody Hagins

Reputation: 28409

You can just use FILE* like you do in C. For example...

- (id)initWithFileUrl:(NSURL *)url
{
    if (self = [super init]) {
        NSFileManager *fileManager = [[NSFileManager alloc] init];
        [fileManager createDirectoryAtPath:[[url path] stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:0];

        char const *path = [fileManager fileSystemRepresentationWithPath:url.path];
        fp = fopen(path, "a");
        if (!fp) {
            [NSException raise:@"Can't open file for recording: " format:@"%s", strerror(errno)];
        }

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication]];
    }
    return self;
}
- (void)writeBytes:(void const *)bytes length:(uint32_t)size
{
    if (fp && fwrite(bytes, size, 1, fp) != 1) {
        [NSException raise:@"File Write Error" format:@"%s", strerror(errno)];
    }
}
- (void)writeBytes:(void const *)bytes andSize:(uint32_t)size
{
    if (!fp) return;
    if (fwrite(&size, sizeof size, 1, fp) != 1 || fwrite(bytes, size, 1, fp) != 1) {
        [NSException raise:@"File Write Error" format:@"%s", strerror(errno)];
    }
}
- (void)writeInt32:(int32_t)value
{
    [self writeBytes:&value length:sizeof value];
}
- (void)writeInt64:(int64_t)value
{
    [self writeBytes:&value length:sizeof value];
}
- (void)writeData:(NSData *)data
{
    [self writeBytes:data.bytes andSize:data.length];
}
- (void)writeCGFloat:(CGFloat)value
{
    [self writeBytes:&value length:sizeof value];
}
- (void)writeCGPoint:(CGPoint)point
{
    [self writeBytes:&point length:sizeof(point)];
}

Upvotes: 0

Related Questions