AirTSP Logo  1.01.12
C++ Simulated Airline Travel Solution Provider (TSP) Library
Loading...
Searching...
No Matches
OnDParserHelper.cpp
Go to the documentation of this file.
1// //////////////////////////////////////////////////////////////////////
2// Import section
3// //////////////////////////////////////////////////////////////////////
4// STL
5#include <cassert>
6// StdAir
7#include <stdair/basic/BasFileMgr.hpp>
8#include <stdair/bom/BomRoot.hpp>
9#include <stdair/service/Logger.hpp>
10// AirTSP
13
14namespace AIRTSP {
15
16 namespace OnDParserHelper {
17
18 // //////////////////////////////////////////////////////////////////////
19 //
20 // Semantic actions
21 //
22 // //////////////////////////////////////////////////////////////////////
23
26 : _onDPeriod (ioOnDPeriod) {
27 }
28
29 // //////////////////////////////////////////////////////////////////////
31 : ParserSemanticAction (ioOnDPeriod) {
32 }
33
34 // //////////////////////////////////////////////////////////////////////
36 iterator_t iStrEnd) const {
37 std::string lOrigin (iStr, iStrEnd);
38 //STDAIR_LOG_DEBUG ( "Origin: " << lOrigin << std::endl);
39
40 // Set the origin
41 _onDPeriod._origin = lOrigin;
42 _onDPeriod._nbOfAirlines = 0;
43 _onDPeriod._airlineCode = "";
44 _onDPeriod._classCode = "";
45 _onDPeriod._airlineCodeList.clear();
46 _onDPeriod._classCodeList.clear();
47 }
48
49 // //////////////////////////////////////////////////////////////////////
53
54 // //////////////////////////////////////////////////////////////////////
56 iterator_t iStrEnd) const {
57 std::string lDestination (iStr, iStrEnd);
58 //STDAIR_LOG_DEBUG ("Destination: " << lDestination << std::endl);
59
60 // Set the destination
61 _onDPeriod._destination = lDestination;
62 }
63
64 // //////////////////////////////////////////////////////////////////////
69
70 // //////////////////////////////////////////////////////////////////////
72 iterator_t iStrEnd) const {
73 _onDPeriod._dateRangeStart = _onDPeriod.getDate();
74 /*STDAIR_LOG_DEBUG ("Date Range Start: "
75 << _onDPeriod._dateRangeStart << std::endl);*/
76
77 // Reset the number of seconds
78 _onDPeriod._itSeconds = 0;
79 }
80
81 // //////////////////////////////////////////////////////////////////////
86
87 // //////////////////////////////////////////////////////////////////////
89 iterator_t iStrEnd) const {
90 // As a Boost date period (COM::DatePeriod_T) defines the last day of
91 // the period to be end-date - one day, we have to add one day to that
92 // end date before.
93 const stdair::DateOffset_T oneDay (1);
94 _onDPeriod._dateRangeEnd = _onDPeriod.getDate() + oneDay;
95 /*STDAIR_LOG_DEBUG ( "Date Range End: "
96 << _onDPeriod._dateRangeEnd << std::endl);*/
97
98 // Transform the date pair (i.e., the date range) into a date period
99 _onDPeriod._datePeriod =
100 stdair::DatePeriod_T (_onDPeriod._dateRangeStart,
101 _onDPeriod._dateRangeEnd);
102
103 // Reset the number of seconds
104 _onDPeriod._itSeconds = 0;
105 }
106
107 // //////////////////////////////////////////////////////////////////////
112
113 // //////////////////////////////////////////////////////////////////////
115 iterator_t iStrEnd) const {
116 _onDPeriod._timeRangeStart = _onDPeriod.getTime();
117
118 // Reset the number of seconds
119 _onDPeriod._itSeconds = 0;
120 }
121
122 // //////////////////////////////////////////////////////////////////////
125 : ParserSemanticAction (ioOnDPeriod) {
126 }
127
128 // //////////////////////////////////////////////////////////////////////
130 iterator_t iStrEnd) const {
131 _onDPeriod._timeRangeEnd = _onDPeriod.getTime();
132
133 // Reset the number of seconds
134 _onDPeriod._itSeconds = 0;
135 }
136
137 // //////////////////////////////////////////////////////////////////////
140 : ParserSemanticAction (ioOnDPeriod) {
141 }
142
143 // //////////////////////////////////////////////////////////////////////
145 iterator_t iStrEnd) const {
146 const std::string lAirlineCodeStr (iStr, iStrEnd);
147 const stdair::AirlineCode_T lAirlineCode(lAirlineCodeStr);
148 // Test if the OnD Period Struct stands for interline products
149 if (_onDPeriod._airlineCodeList.size() > 0) {
150 // update the airline code
151 std::ostringstream ostr;
152 ostr << _onDPeriod._airlineCode << lAirlineCode;
153 _onDPeriod._airlineCode = ostr.str();
154 // Update the number of airlines if necessary
155 const stdair::AirlineCode_T lPreviousAirlineCode =
156 _onDPeriod._airlineCodeList.back();
157 if (lPreviousAirlineCode != lAirlineCode) {
158 _onDPeriod._nbOfAirlines = _onDPeriod._nbOfAirlines + 1;
159 }
160 }
161 else {
162 _onDPeriod._airlineCode = lAirlineCode;
163 _onDPeriod._nbOfAirlines = 1;
164 }
165 _onDPeriod._airlineCodeList.push_back (lAirlineCode);
166
167 //STDAIR_LOG_DEBUG ( "Airline code: " << lAirlineCode << std::endl);
168 }
169
170 // //////////////////////////////////////////////////////////////////////
172 storeClassCode (OnDPeriodStruct& ioOnDPeriod)
173 : ParserSemanticAction (ioOnDPeriod) {
174 }
175
176 // //////////////////////////////////////////////////////////////////////
177 void storeClassCode::operator() (char iChar) const {
178 std::ostringstream ostr;
179 ostr << iChar;
180 std::string classCodeStr = ostr.str();
181 const stdair::ClassCode_T lClassCode (classCodeStr);
182 _onDPeriod._classCodeList.push_back(lClassCode);
183 /*STDAIR_LOG_DEBUG ("Class Code: "
184 << lClassCode << std::endl);*/
185 // Insertion of this class Code in the whole classCode name
186 std::ostringstream ostrr;
187 ostrr << _onDPeriod._classCode << classCodeStr;
188 _onDPeriod._classCode = ostrr.str();
189
190 }
191
192 // //////////////////////////////////////////////////////////////////////
193 doEndOnD::doEndOnD (stdair::BomRoot& ioBomRoot, OnDPeriodStruct& ioOnDPeriod)
194 : ParserSemanticAction (ioOnDPeriod),
195 _bomRoot (ioBomRoot) {
196 }
197
198 // //////////////////////////////////////////////////////////////////////
199 void doEndOnD::operator() (iterator_t iStr, iterator_t iStrEnd) const {
200
201 // DEBUG: Display the result
202 // STDAIR_LOG_DEBUG ("FareRule " << _onDPeriod.describe());
203
204 // Generation of the O&D-Period object.
205 OnDPeriodGenerator::createOnDPeriod (_bomRoot, _onDPeriod);
206 }
207
208 // ///////////////////////////////////////////////////////////////////////
209 //
210 // Utility Parsers
211 //
212 // ///////////////////////////////////////////////////////////////////////
213
216
219
222
225
227 repeat_p_t airport_p (chset_t("0-9A-Z").derived(), 3, 3);
228
231
233 bounded4_p_t year_p (uint4_p.derived(), 2000u, 2099u);
234
236 bounded2_p_t month_p (uint2_p.derived(), 1u, 12u);
237
239 bounded2_p_t day_p (uint2_p.derived(), 1u, 31u);
240
242 bounded2_p_t hours_p (uint2_p.derived(), 0u, 23u);
243
245 bounded2_p_t minutes_p (uint2_p.derived(), 0u, 59u);
246
248 bounded2_p_t seconds_p (uint2_p.derived(), 0u, 59u);
249
252
254 //
255 // (Boost Spirit) Grammar Definition
256 //
258
259 // //////////////////////////////////////////////////////////////////////
261 OnDParser (stdair::BomRoot& ioBomRoot, OnDPeriodStruct& ioOnDPeriod)
262 : _bomRoot (ioBomRoot), _onDPeriod (ioOnDPeriod) {
263 }
264
265 // //////////////////////////////////////////////////////////////////////
266 template<typename ScannerT>
268
269 ond_list = *( boost::spirit::classic::comment_p("//")
270 | boost::spirit::classic::comment_p("/*", "*/")
271 | ond )
272 ;
273
274 ond = ond_key
275 >> +( ';' >> segment )
276 >> ond_end[doEndOnD(self._bomRoot, self._onDPeriod)]
277 ;
278
279 ond_end = boost::spirit::classic::ch_p(';')
280 ;
281
283 >> ';' >> (airport_p)[storeDestination(self._onDPeriod)]
284 >> ';' >> date[storeDateRangeStart(self._onDPeriod)]
285 >> ';' >> date[storeDateRangeEnd(self._onDPeriod)]
286 >> ';' >> time[storeStartRangeTime(self._onDPeriod)]
287 >> ';' >> time[storeEndRangeTime(self._onDPeriod)]
288 ;
289
290 date = boost::spirit::classic::
291 lexeme_d[(year_p)[boost::spirit::classic::
292 assign_a(self._onDPeriod._itYear)]
293 >> '-'
294 >> (month_p)[boost::spirit::classic::
295 assign_a(self._onDPeriod._itMonth)]
296 >> '-'
297 >> (day_p)[boost::spirit::classic::
298 assign_a(self._onDPeriod._itDay)]]
299 ;
300
301 time = boost::spirit::classic::
302 lexeme_d[(hours_p)[boost::spirit::classic::
303 assign_a(self._onDPeriod._itHours)]
304 >> ':'
305 >> (minutes_p)[boost::spirit::classic::
306 assign_a(self._onDPeriod._itMinutes)]
307 >> !(':' >> (seconds_p)[boost::spirit::classic::
308 assign_a(self._onDPeriod._itSeconds)])]
309 ;
310
311 segment = boost::spirit::classic::
313 >> ';' >> (class_code_p)[storeClassCode(self._onDPeriod)]
314 ;
315
316 //BOOST_SPIRIT_DEBUG_NODE (OnDParser);
317 BOOST_SPIRIT_DEBUG_NODE (ond_list);
318 BOOST_SPIRIT_DEBUG_NODE (ond);
319 BOOST_SPIRIT_DEBUG_NODE (segment);
320 BOOST_SPIRIT_DEBUG_NODE (ond_key);
321 BOOST_SPIRIT_DEBUG_NODE (ond_end);
322 BOOST_SPIRIT_DEBUG_NODE (date);
323 BOOST_SPIRIT_DEBUG_NODE (time);
324
325 }
326
327 // //////////////////////////////////////////////////////////////////////
328 template<typename ScannerT>
329 boost::spirit::classic::rule<ScannerT> const&
333 }
334
336 //
337 // Entry class for the file parser
338 //
340
341 // //////////////////////////////////////////////////////////////////////
342 OnDPeriodFileParser::OnDPeriodFileParser (const stdair::Filename_T& iFilename,
343 stdair::BomRoot& ioBomRoot)
344 : _filename (iFilename), _bomRoot (ioBomRoot) {
345 init();
346 }
347
348 // //////////////////////////////////////////////////////////////////////
349 void OnDPeriodFileParser::init() {
350 // Check that the file exists and is readable
351 const bool doesExistAndIsReadable =
352 stdair::BasFileMgr::doesExistAndIsReadable (_filename);
353
354 if (doesExistAndIsReadable == false) {
355 STDAIR_LOG_ERROR ("The O&D file " << _filename
356 << " does not exist or can not be read.");
357
358 throw OnDInputFileNotFoundException ("The O&D file " + _filename
359 + " does not exist or can not be read");
360 }
361
362 // Open the file
363 _startIterator = iterator_t (_filename);
364
365 // Check that the filename exists and can be open
366 if (!_startIterator) {
367 STDAIR_LOG_DEBUG ("The O&D file " << _filename << " can not be open."
368 << std::endl);
369 throw OnDInputFileNotFoundException ("The file " + _filename
370 + " does not exist or can not be read");
371 }
372
373 // Create an EOF iterator
374 _endIterator = _startIterator.make_end();
375 }
376
377 // //////////////////////////////////////////////////////////////////////
379 bool oResult = false;
380
381 STDAIR_LOG_DEBUG ("Parsing O&D input file: " << _filename);
382
383 // Initialise the parser (grammar) with the helper/staging structure.
384 OnDParserHelper::OnDParser lODParser (_bomRoot, _onDPeriod);
385
386 // Launch the parsing of the file and, thanks to the doEndOnD
387 // call-back structure, filling the worldSchedule (Fares)
388 boost::spirit::classic::parse_info<iterator_t> info =
389 boost::spirit::classic::parse (_startIterator, _endIterator, lODParser,
390 boost::spirit::classic::space_p);
391
392 // Retrieves whether or not the parsing was successful
393 oResult = info.hit;
394
395 const std::string hasBeenFullyReadStr = (info.full == true)?"":"not ";
396 if (oResult == true) {
397 STDAIR_LOG_DEBUG ("Parsing of O&D input file: " << _filename
398 << " succeeded: read " << info.length
399 << " characters. The input file has "
400 << hasBeenFullyReadStr
401 << "been fully read. Stop point: " << info.stop);
402
403 } else {
404 // TODO: decide whether to throw an exception
405 STDAIR_LOG_ERROR ("Parsing of O&D input file: " << _filename
406 << " failed: read " << info.length
407 << " characters. The input file has "
408 << hasBeenFullyReadStr
409 << "been fully read. Stop point: " << info.stop);
410 }
411
412 return oResult;
413 }
414}
OnDPeriodFileParser(const stdair::Filename_T &iFilename, stdair::BomRoot &ioBomRoot)
bounded2_p_t seconds_p(uint2_p.derived(), 0u, 59u)
repeat_p_t airline_code_p(alpha_cap_set_p.derived(), 2, 3)
bounded2_p_t hours_p(uint2_p.derived(), 0u, 23u)
repeat_p_t airport_p(chset_t("0-9A-Z").derived(), 3, 3)
bounded2_p_t day_p(uint2_p.derived(), 1u, 31u)
chset_t alpha_cap_set_p("A-Z")
chset_t class_code_p("A-Z")
bounded4_p_t year_p(uint4_p.derived(), 2000u, 2099u)
bounded2_p_t minutes_p(uint2_p.derived(), 0u, 59u)
bounded2_p_t month_p(uint2_p.derived(), 1u, 12u)
boost::spirit::classic::uint_parser< unsigned int, 10, 1, 4 > uint1_4_p_t
boost::spirit::classic::impl::loop_traits< chset_t, unsignedint, unsignedint >::type repeat_p_t
boost::spirit::classic::bounded< uint4_p_t, unsigned int > bounded4_p_t
boost::spirit::classic::uint_parser< unsigned int, 10, 4, 4 > uint4_p_t
boost::spirit::classic::file_iterator< char_t > iterator_t
boost::spirit::classic::uint_parser< unsigned int, 10, 2, 2 > uint2_p_t
boost::spirit::classic::chset< char_t > chset_t
boost::spirit::classic::bounded< uint2_p_t, unsigned int > bounded2_p_t
boost::spirit::classic::rule< ScannerT > ond_list
boost::spirit::classic::rule< ScannerT > date
boost::spirit::classic::rule< ScannerT > time
boost::spirit::classic::rule< ScannerT > ond_end
boost::spirit::classic::rule< ScannerT > const & start() const
boost::spirit::classic::rule< ScannerT > ond
boost::spirit::classic::rule< ScannerT > ond_key
boost::spirit::classic::rule< ScannerT > segment
OnDParser(stdair::BomRoot &, OnDPeriodStruct &)
doEndOnD(stdair::BomRoot &, OnDPeriodStruct &)
void operator()(iterator_t iStr, iterator_t iStrEnd) const
void operator()(iterator_t iStr, iterator_t iStrEnd) const
void operator()(iterator_t iStr, iterator_t iStrEnd) const
void operator()(iterator_t iStr, iterator_t iStrEnd) const
void operator()(iterator_t iStr, iterator_t iStrEnd) const
void operator()(iterator_t iStr, iterator_t iStrEnd) const
void operator()(iterator_t iStr, iterator_t iStrEnd) const
void operator()(iterator_t iStr, iterator_t iStrEnd) const