mirror of https://git.wuffs.org/MWCC
129 lines
2.8 KiB
C
129 lines
2.8 KiB
C
#include "oslib.h"
|
|
#include <errno.h>
|
|
|
|
static int OS_LoadFileHandle(OSFileHandle *hand) {
|
|
int err;
|
|
int ref;
|
|
UInt32 sz;
|
|
void *buffer;
|
|
|
|
hand->loaded = 0;
|
|
|
|
err = OS_Open(&hand->spec, OSReadOnly, &ref);
|
|
if (!err) {
|
|
err = OS_GetSize(ref, &sz);
|
|
if (!err) {
|
|
err = OS_ResizeHandle(&hand->hand, sz);
|
|
if (!err) {
|
|
buffer = OS_LockHandle(&hand->hand);
|
|
err = OS_Read(ref, buffer, &sz);
|
|
if (!err) {
|
|
hand->loaded = 1;
|
|
hand->changed = 0;
|
|
}
|
|
OS_UnlockHandle(&hand->hand);
|
|
}
|
|
}
|
|
OS_Close(ref);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
static int OS_WriteFileHandle(OSFileHandle *hand) {
|
|
int err;
|
|
int ref;
|
|
UInt32 sz;
|
|
void *buffer;
|
|
|
|
if (!hand->loaded && !hand->changed)
|
|
return 0;
|
|
|
|
OS_Delete(&hand->spec);
|
|
err = OS_Create(&hand->spec, &OS_TEXTTYPE);
|
|
if (!err) {
|
|
err = OS_Open(&hand->spec, OSReadWrite, &ref);
|
|
if (!err) {
|
|
err = OS_GetHandleSize(&hand->hand, &sz);
|
|
if (!err) {
|
|
buffer = OS_LockHandle(&hand->hand);
|
|
err = OS_Write(ref, buffer, &sz);
|
|
if (!err)
|
|
hand->changed = 0;
|
|
OS_UnlockHandle(&hand->hand);
|
|
OS_Close(ref);
|
|
}
|
|
}
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int OS_NewFileHandle(const OSSpec *spec, OSHandle *src, Boolean writeable, OSFileHandle *hand) {
|
|
int err;
|
|
|
|
if (!writeable && src)
|
|
return EACCES;
|
|
|
|
hand->spec = *spec;
|
|
hand->writeable = writeable;
|
|
|
|
if (!src) {
|
|
err = OS_NewHandle(0, &hand->hand);
|
|
if (err)
|
|
return err;
|
|
err = OS_LoadFileHandle(hand);
|
|
} else {
|
|
err = OS_CopyHandle(src, &hand->hand);
|
|
if (err)
|
|
return err;
|
|
hand->changed = 1;
|
|
hand->loaded = 1;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int OS_LockFileHandle(OSFileHandle *hand, Ptr *ptr, UInt32 *size) {
|
|
*size = 0;
|
|
|
|
if (!OS_ValidHandle(&hand->hand))
|
|
return ENOMEM;
|
|
|
|
*ptr = OS_LockHandle(&hand->hand);
|
|
OS_GetHandleSize(&hand->hand, size);
|
|
return 0;
|
|
}
|
|
|
|
int OS_UnlockFileHandle(OSFileHandle *hand) {
|
|
if (!OS_ValidHandle(&hand->hand))
|
|
return ENOMEM;
|
|
|
|
OS_UnlockHandle(&hand->hand);
|
|
return 0;
|
|
}
|
|
|
|
int OS_FreeFileHandle(OSFileHandle *hand) {
|
|
int err;
|
|
|
|
if (hand->writeable && hand->changed) {
|
|
err = OS_WriteFileHandle(hand);
|
|
if (err)
|
|
return err;
|
|
}
|
|
|
|
if (!OS_ValidHandle(&hand->hand))
|
|
return ENOMEM;
|
|
|
|
err = OS_FreeHandle(&hand->hand);
|
|
if (err)
|
|
return err;
|
|
|
|
hand->loaded = 0;
|
|
return 0;
|
|
}
|
|
|
|
void OS_GetFileHandleSpec(const OSFileHandle *hand, OSSpec *spec) {
|
|
*spec = hand->spec;
|
|
}
|