298 lines
7 KiB
C
298 lines
7 KiB
C
|
/***
|
||
|
**
|
||
|
** Module: FileIO
|
||
|
**
|
||
|
** Description:
|
||
|
** This is a module of the T1 to TT font converter. The module
|
||
|
** is the interface towards all low level I/O functions that are
|
||
|
** are available on the current platform.
|
||
|
** This version of the module is written specifically for Win32,
|
||
|
** and is based on "memory mapped files".
|
||
|
**
|
||
|
** Author: Michael Jansson
|
||
|
**
|
||
|
** Created: 5/26/93
|
||
|
**
|
||
|
***/
|
||
|
|
||
|
|
||
|
/**** INCLUDES */
|
||
|
/* General types and definitions. */
|
||
|
#include <windows.h>
|
||
|
|
||
|
#undef IN
|
||
|
|
||
|
/* Special types and definitions. */
|
||
|
#include "t1instal.h"
|
||
|
#include "types.h"
|
||
|
#include "safemem.h"
|
||
|
#include "fileio.h"
|
||
|
|
||
|
/* Module dependent types and prototypes. */
|
||
|
/*-none-*/
|
||
|
|
||
|
|
||
|
/***** LOCAL TYPES */
|
||
|
struct ioFile {
|
||
|
HANDLE file;
|
||
|
HANDLE mapping;
|
||
|
LPVOID data;
|
||
|
UBYTE *ptr;
|
||
|
UBYTE *max;
|
||
|
DWORD length;
|
||
|
boolean output;
|
||
|
};
|
||
|
|
||
|
|
||
|
/***** CONSTANTS */
|
||
|
#define FILESIZE 65535L
|
||
|
#define BUFSIZE 8L * 1024L
|
||
|
#define BADSET_ERROR 0xffffffff
|
||
|
|
||
|
/***** MACROS */
|
||
|
#ifndef FASTCALL
|
||
|
# ifdef MSDOS
|
||
|
# define FASTCALL __fastcall
|
||
|
# else
|
||
|
# define FASTCALL
|
||
|
# endif
|
||
|
#endif
|
||
|
#define TRY if (1)
|
||
|
#define EXCEPT(v) else
|
||
|
|
||
|
|
||
|
|
||
|
/***** STATIC FUNCTIONS */
|
||
|
/*-none-*/
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/***** FUNCTIONS */
|
||
|
|
||
|
struct ioFile *io_OpenFile(const char *name, const int mode)
|
||
|
{
|
||
|
DWORD access;
|
||
|
DWORD create;
|
||
|
DWORD attr;
|
||
|
DWORD prot;
|
||
|
DWORD lowsize;
|
||
|
DWORD mapaccess;
|
||
|
SECURITY_ATTRIBUTES sa;
|
||
|
struct ioFile *file;
|
||
|
|
||
|
if ((file = Malloc(sizeof(struct ioFile)))!=NULL) {
|
||
|
file->file = NULL;
|
||
|
file->mapping = NULL;
|
||
|
file->data = NULL;
|
||
|
file->ptr = NULL;
|
||
|
file->length = 0;
|
||
|
|
||
|
if (mode == READONLY) {
|
||
|
access = GENERIC_READ;
|
||
|
create = OPEN_EXISTING;
|
||
|
attr = FILE_ATTRIBUTE_NORMAL /*FILE_FLAG_SEQUENTIAL_SCAN*/;
|
||
|
prot = PAGE_READONLY;
|
||
|
lowsize = 0;
|
||
|
mapaccess = FILE_MAP_READ;
|
||
|
file->output = FALSE;
|
||
|
} else {
|
||
|
access = GENERIC_READ | GENERIC_WRITE;
|
||
|
create = CREATE_ALWAYS;
|
||
|
attr = FILE_ATTRIBUTE_NORMAL;
|
||
|
prot = PAGE_READWRITE;
|
||
|
lowsize = FILESIZE;
|
||
|
mapaccess = FILE_MAP_ALL_ACCESS;
|
||
|
file->output = TRUE;
|
||
|
}
|
||
|
sa.nLength = sizeof(sa);
|
||
|
sa.lpSecurityDescriptor = NULL;
|
||
|
sa.bInheritHandle = FALSE;
|
||
|
if ((file->file = CreateFile(name, access, 0, &sa, create,
|
||
|
attr, NULL))==INVALID_HANDLE_VALUE) {
|
||
|
(void)io_CloseFile(file);
|
||
|
SetLastError(0);
|
||
|
file = NULL;
|
||
|
} else {
|
||
|
if ((file->mapping = CreateFileMapping(file->file, NULL,
|
||
|
prot, 0, lowsize,
|
||
|
NULL))==INVALID_HANDLE_VALUE) {
|
||
|
(void)io_CloseFile(file);
|
||
|
file = NULL;
|
||
|
} else {
|
||
|
if ((file->data = MapViewOfFile(file->mapping,
|
||
|
mapaccess, 0, 0, 0))==NULL) {
|
||
|
(void)io_CloseFile(file);
|
||
|
file = NULL;
|
||
|
} else {
|
||
|
file->ptr = (UBYTE *)file->data;
|
||
|
file->max = file->ptr;
|
||
|
file->max = file->max + GetFileSize(file->file, NULL);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return file;
|
||
|
}
|
||
|
|
||
|
errcode io_CloseFile(struct ioFile *file)
|
||
|
{
|
||
|
errcode status = SUCCESS;
|
||
|
|
||
|
if (file==NULL || file->data==NULL || file->file==0)
|
||
|
status = FAILURE;
|
||
|
|
||
|
|
||
|
if (file) {
|
||
|
if ((DWORD)(file->ptr - (UBYTE *)file->data)>file->length)
|
||
|
file->length = (long)(file->ptr - (UBYTE *)file->data);
|
||
|
|
||
|
if (file->data){
|
||
|
UnmapViewOfFile(file->data);
|
||
|
file->data = NULL;
|
||
|
}
|
||
|
|
||
|
if (file->mapping) {
|
||
|
CloseHandle(file->mapping);
|
||
|
file->mapping = NULL;
|
||
|
}
|
||
|
|
||
|
if (file->file) {
|
||
|
if (file->output) {
|
||
|
if (SetFilePointer(file->file,
|
||
|
file->length,
|
||
|
0,
|
||
|
FILE_BEGIN)==BADSET_ERROR)
|
||
|
status = FAILURE;
|
||
|
else if (SetEndOfFile(file->file)==FALSE)
|
||
|
status = FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
CloseHandle(file->file);
|
||
|
file->file = NULL;
|
||
|
}
|
||
|
|
||
|
Free(file);
|
||
|
}
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
|
||
|
USHORT FASTCALL io_ReadOneByte(struct ioFile *file)
|
||
|
{
|
||
|
USHORT byte;
|
||
|
|
||
|
if (file->ptr<=file->max) {
|
||
|
byte = (USHORT)*(file->ptr++);
|
||
|
} else {
|
||
|
SetLastError(ERROR_READ_FAULT);
|
||
|
byte = ERROR_READ_FAULT;
|
||
|
}
|
||
|
|
||
|
return byte;
|
||
|
}
|
||
|
|
||
|
USHORT FASTCALL io_WriteBytes(const UBYTE *buf,
|
||
|
USHORT len,
|
||
|
struct ioFile *file)
|
||
|
{
|
||
|
if ((file->ptr+len)<=file->max) {
|
||
|
memcpy(file->ptr, buf, len);
|
||
|
file->ptr = file->ptr + len;
|
||
|
} else if (file->data) {
|
||
|
long pos = io_FileTell(file);
|
||
|
long size = MAX(GetFileSize(file->file, NULL),
|
||
|
MAX(file->length, (ULONG)(file->ptr -
|
||
|
(UBYTE *)file->data)));
|
||
|
|
||
|
/* Get rid of the old file mapping. */
|
||
|
UnmapViewOfFile(file->data);
|
||
|
file->data = NULL;
|
||
|
CloseHandle(file->mapping);
|
||
|
file->mapping = NULL;
|
||
|
|
||
|
/* Get a new file mapping. */
|
||
|
if ((file->mapping = CreateFileMapping(file->file, NULL,
|
||
|
PAGE_READWRITE, 0,
|
||
|
size + BUFSIZE,
|
||
|
NULL))==INVALID_HANDLE_VALUE) {
|
||
|
SetLastError(ERROR_WRITE_FAULT);
|
||
|
file->ptr = file->max;
|
||
|
len = 0;
|
||
|
} else if ((file->data = MapViewOfFile(file->mapping,
|
||
|
FILE_MAP_ALL_ACCESS,
|
||
|
0, 0, 0))==NULL) {
|
||
|
SetLastError(ERROR_WRITE_FAULT);
|
||
|
file->ptr = file->max;
|
||
|
len = 0;
|
||
|
} else {
|
||
|
file->ptr = (UBYTE *)file->data;
|
||
|
file->max = (UBYTE *)file->data;
|
||
|
file->max = file->max + size + BUFSIZE;
|
||
|
io_FileSeek(file, pos);
|
||
|
io_WriteBytes(buf, len, file);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
USHORT FASTCALL io_ReadBytes(UBYTE *buf, USHORT len, struct ioFile *file)
|
||
|
{
|
||
|
if ((file->ptr+len)<=file->max) {
|
||
|
memcpy(buf, file->ptr, len);
|
||
|
file->ptr = file->ptr + len;
|
||
|
} else {
|
||
|
SetLastError(ERROR_READ_FAULT);
|
||
|
len = 0;
|
||
|
}
|
||
|
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
boolean io_FileError(struct ioFile *file)
|
||
|
{
|
||
|
return (boolean)GetLastError();
|
||
|
}
|
||
|
|
||
|
|
||
|
long FASTCALL io_FileTell(struct ioFile *file)
|
||
|
{
|
||
|
return (long)(file->ptr - (UBYTE *)file->data);
|
||
|
}
|
||
|
|
||
|
|
||
|
long FASTCALL io_FileSeek(struct ioFile *file, long where)
|
||
|
{
|
||
|
DWORD oldpos = (DWORD)(file->ptr - (UBYTE *)file->data);
|
||
|
|
||
|
/* Keep track of the length of the file. */
|
||
|
if (oldpos>file->length)
|
||
|
file->length = oldpos;
|
||
|
|
||
|
/* Fail if file is not mapped, or if we are jumping out of bounds. */
|
||
|
if (file->data && (where>=0) &&
|
||
|
((UBYTE *)file->data+where) <= file->max) {
|
||
|
file->ptr = (UBYTE *)file->data;
|
||
|
file->ptr = file->ptr + where;
|
||
|
} else {
|
||
|
SetLastError(ERROR_SEEK);
|
||
|
}
|
||
|
|
||
|
return (long)oldpos;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***
|
||
|
** Function: FileSeek
|
||
|
**
|
||
|
** Description:
|
||
|
***/
|
||
|
void FASTCALL io_RemoveFile(const char *name)
|
||
|
{
|
||
|
DeleteFile(name);
|
||
|
}
|