source: cfg_oil/trunk/toppers/csv.hpp@ 23

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

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

File size: 7.5 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2007-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 * \file toppers/csv.hpp
44 * \brief CSVƒtƒ@ƒCƒ‹“üo—Í‚ÉŠÖ‚·‚ééŒ¾’è‹`
45 */
46#ifndef TOPPERS_CSV_HPP_
47#define TOPPERS_CSV_HPP_
48
49#include <stdexcept>
50#include <ostream>
51#include <iterator>
52#include <string>
53#include <vector>
54#include <algorithm>
55#include <boost/utility.hpp>
56#include "toppers/misc.hpp"
57
58namespace toppers
59{
60
61 class csv_error : public std::runtime_error
62 {
63 public:
64 explicit csv_error( long line )
65 : std::runtime_error( "CSV parse error" ), line_( line )
66 {
67 }
68 long line() const
69 {
70 return line_;
71 }
72 private:
73 long line_;
74 };
75
76 /*!
77 * \class basic_csv csv.hpp "toppers/csv.hpp"
78 * \brief CSV ƒtƒ@ƒCƒ‹‚̉ðÍƒNƒ‰ƒX
79 */
80 template < typename CharT, class Traits = std::char_traits< CharT > >
81 class basic_csv
82 {
83 public:
84 typedef std::basic_string< CharT, Traits > string_type;
85 typedef typename std::vector< std::vector< string_type > >::const_iterator const_iterator;
86 typedef typename std::vector< std::vector< string_type > >::const_reference const_reference;
87 typedef typename std::vector< std::vector< string_type > >::value_type value_type;
88 typedef typename std::vector< std::vector< string_type > >::size_type size_type;
89
90 basic_csv();
91 template < class InputIterator >
92 basic_csv( InputIterator first, InputIterator last )
93 {
94 read( first, last );
95 }
96
97 template < class InputIterator >
98 void read( InputIterator first, InputIterator last )
99 {
100 const CharT dquo = widen< CharT >( '\"' );
101 const CharT comma = widen< CharT >( ',' );
102 const CharT lf = widen< CharT >( '\n' );
103 enum
104 {
105 none,
106 non_escaped,
107 escape_opened,
108 escape_closed
109 } state = none;
110 std::vector< std::vector< string_type > > records;
111 std::vector< string_type > record;
112 string_type field;
113 long line = 1;
114
115 record.reserve( 16 );
116 field.reserve( 255 );
117
118 while ( first != last )
119 {
120 CharT ch = *first;
121 if ( ch == dquo )
122 {
123 switch ( state )
124 {
125 case none:
126 state = escape_opened;
127 break;
128 case escape_opened:
129 ++first;
130 ch = *first;
131 if ( ch == dquo ) // "" ‚¾‚Á‚½‚̂ŁA" ‚ð’ljÁ
132 {
133 field.push_back( dquo );
134 }
135 else // •Â‚¶ "
136 {
137 state = escape_closed;
138 }
139 continue; // ++first ‚ð‚±‚êˆÈãŽÀs‚³‚¹‚È‚¢
140 default:
141 throw csv_error( line );
142 break;
143 }
144 }
145 else // ch != dquo
146 {
147 if ( state == escape_opened )
148 {
149 field.push_back( ch );
150 }
151 else
152 {
153 if ( ch == comma || ch == lf )
154 {
155 record.push_back( field );
156 field.clear();
157 state = none;
158 if ( ch == lf ) // ‰üsiRFC4180 ‚Å‚ÍŒµ–§‚É‚Í CR-LF ‚È‚¯‚ê‚΂Ȃç‚È‚¢‚ªA‚Æ‚è‚ ‚¦‚¸ '\n' ‚Æ‚·‚éj
159 {
160 records.push_back( record );
161 record.clear();
162 ++line;
163 }
164 }
165 else
166 {
167 field.push_back( ch );
168// CharT const* debug_string = field.c_str();
169 }
170 }
171 }
172 ++first;
173 }
174 records_.swap( records );
175 }
176 template < class OutputIterator >
177 void write( OutputIterator result ) const
178 {
179 const CharT dquo = widen< CharT >( '\"' );
180 const CharT comma = widen< CharT >( ',' );
181 const CharT lf = widen< CharT >( '\n' );
182
183 for ( typename std::vector< std::vector< string_type > >::const_iterator r_iter( records_.begin() ), r_last( records_.end() );
184 r_iter != r_last;
185 ++r_iter )
186 {
187 for ( typename std::vector< string_type >::const_iterator f_iter( r_iter->begin() ), f_last( r_iter->end() );
188 f_iter != f_last;
189 ++f_iter )
190 {
191 std::string field;
192 bool need_escape = false;
193
194 for ( typename string_type::const_iterator s_iter( f_iter->begin() ), s_last( f_iter->end() );
195 s_iter != s_last;
196 ++s_iter )
197 {
198 CharT ch = *s_iter;
199 if ( ch == dquo )
200 {
201 field.push_back( dquo );
202 need_escape = true;
203 }
204 else if ( ch == comma || ch == lf )
205 {
206 need_escape = true;
207 }
208 field.push_back( ch );
209 }
210
211 if ( need_escape )
212 {
213 field = dquo + field + dquo;
214 }
215 result = std::copy( field.begin(), field.end(), result );
216 if ( boost::next( f_iter ) != f_last )
217 {
218 *result++ = comma;
219 }
220 }
221 *result++ = lf;
222 }
223 }
224
225 const_iterator begin() const
226 {
227 return records_.begin();
228 }
229 const_iterator end() const
230 {
231 return records_.end();
232 }
233 const_reference at( size_type pos ) const
234 {
235 return records_.at( pos );
236 }
237 const_reference operator[]( size_type pos ) const
238 {
239 return records_[ pos ];
240 }
241 bool empty() const
242 {
243 return records_.empty();
244 }
245 size_type size() const
246 {
247 return records_.size();
248 }
249 void swap( basic_csv& other )
250 {
251 records_.swap( other.records_ );
252 }
253 private:
254 std::vector< std::vector< string_type > > records_;
255 };
256
257 typedef basic_csv< char > csv;
258 typedef basic_csv< wchar_t > wcsv;
259
260}
261
262#endif // TOPPERS_CSV_HPP_
Note: See TracBrowser for help on using the repository browser.