Source: include/hp49calc.H
|
|
|
|
/* -------------------------------------------------------------------------
hp49.H - HP49 Calculator Specific Classes and Functions
-------------------------------------------------------------------------
Copyright (C) 2000-2001 Eric R. Schendel
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
------------------------------------------------------------------------- */
#ifndef HP49_H
#define HP49_H
#include<string>
#include<fstream>
#include "status.H"
namespace Hp49Calc {
using namespace StatusMsgs;
const long HPF_ERR_FILE_SIZE = -1;
const unsigned long HPF_DEFAULT_FILE_SIZE = (unsigned long) - 1;
const char HPF_HEADER[] = "HPHP49-X";
const char HPF_HEADER_REPLACE = 'X';
const int HPF_HEADER_SIZE = 8;
const unsigned long HPF_TYPE_STRING = 0x02A2C;
enum HpFileType {HPF_UNDEFINED = 0, HPF_STRING = 1, HPF_UNKNOWN = 2};
const unsigned short HPCRC_SEED = 0x1081;
/**
* This is an abstract base class for all Hp49 files.
* All classes which inherit this one must have an open() method.
*/
class Hp49File {
public:
/**
* Constructor must be supplied with a file name
*
* @param name File name
* @param lvl Log level
*/
Hp49File(string name, LogLevel lvl = NONE);
virtual ~Hp49File();
virtual Error open() = 0;
virtual Error close();
/**
* For any reading or writing file activity, a stream must be created.
*
* @param mode same modes which would be passed to a fstream.open(...)
*/
Error createStream(int mode);
fstream& getStream() { return fs; }
string getName() const { return fname; }
HpFileType getType() const { return type; }
/**
* This is the size of the data portion of the Hp49 file. I know this
* works properly for Hp49 string files but I have not tested it out with
* any other other types of files, so I do not know if this is consistant
* through out. Also the data part is the portion of bytes at the end of
* the file, but this might change in the future.
*/
unsigned long getDataSize() const;
protected:
void setType(HpFileType t) { type = t; }
void setDataSize(unsigned long s) { size = s; }
private:
Log log;
fstream fs;
string fname;
HpFileType type;
long size;
Hp49File();
};
class Hp49FileRead: public Hp49File {
public:
/**
* Constructor must be supplied with a file name
*
* @param name File name
* @param lvl Log level
*/
Hp49FileRead(string name, LogLevel lvl = NONE);
/**
* Checks to see if the file is a valid Hp49 file.
*
* @return Error: SUCCESS, MINOR (not valid Hp49 File), MAJOR (unable
* to physically read file).
*/
Error check();
Error open();
/**
* Trying to read past the end of file will be considered as an
* error, especially since the data size of a file can be known
* before hand.
*/
bool readNibble(unsigned char&);
/**
* Basically two calls to readNibble
*/
bool readByte(unsigned char&);
/**
* Reads nibbles from file to be recognized as a long integer.
* Therefore the first read nibble is the least significant and
* the last is the most significant.
*
* @param n returned result of nibbles read
* @param c_sz number of nibbles to read
*/
Error readNibbles(unsigned long& n, const int c_sz);
/**
* Reads straight from the file, byte by byte, and places it in
* a string.
*
* @param str returned result of bytes read
* @param sz number of bytes to read
*/
Error readBytes(string&, const int sz);
/**
* Reads specified number of bytes of data from Hp49 file. After file is
* read, pointer wil not be reseted and will not go beyond end-of-file.
* This helps to have multiple reads for large files.
*
* @param data String to store data into
* @param size Number of bytes to read. Default is all bytes
*/
Error readData(string& data, unsigned long size = HPF_DEFAULT_FILE_SIZE);
private:
Log log;
bool second_nib;
char buffered_byte;
Error process_header();
Error get_file_type();
Error get_data_size();
};
class Hp49FileWrite: public Hp49File {
public:
/**
* Constructor must be supplied with a file name
*
* @param name File name
* @param lvl Log level
*/
Hp49FileWrite(string name, LogLevel lvl = NONE);
~Hp49FileWrite();
/**
* The only supported file type to write to is a Hp49 String file,
* therefore, open() defaults to openString(). The way this is handled
* might change in the future.
*/
Error open() { return openString(); }
Error openString();
/**
* Very important that this is called or data bytes might be missing.
*/
Error close();
bool writeNibble(unsigned char&);
bool writeByte(unsigned char&);
/**
* Writes specified number of nibbles from long integer to a Hp49 file.
* Therefore the first written nibble is the least significant and
* the last is the most significant.
*
* @param n returned result of nibbles read
* @param c_sz number of nibbles to read
*/
Error writeNibbles(unsigned long n, const int c_sz);
Error writeBytes(string);
/**
* Writes specified string of bytes of data to Hp49 file. This method
* lacks the function to handle multiple writes! In an attempt to append
* data will corrupt the Hp49 binary file. This will be fixed if I become
* bored or find a real reason for it.
*
* @param data String to store data into.
*/
Error writeData(string data);
private:
Log log;
bool first_nib;
char buffered_nib;
Error create_header();
Error set_string_type();
Error set_data_size(unsigned long&);
};
class HpCRC {
public:
HpCRC(LogLevel = NONE);
unsigned short calculate(string data);
unsigned char low() { return crc & 0xFF; }
unsigned char high() { return (crc >> 8) & 0xFF; }
operator unsigned short() const { return crc; }
private:
Log log;
unsigned short crc;
};
} //namespace Hp49Calc //
#endif
Generated on Fri Mar 9 02:04:42 2001, using kdoc 2.0a43. |