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