summaryrefslogtreecommitdiffstats
path: root/common/StSRecordFile.h
blob: 4340c6a1469c49bbce160c3a209ed952ea29e791 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * File:	StSRecordFile.h
 *
 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
 * See included license file for license details.
 */
#if !defined(_StSRecordFile_h_)
#define _StSRecordFile_h_

//#include <stdint.h>
#include "stdafx.h"
#include <istream>
#include <string>
#include <vector>
#include <stdexcept>

enum {
	//! The required first character of an S-record.
	SRECORD_START_CHAR = 'S',
	
	//! The minimum length of a S-record. This is the type (2) + count (2) + addr (4) + cksum (2).
	SRECORD_MIN_LENGTH = 10,
	
	//! Index of the first character of the address field.
	SRECORD_ADDRESS_START_CHAR_INDEX = 4
};

/*!
 * \brief S-record parser.
 *
 * This class takes an input stream and parses it as an S-record file. While
 * the individual records that comprise the file are available for access, the
 * class also provides a higher-level view of the contents. It processes the
 * individual records and builds an image of what the memory touched by the
 * file looks like. Then you can access the contiguous sections of memory.
 */
class StSRecordFile
{
public:
	/*!
	 * Structure representing each individual line of the S-record input data.
	 */
	struct SRecord
	{
		unsigned m_type;		//!< Record number type, such as 9 for "S9", 3 for "S3" and so on.
		unsigned m_count;		//!< Number of character pairs (bytes) from address through checksum.
		uint32_t m_address;			//!< The address specified as part of the S-record.
		unsigned m_dataCount;	//!< Number of bytes of data.
		uint8_t * m_data;			//!< Pointer to data, or NULL if no data for this record type.
		uint8_t m_checksum;			//!< The checksum byte present in the S-record.
	};
	
	//! Iterator type.
	typedef std::vector<SRecord>::const_iterator const_iterator;
	
public:
	//! \brief Constructor.
	StSRecordFile(std::istream & inStream);
	
	//! \brief Destructor.
	virtual ~StSRecordFile();

	//! \name File name
	//@{
	virtual void setName(const std::string & inName) { m_name = inName; }
	virtual std::string getName() const { return m_name; }
	//@}
	
	//! \name Parsing
	//@{
	//! \brief Determine if the file is an S-record file.
	virtual bool isSRecordFile();
	
	//! \brief Parses the entire S-record input stream.
	virtual void parse();
	//@}
	
	//! \name Record access
	//@{
	//! \return the number of S-records that have been parsed from the input stream.
	inline unsigned getRecordCount() const { return static_cast<unsigned>(m_records.size()); }
	
	//! \return iterator for 
	inline const_iterator getBegin() const { return m_records.begin(); }
	inline const_iterator getEnd() const { return m_records.end(); }
	//@}
	
	//! \name Operators
	//@{
	inline const SRecord & operator [] (unsigned inIndex) { return m_records[inIndex]; }
	//@}
	
protected:
	std::istream& m_stream;	//!< The input stream for the S-record data.
	std::vector<SRecord> m_records;	//!< Vector of S-records in the input data.

    std::string m_name;			//!< File name. (optional)

	//! \name Parsing utilities
	//@{
	virtual void parseLine(std::string & inLine);
	
	bool isHexDigit(char c);
	int hexDigitToInt(char digit);
	int readHexByte(std::string & inString, int inIndex);
	//@}
};

/*!
 * \brief Simple exception thrown to indicate an error in the input SRecord data format.
 */
class StSRecordParseException : public std::runtime_error
{
public:
    //! \brief Default constructor.
    StSRecordParseException(const std::string & inMessage) : std::runtime_error(inMessage) {}
};

#endif // _StSRecordFile_h_