xref: /netbsd-src/external/bsd/elftosb/dist/common/StSRecordFile.h (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
1*993229b6Sjkunz /*
2*993229b6Sjkunz  * File:	StSRecordFile.h
3*993229b6Sjkunz  *
4*993229b6Sjkunz  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5*993229b6Sjkunz  * See included license file for license details.
6*993229b6Sjkunz  */
7*993229b6Sjkunz #if !defined(_StSRecordFile_h_)
8*993229b6Sjkunz #define _StSRecordFile_h_
9*993229b6Sjkunz 
10*993229b6Sjkunz //#include <stdint.h>
11*993229b6Sjkunz #include "stdafx.h"
12*993229b6Sjkunz #include <istream>
13*993229b6Sjkunz #include <string>
14*993229b6Sjkunz #include <vector>
15*993229b6Sjkunz #include <stdexcept>
16*993229b6Sjkunz 
17*993229b6Sjkunz enum {
18*993229b6Sjkunz 	//! The required first character of an S-record.
19*993229b6Sjkunz 	SRECORD_START_CHAR = 'S',
20*993229b6Sjkunz 
21*993229b6Sjkunz 	//! The minimum length of a S-record. This is the type (2) + count (2) + addr (4) + cksum (2).
22*993229b6Sjkunz 	SRECORD_MIN_LENGTH = 10,
23*993229b6Sjkunz 
24*993229b6Sjkunz 	//! Index of the first character of the address field.
25*993229b6Sjkunz 	SRECORD_ADDRESS_START_CHAR_INDEX = 4
26*993229b6Sjkunz };
27*993229b6Sjkunz 
28*993229b6Sjkunz /*!
29*993229b6Sjkunz  * \brief S-record parser.
30*993229b6Sjkunz  *
31*993229b6Sjkunz  * This class takes an input stream and parses it as an S-record file. While
32*993229b6Sjkunz  * the individual records that comprise the file are available for access, the
33*993229b6Sjkunz  * class also provides a higher-level view of the contents. It processes the
34*993229b6Sjkunz  * individual records and builds an image of what the memory touched by the
35*993229b6Sjkunz  * file looks like. Then you can access the contiguous sections of memory.
36*993229b6Sjkunz  */
37*993229b6Sjkunz class StSRecordFile
38*993229b6Sjkunz {
39*993229b6Sjkunz public:
40*993229b6Sjkunz 	/*!
41*993229b6Sjkunz 	 * Structure representing each individual line of the S-record input data.
42*993229b6Sjkunz 	 */
43*993229b6Sjkunz 	struct SRecord
44*993229b6Sjkunz 	{
45*993229b6Sjkunz 		unsigned m_type;		//!< Record number type, such as 9 for "S9", 3 for "S3" and so on.
46*993229b6Sjkunz 		unsigned m_count;		//!< Number of character pairs (bytes) from address through checksum.
47*993229b6Sjkunz 		uint32_t m_address;			//!< The address specified as part of the S-record.
48*993229b6Sjkunz 		unsigned m_dataCount;	//!< Number of bytes of data.
49*993229b6Sjkunz 		uint8_t * m_data;			//!< Pointer to data, or NULL if no data for this record type.
50*993229b6Sjkunz 		uint8_t m_checksum;			//!< The checksum byte present in the S-record.
51*993229b6Sjkunz 	};
52*993229b6Sjkunz 
53*993229b6Sjkunz 	//! Iterator type.
54*993229b6Sjkunz 	typedef std::vector<SRecord>::const_iterator const_iterator;
55*993229b6Sjkunz 
56*993229b6Sjkunz public:
57*993229b6Sjkunz 	//! \brief Constructor.
58*993229b6Sjkunz 	StSRecordFile(std::istream & inStream);
59*993229b6Sjkunz 
60*993229b6Sjkunz 	//! \brief Destructor.
61*993229b6Sjkunz 	virtual ~StSRecordFile();
62*993229b6Sjkunz 
63*993229b6Sjkunz 	//! \name File name
64*993229b6Sjkunz 	//@{
setName(const std::string & inName)65*993229b6Sjkunz 	virtual void setName(const std::string & inName) { m_name = inName; }
getName()66*993229b6Sjkunz 	virtual std::string getName() const { return m_name; }
67*993229b6Sjkunz 	//@}
68*993229b6Sjkunz 
69*993229b6Sjkunz 	//! \name Parsing
70*993229b6Sjkunz 	//@{
71*993229b6Sjkunz 	//! \brief Determine if the file is an S-record file.
72*993229b6Sjkunz 	virtual bool isSRecordFile();
73*993229b6Sjkunz 
74*993229b6Sjkunz 	//! \brief Parses the entire S-record input stream.
75*993229b6Sjkunz 	virtual void parse();
76*993229b6Sjkunz 	//@}
77*993229b6Sjkunz 
78*993229b6Sjkunz 	//! \name Record access
79*993229b6Sjkunz 	//@{
80*993229b6Sjkunz 	//! \return the number of S-records that have been parsed from the input stream.
getRecordCount()81*993229b6Sjkunz 	inline unsigned getRecordCount() const { return static_cast<unsigned>(m_records.size()); }
82*993229b6Sjkunz 
83*993229b6Sjkunz 	//! \return iterator for
getBegin()84*993229b6Sjkunz 	inline const_iterator getBegin() const { return m_records.begin(); }
getEnd()85*993229b6Sjkunz 	inline const_iterator getEnd() const { return m_records.end(); }
86*993229b6Sjkunz 	//@}
87*993229b6Sjkunz 
88*993229b6Sjkunz 	//! \name Operators
89*993229b6Sjkunz 	//@{
90*993229b6Sjkunz 	inline const SRecord & operator [] (unsigned inIndex) { return m_records[inIndex]; }
91*993229b6Sjkunz 	//@}
92*993229b6Sjkunz 
93*993229b6Sjkunz protected:
94*993229b6Sjkunz 	std::istream& m_stream;	//!< The input stream for the S-record data.
95*993229b6Sjkunz 	std::vector<SRecord> m_records;	//!< Vector of S-records in the input data.
96*993229b6Sjkunz 
97*993229b6Sjkunz     std::string m_name;			//!< File name. (optional)
98*993229b6Sjkunz 
99*993229b6Sjkunz 	//! \name Parsing utilities
100*993229b6Sjkunz 	//@{
101*993229b6Sjkunz 	virtual void parseLine(std::string & inLine);
102*993229b6Sjkunz 
103*993229b6Sjkunz 	bool isHexDigit(char c);
104*993229b6Sjkunz 	int hexDigitToInt(char digit);
105*993229b6Sjkunz 	int readHexByte(std::string & inString, int inIndex);
106*993229b6Sjkunz 	//@}
107*993229b6Sjkunz };
108*993229b6Sjkunz 
109*993229b6Sjkunz /*!
110*993229b6Sjkunz  * \brief Simple exception thrown to indicate an error in the input SRecord data format.
111*993229b6Sjkunz  */
112*993229b6Sjkunz class StSRecordParseException : public std::runtime_error
113*993229b6Sjkunz {
114*993229b6Sjkunz public:
115*993229b6Sjkunz     //! \brief Default constructor.
StSRecordParseException(const std::string & inMessage)116*993229b6Sjkunz     StSRecordParseException(const std::string & inMessage) : std::runtime_error(inMessage) {}
117*993229b6Sjkunz };
118*993229b6Sjkunz 
119*993229b6Sjkunz #endif // _StSRecordFile_h_
120