/*========================================================================= * * FILEUTIL.CPP - 28 November 1998, Dave Humphrey * * Common file related procedures and functions which I use often. * *=======================================================================*/ /* Required includes */ #include "genutil.h" /*========================================================================= * * Begin Variable Definitions * *=======================================================================*/ CLogFile SystemLog; /* The default log file for all applications */ /* Reduces the amount of log output for some of the functions * in this module */ boolean QuietLogOutput = FALSE; /*========================================================================= * End of Variable Definitions *=======================================================================*/ /*---------- MSDOS Specific Routines ------------------------------------*/ #ifdef __MSDOS__ #undef __FUNC__ #define __FUNC__ "CheckDisk()" /*========================================================================= * * Function - boolean CheckDisk (NewDrive); * * Returns TRUE if there is a disk in the specified drive. Drive 0 is A. * This is DOS specific routine. * *=======================================================================*/ boolean CheckDisk (const int NewDrive) { struct find_t FileBlock; int InitialDisk; /* Save the current drive and attempt to change drives */ InitialDisk = getdisk(); setdisk (NewDrive); /* Try and find files in drive...no files means no disk. If there is * an error hopefully the DOS error handler will be called with the * familiar 'Ignore, Retry, Abort' message. Return value appropiately */ if (_dos_findfirst("*.*", FA_DIREC, &FileBlock) != 0) { setdisk (InitialDisk); return (FALSE); } /* Change Was succesful */ return (TRUE); } /*========================================================================= * End of Function check_disk() *=======================================================================*/ #endif /*---------- End of if __MSDOS__ ----------------------------------------*/ #undef __FUNC__ #define __FUNC__ "CLogFile::Close()" /*=========================================================================== * * Class CLogFile Method - boolean Close (void); * * Closes the log file, if currently open. Returns TRUE on success or FALSE * if no log file is currently open. * *=========================================================================*/ boolean CLogFile::Close (void) { /* Is the log file currently open? */ if (LogFileHandle == NULL) return (FALSE); /* Display some status messages */ Printf ("Closing Log File..."); Printf ("\tHeap is %s", GetHeapStatusString()); Printf ("\tUsed/Free/Total Memory: %lu/%lu/%lu bytes", GetUsedMemory(), GetFreeMemory(), GetTotalMemory()); #ifdef _DEBUG #ifdef _WIN32 Printf ("\tCrtDumpMemoryLeaks returns %d", _CrtDumpMemoryLeaks()); #endif #endif /* Close log file */ fclose (LogFileHandle); LogFileHandle = NULL; NumTabs = 0; return (TRUE); } /*=========================================================================== * End of Class Method CLogFile::Close() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CLogFile::Open()" /*=========================================================================== * * Class CLogFile Method - boolean Open (pFilename, Append); * * Attempts to create a new log file using the given filename. Any current * log file is closed. If the Append flag is TRUE and the log file currently * exists, log entries will be appended to the end of the file. If FALSE, * the log file will be overwritten if it exists (the default). Returns * TRUE if the log file was successfully opened. * *=========================================================================*/ boolean CLogFile::Open (const char *pFilename, const boolean Append) { char DateString[21]; /* Close the current log file */ Close(); /* Attempt to open file for output, depending on the append flag */ if (Append) LogFileHandle = fopen(pFilename, "at"); else LogFileHandle = fopen(pFilename, "wt"); /* Ensure the file was successfully opened */ if (LogFileHandle == NULL) { ErrorHandler.SetError(ERR_FILE); return (FALSE); } /* Get the current Date and write it to file */ _strdate (DateString); Printf ("Opened Log File '%s' on %s", pFilename, DateString); /* Display the initial memory status */ Printf ("\tHeap is %s", GetHeapStatusString()); Printf ("\tUsed/Free/Total Memory: %lu/%lu/%lu bytes", GetUsedMemory(), GetFreeMemory(), GetTotalMemory()); return (TRUE); } /*=========================================================================== * End of Class Method CLogFile::Open() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CLogFile::Open()" /*=========================================================================== * * Class CLogFile Method - boolean OpenTemp (pFilename, Append); * * Same as the Open() method but attempts to append the temp directory as * given by the envirornment variables. So, if the filename passed was * 'SomeApp.LOG' and the Temp variable was 'C:\TEMP', the log would be * opened as 'C:\TEMP\SomeApp.Log'. * *=========================================================================*/ boolean CLogFile::OpenTemp (const char *pFilename, const boolean Append) { char LogFilename[512]; char* pTempPath; /* Get the temporary directory path */ pTempPath = getenv("TEMP"); if (pTempPath == NULL) getenv("TMP"); /* No temp path exists, just use the given filename */ if (pTempPath == NULL) { strnncpy (LogFilename, pFilename, 500); } else { strnncpy (LogFilename, pTempPath, 500); TerminatePath(LogFilename); strncat (LogFilename, pFilename, 511 - strlen(LogFilename)); } /* Call the Open() method with the new filename */ return Open(LogFilename, Append); } /*=========================================================================== * End of Class Method CLogFile::Open() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CLogFile::Printf()" /*=========================================================================== * * Class CLogFile Method - boolean Printf (pString, ...); * * Outputs a log file entry in the usual printf() format. Returns TRUE * on success, or FALSE on error. * *=========================================================================*/ boolean CLogFile::Printf (const char *pString, ...) { char TimeString[16]; va_list args; int LoopCounter; /* Ensure the log file is currently open and ensure valid input */ if (!IsOpen() || pString == NULL) return (FALSE); /* Get the current Time and write to file has a header text */ _strtime (TimeString); fprintf (LogFileHandle, "%s - ", TimeString); /* Output the tabs, if any */ for (LoopCounter = 0; LoopCounter < NumTabs; LoopCounter++) { fputc('\t', LogFileHandle); } /* Print the arugment list to file */ va_start (args, pString); vfprintf (LogFileHandle, pString, args); /* Output to the optional hook procedure */ if (pHookProc != NULL) pHookProc(pString, args); va_end (args); /* A linefeed */ fprintf (LogFileHandle, "\n"); /* Flush the file stream to make sure the written characters are written * to the file. This is in case the program crashes and isn't closed. If * this did happen without the following line, we'd probably lose some data. */ fflush (LogFileHandle); return (TRUE); } /*=========================================================================== * End of Class Method CLogFile::Printf() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CLogFile::Printf()" /*=========================================================================== * * Class CLogFile Method - boolean Printf (pFile, pString, ...); * * Outputs a log file entry in the usual printf() format to the log file * and the given stream. Returns TRUE on success, or FALSE on error. * *=========================================================================*/ boolean CLogFile::Printf (FILE* pFile, const char *pString, ...) { char TimeString[16]; va_list args; int LoopCounter; /* Ensure the log file is currently open and ensure valid input */ if (!IsOpen() || pString == NULL) return (FALSE); /* Get the current Time and write to file has a header text */ _strtime (TimeString); fprintf (LogFileHandle, "%s - ", TimeString); /* Output the tabs, if any */ for (LoopCounter = 0; LoopCounter < NumTabs; LoopCounter++) { fputc('\t', LogFileHandle); fputc('\t', pFile); } /* Print the arugment list to file */ va_start (args, pString); vfprintf (LogFileHandle, pString, args); if (pFile != NULL) vfprintf (pFile, pString, args); /* Output to the optional hook procedure */ if (pHookProc != NULL) pHookProc(pString, args); va_end (args); /* Flush the file stream to make sure the written characters are written * to the file. This is in case the program crashes and isn't closed. If * this did happen without the following line, we'd probably lose some data. */ fflush (LogFileHandle); fflush (pFile); return (TRUE); } /*=========================================================================== * End of Class Method CLogFile::Printf() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "ChangeDirectory()" /*========================================================================= * * Function - ChangeDirectory (pPath); * * Returns TRUE if the specified path is a valid directory. Does this * by attempting to change paths. If successful the current path is * changed to the given directory. * *=======================================================================*/ boolean ChangeDirectory (const char* pPath) { /* Make sure the given path is valid */ if (pPath == NULL || *pPath == '\0') { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Attempt to change directory */ if (chdir(pPath)) return(FALSE); return(TRUE); } /*========================================================================= * End of Function ChangeDirectory() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "CompareExtension()" /*=========================================================================== * * Function - boolean CompareExtension (pFilename, pString); * * Compares the extension of the given filename with the given string * and returns true if they match (case insensitive). The '.' extension * character is not included. * *=========================================================================*/ boolean CompareExtension (const char* pFilename, const char* pString) { size_t StringIndex; int Result; /* Ensure valid input */ if (pFilename == NULL || pString == NULL) { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Find the end of the filename */ StringIndex = strlen(pFilename) - 1; /* Find the last '.' character before the path starts */ while (pFilename[StringIndex] != PATH_CHARACTER && StringIndex != 0) { /* Is the current character the '.'? */ if (pFilename[StringIndex] == '.') { /* Compare the extension starting at the next character in filename */ Result = stricmp(pFilename + StringIndex + 1, pString); if (Result == 0) return (TRUE); return (FALSE); } StringIndex--; } /* No extension found */ return (FALSE); } /*=========================================================================== * End of Function CompareExtension() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CopyFile()" /*========================================================================= * * Function - boolean CopyFile (const char* pInputFile, const char* pOutputFile); * * Copies the given input file to the output file. Returns FALSE on any * error. * *=======================================================================*/ boolean CopyFile (const char* pInputFile, const char* pOutputFile) { FILE* pInputHandle; FILE* pOutputHandle; unsigned char Buffer[COPYFILE_BUFFERSIZE]; size_t ReadSize; size_t WriteSize; /* Ensure valid input */ if (pInputFile == NULL || pOutputFile == NULL) { SET_EXT_ERROR2(ERR_NULL, "Invalid filename(s) input!"); return (FALSE); } /* Attempt to open input file */ pInputHandle = openfile(pInputFile, "rb"); if (pInputHandle == NULL) { SET_EXT_ERROR3(ERR_FILE, "Failed to open input file '%s'!", pInputFile); return (FALSE); } /* Attempt to open output file */ pOutputHandle = openfile(pOutputFile, "wb"); if (pOutputHandle == NULL) { SET_EXT_ERROR3(ERR_FILE, "Failed to open output file '%s'!", pOutputFile); fclose (pInputHandle); return (FALSE); } /* Read and copy file in parts until finished */ do { /* Input data from file */ ReadSize = fread(Buffer, 1, COPYFILE_BUFFERSIZE, pInputHandle); /* Output to file */ WriteSize = fwrite(Buffer, 1, ReadSize, pOutputHandle); if (WriteSize != ReadSize) { fclose (pInputHandle); fclose (pOutputHandle); SET_EXT_ERROR2(ERR_WRITE, "Failed to write to output file!"); return (FALSE); } } while (ReadSize == COPYFILE_BUFFERSIZE); /* Close files */ fclose (pInputHandle); fclose (pOutputHandle); return (TRUE); } /*========================================================================= * End of Function CopyFile() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "CreateNewExtension()" /*======================================================================== * * Function - char* CreateNewExtension (pOldFile, pNewFile, pNewExt, MaxSize); * * Creates a copies the given filename into the new string, replacing the * old extension with the new one. Returns NULL on any error or the * new string on success. The input extension can include the '.' character * or not. If it doesn't, one is automatically inserted. * *======================================================================*/ char* CreateNewExtension (const char* pOldFile, char* pNewFile, const char* pNewExt, const size_t MaxSize) { /* Ensure valid input */ if (MaxSize < 4 || pOldFile == NULL || pNewFile == NULL || pNewExt == NULL) { SET_EXT_ERROR(ERR_NULL); return (NULL); } /* Create the new filename */ strnncpy(pNewFile, pOldFile, MaxSize-4); RemoveExt(pNewFile); /* Add the extension, ensuring the '.' character is present */ if (*pNewExt != '.') chrcat(pNewFile, '.'); strcat(pNewFile, pNewExt); return (pNewFile); } /*======================================================================== * End of Function CreateNewExtension() *======================================================================*/ #undef __FUNC__ #define __FUNC__ "CreatePath()" /*========================================================================= * * Function - char *CreatePath (pNewPath, pString, MaxStringLength); * * Creates a path from the given string. Copies up to MaxStringLength * bytes into the path string and ensures that the given path ends in * a '\' or '/' character. * *=======================================================================*/ char *CreatePath (char* pNewPath, const char* pString, const size_t MaxStringLength) { /* Ensure all input is valid */ if (pNewPath == NULL || pString == NULL || MaxStringLength == 0) return (pNewPath); /* Copy the given string into the new path */ strnncpy (pNewPath, pString, MaxStringLength-1); /* Ensure the path ends with a path character */ TerminatePath(pNewPath); return (pNewPath); } /*========================================================================= * End of Function CreatePath() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "ExtractFilename()" /*========================================================================= * * Function - char *ExtractFilename (pFilename, pPath, MaxStringLength); * * Copies just the filename from the given path into the given file (up * to MaxStringLength bytes). * *=======================================================================*/ char* ExtractFilename (char* pFilename, char* pPath, const size_t MaxStringLength) { /* Find the start of the filename */ pPath = FindFilename (pPath); if (pPath == NULL) return (pFilename); /* Copy the filename into the given buffer */ strnncpy (pFilename, pPath, MaxStringLength); return (pFilename); } /*========================================================================= * End of Function ExtractFilename() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "ExtractPath()" /*========================================================================= * * Function - char *ExtractPath (pPath, pString, MaxStringLength); * * Copies just the path from the given string and copies into the * specified path (at most MaxStringLength bytes). Returns a pointer to * the new path string. * *=======================================================================*/ char* ExtractPath (char* pPath, const char* pString, const size_t MaxStringLength) { size_t StringIndex; /* Ensure all the input is valid */ if (pString == NULL || pPath == NULL || MaxStringLength == 0) { SET_EXT_ERROR(ERR_NULL); return (pPath); } /* Copy the string into the new path */ strnncpy (pPath, pString, MaxStringLength); StringIndex = strlen(pPath); /* Remove any filename from the new path, if any */ while (StringIndex != 0) { StringIndex--; if (pPath[StringIndex] == PATH_CHARACTER) { StringIndex++; break; } } pPath[StringIndex] = 0; return (pPath); } /*========================================================================= * End of Function ExtractPath() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "FileExists()" /*========================================================================= * * Function - boolean FileExists (pFilename); * * Returns TRUE if the specified file exists and can be opened for reading. * *=======================================================================*/ boolean FileExists (const char* pFilename) { FILE* FileHandle; /* File pointer */ /* Attempt to open the file for reading */ if (pFilename == NULL || *pFilename == NULL_CHAR) return (FALSE); if (!(FileHandle = fopen(pFilename, "r"))) return(FALSE); /* File was opened and therefore exists, close and return success */ fclose(FileHandle); return(TRUE); } /*========================================================================= * End of Function FileExists) *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "FindFilename()" /*========================================================================= * * Function - char *FindFilename (pPath); * * Returns a pointer to the first character in the filename in the given * complete path. * *=======================================================================*/ char* FindFilename (char* pPath) { size_t StringIndex; /* Ensure the input is valid */ if (pPath == NULL) { SET_EXT_ERROR(ERR_NULL); return (pPath); } /* Start at the end of the given path */ StringIndex = strlen(pPath); while (StringIndex != 0) { StringIndex--; if (pPath[StringIndex] == '\\') { StringIndex++; break; } } return (pPath+StringIndex); } /*========================================================================= * End of Function ExtractFilename() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "GetFilesize()" /*========================================================================= * * Function - long GetFilesize (pFilename); * * Returns the size, in bytes, of the specified filename. Returns * INVALID_FILESIZE on any error. * *=======================================================================*/ long GetFilesize (const char* pFilename) { FILE* FileHandle; long FileSize; /* Attempt to open the file */ if (!(FileHandle = fopen(pFilename, "r"))) return (INVALID_FILESIZE); /* Jump to the end of the file and record file size*/ fseek (FileHandle, 0, SEEK_END); FileSize = ftell(FileHandle); fclose(FileHandle); /* Return filesize... */ return (FileSize); } /*========================================================================= * End of Function GetFilesize() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "GetFilesize()" /*========================================================================= * * Function - long GetFilesize (FileHandle); * * Returns the size a currently open file. Returns INVALID_FILESIZE * on any error. * *=======================================================================*/ long GetFilesize (FILE* FileHandle) { long FileSize; long InitialOffset; /* Make sure the file pointer is valid */ if (FileHandle == NULL) { SET_EXT_ERROR(ERR_NULL); return (INVALID_FILESIZE); } /* Save the current offset in the file */ InitialOffset = ftell(FileHandle); /* Move to end of file and save offset */ fseek (FileHandle, 0, SEEK_END); FileSize = ftell(FileHandle); /* Return to initial offset */ fseek (FileHandle, InitialOffset, SEEK_SET); return (FileSize); } /*========================================================================= * End of Function GetFilesize() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "HasExtension()" /*========================================================================= * * Function - boolean HasExtension (pFilename); * * Returns TRUE if the given filename contains an extension. * *=======================================================================*/ boolean HasExtension (const char* pFilename) { size_t StringIndex; /* Check for invalid input */ if (pFilename == NULL || *pFilename == '\0') { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Find the end of the filename */ StringIndex = strlen(pFilename) - 1; /* Look for an extension character before any path information */ while (pFilename[StringIndex] != 0) { if (pFilename[StringIndex] == '.') return (TRUE); else if (pFilename[StringIndex] == PATH_CHARACTER) return (FALSE); StringIndex--; } /* No extension found */ return (FALSE); } /*========================================================================= * End of Function HasExtension() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "HasPath()" /*========================================================================= * * Function - boolean HasPath (pString); * * Returns TRUE if the given string contains path information. * *=======================================================================*/ boolean HasPath (const char* pString) { /* Make sure string is valid */ if (pString == NULL) { SET_EXT_ERROR(ERR_NULL); return (FALSE); } while (*pString) { if (*pString == '\\' || *pString == '/' || *pString == ':') return (TRUE); pString++; } return (FALSE); } /*========================================================================= * End of Function HasPath() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "IsDirectory()" /*========================================================================= * * Function - boolean IsDirectory (pPath); * * Returns TRUE if the specified path is a valid but does not change * change directories. * *=======================================================================*/ boolean IsDirectory(const char* pPath) { char InitialPath[_MAX_PATH+1]; /* Save the initial directory */ if (getcwd(InitialPath, _MAX_PATH) == NULL) { SET_EXT_ERROR(ERR_STRING); return (FALSE); } /* Attempt to change directory */ if (chdir(pPath)) return(FALSE); /* Restore the initial path and return success */ chdir(InitialPath); return(TRUE); } /*========================================================================= * End of Function IsDirectory() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "IsFileWriteable()" /*======================================================================== * * Function - boolean IsFileWriteable (pFilename); * * Returns TRUE if the given file can be written to. * *======================================================================*/ boolean IsFileWriteable (const char* pFilename) { FILE* pFileHandle; /* Ensure valid input */ if (pFilename == NULL) return (FALSE); /* Attempt to open the file for writing */ pFileHandle = fopen (pFilename, "ab"); if (pFileHandle == NULL) return (FALSE); /* Close the now open file and return success */ fclose (pFileHandle); return (TRUE); } /*======================================================================== * End of Function IsFileWriteable(0 *======================================================================*/ #undef __FUNC__ #define __FUNC__ "IsWildcard()" /*========================================================================= * * Function - boolean iswildcard (pString); * * Returns TRUE if the given string has any '*' or '?' wildcard characters * in it. * *=======================================================================*/ boolean IsWildcard (const char* pString) { /* Make sure the given string is valid */ if (pString == NULL) { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Search entire string for a wildcard character */ while (*pString != NULL_CHAR) { if (*pString == '*' || *pString == '?') return(TRUE); pString++; } /* No wildcard characters found */ return (FALSE); } /*========================================================================= * End of Function IsWildcard() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "MakeExtDirectory()" /*=========================================================================== * * Function - boolean MakeExtDriectory (pNewPath); * * Makes the given directory. Supports making of multiple sub-dirs at * once. Returns FALSE on any error. * *=========================================================================*/ boolean MakeExtDirectory (const char* pNewPath) { char* pAllocatedPath; char* pPath; char* pSubPath; char* pPathStart; /* Make sure the input path is valid */ if (pNewPath == NULL || *pNewPath == NULL_CHAR) { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Parse out the first dir level of the given path */ pAllocatedPath = CreateString(pNewPath); pPathStart = pAllocatedPath; pPath = strtok(pAllocatedPath, "\\"); /* Ignore the drive parameter, if any */ if (pPath[1] == ':' && pPath[2] == NULL_CHAR) { pSubPath = pPath; pPath = strtok(NULL, "\\"); pSubPath[2] = PATH_CHARACTER; } /* Parse out each subpath from the given string */ while (pPath != NULL) { /* Does the sub-path currently exist? */ if (!IsDirectory(pPathStart)) { /* Path doesn't exist, try to create it */ if (mkdir(pPathStart) == -1) { ErrorHandler.SetError(ERR_SYSTEM); DestroyPointer(pAllocatedPath); return (FALSE); } } pSubPath = pPath; pPath = strtok(NULL, "\\"); if (pPath != NULL) pPath[-1] = PATH_CHARACTER; } DestroyPointer(pAllocatedPath); return (TRUE); } /*=========================================================================== * End of Function MakeExtDirectory() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "openfile()" /*========================================================================= * * Function - FILE *openfile (filename, mode, ExitOnError); * * A function I use to open files as per fopen(). Returns a handle to the * open file or NULL on error. If ExitOnError is TRUE program will halt on * a critical error (default is FALSE). Writes log entries as required. * *=======================================================================*/ FILE* openfile (const char* pFilename, const char* pMode, const boolean ExitOnError) { FILE* FileHandle; /* Ensure valid input */ if (pFilename == NULL || pMode == NULL) { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Output log file entry */ if (!QuietLogOutput) SystemLog.Printf ("Attempting to open file '%s' in mode '%s'", pFilename, pMode); /* Attempt to open the filename in the given mode */ if (!(FileHandle = fopen(pFilename, pMode))) { /* Output the log entry and set error code on failure */ SET_EXT_ERROR4(ERR_FILE, "Failed to open file '%s' in mode '%s'!", pFilename, pMode); /* Halt the program if required */ if (ExitOnError) ErrorHandler.Exit("Failed to open the file '%s' in mode '%s'!", pFilename, pMode); else return (NULL); } /* A successful open, return the file pointer */ return (FileHandle); } /*========================================================================= * End of Function openfile() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_eol()" /*========================================================================= * * Function - int read_eol (FileHandle, pString, MaxStringLength); * * Reads up to MaxStringLength characters or a the first Carriage Return * from the given file f into the given string. If string is NULL * characters are merely read and not stored in string. Returns READ_OK * on success, READ_MSL if max string length was reached, or READ_EOF * on end-of-file. * *=======================================================================*/ int read_eol (FILE* FileHandle, char* pString, const size_t MaxStringLength) { int InputChar; size_t StringLength = 0; /* Ignore any invalid file handle input */ if (FileHandle == NULL) { SET_EXT_ERROR(ERR_NULL); return (READ_EOF); } /* Read in the 1st character from file */ InputChar = fgetc(FileHandle); /* Loop until an EOF marker is found, a Carriage Return is found or * the loaded string length exceeds the maximum allowable */ while (InputChar != EOF && InputChar != CR && (pString == NULL || StringLength < MaxStringLength || MaxStringLength == 0)) { /* If buffer is NULL, this means that we want to read to the end of * the current line in a file, ignoring all the data on that line */ if (pString != NULL) { pString[StringLength] = InputChar; StringLength++; } /* Read the next character */ InputChar = fgetc(FileHandle); } /* Make sure the string is terminated */ if (pString != NULL) pString[StringLength] = NULL_CHAR; /* Determine what to return */ if (InputChar == EOF) return (READ_EOF); /* Max String Length Reached */ else if (pString && StringLength >= MaxStringLength) { SystemLog.Printf ("FILEUTIL.CPP - read_eol(): Max string length exceeded, %u!", MaxStringLength); return (READ_MSL); } /* Otherwise, return success */ return(READ_OK); } /*========================================================================= * End of Function read_eol() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_word()" /*========================================================================= * * Function - int read_word (FileHandle, pString, MaxStringLength); * * Attempt to read in a word from the given file into a string (up to * MaxStringLength characters). If string is NULL, bytes are just read and * not stored. Returns READ_EOF on end-of-file, READ_MSL if max string * length was reaced, READ_OK on success, or READ_EOL on end of line found. * White space is considered any space, end-of-line or TAB character. * *=======================================================================*/ int read_word (FILE* FileHandle, char* pString, const unsigned int MaxStringLength) { int InputChar; size_t StringLength = 0; /* Make sure the file handle is valid */ if (FileHandle == NULL) { SET_EXT_ERROR(ERR_NULL); return (READ_EOF); } /* Ignore any initial spaces and tabs from file */ do { InputChar = fgetc(FileHandle); } while (InputChar == ' ' && InputChar == 9 && InputChar != EOF && InputChar != CR); /* Loop until a space is read, a Carriage return is read, an EOF * marker is read, or max_string_length characters have been read */ while (InputChar != ' ' && InputChar != 9 && InputChar != EOF && InputChar != CR && (pString == NULL || StringLength < MaxStringLength)) { /* Add the string buffer, but only if it was supplied */ if (pString != NULL) { pString[StringLength] = InputChar; StringLength++; } /* Get the next character from the file */ InputChar = fgetc(FileHandle); } /* Make sure the string is null terminated */ if (pString == NULL) pString[StringLength] = NULL_CHAR; /* Determine what code to return */ if (InputChar == EOF) return (READ_EOF); else if (pString != NULL && StringLength >= MaxStringLength) { SystemLog.Printf ("FILEUTIL.CPP - read_word(): Max string length exceeded, %u!", MaxStringLength); return (READ_MSL); } else if (InputChar == CR) return (READ_EOL); /* Return a success */ return (READ_OK); } /*========================================================================= * End of Function read_word() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_file()" /*========================================================================= * * Function - char *read_file (pFilename); * * Attempts to read in an entire file and returns an allocated pointer. * On error returns NULL. Can only read a file up to UINT_MAX in size. * *=======================================================================*/ char* read_file (const char* pFilename) { FILE* FileHandle; char* pFileData; long FileSize; long InputSize; /* Attempt to Open file in read-only binary mode */ FileHandle = openfile(pFilename, "rb"); if (FileHandle == NULL) return (NULL); /* Retrieve the size of the file in bytes and ensure a valid size */ FileSize = GetFilesize(FileHandle); if ((unsigned long) FileSize > (unsigned long)UINT_MAX) { SET_EXT_ERROR3(ERR_UINTMAX, "File larger than %u in size specified!", UINT_MAX); fclose (FileHandle); return (NULL); } /* Attempt to allocate memory to hold file data*/ pFileData = CreateString((size_t)(FileSize + 1)); /* Read in the file all at once */ InputSize = fread (pFileData, sizeof(char), (size_t)FileSize, FileHandle); /* Ensure the proper number of bytes read */ if (InputSize != FileSize) { SET_EXT_ERROR4(ERR_READ, "Expected %ld bytes but read only %ld!", FileSize, InputSize); } /* Close file and return pointer */ fclose (FileHandle); return (pFileData); } /*========================================================================= * End of Function read_file() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_int()" /*========================================================================= * * Function - int read_int (pFileHandle); * * Reads an integer from the specified file. Sets the error code on any * error to the appropiate value and returns 0. Any previous error * information is cleared. * *=======================================================================*/ int read_int (FILE* pFileHandle) { int InputInteger; boolean Result; /* Clear any error information */ ErrorHandler.SetError(); Result = read_int(pFileHandle, InputInteger); if (Result) return (InputInteger); return (0); } /*========================================================================= * End of Function read_int() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_long()" /*========================================================================= * * Function - long read_long (pFileHandle); * * Reads a long integer from the specified file. Set the appropiate error * code on any error and returns 0. Any previous error information is cleared. * *=======================================================================*/ long read_long (FILE* pFileHandle) { long InputInteger; boolean Result; /* Clear any error information */ ErrorHandler.SetError(); Result = read_long(pFileHandle, InputInteger); if (Result) return (InputInteger); return (0); } /*========================================================================= * End of Function read_long() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_short()" /*========================================================================= * * Function - short read_short (pFileHandle); * * Reads a short integer from the specified file. Sets the appropiate * error code on any error and returns 0. Any previous error information * is cleared. * *=======================================================================*/ short read_short (FILE* pFileHandle) { short InputInteger; boolean Result; /* Clear any error information */ ErrorHandler.SetError(); Result = read_short(pFileHandle, InputInteger); if (Result) return (InputInteger); return (0); } /*========================================================================= * End of Function read_short() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_motlong()" /*========================================================================= * * Function - long read_motlong (pFileHandle); * * Reads a long integer from the specified file using the Motorolal byte * order. Sets the appropiate error code on any error and returns 0. * Any previous error information is cleared. * *=======================================================================*/ long read_motlong (FILE* pFileHandle) { long InputInteger; boolean Result; /* Clear any error information */ ErrorHandler.SetError(); Result = read_motlong(pFileHandle, InputInteger); if (Result) return (InputInteger); return (0); } /*========================================================================= * End of Function read_motlong() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_int()" /*========================================================================= * * Function - boolean read_int (pFileHandle, Value); * * Reads an integer from the specified file. Returns FALSE on any error. * The size of an integer depends on the platform compiled under. In DOS * it is usually 16 bit, in Windows it is 32 bit. * *=======================================================================*/ boolean read_int (FILE* pFileHandle, int& Value) { size_t InputSize; /* Make sure the file handle is valid */ if (pFileHandle == NULL) { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Read in the integer value */ InputSize = fread(&Value, 1, sizeof(int), pFileHandle); /* Check for any read error */ if (InputSize != sizeof(int)) { SET_EXT_ERROR4(ERR_READ, "Input only %u of %u bytes!", InputSize, sizeof(int)); return (FALSE); } return (TRUE); } /*========================================================================= * End of Function read_int() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_long()" /*========================================================================= * * Function - boolean read_long (pFileHandle, Value); * * Reads a long integer from the specified file. Returns FALSE on any * error. A long integer may be different sizes on various platforms, * though it is usually 32 bit. * *=======================================================================*/ boolean read_long (FILE* pFileHandle, long& Value) { size_t InputSize; /* Make sure the file handle is valid */ if (pFileHandle == NULL) { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Read the value */ InputSize = fread (&Value, 1, sizeof(long), pFileHandle); /* Ensure the value was correctly read */ if (InputSize != sizeof(long)) { SET_EXT_ERROR4(ERR_READ, "Input only %u of %u bytes!", InputSize, sizeof(long)); return (FALSE); } return (TRUE); } /*========================================================================= * End of Function read_long() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_short()" /*========================================================================= * * Function - boolean read_short (pFileHandle, Value); * * Reads a short integer from the specified file. Returns FALSE on any * error. A short integer is usually 16 bit but may depend on the * platform compiled under. * *=======================================================================*/ boolean read_short (FILE* pFileHandle, short& Value) { size_t InputSize; /* Make sure the file handle is valid */ if (pFileHandle == NULL) { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Read in the integer value */ InputSize = fread(&Value, 1, sizeof(short), pFileHandle); /* Check for any read error */ if (InputSize != sizeof(short)) { SET_EXT_ERROR4(ERR_READ, "Input only %u of %u bytes!", InputSize, sizeof(short)); return (FALSE); } return (TRUE); } /*========================================================================= * End of Function read_short() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_motlong()" /*========================================================================= * * Function - long read_motlong (pFileHandle, Value); * * Reads a long integer from the specified file using the Motorolal byte * order. Returns FALSE on any error. A long integer * is usually 32 bit but may depend on the platform compiled under. * *=======================================================================*/ boolean read_motlong (FILE* pFileHandle, long& Value) { unsigned char InputData[sizeof(long)]; size_t InputSize; /* Make sure the file handle is valid */ if (pFileHandle == NULL) { SET_EXT_ERROR(ERR_NULL); return (FALSE); } /* Read in the integer value */ InputSize = fread(&InputData, 1, sizeof(long), pFileHandle); /* Check for any read error */ if (InputSize != sizeof(long)) { SET_EXT_ERROR4(ERR_READ, "Input only %u of %u bytes!", InputSize, sizeof(long)); return (FALSE); } /* Compute the proper long integer value */ Value = (long) (((unsigned long)InputData[3]) + (((unsigned long)InputData[2])<<8) + (((unsigned long)InputData[1])<<16) + (((unsigned long)InputData[0])<<32)); return (TRUE); } /*========================================================================= * End of Function read_motlong() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "read_textfile()" /*========================================================================= * * Function - char *read_textfile (pFilename); * * Just like the read_file() function except for the case of a text file. * Attempts to read in an entire file and returns an allocated pointer. * On error returns NULL. Can only read a file up to UINT_MAX in size. * *=======================================================================*/ char* read_textfile (const char *pFilename) { FILE* FileHandle; char* pFileData; long FileSize; long InputSize; /* Attempt to Open file in read-only text mode */ FileHandle = openfile(pFilename, "rt"); if (FileHandle == NULL) return (NULL); /* Retrieve the size of the file in bytes and ensure a valid size */ FileSize = GetFilesize(FileHandle); if ((unsigned long) FileSize > (unsigned long)UINT_MAX) { SET_EXT_ERROR3(ERR_UINTMAX, "File larger than %u in size specified!", UINT_MAX); fclose (FileHandle); return (NULL); } /* Attempt to allocate memory to hold file data*/ pFileData = CreateString((size_t)(FileSize + 1)); /* Read in the file all at once */ InputSize = fread (pFileData, sizeof(char), (size_t)FileSize, FileHandle); /* Ensure the proper number of bytes read */ if (InputSize != FileSize) { SET_EXT_ERROR4(ERR_READ, "Expected %ld bytes but read only %ld!", FileSize, InputSize); } /* Close file and return pointer */ fclose (FileHandle); return (pFileData); } /*========================================================================= * End of Function read_textfile() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "RemoveExt()" /*========================================================================= * * Function - char *RemoveExt (pFilename); * * Removes the extension from the specified filename, if present. Returns * the pointer to the string. * *=======================================================================*/ char *RemoveExt (char *pFilename) { size_t StringIndex; /* Ignore any invalid input */ if (pFilename == NULL) { SET_EXT_ERROR(ERR_NULL); return (NULL); } /* Find the end of the filename */ StringIndex = strlen(pFilename) - 1; /* Find the last '.' character before the path starts */ while (pFilename[StringIndex] != PATH_CHARACTER && StringIndex != 0) { /* Is the current character the '.'? Truncate string and return if so */ if (pFilename[StringIndex] == '.') { pFilename[StringIndex] = NULL_CHAR; return (pFilename); } StringIndex--; } /* No extension found in string */ return (pFilename); } /*========================================================================= * End of Function RemoveExt() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "TerminatePath()" /*========================================================================= * * Function - char *TerminatePath (pString); * * Ensures that the given path ends in a '\' or '/' character. Returns * a pointer to the string. Assumes that the string is large enough for * another character to be added. * *=======================================================================*/ char* TerminatePath (char* pString) { size_t LastChar; /* Ignore invalid input */ if (pString == NULL || *pString == '\0') return (pString); /* Find the last character in the string */ LastChar = strlen(pString) - 1; /* Ensure the last character is a path character */ if (pString[LastChar] != PATH_CHARACTER) { pString[LastChar+1] = PATH_CHARACTER; pString[LastChar+2] = 0; } return (pString); } /*========================================================================= * End of Function TerminatePath() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "write_short()" /*========================================================================= * * Function - boolean write_short (FileHandle, OutputValue); * * Writes a short integer to a file. Returns FALSE on any error. * *=======================================================================*/ boolean write_short (FILE* FileHandle, const short OutputValue) { size_t OutputSize; /* Output the data */ OutputSize = fwrite(&OutputValue, sizeof(short), 1, FileHandle); /* Ensure the data was properly output */ if (OutputSize != 1) { SET_EXT_ERROR(ERR_WRITE); return (FALSE); } return (TRUE); } /*========================================================================= * End of Function write_short() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "write_int()" /*========================================================================= * * Function - boolean write_int (FileHandle, OutputValue); * * Writes an integer to a file. Returns FALSE on any error. * *=======================================================================*/ boolean write_long (FILE* FileHandle, const int OutputValue) { size_t OutputSize; /* Output the data */ OutputSize = fwrite(&OutputValue, sizeof(int), 1, FileHandle); /* Ensure the data was properly output */ if (OutputSize != 1) { ErrorHandler.SetError(ERR_WRITE); return (FALSE); } return (TRUE); } /*========================================================================= * End of Function write_int() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "write_long()" /*========================================================================= * * Function - boolean write_long (FileHandle, OutputValue); * * Writes a long integer to a file. Returns FALSE on any error. * *=======================================================================*/ boolean write_long (FILE* FileHandle, const long OutputValue) { size_t OutputSize; /* Output the data */ OutputSize = fwrite(&OutputValue, sizeof(long), 1, FileHandle); /* Ensure the data was properly output */ if (OutputSize != 1) { SET_EXT_ERROR(ERR_WRITE); return (FALSE); } return (TRUE); } /*========================================================================= * End of Function write_long() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "write_motlong()" /*========================================================================= * * Function - boolean write_motlong (FileHandle, OutputValue); * * Writes a long integer to a file using the Motorolal byte order. * Returns FALSE on any error. * *=======================================================================*/ boolean write_motlong (FILE* FileHandle, const long OutputValue) { unsigned char OutputData[4]; size_t OutputSize; /* Create the output buffer */ OutputData[0] = (unsigned char) ((OutputValue >> 24) & 0xFF); OutputData[1] = (unsigned char) ((OutputValue >> 16) & 0xFF); OutputData[2] = (unsigned char) ((OutputValue >> 8) & 0xFF); OutputData[3] = (unsigned char) (OutputValue & 0xFF); /* Output the data */ OutputSize = fwrite (OutputData, sizeof(long), 1, FileHandle); /* Ensure the data was properly output */ if (OutputSize != 1) { SET_EXT_ERROR(ERR_WRITE); return (FALSE); } return (TRUE); } /*========================================================================= * End of Function write_motlong() *=======================================================================*/ #undef __FUNC__ #define __FUNC__ "write_textfile()" /*========================================================================= * * Function - boolean write_textfile (filename, string); * * Writes the specified string pointer to the given filename returning TRUE * on success. If the file already exists it is overwritten. * *=======================================================================*/ boolean write_textfile (const char* pFilename, const char* pString) { size_t StringSize; size_t OutputSize; FILE* FileHandle; /* Attempt to open file */ FileHandle = openfile(pFilename, "wt"); /* Make sure the file was properly opened */ if (FileHandle == NULL) return (FALSE); /* Write the pointer if specified */ if (pString != NULL) { StringSize = strlen(pString); OutputSize = fwrite (pString, sizeof(char), StringSize, FileHandle); /* Ensure the string was output successfully */ if (OutputSize != StringSize) { SET_EXT_ERROR4(ERR_WRITE, "Wrote only %u bytes but expected %u!", OutputSize, StringSize); fclose (FileHandle); return (FALSE); } } fclose (FileHandle); return (TRUE); } /*========================================================================= * End of Function write_textfile() *=======================================================================*/