994 lines
22 KiB
C++
994 lines
22 KiB
C++
/*
|
|
* Modification History
|
|
*
|
|
* 2001-February-11 Jason Rohrer
|
|
* Created.
|
|
*
|
|
* 2001-February-25 Jason Rohrer
|
|
* Fixed file name bugs in length and existence functions.
|
|
*
|
|
* 2001-May-11 Jason Rohrer
|
|
* Added a missing include.
|
|
*
|
|
* 2001-November-3 Jason Rohrer
|
|
* Added a function for checking if a file is a directory.
|
|
* Added a function for getting the child files of a directory.
|
|
* Added a function for getting a pathless file name.
|
|
*
|
|
* 2001-November-13 Jason Rohrer
|
|
* Made name length parameter optional in constructor.
|
|
* Made return length parameter optional in name getting functions.
|
|
*
|
|
* 2001-November-17 Jason Rohrer
|
|
* Added a functions for removing a file and for copying a file.
|
|
*
|
|
* 2002-March-11 Jason Rohrer
|
|
* Added destruction comment to getFullFileName().
|
|
*
|
|
* 2002-March-13 Jason Rohrer
|
|
* Changed mName to be \0-terminated to fix interaction bugs with Path.
|
|
* Fixed a missing delete.
|
|
* Added a function for creating a directory.
|
|
*
|
|
* 2002-March-31 Jason Rohrer
|
|
* Fixed some bad syntax.
|
|
*
|
|
* 2002-April-6 Jason Rohrer
|
|
* Replaced use of strdup.
|
|
*
|
|
* 2002-April-8 Jason Rohrer
|
|
* Fixed fopen bug.
|
|
*
|
|
* 2002-April-11 Jason Rohrer
|
|
* Fixed a memory leak.
|
|
* Fixed a casting error.
|
|
*
|
|
* 2002-June-28 Jason Rohrer
|
|
* Added a function for copying a file class.
|
|
*
|
|
* 2002-August-3 Jason Rohrer
|
|
* Added a function for getting the parent file.
|
|
*
|
|
* 2002-August-5 Jason Rohrer
|
|
* Used an unused error variable.
|
|
*
|
|
* 2002-September-11 Jason Rohrer
|
|
* Added return value to remove.
|
|
*
|
|
* 2003-January-27 Jason Rohrer
|
|
* Added a function for reading file contents.
|
|
*
|
|
* 2003-February-3 Jason Rohrer
|
|
* Added a function for writing a string to a file.
|
|
*
|
|
* 2003-March-13 Jason Rohrer
|
|
* Added a function for getting a child file from a directory.
|
|
*
|
|
* 2003-June-2 Jason Rohrer
|
|
* Fixed parent directory behavior when current file is root directory.
|
|
* Fixed a bug in getting child files of root directory.
|
|
*
|
|
* 2003-November-6 Jason Rohrer
|
|
* Added function for getting last modification time.
|
|
*
|
|
* 2003-November-10 Jason Rohrer
|
|
* Changed to use platform-dependent makeDirectory function.
|
|
*
|
|
* 2004-January-4 Jason Rohrer
|
|
* Added recursive child file functions.
|
|
*
|
|
* 2005-August-29 Jason Rohrer
|
|
* Fixed an uninitialized variable warning.
|
|
*
|
|
* 2010-March-6 Jason Rohrer
|
|
* Added versions of writeToFile readFileContents for binary data.
|
|
*
|
|
* 2010-April-23 Jason Rohrer
|
|
* Fixed a string length bug when line ends are Windows.
|
|
*
|
|
* 2010-May-14 Jason Rohrer
|
|
* String parameters as const to fix warnings.
|
|
*/
|
|
|
|
|
|
|
|
#include "minorGems/common.h"
|
|
|
|
|
|
|
|
#ifndef FILE_CLASS_INCLUDED
|
|
#define FILE_CLASS_INCLUDED
|
|
|
|
#include <sys/stat.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include "Path.h"
|
|
|
|
#include "minorGems/util/SimpleVector.h"
|
|
#include "minorGems/util/stringUtils.h"
|
|
|
|
|
|
|
|
/**
|
|
* File interface. Provides access to information about a
|
|
* file.
|
|
*
|
|
* @author Jason Rohrer
|
|
*/
|
|
class File {
|
|
|
|
public:
|
|
|
|
/**
|
|
* Constructs a file.
|
|
*
|
|
* @param inPath the path for this file.
|
|
* Is destroyed when this class is destroyed.
|
|
* Pass in NULL to specify
|
|
* no path (the current working directory).
|
|
* @param inName the name of the file to open.
|
|
* Must be destroyed by caller if not const.
|
|
* Copied internally.
|
|
* @param inNameLength length of the name in chars,
|
|
* or -1 to use the c-string length of inName
|
|
* (assuming that inName is \0-terminated).
|
|
* Defaults to -1.
|
|
*/
|
|
File( Path *inPath, const char *inName, int inNameLength = -1 );
|
|
|
|
|
|
~File();
|
|
|
|
|
|
|
|
/**
|
|
* Gets whether this file is a directory.
|
|
*
|
|
* @return true iff this file is a directory.
|
|
*/
|
|
char isDirectory();
|
|
|
|
|
|
|
|
/**
|
|
* Makes a directory in the location of this file.
|
|
*
|
|
* Can only succeed if exists() is false.
|
|
*
|
|
* @return true iff directory creation succeeded.
|
|
*/
|
|
char makeDirectory();
|
|
|
|
|
|
|
|
/**
|
|
* Gets the files contained in this file if it is a directory.
|
|
*
|
|
* @param outNumFiles pointer to where the number of
|
|
* files will be returned.
|
|
*
|
|
* @return an array of files, or NULL if this
|
|
* file is not a directory, is an empty directory, or doesn't exist.
|
|
* Must be destroyed by caller if non-NULL.
|
|
*/
|
|
File **getChildFiles( int *outNumFiles );
|
|
|
|
|
|
|
|
/**
|
|
* Gets the files contained in this file if it is a directory and
|
|
* recursively in subdirectories of this file.
|
|
*
|
|
* @param inDepthLimit the maximum subdirectory depth to recurse into.
|
|
* If inDepthLimit is 0, then only child files in this directory
|
|
* will be returned.
|
|
* @param outNumFiles pointer to where the number of
|
|
* files will be returned.
|
|
*
|
|
* @return an array of files, or NULL if this
|
|
* file is not a directory, is an empty directory (or a directory
|
|
* containing empty subdirectories), or doesn't exist.
|
|
* Must be destroyed by caller if non-NULL.
|
|
*/
|
|
File **getChildFilesRecursive( int inDepthLimit, int *outNumFiles );
|
|
|
|
|
|
|
|
/**
|
|
* Gets a child of this directory.
|
|
*
|
|
* @param inChildFileName the name of the child file.
|
|
* Must be destroyed by caller if non-const.
|
|
*
|
|
* @return the child file (even if it does not exist), or NULL if
|
|
* this file is not a directory.
|
|
* Must be destroyed by caller if non-NULL.
|
|
*/
|
|
File *getChildFile( const char *inChildFileName );
|
|
|
|
|
|
|
|
/**
|
|
* Gets the parent directory of this file.
|
|
*
|
|
* @return the parent directory of this file.
|
|
* Must be destroyed by caller.
|
|
*/
|
|
File *getParentDirectory();
|
|
|
|
|
|
|
|
/**
|
|
* Gets the length of this file.
|
|
*
|
|
* @return the length of this file in bytes. Returns
|
|
* 0 if the file does not exist.
|
|
*/
|
|
long getLength();
|
|
|
|
|
|
/**
|
|
* Gets whether a file exists.
|
|
*
|
|
* @return true if the file exists.
|
|
*/
|
|
char exists();
|
|
|
|
|
|
|
|
/**
|
|
* Gets the last modification time of this file.
|
|
*
|
|
* @return the modification time in seconds based on the
|
|
* system clock. Returns 0 if the file does not exist.
|
|
*/
|
|
unsigned long getModificationTime();
|
|
|
|
|
|
|
|
/**
|
|
* Removes this file from the disk, if it exists.
|
|
*
|
|
* @return true iff the remove succeeded, false if the removal
|
|
* fails or the file does not exist.
|
|
*/
|
|
char remove();
|
|
|
|
|
|
|
|
/**
|
|
* Copies this file object (does not copy the file described by
|
|
* this object).
|
|
*
|
|
* @return a deep copy of this file object.
|
|
*/
|
|
File *copy();
|
|
|
|
|
|
|
|
/**
|
|
* Copies the contents of this file into another file.
|
|
*
|
|
* @param inDestination the file to copy this file into.
|
|
* If it exists, it will be overwritten.
|
|
* If it does not exist, it will be created.
|
|
* Must be destroyed by caller.
|
|
* @param inBlockSize the block size to use when copying.
|
|
* Defaults to blocks of 5000 bytes.
|
|
*/
|
|
void copy( File *inDestination, long inBlockSize = 5000 );
|
|
|
|
|
|
|
|
/**
|
|
* Gets the full-path file name sufficient
|
|
* to access this file from the current working
|
|
* directory.
|
|
*
|
|
* @param outLength pointer to where the name length, in
|
|
* characters, will be returned. Set to NULL to ignore
|
|
* the output length. Defaults to NULL.
|
|
*
|
|
* @return the full path file name for this file,
|
|
* in platform-specific form. Must be destroyed by caller.
|
|
* The returned string is '\0' terminated, but this
|
|
* extra character is not included in the length.
|
|
* Must be destroyed by caller.
|
|
*/
|
|
char *getFullFileName( int *outLength = NULL );
|
|
|
|
|
|
|
|
/**
|
|
* Gets the pathless name of this file.
|
|
*
|
|
* @param outLength pointer to where the name length, in
|
|
* characters, will be returned. Set to NULL to ignore
|
|
* the output length. Defaults to NULL.
|
|
*
|
|
* @return the name of this file. Must be destroyed by caller.
|
|
*/
|
|
char *getFileName( int *outLength = NULL );
|
|
|
|
|
|
|
|
/**
|
|
* Reads the contents of this file.
|
|
*
|
|
* @return a \0-terminated string containing the file contents,
|
|
* or NULL if reading the file into memory failed.
|
|
* Must be destroyed by caller.
|
|
*/
|
|
char *readFileContents();
|
|
|
|
|
|
|
|
/**
|
|
* Reads the contents of this file.
|
|
*
|
|
* @param outLength pointer to where the return array length should
|
|
* be returned.
|
|
* @param inTextMode true to open the file as text, false as binary.
|
|
* Defaults to false.
|
|
*
|
|
* @return an array containing the binary file contents,
|
|
* or NULL if reading the file into memory failed.
|
|
* Must be destroyed by caller.
|
|
*/
|
|
unsigned char *readFileContents( int *outLength,
|
|
char inTextMode = false );
|
|
|
|
|
|
|
|
/**
|
|
* Writes a string to this file.
|
|
*
|
|
* @param inString the \0-terminated string to write.
|
|
* Must be destroyed by caller if non-const.
|
|
*
|
|
* @return true if the file was written to successfully, or
|
|
* false otherwise.
|
|
*/
|
|
char writeToFile( const char *inString );
|
|
|
|
|
|
/**
|
|
* Writes a binary data to this file.
|
|
*
|
|
* @param inData the data to write.
|
|
* Must be destroyed by caller if non-const.
|
|
* @param inLength length of inData.
|
|
*
|
|
* @return true if the file was written to successfully, or
|
|
* false otherwise.
|
|
*/
|
|
char writeToFile( unsigned char *inData, int inLength );
|
|
|
|
|
|
|
|
private:
|
|
Path *mPath;
|
|
char *mName;
|
|
int mNameLength;
|
|
|
|
|
|
|
|
/**
|
|
* Gets the files contained in this file if it is a directory and
|
|
* recursively in subdirectories of this file.
|
|
*
|
|
* @param inDepthLimit the maximum subdirectory depth to recurse into.
|
|
* If inDepthLimit is 0, then only child files in this directory
|
|
* will be returned.
|
|
* @param inResultVector vector to add the discovered files to.
|
|
* Must be destroyed by caller.
|
|
*/
|
|
void getChildFilesRecursive( int inDepthLimit,
|
|
SimpleVector<File *> *inResultVector );
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
inline File::File( Path *inPath, const char *inName, int inNameLength )
|
|
: mPath( inPath ), mNameLength( inNameLength ) {
|
|
|
|
if( inNameLength == -1 ) {
|
|
inNameLength = strlen( inName );
|
|
mNameLength = inNameLength;
|
|
}
|
|
|
|
// copy name internally
|
|
mName = stringDuplicate( inName );
|
|
|
|
}
|
|
|
|
|
|
|
|
inline File::~File() {
|
|
delete [] mName;
|
|
|
|
if( mPath != NULL ) {
|
|
delete mPath;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
inline long File::getLength() {
|
|
struct stat fileInfo;
|
|
|
|
// get full file name
|
|
int length;
|
|
char *stringName = getFullFileName( &length );
|
|
|
|
int statError = stat( stringName, &fileInfo );
|
|
|
|
delete [] stringName;
|
|
|
|
if( statError == 0 ) {
|
|
return fileInfo.st_size;
|
|
}
|
|
else {
|
|
// file does not exist
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
inline char File::isDirectory() {
|
|
struct stat fileInfo;
|
|
|
|
// get full file name
|
|
int length;
|
|
char *stringName = getFullFileName( &length );
|
|
|
|
int statError = stat( stringName, &fileInfo );
|
|
|
|
delete [] stringName;
|
|
|
|
if( statError == -1 ) {
|
|
return false;
|
|
}
|
|
else {
|
|
return S_ISDIR( fileInfo.st_mode );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
inline File **File::getChildFiles( int *outNumFiles ) {
|
|
|
|
int length;
|
|
char *stringName = getFullFileName( &length );
|
|
|
|
DIR *directory = opendir( stringName );
|
|
|
|
if( directory != NULL ) {
|
|
|
|
SimpleVector< File* > *fileVector = new SimpleVector< File* >();
|
|
|
|
struct dirent *entry = readdir( directory );
|
|
|
|
if( entry == NULL ) {
|
|
delete fileVector;
|
|
|
|
closedir( directory );
|
|
|
|
delete [] stringName;
|
|
|
|
*outNumFiles = 0;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
while( entry != NULL ) {
|
|
// skip parentdir and thisdir files, if they occur
|
|
if( strcmp( entry->d_name, "." ) &&
|
|
strcmp( entry->d_name, ".." ) ) {
|
|
|
|
Path *newPath;
|
|
|
|
if( mPath != NULL ) {
|
|
newPath = mPath->append( mName );
|
|
}
|
|
else {
|
|
|
|
if( Path::isRoot( mName ) ) {
|
|
// use name as a string path
|
|
newPath = new Path( mName );
|
|
}
|
|
else {
|
|
char **folderPathArray = new char*[1];
|
|
folderPathArray[0] = mName;
|
|
|
|
// a non-absolute path to this directory's contents
|
|
int numSteps = 1;
|
|
char absolute = false;
|
|
newPath =
|
|
new Path( folderPathArray, numSteps,
|
|
absolute );
|
|
|
|
delete [] folderPathArray;
|
|
}
|
|
}
|
|
|
|
// safe to pass d_name in directly because it is copied
|
|
// internally by the constructor
|
|
|
|
fileVector->push_back(
|
|
new File( newPath,
|
|
entry->d_name,
|
|
strlen( entry->d_name ) ) );
|
|
}
|
|
|
|
entry = readdir( directory );
|
|
}
|
|
|
|
// now we have a vector full of this directory's files
|
|
int vectorSize = fileVector->size();
|
|
|
|
*outNumFiles = vectorSize;
|
|
|
|
if( vectorSize == 0 ) {
|
|
delete fileVector;
|
|
|
|
closedir( directory );
|
|
|
|
delete [] stringName;
|
|
|
|
return NULL;
|
|
}
|
|
else {
|
|
File **returnFiles = new File *[vectorSize];
|
|
for( int i=0; i<vectorSize; i++ ) {
|
|
returnFiles[i] = *( fileVector->getElement( i ) );
|
|
}
|
|
|
|
delete fileVector;
|
|
|
|
closedir( directory );
|
|
|
|
delete [] stringName;
|
|
|
|
return returnFiles;
|
|
}
|
|
}
|
|
else {
|
|
delete [] stringName;
|
|
|
|
*outNumFiles = 0;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
inline File **File::getChildFilesRecursive( int inDepthLimit,
|
|
int *outNumFiles ) {
|
|
|
|
// create a vector for results
|
|
SimpleVector<File *> *resultVector = new SimpleVector<File *>();
|
|
|
|
// call the recursive function
|
|
getChildFilesRecursive( inDepthLimit, resultVector );
|
|
|
|
|
|
// extract results from vector
|
|
File **resultArray = NULL;
|
|
|
|
int numResults = resultVector->size();
|
|
|
|
if( numResults > 0 ) {
|
|
resultArray = resultVector->getElementArray();
|
|
}
|
|
|
|
delete resultVector;
|
|
|
|
|
|
|
|
*outNumFiles = numResults;
|
|
return resultArray;
|
|
}
|
|
|
|
|
|
|
|
inline void File::getChildFilesRecursive(
|
|
int inDepthLimit,
|
|
SimpleVector<File *> *inResultVector ) {
|
|
|
|
// get our child files
|
|
int numChildren;
|
|
File **childFiles = getChildFiles( &numChildren );
|
|
|
|
if( childFiles != NULL ) {
|
|
|
|
// for each child, add it to vector and
|
|
// recurse into it if it is a directory
|
|
|
|
for( int i=0; i<numChildren; i++ ) {
|
|
|
|
File *child = childFiles[i];
|
|
|
|
// add it to results vector
|
|
inResultVector->push_back( child );
|
|
|
|
if( child->isDirectory() ) {
|
|
// skip recursion if we have hit our depth limit
|
|
if( inDepthLimit > 0 ) {
|
|
// recurse into this subdirectory
|
|
child->getChildFilesRecursive( inDepthLimit - 1,
|
|
inResultVector );
|
|
}
|
|
}
|
|
}
|
|
|
|
delete [] childFiles;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
inline File *File::getChildFile( const char *inChildFileName ) {
|
|
// make sure we are a directory
|
|
if( !isDirectory() ) {
|
|
return NULL;
|
|
}
|
|
|
|
// get a path to this directory
|
|
Path *newPath;
|
|
|
|
if( mPath != NULL ) {
|
|
newPath = mPath->append( mName );
|
|
}
|
|
else {
|
|
|
|
char **folderPathArray = new char*[1];
|
|
folderPathArray[0] = mName;
|
|
|
|
// a non-absolute path to this directory's contents
|
|
int numSteps = 1;
|
|
char absolute = false;
|
|
newPath =
|
|
new Path( folderPathArray, numSteps,
|
|
absolute );
|
|
|
|
delete [] folderPathArray;
|
|
}
|
|
|
|
return new File( newPath, inChildFileName );
|
|
}
|
|
|
|
|
|
|
|
inline File *File::getParentDirectory() {
|
|
|
|
if( mPath != NULL ) {
|
|
|
|
char *parentName;
|
|
|
|
Path *parentPath;
|
|
|
|
if( strcmp( mName, ".." ) == 0 ) {
|
|
// already a parent dir reference
|
|
// append one more parent dir reference with parentName below
|
|
parentPath = mPath->append( ".." );
|
|
|
|
parentName = stringDuplicate( ".." );
|
|
}
|
|
else {
|
|
// not a parent dir reference, so we can truncate
|
|
parentPath = mPath->truncate();
|
|
|
|
parentName = mPath->getLastStep();
|
|
}
|
|
|
|
File *parentFile = new File( parentPath, parentName );
|
|
|
|
delete [] parentName;
|
|
|
|
return parentFile;
|
|
}
|
|
else {
|
|
if( Path::isRoot( mName ) ) {
|
|
// we are already at the root
|
|
return new File( NULL, mName );
|
|
}
|
|
else {
|
|
// append parent dir symbol to path
|
|
char **parentPathSteps = new char*[1];
|
|
parentPathSteps[0] = mName;
|
|
|
|
Path *parentPath = new Path( parentPathSteps, 1, false );
|
|
|
|
const char *parentName = "..";
|
|
|
|
File *parentFile = new File( parentPath, parentName );
|
|
|
|
delete [] parentPathSteps;
|
|
|
|
return parentFile;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
inline char File::exists() {
|
|
struct stat fileInfo;
|
|
|
|
// get full file name
|
|
int length;
|
|
char *stringName = getFullFileName( &length );
|
|
|
|
int statError = stat( stringName, &fileInfo );
|
|
|
|
delete [] stringName;
|
|
|
|
if( statError == 0 ) {
|
|
return true;
|
|
}
|
|
else {
|
|
// file does not exist
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
inline unsigned long File::getModificationTime() {
|
|
struct stat fileInfo;
|
|
|
|
// get full file name
|
|
int length;
|
|
char *stringName = getFullFileName( &length );
|
|
|
|
int statError = stat( stringName, &fileInfo );
|
|
|
|
delete [] stringName;
|
|
|
|
if( statError == 0 ) {
|
|
return fileInfo.st_mtime;
|
|
}
|
|
else {
|
|
// file does not exist
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
inline char File::remove() {
|
|
char returnVal = false;
|
|
|
|
if( exists() ) {
|
|
char *stringName = getFullFileName();
|
|
|
|
int error = ::remove( stringName );
|
|
|
|
if( error == 0 ) {
|
|
returnVal = true;
|
|
}
|
|
|
|
delete [] stringName;
|
|
}
|
|
|
|
return returnVal;
|
|
}
|
|
|
|
|
|
|
|
inline File *File::copy() {
|
|
Path *pathCopy = NULL;
|
|
|
|
if( mPath != NULL ) {
|
|
pathCopy = mPath->copy();
|
|
}
|
|
|
|
return new File( pathCopy, mName );
|
|
}
|
|
|
|
|
|
|
|
inline void File::copy( File *inDestination, long inBlockSize ) {
|
|
char *thisFileName = getFullFileName();
|
|
char *destinationFileName = inDestination->getFullFileName();
|
|
|
|
FILE *thisFile = fopen( thisFileName, "rb" );
|
|
FILE *destinationFile = fopen( destinationFileName, "wb" );
|
|
|
|
long length = getLength();
|
|
|
|
long bytesCopied = 0;
|
|
|
|
char *buffer = new char[ inBlockSize ];
|
|
|
|
while( bytesCopied < length ) {
|
|
|
|
long bytesToCopy = inBlockSize;
|
|
|
|
// end of file case
|
|
if( length - bytesCopied < bytesToCopy ) {
|
|
bytesToCopy = length - bytesCopied;
|
|
}
|
|
|
|
fread( buffer, 1, bytesToCopy, thisFile );
|
|
fwrite( buffer, 1, bytesToCopy, destinationFile );
|
|
|
|
bytesCopied += bytesToCopy;
|
|
}
|
|
|
|
fclose( thisFile );
|
|
fclose( destinationFile );
|
|
|
|
delete [] buffer;
|
|
delete [] thisFileName;
|
|
delete [] destinationFileName;
|
|
}
|
|
|
|
|
|
|
|
inline char *File::getFileName( int *outLength ) {
|
|
char *returnName = stringDuplicate( mName );
|
|
|
|
if( outLength != NULL ) {
|
|
*outLength = mNameLength;
|
|
}
|
|
|
|
return returnName;
|
|
}
|
|
|
|
|
|
|
|
inline char *File::getFullFileName( int *outLength ) {
|
|
int length = mNameLength;
|
|
|
|
int pathLength = 0;
|
|
char *path = NULL;
|
|
if( mPath != NULL ) {
|
|
path = mPath->getPathString( &pathLength );
|
|
|
|
length += pathLength;
|
|
}
|
|
|
|
// extra character for '\0' termination
|
|
char *returnString = new char[ length + 1 ];
|
|
|
|
if( path != NULL ) {
|
|
memcpy( returnString, path, pathLength );
|
|
memcpy( &( returnString[pathLength] ), mName, mNameLength );
|
|
|
|
delete [] path;
|
|
}
|
|
else {
|
|
// no path, so copy the name directly in
|
|
memcpy( returnString, mName, mNameLength );
|
|
}
|
|
|
|
// terminate the string
|
|
returnString[ length ] = '\0';
|
|
|
|
|
|
if( outLength != NULL ) {
|
|
*outLength = length;
|
|
}
|
|
|
|
return returnString;
|
|
}
|
|
|
|
|
|
|
|
#include "minorGems/io/file/FileInputStream.h"
|
|
#include "minorGems/io/file/FileOutputStream.h"
|
|
|
|
|
|
|
|
inline char *File::readFileContents() {
|
|
|
|
int length;
|
|
// text mode!
|
|
unsigned char *data = readFileContents( &length, true );
|
|
|
|
if( data == NULL ) {
|
|
return NULL;
|
|
}
|
|
|
|
char *dataString = new char[ length + 1 ];
|
|
|
|
memcpy( dataString, data, length );
|
|
dataString[ length ] = '\0';
|
|
|
|
delete [] data;
|
|
return dataString;
|
|
}
|
|
|
|
|
|
|
|
inline unsigned char *File::readFileContents( int *outLength,
|
|
char inTextMode ) {
|
|
|
|
if( exists() ) {
|
|
int length = getLength();
|
|
|
|
unsigned char *returnData = new unsigned char[ length ];
|
|
|
|
if( returnData != NULL ) {
|
|
FileInputStream *input = new FileInputStream( this, inTextMode );
|
|
int numRead = input->read( returnData, length );
|
|
|
|
delete input;
|
|
|
|
// in text mode, read length might not equal binary file length,
|
|
// due to line end conversion
|
|
if( numRead == length ||
|
|
( inTextMode && numRead >= 0 ) ) {
|
|
*outLength = numRead;
|
|
return returnData;
|
|
}
|
|
else {
|
|
delete [] returnData;
|
|
return NULL;
|
|
}
|
|
}
|
|
else {
|
|
// failed to allocate this much memory
|
|
return NULL;
|
|
}
|
|
}
|
|
else {
|
|
return NULL;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline char File::writeToFile( const char *inString ) {
|
|
return writeToFile( (unsigned char *)inString, strlen( inString ) );
|
|
}
|
|
|
|
|
|
|
|
inline char File::writeToFile( unsigned char *inData, int inLength ) {
|
|
FileOutputStream *output = new FileOutputStream( this );
|
|
|
|
long numWritten = output->write( inData, inLength );
|
|
|
|
delete output;
|
|
|
|
if( inLength == numWritten ) {
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "Directory.h"
|
|
|
|
|
|
|
|
inline char File::makeDirectory() {
|
|
if( exists() ) {
|
|
return false;
|
|
}
|
|
else {
|
|
return Directory::makeDirectory( this );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endif
|