//
// srecord - manipulate eprom load files
// Copyright (C) 1998-2003, 2005-2007 Peter Miller
//
// 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 3 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, see
// .
//
#ifndef INCLUDE_SREC_OUTPUT_FILE_H
#define INCLUDE_SREC_OUTPUT_FILE_H
#include
#include
#include
/**
* The srec_output_file class is used to represent a generic output file.
* It provides a numnber of services useful to many output file formats.
*/
class srec_output_file:
public srec_output
{
public:
/**
* The default constructor.
* Output will be sent to the standard output.
*/
srec_output_file();
/**
* The constructor. The output will be sent to the named file (or
* the standard output if the file name is "-").
*
* @param file_name
* The name of the file to be written.
*/
srec_output_file(const std::string &file_name);
/**
* The destructor.
*/
virtual ~srec_output_file();
// See base class for documentation.
virtual const std::string filename() const;
/**
* Call this method if you want the output to contain only data
* records. No header records or start address records (or any
* other records) will be emitted.
*/
static void data_only();
/**
* The crlf method is used to force CRLF line termination, event if
* the current operating system's native text files use something
* else.
*/
static void crlf();
protected:
/**
* The put_char method is used to send a character to the output.
* Usually, this is sufficient, however derived classes may
* over-ride it if they have a special case. Over-ride with
* caution, as it affects many other methods.
*/
virtual void put_char(int);
/**
* The put_nibble method is used to send a hexadecimal digit (0..9,
* A..F) to the output. It calls put_char to send the output.
*/
void put_nibble(int);
/**
* The put_byte method is used to send a byte value to the output.
* The default implementation is to call the put_nibble method
* twice, big-endian (most significant nibble first).
*
* The value of the byte will be added to the running checksum, via
* the checksum_add() method.
*
* Usually, this get_byte() method implemention is sufficient for
* most output classes, however derived classes may over-ride it if
* they have a special case. Over-ride with caution, as it affects
* many other methods.
*/
virtual void put_byte(unsigned char);
/**
* The put_word method is used to send a 16-bit value to the
* output. The put_byte() method is called twice, and the two byte
* values are sent big-endian (most significant byte first).
*/
virtual void put_word(int);
/**
* The put_3bytes method is used to send a 24-bit value to the
* output. The put_byte() method is called three times, and the
* three byte values are sent big-endian (most significant byte
* first).
*/
virtual void put_3bytes(unsigned long);
/**
* The put_4bytes method is used to send a 32-bit value to the
* output. The put_byte() method is called four times, and the
* four byte values are sent big-endian (most significant byte
* first).
*/
virtual void put_4bytes(unsigned long);
/**
* The checksum_reset method is used to set the running checksum to
* zero.
*/
void checksum_reset();
/**
* The checksum_add method is used to add another 8-bit value to
* the running checksum.
*
* The default implementation uses a simple addition. Derived
* classesmay override if they need to. Do this with caution, as
* it affects other methods.
*/
virtual void checksum_add(unsigned char n);
/**
* The checksum_get method is used to get the current value of the
* running checksum (added to by the checksum_add() method, usually
* called by the get_byte() method). Only the lower 8 bits of the
* sum are returned.
*/
int checksum_get();
/**
* The checksum_get16 method is used to get the current value of
* the running checksum (added to by the checksum_add() method,
* usually called by the get_byte() method). Only the lower 16
* bits of the sum are returned.
*/
int checksum_get16();
/**
* The seek_to method is used to move the output position to the
* specified location in the output file.
*/
void seek_to(unsigned long);
/**
* The put_string method is used to send a nul-terminated C string
* to the output. Multiple calls to put_char() are made.
*/
void put_string(const char *);
/**
* The put_string method is used to send C++ string
* to the output. Multiple calls to put_char() are made.
*
* @param s
* The string to pint.
*/
void put_string(const std::string &s);
/**
* The put_stringf method is used to send a formatted string to the
* output. The format and operation ios similar to the standard
* printf function. Multiple calls to put_char() are made.
*/
void put_stringf(const char *, ...) FORMAT_PRINTF(2, 3);
/**
* The mode method returns a suitable mode for passing to fopen.
* The default implementation returns "w+" but derived classes may
* over-ride it (e.g. "wb" for binary).
*/
virtual const char *mode() const;
/**
* The data_only_flag class variable is set by the data_only()
* method, to remember that only data records are to be sent to the
* output. Header records, start address records, etc, are all
* suppressed.
*/
static bool data_only_flag;
/**
* The crlf_flag class variable is used to remember whether or not
* to force CRLF line termination, event if the current operating
* system's native text files use something else.
*/
static bool crlf_flag;
private:
/**
* The file_name instance variable is used by the filename() and
* filename_and_line() methods to report the name of the input
* file. This makes for informative error mesages.
*/
std::string file_name;
/**
* The line_number instance variable is used by the get_char
* method to remember the current line number. It us used by the
* filename_and_line() method to report the current file location.
*/
int line_number;
/**
* The vfp instance variable is used by the get_fp() method to
* remember the file pointer. You need to cast it to FILE* befor
* you use it. Never access this instance variable directly,
* always go via the get_fp() method. This ensures the file has
* been opened first!
*/
void *vfp;
protected:
/**
* The checksum instance variable is used record the running
* checksum. NEVER access this variable directly. Always use the
* checksum_reset() method to set it mack to its initial state.
* Always use the checksum_add() method to add a byte to it.
* Always use the checksum_get() or checksum_get16() methods to
* read its value.
*/
int checksum;
/**
* The fatal_alignment_error method is used to report problems
* with unaligned data in formats that require aligned data. It
* suggests a fill to fix the problem.
*
* @param alignment
* The necessary byte alignment
*/
void fatal_alignment_error(int alignment);
private:
/**
* The position instance variable is used to remember the
* current position within the output file. Set by the put_char
* method, and the seek_to method. Used by the seek_to method.
*/
unsigned long position;
/**
* The is_regular instance variable is used to remember whther
* or not the file is a regular file. This is set by the
* set_is_regular method. It is used by the seek_to method.
*/
bool is_regular;
/**
* The set_is_regular method shall be used whenevr vfp is assigned,
* to estanblish whther the output file is a regular file or a
* special file (like a pipe).
*/
void set_is_regular(void);
/**
* The get_fp method is used to get the stdio file pointer
* associated with this input file. (By avoiding a FILE*
* declaraion, we avoid having to include for not
* particularly good reason. Take care when casting.)
*
* If the file has not been opened yet, it will be opened by this
* method.
*/
void *get_fp();
/**
* The copy constructor. Do not use.
*/
srec_output_file(const srec_output_file &);
/**
* The assignment operator. Do not use.
*/
srec_output_file &operator=(const srec_output_file &);
};
#endif // INCLUDE_SREC_OUTPUT_FILE_H