クラス toppers::s_record

モトローラSレコードを扱うためのクラス [詳細]

#include "toppers/s_recored.hpp"

toppers::s_recordのコラボレーション図

Collaboration graph
[凡例]
すべてのメンバ一覧

Public 型

typedef std::pair< unsigned
long, std::vector< unsigned
char > > 
value_type
typedef std::vector< value_type
>::size_type 
size_type

Public メソッド

 s_record ()
 デフォルトコンストラクタ
 s_record (std::istream &istr)
 コンストラクタ
virtual ~s_record ()
 デストラクタ
void load (std::istream &istr)
 Sレコードのロード
int operator[] (size_type address) const
 指定アドレスのバイトデータ取得
unsigned long lower_bound () const
unsigned long upper_bound () const

Static Protected メソッド

static const record read_record (const std::string &rec_buf)
 Sレコードの1行読み込み
static int xdigit_to_int (int ch)
 十六進数字から数値への変換

構成

class  checksum_error
 Sレコードのチェックサムエラー例外クラス [詳細]
class  format_error
 Sレコードの書式エラー例外クラス [詳細]
struct  record
 Sレコードの1行レコード情報を格納するための構造体 [詳細]

説明

モトローラSレコードを扱うためのクラス

参照:
s_record::record, s_record::format_error, s_record::checksum_error

s_record.hpp68 行で定義されています。


コンストラクタとデストラクタ

toppers::s_record::s_record std::istream &  istr  )  [inline, explicit]
 

コンストラクタ

引数:
istr 入力ストリーム
s_record クラスの生成と同時にデータのロードを行います。

s_record.hpp116 行で定義されています。

参照先 load().

00116 { load( istr ); }

関数の呼び出しグラフ:


関数

void toppers::s_record::load std::istream &  istr  ) 
 

Sレコードのロード

引数:
istr 入力ストリーム

s_record.cpp53 行で定義されています。

参照先 toppers::s_record::record::addresstoppers::s_record::record::datatoppers::s_record::record::lengthread_record()toppers::s_record::record::type.

参照元 s_record().

00054   {
00055     int type = -1;
00056 
00057     while ( istr )
00058     {
00059       std::string buf;
00060       std::getline( istr, buf );
00061       if ( buf.empty() )
00062       {
00063         break;
00064       }
00065       record rec = read_record( buf );
00066 
00067       // あまり厳密には処理しない
00068       if ( '1' <= rec.type && rec.type <= '3' )
00069       {
00070         bool done = false;
00071         typedef std::vector<value_type>::iterator iterator;
00072         for ( iterator iter( data_.begin() ), last( data_.end() ); iter != last; ++iter )
00073         {
00074           if ( rec.address == iter->first + iter->second.size() )
00075           {
00076             std::copy( rec.data, rec.data+rec.length, std::back_inserter( iter->second ) );
00077             done = true;
00078           }
00079         }
00080         if ( !done )
00081         {
00082           data_.push_back( value_type( rec.address, std::vector<unsigned char>( rec.data, rec.data+rec.length ) ) );
00083         }
00084       }
00085       type = rec.type;
00086     }
00087 
00088     cache_ = data_.begin();
00089   }

関数の呼び出しグラフ:

int toppers::s_record::operator[] size_type  address  )  const
 

指定アドレスのバイトデータ取得

引数:
address アドレス指定
戻り値:
address で指定したアドレスのバイトデータを返す

s_record.cpp96 行で定義されています。

00097   {
00098     typedef std::vector<value_type>::const_iterator const_iterator;
00099     if ( cache_ != data_.end() )
00100     {
00101       const_iterator iter( cache_ );
00102       if ( iter->first <= address && address < iter->first + iter->second.size() )
00103       {
00104         return iter->second.at( address - iter->first );
00105       }
00106     }
00107     for ( const_iterator iter( cache_ ), last( data_.end() ); iter != last; ++iter )
00108     {
00109       if ( iter->first <= address && address < iter->first + iter->second.size() )
00110       {
00111         cache_ = iter;
00112         return iter->second.at( address - iter->first );
00113       }
00114     }
00115     for ( const_iterator iter( data_.begin() ), last( cache_ ); iter != last; ++iter )
00116     {
00117       if ( iter->first <= address && address < iter->first + iter->second.size() )
00118       {
00119         cache_ = iter;
00120         return iter->second.at( address - iter->first );
00121       }
00122     }
00123     return -1;
00124   }

const s_record::record toppers::s_record::read_record const std::string &  rec_buf  )  [static, protected]
 

Sレコードの1行読み込み

引数:
rec_buf 1行バッファ
戻り値:
読み込み結果を返す

s_record.cpp141 行で定義されています。

参照元 load().

00142   {
00143     std::string buf( rec_buf );
00144 
00145     // 行末に'\r'または'\n'が残留している場合の対策
00146     while ( std::isspace( static_cast<unsigned char>( *buf.rbegin() ) ) )
00147     {
00148       buf = buf.substr( 0, buf.size()-1 );
00149     }
00150 
00151     if ( buf.size() < 10 || buf[0] != 'S' )
00152     {
00153       throw format_error();
00154     }
00155     int ch = static_cast<unsigned char>( buf[1] );
00156     int address_length = 4;
00157     std::string::size_type size = buf.size();
00158 
00159     switch ( ch )
00160     {
00161     case '1':
00162     case '9':
00163       address_length = 4;
00164       break;
00165     case '2':
00166     case '8':
00167       address_length = 6;
00168       break;
00169     case '3':
00170     case '7':
00171       address_length = 8;
00172       break;
00173     default:
00174       if ( !std::isdigit( ch ) )
00175       {
00176         throw format_error();
00177       }
00178       break;
00179     }
00180     
00181     record rec;
00182     rec.type = ch;
00183     rec.length = xdigit_to_int( buf[2] ) << 4 | xdigit_to_int( buf[3] );
00184     if ( rec.length * 2 + 4 != buf.size() )
00185     {
00186       throw format_error();
00187     }
00188     rec.length -= address_length/2 + 1; // アドレスとチェックサムの長さを引いて、データ長に直す
00189 
00190     rec.address = 0;
00191     int base = 4;
00192     for ( int i = 0; i < address_length; i++ )
00193     {
00194       rec.address = rec.address << 4 | xdigit_to_int( buf[base+i] );
00195     }
00196 
00197     base += address_length;
00198     for ( int i = 0; i < rec.length; i++ )
00199     {
00200       rec.data[i] = xdigit_to_int( buf[base+i*2] ) << 4 | xdigit_to_int( buf[base+i*2+1] );
00201     }
00202 
00203     rec.checksum = xdigit_to_int( buf[size-2] ) << 4 | xdigit_to_int( buf[size-1] );
00204 
00205     // チェックサム判定は省略
00206 
00207     return rec;
00208   }

int toppers::s_record::xdigit_to_int int  ch  )  [static, protected]
 

十六進数字から数値への変換

引数:
ch 十六進数字(文字)
戻り値:
ch に対応する数値

s_record.cpp215 行で定義されています。

参照先 toppers::tolower().

00216   {
00217     static const char xdigits[] = "0123456789abcdef";
00218 
00219     ch = std::tolower( static_cast<unsigned char>( ch ) );
00220     const char* s = std::strchr( xdigits, ch );
00221     if ( s == 0 )
00222     {
00223       return -1;
00224     }
00225     return s - xdigits;
00226   }

関数の呼び出しグラフ:


このクラスの説明は次のファイルから生成されました:
Copyright © 2006 by TAKAGI Nobuhisa.
このページは Wed Apr 12 16:32:03 2006 に Doxygen によって生成されました。