EAFileBase

Introduction

EAFileBase provides basic typedefs and enumerations that the EAFile system uses. Some of these are platform-specific definitions while others are simply generic definitions used by EAFile.

Most of this document is simply an echo of what's in EAFileBase.h, but we'll add some additional comments where useful.

Fundamental Typedefs

All the file IO APIs use the size_type and off_type typedefs. These typedefs are used because file systems on different platforms have different file IO APIs, some of which are 32 bit and some of which are 64 bit, and this bit depth is not always the same as the size of pointers or registers on the given platform. For example, the Win32 API has support for 64 bit file IO.

/// Unsigned type used to denote data position values.
typedef <platform specific> size_type;

/// Unsigned type used to denote data position offsets.
/// sizeof(off_type) == sizeof(size_type)
typedef <platform specific> off_type;

/// Used to designate an error condition for many functions that return size_type.
const size_type kSizeTypeError = (size_type)-1;

/// Used to designtate a nul-terminated string or similarly terminated entity. const size_type kLengthNull = (size_type)-1;

File Attributes

File attributes are boolean properties assigned to files and directories. The Attribute enumeration is used in file manipulation APIs found in EAFileUtil.

enum Attribute
{
kAttributeNone = 0x00, /// No attribute in particular.
kAttributeReadable = 0x01, /// The entity is readable. For multi-user systems, this refers to the current user.
kAttributeWritable = 0x02, /// The entity is writable. For multi-user systems, this refers to the current user.
kAttributeExecutable = 0x04, /// The entity is executable. For multi-user systems, this refers to the current user.
kAttributeDirectory = 0x08, /// The entity is a directory, as opposed to being a file.
kAttributeAlias = 0x10, /// The entity is an alias (a.k.a. "symbolic link", or "shortcut").
kAttributeArchive = 0x20, /// The entity has the archive attribute set.
kAttributeHidden = 0x40, /// The entity is hidden. This is somewhat Microsoft-specific.
kAttributeSystem = 0x80 /// The entity is a system file. This is somewhat Microsoft-specific.
};

Directory Entry Types

DirectoryEntry is an enumeration that defines things that might exist in a directory, such as files and (sub)directories. This enumeration is used in functions such as the directory iteration functions found in EAFileDirectory. DirectoryEntry values are powers of two so that they may also be used as flags.

enum DirectoryEntry
{
kDirectoryEntryNone = 0x00, /// No type in particular.
kDirectoryEntryDirectory = 0x01, /// Refers to a directory.
kDirectoryEntryFile = 0x02, /// Refers to a file.
kDirectoryEntryCurrent = 0x04, /// Refers to the "current" directory ("."). kDirectoryEntryParent = 0x08, /// Refers to the "parent" directory ("..") of the current directory.
kDirectoryEntryAll = 0xff /// This is a flag that refers to all types of file system entries.
};

File Time Types

Desktop and server operating systems keep track of file modification times, and tools and even games for those platforms can make use of this information. The FileTimeType enumeration defines basic types of file times for use in API functions that query modify file time information. Some of these functions are found in EAFileUtil.

enum FileTimeType
{
kFileTimeTypeNone = 0x00, /// No time in particular.
kFileTimeTypeCreation = 0x01, /// The time the file was created.
kFileTimeTypeLastModification = 0x02, /// The time the file was last modified.
kFileTimeTypeLastAccess = 0x04 /// The time the file was last opened.
};

File System

A file system has intrinsic attributes that relate to its organization and limitations. An well-known example of this is the FAT file system's file name limitation to "8.3" names. Other attributes include the file system's character set and encoding, maximum file count per directory, maximum file size, and maximum file system size. There are a few APIs in EAFileUtil that use this enumeration, but its use is not mandatory; most of the time users don't have to worry about the file system in use.

enum FileSystem
{
kFileSystemNone, /// No file system in particular. kFileSystemFAT, /// File Allocation Table. Single byte path names.
kFileSystemFAT32, /// 32 bit extentsion of FAT. Single byte and UCS2 Unicode path names.
kFileSystemNTFS, /// Windows NT File System. UCS2 Unicode path names.
kFileSystemUnix, /// Unix family of file systems. UTF8 Unicode path names.
kFileSystemISO9660, /// Basic CD file system, 31 character single byte path component names.
kFileSystemJoliet, /// An extension of ISO9660 which supports UCS2 Unicode in path component names.
kFileSystemUDF, /// Universal Disk Format, used by modern CD and DVD systems. UTF8 or UCS2 Unicode.
kFileSystemDefault /// The default file system used by the given platform. };

Drive Types

We provide a basic enumeration of drive types found on platforms of interest.

enum DriveType                 
{
kDriveTypeUnknown, /// Unknown drive type.
kDriveTypeFixed, /// Fixed (normally internal) drives. FireWire and USB drives are considered 'fixed' drives.
kDriveTypeCD, /// Includes generic compact discs (CDs).
kDriveTypeDVD, /// Includes generic DVD discs. Similar to CDs but can store more data.
kDriveTypeMemoryCard, /// Console memory cards as drives.
kDriveTypeRAM, /// A RAM disk is a virtual disk drive whose storage is implemented via RAM memory.
kDriveTypeRemovable, /// Generic removable drive. This encompasses removable drives not specifically enumerated.
kDriveTypeRemote /// Remote (normally network) drive.
};

Special Directories

Desktop operating systems have the concept of specially designated directory locations. Windows users are familiar with the concept of the "My Documents" directory which differs on a per-user basis. It turns out that there are additional special directories that a properly written Windows application or installer must recognize. The Macintosh and Unix operating systems have a similar concept, and some console machines (e.g. XBox 360) have a little bit of this functionality as well. We have the SpecialDirectory enum and have functions which look up these directories in EAFileUtil.

enum SpecialDirectory
{
kSpecialDirectoryNone, /// No directory in particular
kSpecialDirectoryTemp, /// Windows example: "C:\WinNT\Temp\"
kSpecialDirectoryOperatingSystem, /// Windows example: "C:\WinNT\"
kSpecialDirectoryOperatingSystemTrash, /// Windows example: "Recycle Bin"
kSpecialDirectoryOperatingSystemFonts, /// Windows example: "C:\WinNT\Fonts\"
kSpecialDirectoryCurrentApplication, /// Windows example: "C:\Program Files\Some App\"
kSpecialDirectoryUserDesktop, /// Windows example: "C:\Documents and Settings\<username>\Desktop\"
kSpecialDirectoryCommonDesktop, /// Windows example: "C:\Documents and Settings\All Users\Desktop\"
kSpecialDirectoryUserApplicationData, /// Windows example: "C:\Documents and Settings\<username>\Application Data\"
kSpecialDirectoryCommonApplicationData, /// Windows example: "C:\Documents and Settings\All Users\Application Data\"
kSpecialDirectoryUserDocuments, /// Windows example: "C:\Documents and Settings\<username>\My Documents\"
kSpecialDirectoryCommonDocuments, /// Windows example: "C:\Documents and Settings\All Users\Documents\"
kSpecialDirectoryUserMusic, /// Windows example: "C:\Documents and Settings\<username>\My Documents\My Music\"
kSpecialDirectoryCommonMusic, /// Windows example: "C:\Documents and Settings\All Users\Documents\My Music\"
kSpecialDirectoryUserProgramsShortcuts, /// Windows example: "C:\Documents and Settings\<username>\Start Menu\Programs\"
kSpecialDirectoryCommonProgramsShortcuts /// Windows example: "C:\Documents and Settings\All Users\Start Menu\Programs\"
};

Path Components

The file and directory path manipulation functions in EAFilePath

enum PathComponent
{
kPathComponentNone = 0x00, /// No component in particular.
kPathComponentDrive = 0x01, /// Also known as volume.
kPathComponentDirectory = 0x02, /// Defines a directory.
kPathComponentDirectoryAlone = 0x04, /// Same as kPathComponentDirectory except ... (see EAFileBase.h)
kPathComponentFile = 0x08, /// Defines a file name.
kPathComponentFileAlone = 0x10, /// Same as kPathComponentFile except ... (see EAFileBase.h)
kPathComponentFileExtension = 0x20 /// Defines a file name extension alone.
};

A drive is any prefix characters in the path up to but not including the first directory separator. Thus in the path "c:\a\b\c" the drive is "c:". The UTF file system treats drives and volumes equivalently. Thus in the UNC path "\\server\a\b\c" the drive is "\\server".

A directory is the string of characters from the beginning of the path (including an initial drive) up to the last path separator before a file name. If no file name is present, the path is a directory path and ends with a path separator. If no path separator was specified at the end of a directory path, it would be ambiguous as to whether the path referred to a file or a directory. A directory that refers to only the characters after the drive/volume is referred to as the 'directory name alone', as with kPathComponentDirectoryAlone.

A file is the string of all characters after the last directory separator in a path string, including any characters after a dot ('.'). A file name that refers to only the characters before the dot (i.e. extension) is referred to as the 'file name alone', as with kPathComponentFileAlone.

A file extension is defined as the last dot ('.') and anything after it in the file name. If no dot chars are present, there is no extension. If multiple dots are present, the extension is the text from the last dot onward. If there is nothing after the dot, the extension is simply ".".

Path Properties

File paths are represented by strings and more or less have a layout format. However, this format differs between platforms. Here are some examples of how they differ between platforms, by example:

Platform Example file paths
Windows

C:\Program Files\Chess\data\game.pak
\\SomeUNCName\Chess\data\game.pak

Unix /usr/local/bin/Chess/game.pak
XBox 360 d:\Chess\data\game.pak
dvd:\Chess\data\game.pak
PS3 /dvd/Chess/data/game.pak

Here are the path properties defined by EAFileBase for the Windows platform. Other platforms will have the same properties but possibly different values.

// Here is the Windows version of path properties; other platforms may differ.
 
const char16_t        kFilePathSeparator16              = '\\';
const char16_t* const kFilePathSeparatorString16 = L"\\"; const char16_t kFilePathSeparatorAlt16 = '/';
const char16_t* const kFilePathSeparatorAltString16 = L"/"; const char16_t kFilePathDriveSeparator16 = ':'; const char16_t* const kFilePathDriveSeparatorString16 = L":"; const char kFilePathSeparator8 = '\\';
const char* const kFilePathSeparatorString8 = "\\";
const char kFilePathSeparatorAlt8 = '/';
const char* const kFilePathSeparatorAltString8 = "/";
const char kFilePathDriveSeparator8 = ':';
const char* const kFilePathDriveSeparatorString8 = ":"; const int kMaxPathLength = 260; const int kMaxDriveLength = 256; const int kMaxDirectoryLength = 256;
const int kMaxFileNameLength = 256; const int kMaxDirectoryNameLength = 256; const int kMaxExtensionLength = 256; const int kMaxVolumeNameLength = 128; const int kMaxVolumeSerialNumberLength = 128; // Utility function for portably testing if a character is a path separator. inline bool IsFilePathSeparator(int c){ ... }

Line Termination

Plain text files use "\n" or "\r\n" to mark the endings of lines. Which is used tends to depend on the platform, with Windows using "\r\n" and just about all other platforms using simply "\n". It turns out that even Windows appears to be migrating towards "\n", as most software written for Windows now recognizes "\n" as a line delimiter. EAFile provides definitions for line delimiters and EAFile functions which read lines accept both forms of line termination.

Here are the definitions that EAFileBase provides:

#define EA_LINEEND_WINDOWS_8   "\r\n"
#define EA_LINEEND_WINDOWS_16 L"\r\n" #define EA_LINEEND_UNIX_8 "\n" #define EA_LINEEND_UNIX_16 L"\n" #define EA_LINEEND_NATIVE_8 <platform specific>
#define EA_LINEEND_NATIVE_16 <platform specific>