Show MFile.cpp syntax highlighted
/**
**************************************************************************************
*Palisma - Secrets of the Illuminati is an open-source 2D RPG *
*Copyright (C) 2006, Tony Sparks *
* *
*This library is free software; you can redistribute it and/or *
*modify it under the terms of the GNU Lesser General Public *
*License as published by the Free Software Foundation; either *
*version 2.1 of the License, or (at your option) any later version. *
* *
*This library is distributed in the hope that it will be useful, *
*but WITHOUT ANY WARRANTY; without even the implied warranty of *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
*Lesser General Public License for more details. *
* *
*You should have received a copy of the GNU Lesser General Public *
*License along with this library; if not, write to the Free Software *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
**************************************************************************************
*/
#include "StdAfx.h"
#include "MFile.h"
#include "physfs.h"
#include <iostream>
#include <fstream>
// helper function
bool IsNumber( char c )
{
// a number
char nums[] = { '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9',
};
// search the array
for ( int i = 0; i < 10; i++ )
{
// if we have a match
// it is a number
if ( c == nums[i] )
return true;
}
return false;
}
/**
=========================================
Myriad File System
=========================================
*/
MFile::MFile(void)
{
m_position = 0;
m_data = NULL;
m_size = 0;
}
/** Open a file */
bool MFile::Open( const std::string &filename )
{
m_name = filename;
// file
std::ifstream file;
// open a stream to the file
file.open( filename.c_str(), std::ios::in );
m_opened = file.good();
if ( !m_opened )
return true;
// fetch the size
file.seekg(0, std::ios::end );
m_size = file.tellg();
file.seekg(0, std::ios::beg );
m_data = new char[ m_size ];
file.read( m_data, m_size);
return false;
}
/** Open a file in a zipped Archive */
bool MFile::OpenZippedFile( const std::string &file )
{
if ( PHYSFS_exists( file.c_str() ) )
{
m_name = file;
m_opened = true;
PHYSFS_file* phyFile = PHYSFS_openRead( file.c_str() );
m_size = PHYSFS_fileLength( phyFile );
m_data = new char[ m_size ];
PHYSFS_read (phyFile, m_data, 1 , m_size );
// close the file
PHYSFS_close( phyFile );
return false; // no errors
}
return true; // error
}
/** Close the stream */
void MFile::Close()
{
if ( m_opened ) {
delete m_data;
m_data = NULL;
m_opened = false;
}
}
/** Read the next line */
std::string MFile::ReadLine()
{
return ReadNext( "\n", false, false, false );
}
/** Read the next delimeter */
std::string MFile::ReadNext( const std::string &delim, bool ignoreReturn, bool ignoreWhiteSpace, bool ignoreTab )
{
// line to return
std::string line;
// next character in the stream
char c;
// number to delimeter length
int todelim = 0;
// first actual letter
bool firstLetterFound = false;
while( !IsEnd() )
{
// read in next char in stream
c = Read();
//if ( c == 0x0d ) continue;
if ( c == '\n' && ignoreReturn )
continue;
if ( c == '\t' && ignoreTab && !firstLetterFound)
continue;
if ( c == ' ' && ignoreWhiteSpace && !firstLetterFound )
continue;
firstLetterFound = true;
// append to our line
line += c;
// get the new length
size_t ndel = (line.length() - todelim);
// if we reached our delimeter, return the line
if ( delim.compare( 0, delim.length(), line, todelim, ndel ) == 0 )
return line.substr(0, todelim );
// else increment our delimeter length if we don't match our delimeter
else if ( delim.compare( 0, ndel, line.substr( todelim, ndel ) ) != 0)
todelim++;
}
return line;
}
/** Read a number */
std::string MFile::ReadNumber(bool decimal)
{
std::string number;
bool found = false;
bool first = true;
while( !IsEnd() )
{
char c = Read();
// check for negative sign
if ( first )
{
if ( c == '-' )
{
number += c;
first = false;
continue;
}
}
// skip a return statement or white space
if ( number.empty() && (c == '\n'|| c == 32||c == '\t' ) )
continue;
// add if it is a number
if ( IsNumber( c ) )
number += c;
// if we allow a decimal, make sure there
// is only one decimal
else if ( c == '.' && decimal && !found )
{
// decimal has been found
found = true;
// look at the next char to see if there is
// a number
if ( !IsEnd() && IsNumber( Peek() ) )
number += c;
else
return number;
} else
// return the number
return number;
}
return number;
}
/** Read the next number */
double MFile::ReadDouble()
{
std::string num = ReadNumber( true );
return atof( num.c_str() );
}
/** Read the next int */
int MFile::ReadInt()
{
std::string num = ReadNumber( false );
return atoi( num.c_str() );
}
/** Get a single byte */
int MFile::Read()
{
// will only be one in a sequence of NULL
// terminating... this is due to how
// PHYSFS handles NULL terminating strings
if ( m_data [ m_position ] == 0x0d )
{
if ( ! IsEnd() )
{
++m_position; // skip the null char
}
}
return m_data[ m_position++ ]; // update the pos
}
/** Peek at the next char in the stream */
char MFile::Peek()
{
return m_data[ m_position ];
}
/** End of File */
bool MFile::IsEnd()
{
return m_position >= m_size;
}
/** Set Data */
void MFile::SetData( char* buf, int size )
{
if ( m_data ) delete m_data;
m_data = buf;
m_size = size;
}
MFile::~MFile(void)
{
Close();
}
See more files for this project here