April 26, 2024, 09:54:32 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


FileReader class

Started by Parker, September 21, 2006, 09:11:28 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Parker

This class reads files in chunks of 1024 bytes, so I think it's fairly fast (please let me know if it's not). It was originally a C++ class created for a lexer to read pieces of files without reading the whole file at a time or one character, therefore there is a lookahead() method to peek ahead of where you are currently.

Note the private: and public: specifiers will mean something in the next update, but they don't affect the file right now as long as there is nothing else (not even whitespace) on that line.

The include file:
#ifndef _FILEREADER_INC_
#define _FILEREADER_INC_

class FileReader
{
private:
dstring buf1[1024];
dstring buf2[1024];
unsigned int pos;
unsigned int flen;
unsigned int file;

declare updateBuffers( );
public:
//declare FileReader( string *name ); - this not supported yet
declare FileReader( );
declare _FileReader( );

declare loadFile( string *name ),int;
declare closeFile( );
declare readChar( ),int;
declare currChar( ),int;
declare lookahead( int where ),int;
declare isOkay( ),int;
}

#endif // _FILEREADER_INC_


The implementation:
#include "filereader.inc"

declare cdecl extern memcpy( void *dest, void *src, int bytes );
declare cdecl extern memset( void *dest, int value, int bytes );

FileReader::updateBuffers( )
{
memcpy( buf1, buf2, 1024 );
memset( buf2, 0, 1024 );
read( file, buf2, 1023 );
}

FileReader::FileReader( )
{
file = 0;
}

FileReader::_FileReader( )
{
if( file ) ::closefile( file );
}

FileReader::loadFile( string *name )
{
if( file ) ::closefile( file );

file = openfile( *name, MODE_READ );
if( !file ) return 0;
flen = getfilelength( file );

memset( buf2, 0, 1024 );
read( file, buf2, 1023 );

pos = 0;

updateBuffers( );
return 1;
}

FileReader::closeFile( )
{
::closefile( file );
}

FileReader::readChar( )
{
if( buf1[pos] != 0 )
{
// can increment
pos++;
return buf1[pos-1];
}
else
{
if( pos < 1023 )
{
return 0;
}
else
{
updateBuffers( );
pos = 1;
return buf1[0];
}
}
}

FileReader::currChar( )
{
return buf1[pos];
}

FileReader::lookahead( int where )
{
int place = where + pos;

// lookahead( 0 ) is the same as currChar( ).
if( place < 1023 )
return buf1[place];
// else - not needed since IF w/ return above.

place -= 1023;
if( place < 1023 )
return buf2[place];
// else - again not needed since IF w/ return.

return 0; // Error - can't look that far ahead.
}

FileReader::isOkay( )
{
return file != 0;
}


Example usage (assumes the file is in the projects directory of your Aurora installation):
#include "filereader.inc"

global sub main( )
{
FileReader fr;
fr.loadFile( "..\\bin\\gui.inc" );
dstring ch[2];
ch[1] = 0;
do
{
ch[0] = fr.readChar( );
print( ch, );
} until ch[0] == 0;
// fr falls out of scope, destructor is called, file is closed.
}

Haim

Neat!

I am still not up to speed with OOPS, and trying to learn from every  example on the forum.
I would appreciate an explanation as to the usage of  "::Closefile()" in the destructor.

FileReader::_FileReader( )
{
   if( file ) ::closefile( file );
}

Why is the double colon required in this place?
Why can't you just call the class method and be done?     " if( file ) closefile( file );   "

Haim

Ionic Wind Support Team

It's called name resolution.

::closefile calls the API function whereas closefile would call the class method.  Parker chose to name the method the same as the windows API function.  The :: tells the compiler what to use.  Look at the closefile method if I were to remove the double colons:


FileReader::closeFile( )
{
closefile( file );
}

That would be an endless loop as default scope is the class method. 
Ionic Wind Support Team

Haim


Kale

Quote from: Paul Turley on September 22, 2006, 12:08:53 AM
It's called name resolution.

::closefile calls the API function whereas closefile would call the class method.ÂÃ,  Parker chose to name the method the same as the windows API function.ÂÃ,  The :: tells the compiler what to use.ÂÃ,  Look at the closefile method if I were to remove the double colons:


FileReader::closeFile( )
{
closefile( file );
}

That would be an endless loop as default scope is the class method.ÂÃ, 

What API? Where is the API 'closeFile( )' command imported?

Zen

Good point. Its called but not imported.

I am assuming Parker has included the headers himself but not put that in the above code.

Lewis

Parker

It's a translation from C; originally I had used fopen, fread, etc but I changed that in the Aurora version. CLOSEFILE is a function in fileio.inc in the bin directory, as are OPENFILE, GETFILELENGTH, and READ. They internally call the windows API, but those declares aren't needed in my code. The only ones needed are the C functions memcpy and memset, and those are already declared. When Paul said "API function", he wasn't refering to the Windows API, but instead the Aurora API.

Ionic Wind Support Team

Sorry I meant the Aurora function CloseFile.  Samep principle applies.
Ionic Wind Support Team