ebmDevMag.com home
ebm Developer's Magazine
links

developer's mag
main page

article
part 1
part 2
part 3
part 4
part 5
part 6


5 - File I/O, With Class

Enough theory, now on to the code - this column's example program contains a file object that wraps many of the details of access (example 3 program files zipped). The program itself lets you test the functions with button presses, and displays file status. It'll even let you do naughty things like writing to a file opened read-only, or reading a closed file, so you can see what a failure looks like! I urge you to look at the code and walk around it in the debugger, and watch the results of different actions; it'll show you how to incorporate the class into your program, and how to use the low-level calls as well.

To get familiar with the class, let's review some of the main functions, starting with the constructor:

CPaFile::CPaFile(const ebo_name_t*info)
: m_ptr(0), m_size(0), m_maxSize(0),
m_open(false), m_readWrite(false), m_newFile(false)
{
memcpy(&m_fileInfo,info,sizeof(ebo_name_t));// keep our own copy
m_maxSize=ebo_roundup(8000000UL); // set aside more than enough space
m_ptr=(BYTE*)ebo_roundup(OS_availaddr); // align on 4k boundary beyond last mem. addr. used
OS_availaddr=(U32)m_ptr+m_maxSize; // protect mem. by adjusting avail. mem. pointer }

We first initialize the bookkeeping variables, and then create a copy of the file description. Following that, we set aside memory for the file, create our pointer for the mapping, and then mark the memory in use by adjusting OS_availaddr.

Open() first tries to open the file via ebo_mapin(), and if that fails, uses ebo_new() to try to create a new file. The result is an open file, or failure and a false value returned by Open().

bool CPaFile::Open(bool readAndWrite)
{
if (m_open)
Close(); // we can't work on open (mapped) files!
m_newFile=false;
size_t size=m_maxSize;
m_readWrite=readAndWrite;
if (0>ebo_mapin(&m_fileInfo,0,m_ptr,&size,readAndWrite))
{
if ( 0>ebo_new(&m_fileInfo,EBO_BLK_SIZE,1)) // failed-try to create new file
return false; // failed to new - catastrophic error
m_newFile=true; // let everyone know we just created this file
if ( 0>ebo_mapin(&m_fileInfo,0,m_ptr,&size,readAndWrite) ) // map in new file
return false; // failed again!
}
// at this point, we have a valid file mapped in
m_size=size;
m_open=true;
return true;
}

Resize() takes care of file adjustment. The function checks if the new and old sizes are different after rounding with ebo_roundup(), and if so, adjusts accordingly:

bool CPaFile::Resize(unsigned int newSize)
{
newSize=ebo_roundup(newSize); // make sure even 4k blocks
if (newSize==m_size) // if we don't need to expand or contract, quit now
return true;
bool oldFlag=m_open, readWrite=m_readWrite; // save for later
if (m_open)
Close(); // can't work on mapped file
bool failure=true;
if (newSize<m_size)
{
if (0<=ebo_contract(&m_fileInfo,newSize)) // success?
{
m_size=newSize;
failure=false;
}
}
else
{
if (0<=ebo_extend(&m_fileInfo,newSize)) // success?
{
m_size=newSize;
failure=false;
}
}
if (oldFlag) // open again if was previously opened, and no failure
failure = failure || ( !Open(readWrite) ); // keep flag after opening
return !failure;
}


Previous Section
Next Section

Copyright © 2001-2006 ebmDevMag.com - Legal Notice