Skip to content

Commit ea6a868

Browse files
authored
feat(filesystem): Implement custom buffer options for File::open() (#1301)
Adds new LINEBUF and FULLBUF file flags and a buffer size argument for file open
1 parent 4e23a3e commit ea6a868

File tree

17 files changed

+81
-43
lines changed

17 files changed

+81
-43
lines changed

Core/GameEngine/Include/Common/FileSystem.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@
5050
// Includes
5151
//----------------------------------------------------------------------------
5252

53+
#include "Common/file.h"
5354
#include "Common/STLTypedefs.h"
5455
#include "Common/SubsystemInterface.h"
5556

5657
//----------------------------------------------------------------------------
5758
// Forward References
5859
//----------------------------------------------------------------------------
59-
class File;
6060

6161
//----------------------------------------------------------------------------
6262
// Type Defines
@@ -130,7 +130,7 @@ class FileSystem : public SubsystemInterface
130130
void reset();
131131
void update();
132132

133-
File* openFile( const Char *filename, Int access = 0 ); ///< opens a File interface to the specified file
133+
File* openFile( const Char *filename, Int access = File::NONE, size_t bufferSize = File::BUFFERSIZE ); ///< opens a File interface to the specified file
134134
Bool doesFileExist(const Char *filename) const; ///< returns TRUE if the file exists. filename should have no directory.
135135
void getFileListInDirectory(const AsciiString& directory, const AsciiString& searchName, FilenameList &filenameList, Bool searchSubdirectories) const; ///< search the given directory for files matching the searchName (egs. *.ini, *.rep). Possibly search subdirectories.
136136
Bool getFileInfo(const AsciiString& filename, FileInfo *fileInfo) const; ///< fills in the FileInfo struct for the file given. returns TRUE if successful.

Core/GameEngine/Include/Common/LocalFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class LocalFile : public File
9696
//virtual ~LocalFile();
9797

9898

99-
virtual Bool open( const Char *filename, Int access = 0 ); ///< Open a file for access
99+
virtual Bool open( const Char *filename, Int access = NONE, size_t bufferSize = BUFFERSIZE ); ///< Open a file for access
100100
virtual void close( void ); ///< Close the file
101101
virtual Int read( void *buffer, Int bytes ); ///< Read the specified number of bytes in to buffer: See File::read
102102
virtual Int write( const void *buffer, Int bytes ); ///< Write the specified number of bytes from the buffer: See File::write

Core/GameEngine/Include/Common/LocalFileSystem.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
#include "Common/SubsystemInterface.h"
3535
#include "FileSystem.h" // for typedefs, etc.
3636

37-
class File;
38-
3937
class LocalFileSystem : public SubsystemInterface
4038
{
4139
public:
@@ -45,7 +43,7 @@ class LocalFileSystem : public SubsystemInterface
4543
virtual void reset() = 0;
4644
virtual void update() = 0;
4745

48-
virtual File * openFile(const Char *filename, Int access = 0) = 0;
46+
virtual File * openFile(const Char *filename, Int access = File::NONE, size_t bufferSize = File::BUFFERSIZE) = 0;
4947
virtual Bool doesFileExist(const Char *filename) const = 0;
5048
virtual void getFileListInDirectory(const AsciiString& currentDirectory, const AsciiString& originalDirectory, const AsciiString& searchName, FilenameList &filenameList, Bool searchSubdirectories) const = 0; ///< search the given directory for files matching the searchName (egs. *.ini, *.rep). Possibly search subdirectories.
5149
virtual Bool getFileInfo(const AsciiString& filename, FileInfo *fileInfo) const = 0; ///< see FileSystem.h

Core/GameEngine/Include/Common/RAMFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class RAMFile : public File
8787
//virtual ~RAMFile();
8888

8989

90-
virtual Bool open( const Char *filename, Int access = 0 ); ///< Open a file for access
90+
virtual Bool open( const Char *filename, Int access = NONE, size_t bufferSize = 0 ); ///< Open a file for access
9191
virtual void close( void ); ///< Close the file
9292
virtual Int read( void *buffer, Int bytes ); ///< Read the specified number of bytes in to buffer: See File::read
9393
virtual Int write( const void *buffer, Int bytes ); ///< Write the specified number of bytes from the buffer: See File::write

Core/GameEngine/Include/Common/StreamingArchiveFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class StreamingArchiveFile : public RAMFile
8888
//virtual ~StreamingArchiveFile();
8989

9090

91-
virtual Bool open( const Char *filename, Int access = 0 ); ///< Open a file for access
91+
virtual Bool open( const Char *filename, Int access = NONE, size_t bufferSize = BUFFERSIZE ); ///< Open a file for access
9292
virtual void close( void ); ///< Close the file
9393
virtual Int read( void *buffer, Int bytes ); ///< Read the specified number of bytes in to buffer: See File::read
9494
virtual Int write( const void *buffer, Int bytes ); ///< Write the specified number of bytes from the buffer: See File::write

Core/GameEngine/Include/Common/file.h

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
*
7777
* All code should use the File class and not its derivatives, unless
7878
* absolutely necessary. Also FS::Open should be used to create File objects and open files.
79+
*
80+
* TheSuperHackers @feature Adds LINEBUF and FULLBUF modes and buffer size argument for file open.
7981
*/
8082
//===============================
8183

@@ -89,19 +91,28 @@ class File : public MemoryPoolObject
8991

9092
enum access
9193
{
92-
NONE = 0x00000000,
94+
NONE = 0x00000000, ///< Access file. Reading by default
95+
9396
READ = 0x00000001, ///< Access file for reading
9497
WRITE = 0x00000002, ///< Access file for writing
98+
READWRITE = (READ | WRITE),
99+
95100
APPEND = 0x00000004, ///< Seek to end of file on open
96101
CREATE = 0x00000008, ///< Create file if it does not exist
97102
TRUNCATE = 0x00000010, ///< Delete all data in file when opened
103+
104+
// NOTE: accesses file as text data if neither TEXT and BINARY are set
98105
TEXT = 0x00000020, ///< Access file as text data
99106
BINARY = 0x00000040, ///< Access file as binary data
100-
READWRITE = (READ | WRITE),
107+
101108
ONLYNEW = 0x00000080, ///< Only create file if it does not exist
102109

103110
// NOTE: STREAMING is Mutually exclusive with WRITE
104-
STREAMING = 0x00000100 ///< Do not read this file into a ram file, read it as requested.
111+
STREAMING = 0x00000100, ///< Do not read this file into a ram file, read it as requested.
112+
113+
// NOTE: accesses file with full buffering if neither LINEBUF and FULLBUF are set
114+
LINEBUF = 0x00000200, ///< Access file with line buffering
115+
FULLBUF = 0x00000400, ///< Access file with full buffering
105116
};
106117

107118
enum seekMode
@@ -111,6 +122,11 @@ class File : public MemoryPoolObject
111122
END ///< Seek position is relative from the end of the file
112123
};
113124

125+
enum
126+
{
127+
BUFFERSIZE = BUFSIZ,
128+
};
129+
114130
protected:
115131

116132
AsciiString m_nameStr; ///< Stores file name
@@ -128,20 +144,20 @@ class File : public MemoryPoolObject
128144

129145

130146
Bool eof();
131-
virtual Bool open( const Char *filename, Int access = 0 ); ///< Open a file for access
147+
virtual Bool open( const Char *filename, Int access = NONE, size_t bufferSize = BUFFERSIZE ); ///< Open a file for access
132148
virtual void close( void ); ///< Close the file !!! File object no longer valid after this call !!!
133149

134150
virtual Int read( void *buffer, Int bytes ) = NULL ; /**< Read the specified number of bytes from the file in to the
135151
* memory pointed at by buffer. Returns the number of bytes read.
136-
* Returns -1 if an error occured.
152+
* Returns -1 if an error occurred.
137153
*/
138154
virtual Int write( const void *buffer, Int bytes ) = NULL ; /**< Write the specified number of bytes from the
139155
* memory pointed at by buffer to the file. Returns the number of bytes written.
140-
* Returns -1 if an error occured.
156+
* Returns -1 if an error occurred.
141157
*/
142158
virtual Int seek( Int bytes, seekMode mode = CURRENT ) = NULL; /**< Sets the file position of the next read/write operation. Returns the new file
143159
* position as the number of bytes from the start of the file.
144-
* Returns -1 if an error occured.
160+
* Returns -1 if an error occurred.
145161
*
146162
* seekMode determines how the seek is done:
147163
*

Core/GameEngine/Source/Common/System/File.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ File::~File()
134134
*/
135135
//=================================================================
136136

137-
Bool File::open( const Char *filename, Int access )
137+
Bool File::open( const Char *filename, Int access, size_t bufferSize )
138138
{
139139
if( m_open )
140140
{
@@ -160,7 +160,7 @@ Bool File::open( const Char *filename, Int access )
160160
access |= READ;
161161
}
162162

163-
if ( !(access & (READ|APPEND)) )
163+
if ( (access & (READ|APPEND)) == 0 )
164164
{
165165
access |= TRUNCATE;
166166
}

Core/GameEngine/Source/Common/System/FileSystem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,14 @@ void FileSystem::reset( void )
171171
// FileSystem::open
172172
//============================================================================
173173

174-
File* FileSystem::openFile( const Char *filename, Int access )
174+
File* FileSystem::openFile( const Char *filename, Int access, size_t bufferSize )
175175
{
176176
USE_PERF_TIMER(FileSystem)
177177
File *file = NULL;
178178

179179
if ( TheLocalFileSystem != NULL )
180180
{
181-
file = TheLocalFileSystem->openFile( filename, access );
181+
file = TheLocalFileSystem->openFile( filename, access, bufferSize );
182182

183183
#if ENABLE_FILESYSTEM_EXISTENCE_CACHE
184184
if (file != NULL && (file->getAccess() & File::CREATE))

Core/GameEngine/Source/Common/System/LocalFile.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,14 @@ LocalFile::~LocalFile()
134134
// LocalFile::open
135135
//=================================================================
136136
/**
137-
* This function opens a file using the standard C open() call. Access flags
138-
* are mapped to the appropriate open flags. Returns true if file was opened
139-
* successfully.
137+
* This function opens a file using the standard C open() or
138+
* fopen() call. Access flags are mapped to the appropriate flags.
139+
* Returns true if file was opened successfully.
140140
*/
141141
//=================================================================
142142

143143
//DECLARE_PERF_TIMER(LocalFile)
144-
Bool LocalFile::open( const Char *filename, Int access )
144+
Bool LocalFile::open( const Char *filename, Int access, size_t bufferSize )
145145
{
146146
//USE_PERF_TIMER(LocalFile)
147147
if( !File::open( filename, access) )
@@ -171,7 +171,6 @@ Bool LocalFile::open( const Char *filename, Int access )
171171

172172
// Mode string selection (mimics _open flag combinations)
173173
// TEXT is implicit for fopen if 'b' is not present
174-
// READ is implicit here if not READWRITE or WRITE
175174
if (readwrite)
176175
{
177176
if (append)
@@ -199,6 +198,26 @@ Bool LocalFile::open( const Char *filename, Int access )
199198
goto error;
200199
}
201200

201+
{
202+
Int result = 0;
203+
204+
if (bufferSize == 0)
205+
{
206+
result = setvbuf(m_file, NULL, _IONBF, 0); // Uses no buffering
207+
}
208+
else
209+
{
210+
const Int bufferMode = (m_access & LINEBUF)
211+
? _IOLBF // Uses line buffering
212+
: _IOFBF; // Uses full buffering
213+
214+
// Buffer is expected to lazy allocate on first read or write later
215+
result = setvbuf(m_file, NULL, bufferMode, bufferSize);
216+
}
217+
218+
DEBUG_ASSERTCRASH(result == 0, ("LocalFile::open - setvbuf failed"));
219+
}
220+
202221
#else
203222

204223
int flags = 0;

Core/GameEngine/Source/Common/System/RAMFile.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,17 +133,20 @@ RAMFile::~RAMFile()
133133
// RAMFile::open
134134
//=================================================================
135135
/**
136-
* This function opens a file using the standard C open() call. Access flags
137-
* are mapped to the appropriate open flags. Returns true if file was opened
138-
* successfully.
136+
* This function opens a file using the standard C open() or
137+
* fopen() call. Access flags are mapped to the appropriate flags.
138+
* Returns true if file was opened successfully.
139139
*/
140140
//=================================================================
141141

142142
//DECLARE_PERF_TIMER(RAMFile)
143-
Bool RAMFile::open( const Char *filename, Int access )
143+
Bool RAMFile::open( const Char *filename, Int access, size_t bufferSize )
144144
{
145145
//USE_PERF_TIMER(RAMFile)
146-
File *file = TheFileSystem->openFile( filename, access );
146+
147+
bufferSize = 0; // RAM File needs no file buffer because it is read in one go.
148+
149+
File *file = TheFileSystem->openFile( filename, access, bufferSize );
147150

148151
if ( file == NULL )
149152
{
@@ -169,7 +172,7 @@ Bool RAMFile::open( File *file )
169172
return NULL;
170173
}
171174

172-
Int access = file->getAccess();
175+
const Int access = file->getAccess();
173176

174177
if ( !File::open( file->getName(), access ))
175178
{

0 commit comments

Comments
 (0)