You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

262 lines
5.3 KiB

#include "HeadSpin.h"
#include "pfTextFile.h"
#include <stdio.h>
#include <ctype.h>
//-----------------------------------------------------------------------------
namespace dev
{
class TextFile::TextFileImpl
{
public:
TextFile::ErrorType err;
int line;
explicit TextFileImpl( const char* filename )
{
err = TextFile::ERROR_NONE;
line = 1;
m_peeked = false;
m_peekedChar = 0;
m_file = fopen( filename, "rt" );
if ( !m_file )
err = TextFile::ERROR_OPEN;
}
~TextFileImpl()
{
if ( m_file )
{
fclose( m_file );
m_file = 0;
}
}
bool eof() const
{
if ( err )
return true;
return 0 != feof(m_file);
}
bool peekChar( char* ch )
{
if ( err )
return false;
if ( !m_peeked )
{
int c = getc( m_file );
if ( EOF != c )
{
m_peeked = true;
m_peekedChar = (char)c;
}
else
{
if ( ferror(m_file) )
err = TextFile::ERROR_READ;
}
}
if ( m_peeked )
*ch = m_peekedChar;
return m_peeked;
}
bool readChar( char* ch )
{
if ( err )
return false;
bool more = peekChar( ch );
m_peeked = false;
if ( more && *ch == '\n' )
++line;
return more;
}
bool skipWhitespace()
{
if ( err )
return false;
char ch;
while ( peekChar(&ch) )
{
if ( !isspace(ch) )
break;
readChar( &ch );
}
return !eof();
}
bool readString( char* buf, int size )
{
if ( err )
return false;
skipWhitespace();
int count = 0;
char ch;
while ( peekChar(&ch) )
{
if ( isspace(ch) )
break;
if ( count+1 < size )
buf[count++] = ch;
readChar( &ch );
}
if ( size > 0 )
buf[count] = 0;
return count > 0;
}
void skipLine()
{
if ( err )
return;
char ch;
while ( readChar(&ch) )
{
if ( ch == '\n' )
break;
}
}
long readHex()
{
if ( err )
return 0;
skipWhitespace();
// hex must start with alphanumeric character
char ch;
if ( !peekChar(&ch) || !isalnum(ch) )
{
err = TextFile::ERROR_PARSE;
return 0;
}
long x = 0;
while ( peekChar(&ch) )
{
switch ( ch )
{
case '0': x <<= 4; x += 0; break;
case '1': x <<= 4; x += 1; break;
case '2': x <<= 4; x += 2; break;
case '3': x <<= 4; x += 3; break;
case '4': x <<= 4; x += 4; break;
case '5': x <<= 4; x += 5; break;
case '6': x <<= 4; x += 6; break;
case '7': x <<= 4; x += 7; break;
case '8': x <<= 4; x += 8; break;
case '9': x <<= 4; x += 9; break;
case 'a':
case 'A': x <<= 4; x += 0xA; break;
case 'b':
case 'B': x <<= 4; x += 0xB; break;
case 'c':
case 'C': x <<= 4; x += 0xC; break;
case 'd':
case 'D': x <<= 4; x += 0xD; break;
case 'e':
case 'E': x <<= 4; x += 0xE; break;
case 'f':
case 'F': x <<= 4; x += 0xF; break;
default: return x;
}
readChar( &ch );
}
return x;
}
private:
bool m_peeked;
char m_peekedChar;
FILE* m_file;
TextFileImpl( const TextFileImpl& );
TextFileImpl& operator=( const TextFileImpl& );
};
//-----------------------------------------------------------------------------
TextFile::TextFile( const char* filename )
{
m_this = TRACKED_NEW TextFileImpl( filename );
}
TextFile::~TextFile()
{
delete m_this;
}
bool TextFile::readString( char* buf, int size )
{
return m_this->readString( buf, size );
}
void TextFile::skipLine()
{
m_this->skipLine();
}
long TextFile::readHex()
{
return m_this->readHex();
}
bool TextFile::skipWhitespace()
{
return m_this->skipWhitespace();
}
TextFile::ErrorType TextFile::error() const
{
return m_this->err;
}
bool TextFile::readChar( char* ch )
{
return m_this->readChar( ch );
}
bool TextFile::peekChar( char* ch )
{
return m_this->peekChar( ch );
}
bool TextFile::eof() const
{
return m_this->eof();
}
int TextFile::line() const
{
return m_this->line;
}
} // dev
/*
* Copyright (c) 2001 Jani Kajala
*
* Permission to use, copy, modify, distribute and sell this
* software and its documentation for any purpose is hereby
* granted without fee, provided that the above copyright notice
* appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation.
* Jani Kajala makes no representations about the suitability
* of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/