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