/*** ** ** 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 #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); }