ObjFW  Artifact [e3b833eee4]

Artifact e3b833eee4e8ebe25482865ce95dc9074bb8aeacd1ca2756c7d8d47f88941018:

  • File src/OFFile.m — part of check-in [c83137e7cd] at 2008-12-11 13:43:35 on branch trunk — Remove - close from OFStream protocol.
    The reason is that closing a file isn't too useful, because an OFFile
    object can't be reused, whereas an OFTCPSocket can. So only the
    OFTCPSocket should have closed. Plus, we don't need to handle the case
    that someone tried to read from / write to a closed OFFile. (user: js, size: 3186) [annotate] [blame] [check-ins using]

/*
 * Copyright (c) 2008
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of libobjfw. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import "config.h"

#import <stdio.h>
#import <string.h>
#import <unistd.h>

#import <sys/types.h>
#import <sys/stat.h>

#import "OFFile.h"
#import "OFExceptions.h"

@implementation OFFile
+ newWithPath: (const char*)path
      andMode: (const char*)mode
{
	return [[self alloc] initWithPath: path
				    andMode: mode];
}

+ (BOOL)changeModeOfFile: (const char*)path
		 toMode: (mode_t)mode
{
	// FIXME: On error, throw exception
	return (chmod(path, mode) == 0 ? YES : NO);
}

+ (BOOL)changeOwnerOfFile: (const char*)path
		 toOwner: (uid_t)owner
		andGroup: (gid_t)group
{
	// FIXME: On error, throw exception
	return (chown(path, owner, group) == 0 ? YES : NO);
}

+ (BOOL)delete: (const char*)path
{
	// FIXME: On error, throw exception
	return (unlink(path) == 0 ? YES : NO);
}

+ (BOOL)link: (const char*)src
	 to: (const char*)dest
{
	// FIXME: On error, throw exception
	return (link(src, dest) == 0 ? YES : NO);
}

+ (BOOL)symlink: (const char*)src
	    to: (const char*)dest
{
	// FIXME: On error, throw exception
	return (symlink(src, dest) == 0 ? YES : NO);
}

- initWithPath: (const char*)path
       andMode: (const char*)mode
{
	if ((self = [super init])) {
		if ((fp = fopen(path, mode)) == NULL)
			@throw [OFOpenFileFailedException newWithObject: self
								andPath: path
								andMode: mode];
	}
	return self;
}

- free
{
	fclose(fp);

	return [super free];
}

- (BOOL)atEndOfFile
{
	return (feof(fp) == 0 ? NO : YES);
}

- (size_t)readNItems: (size_t)nitems
	      ofSize: (size_t)size
	  intoBuffer: (uint8_t*)buf
{
	size_t ret;

	if ((ret = fread(buf, size, nitems, fp)) == 0 && !feof(fp))
		@throw [OFReadFailedException newWithObject: self
						    andSize: size
						  andNItems: nitems];

	return ret;
}

- (size_t)readNBytes: (size_t)size
	  intoBuffer: (uint8_t*)buf
{
	return [self readNItems: size
			 ofSize: 1
		     intoBuffer: buf];
}

- (uint8_t*)readNItems: (size_t)nitems
		ofSize: (size_t)size
{
	uint8_t	*ret;

	ret = [self getMemForNItems: nitems
			     ofSize: size];

	@try {
		[self readNItems: nitems
			  ofSize: size
		      intoBuffer: ret];
	} @catch (id exception) {
		[self freeMem: ret];
		@throw exception;
	}

	return ret;
}

- (uint8_t*)readNBytes: (size_t)size
{
	return [self readNItems: size
			 ofSize: 1];
}

- (size_t)writeNItems: (size_t)nitems
	       ofSize: (size_t)size
	   fromBuffer: (const uint8_t*)buf
{
	size_t ret;

	if ((ret = fwrite(buf, size, nitems, fp)) == 0 &&
	    size != 0 && nitems != 0)
		@throw [OFWriteFailedException newWithObject: self
						     andSize: size
						   andNItems: nitems];
	
	return ret;
}

- (size_t)writeNBytes: (size_t)size
	   fromBuffer: (const uint8_t*)buf
{
	return [self writeNItems: size
			  ofSize: 1
		      fromBuffer: buf];
}

- (size_t)writeCString: (const char*)str
{
	return [self writeNItems: strlen(str)
			  ofSize: 1
		      fromBuffer: (const uint8_t*)str];
}
@end