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