source: cfg_oil/trunk/toppers/s_record.cpp@ 8

Last change on this file since 8 was 8, checked in by msugi, 13 years ago

ディレクトリ構造の作成,ソース一式とReleaseビルドのコミット.

File size: 7.6 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
6 *
7 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
8 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
9 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
10 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
11 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
12 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
13 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
14 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
15ƒƒ“ƒgi—˜—p
16 * ŽÒƒ}ƒjƒ…
17ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
18 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
19 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
20 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
21 * ‚ƁD
22 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
23ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
24ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
25 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
26 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
27 * •ñ‚·‚邱‚ƁD
28 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
29 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
30 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
31 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
32 * –Ɛӂ·‚邱‚ƁD
33 *
34 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
35 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
36 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
37 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
38 * ‚̐ӔC‚𕉂í‚È‚¢D
39 *
40 */
41
42/*
43 * toppers/s_record.cpp
44 */
45#include "toppers/s_record.hpp"
46#include <istream>
47#include <algorithm>
48#include <cctype>
49#include <cstring>
50
51namespace toppers
52{
53
54 /*!
55 * \brief SƒŒƒR[ƒh‚̃[ƒh
56 * \param istr “ü—̓XƒgƒŠ[ƒ€
57 */
58 void s_record::load( std::istream& istr )
59 {
60 int type = -1;
61
62 while ( istr )
63 {
64 std::string buf;
65 std::getline( istr, buf );
66 if ( buf.empty() )
67 {
68 break;
69 }
70 record rec = read_record( buf );
71
72 // ‚ ‚܂茵–§‚ɂ͏ˆ—‚µ‚È‚¢
73 if ( '1' <= rec.type && rec.type <= '3' )
74 {
75 bool done = false;
76 typedef std::vector< value_type >::iterator iterator;
77 for ( iterator iter( data_.begin() ), last( data_.end() ); iter != last; ++iter )
78 {
79 if ( rec.address == iter->first + iter->second.size() )
80 {
81 std::copy( rec.data.begin(), rec.data.end(), std::back_inserter( iter->second ) );
82 done = true;
83 }
84 }
85 if ( !done )
86 {
87 data_.push_back( value_type( rec.address, std::vector< unsigned char >( rec.data.begin(), rec.data.end() ) ) );
88 }
89 }
90 type = rec.type;
91 }
92
93 cache_ = data_.begin();
94 }
95
96 /*!
97 * \brief Žw’èƒAƒhƒŒƒX‚̃oƒCƒgƒf[ƒ^Žæ“¾
98 * \param address ƒAƒhƒŒƒXŽw’è
99 * \return address ‚ÅŽw’肵‚½ƒAƒhƒŒƒX‚̃oƒCƒgƒf[ƒ^‚ð•Ô‚·
100 */
101 int s_record::operator[]( size_type address ) const
102 {
103 typedef std::vector< value_type >::const_iterator const_iterator;
104 if ( cache_ != data_.end() )
105 {
106 const_iterator iter( cache_ );
107 if ( iter->first <= address && address < iter->first + iter->second.size() )
108 {
109 return iter->second.at( address - iter->first );
110 }
111 }
112 for ( const_iterator iter( cache_ ), last( data_.end() ); iter != last; ++iter )
113 {
114 if ( iter->first <= address && address < iter->first + iter->second.size() )
115 {
116 cache_ = iter;
117 return iter->second.at( address - iter->first );
118 }
119 }
120 for ( const_iterator iter( data_.begin() ), last( cache_ ); iter != last; ++iter )
121 {
122 if ( iter->first <= address && address < iter->first + iter->second.size() )
123 {
124 cache_ = iter;
125 return iter->second.at( address - iter->first );
126 }
127 }
128 return -1;
129 }
130
131 /*!
132 * \brief SƒŒƒR[ƒh’†‚̐®”’l“ǂݍž‚Ý
133 * \param base “ǂݍž‚݈ʒu‚̐擪ƒAƒhƒŒƒX
134 * \param size ®”’l‚̃oƒCƒg”
135 * \param little_endian ƒŠƒgƒ‹ƒGƒ“ƒfƒBƒAƒ“‚È‚ç trueAƒrƒbƒOƒGƒ“ƒfƒBƒAƒ“‚È‚ç false ‚ðŽw’è
136 * \return “ǂݍž‚ñ‚¾®”’l‚ð•Ô‚·
137 */
138 boost::uintmax_t s_record::get_value( std::size_t base, std::size_t size, bool little_endian ) const
139 {
140 boost::uintmax_t value = 0;
141 if ( little_endian )
142 {
143 for ( long j = static_cast< long >( size-1 ); j >= 0; j-- )
144 {
145 int t = ( *this )[ base + j ];
146 if ( t < 0 )
147 {
148 throw data_error();
149 }
150 value = ( value << 8 ) | ( t & 0xff );
151 }
152 }
153 else
154 {
155 for ( std::size_t j = 0; j < size; j++ )
156 {
157 int t = ( *this )[ base + j ];
158 if ( t < 0 )
159 {
160 throw data_error();
161 }
162 value = ( value << 8 ) | ( t & 0xff );
163 }
164 }
165 return value;
166 }
167
168 unsigned long s_record::lower_bound() const
169 {
170 return data_.front().first;
171 }
172
173 unsigned long s_record::upper_bound() const
174 {
175 return data_.back().first + data_.back().second.size();
176 }
177
178 /*!
179 * \brief SƒŒƒR[ƒh‚Ì‚Ps“ǂݍž‚Ý
180 * \param rec_buf ‚Psƒoƒbƒtƒ@
181 * \return “ǂݍž‚ÝŒ‹‰Ê‚ð•Ô‚·
182 */
183 s_record::record const s_record::read_record( std::string const& rec_buf )
184 {
185 std::string buf( rec_buf );
186
187 // s––‚É'\r'‚Ü‚½‚Í'\n'‚ªŽc—¯‚µ‚Ä‚¢‚éê‡‚̑΍ô
188 while ( std::isspace( static_cast< unsigned char >( *buf.rbegin() ) ) )
189 {
190 buf = buf.substr( 0, buf.size()-1 );
191 }
192
193 if ( buf.size() < 10 || buf[0] != 'S' )
194 {
195 throw format_error();
196 }
197 int ch = static_cast< unsigned char >( buf[1] );
198 int address_length = 4;
199 std::string::size_type size = buf.size();
200
201 switch ( ch )
202 {
203 case '1':
204 case '9':
205 address_length = 4;
206 break;
207 case '2':
208 case '8':
209 address_length = 6;
210 break;
211 case '3':
212 case '7':
213 address_length = 8;
214 break;
215 default:
216 if ( !std::isdigit( static_cast< unsigned char >( ch ) ) )
217 {
218 throw format_error();
219 }
220 break;
221 }
222
223 record rec;
224 rec.type = ch;
225 rec.length = xdigit_to_int( buf[2] ) << 4 | xdigit_to_int( buf[3] );
226 if ( rec.length * 2u + 4 != buf.size() )
227 {
228 throw format_error();
229 }
230 rec.length -= address_length/2 + 1; // ƒAƒhƒŒƒX‚ƃ`ƒFƒbƒNƒTƒ€‚Ì’·‚³‚ðˆø‚¢‚āAƒf[ƒ^’·‚É’¼‚·
231
232 rec.address = 0;
233 int base = 4;
234 for ( int i = 0; i < address_length; i++ )
235 {
236 rec.address = rec.address << 4 | xdigit_to_int( buf[base+i] );
237 }
238
239 base += address_length;
240 rec.data.reserve( rec.length );
241 for ( int i = 0; i < rec.length; i++ )
242 {
243 rec.data.push_back( static_cast< unsigned char >( xdigit_to_int( buf[base+i*2] ) << 4 | xdigit_to_int( buf[base+i*2+1] ) ) );
244 }
245
246 rec.checksum = xdigit_to_int( buf[size-2] ) << 4 | xdigit_to_int( buf[size-1] );
247
248 // ƒ`ƒFƒbƒNƒTƒ€”»’è‚͏ȗª
249
250 return rec;
251 }
252
253 /*!
254 * \brief \˜Zi”Žš‚©‚琔’l‚Ö‚Ì•ÏŠ·
255 * \param ch \˜Zi”Žši•¶Žšj
256 * \return ch ‚ɑΉž‚·‚鐔’l
257 */
258 int s_record::xdigit_to_int( int ch )
259 {
260 static char const xdigits[] = "0123456789abcdef";
261
262 ch = std::tolower( static_cast< unsigned char >( ch ) );
263 char const* s = std::strchr( xdigits, ch );
264 if ( s == 0 )
265 {
266 return -1;
267 }
268 return s - xdigits;
269 }
270
271}
Note: See TracBrowser for help on using the repository browser.