begin of config file parsing
Stefan Schuermans authored 7 years ago
|
1) /*
2) * EtherPix simulator
3) *
4) * Copyright 2017 Stefan Schuermans <stefan schuermans info>
5) *
6) * This program is free software: you can redistribute it and/or modify
7) * it under the terms of the GNU General Public License as published by
8) * the Free Software Foundation, version 3 of the License.
9) *
10) *
11) * This program is distributed in the hope that it will be useful,
12) * but WITHOUT ANY WARRANTY; without even the implied warranty of
13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14) * GNU General Public License for more details.
15) *
16) * You should have received a copy of the GNU Lesser General Public License
17) * along with this program. If not, see <http://www.gnu.org/licenses/>.
18) */
19)
20) #include <algorithm>
|
complete implementation of...
Stefan Schuermans authored 7 years ago
|
21) #include <arpa/inet.h>
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
22) #include <cctype>
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
23) #include <cmath>
24) #include <cstdlib>
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
25) #include <functional>
26) #include <fstream>
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
27) #include <map>
|
complete implementation of...
Stefan Schuermans authored 7 years ago
|
28) #include <netinet/in.h>
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
29) #include <stdexcept>
30) #include <sstream>
31) #include <string>
|
complete implementation of...
Stefan Schuermans authored 7 years ago
|
32) #include <sys/socket.h>
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
33)
|
implement drawing pixels
Stefan Schuermans authored 7 years ago
|
34) #include "bbox.h"
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
35) #include "config.h"
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
36) #include "distri.h"
37) #include "mapping.h"
|
complete implementation of...
Stefan Schuermans authored 7 years ago
|
38) #include "pixel.h"
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
39)
40) /**
41) * @brief constructor
42) * @param[in] configFile name of config file
43) */
|
implement drawing pixels
Stefan Schuermans authored 7 years ago
|
44) Config::Config(std::string const &configFile):
45) m_distriMap(),
46) m_bb()
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
47) {
48) readFile(configFile);
49) }
50)
|
implement drawing pixels
Stefan Schuermans authored 7 years ago
|
51) /**
52) * @brief draw pixels of all distributors
53) * @param[in] cairo cairo context for drawing
54) * @param[in] tf coordinate transformation
55) */
56) void Config::draw(Cairo::RefPtr<Cairo::Context> &cairo,
57) Transform const &tf) const
58) {
59) DistriMap::const_iterator dist;
60) for (dist = m_distriMap.begin(); dist != m_distriMap.end(); ++dist) {
61) Distri const &distri = dist->second;
62) distri.draw(cairo, tf);
63) }
64) }
65)
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
66) /**
67) * @brief remove whitespace at beging and end of string
68) * @param[in,out] str string to process
69) */
70) void Config::trim(std::string &str)
71) {
72) // remove leading whitespace
73) str.erase(str.begin(),
74) std::find_if(str.begin(), str.end(),
75) std::not1(std::ptr_fun<int, int>(std::isspace))));
76)
77) // remove trailing whitespace
78) str.erase(std::find_if(str.rbegin(), str.rend(),
79) std::not1(std::ptr_fun<int, int>(std::isspace))).base(),
80) str.end());
81) }
82)
83) /**
84) * @brief split string at sequences of whitespace
85) * @param[in] str string to split
86) * @param[out] fields fields of string
87) */
88) void Config::split(std::string const &str, std::vector<std::string> &fields)
89) {
90) std::stringstream strm(str);
91) fields.clear();
92) while (! strm.eof()) {
93) std::string field;
94) strm >> field;
95) if (! field.empty()) {
96) fields.push_back(field);
97) }
98) }
99) }
100)
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
101) /**
102) * @brief split string at specific character
103) * @param[in] str string to split
104) * @param[in] delim delimiter character
105) * @param[out] fields fields of string
106) */
107) void Config::split_chr(std::string const &str, char delim,
108) std::vector<std::string> &fields)
109) {
110) std::string::size_type pos = 0, end;
111) fields.clear();
112) while ((end = str.find(delim, pos)) != std::string::npos) {
113) fields.push_back(str.substr(pos, end - pos));
114) pos = end + 1;
115) }
116) fields.push_back(str.substr(pos));
117) }
118)
119) /**
120) * @brief convert string to unsigned long
121) * @param[in] str string to convert
122) * @return unsigned long parsed from string
123) * @throws std::exception in case of error
124) */
125) unsigned long Config::str2ul(std::string const &str)
126) {
127) char const *sz = str.c_str();
128) char *end;
129) unsigned long ul = strtoul(sz, &end, 0);
130) if (end == sz || *end != 0) {
131) std::stringstream msg;
132) msg << "invalid unsigned integer \"" << str << "\"";
133) throw std::runtime_error(msg.str());
134) }
135) return ul;
136) }
137)
138) /**
139) * @brief convert string to two unsigned longs
140) * @param[in] str string containing two comma-separated unsigned integers
141) * @param[out] ul1 first unsigned long parsed from string
142) * @param[out] ul2 second unsigned long parsed from string
143) * @throws std::exception in case of error
144) */
145) void Config::str2ul2(std::string const &str,
146) unsigned long &ul1, unsigned long &ul2)
147) {
148) std::vector<std::string> fields;
149) split_chr(str, ',', fields);
150) if (fields.size() != 2) {
151) std::stringstream msg;
152) msg << "expected two comma-separated unsigned integers, found \""
153) << str << "\"";
154) throw std::runtime_error(msg.str());
155) }
156) try {
157) ul1 = str2ul(fields[0]);
158) ul2 = str2ul(fields[1]);
159) } catch (std::exception &ex) {
160) std::stringstream msg;
161) msg << "invalid unsigned integer pair \"" << str << "\": " << ex.what();
162) throw std::runtime_error(msg.str());
163) }
164) }
165)
166) /**
167) * @brief convert string to double (using the decimal dot for any locale)
168) * @param[in] str string to convert
169) * @return double parsed from string
170) * @throws std::exception in case of error
171) */
172) double Config::str2d(std::string const &str)
173) {
174) char const *sz = str.c_str();
175)
176) // skip leading whitespace
177) while (isspace(*sz)) {
178) ++sz;
179) }
180)
181) // start processing after leading whitespace
182) char const *ptr = sz;
183)
184) // read optional sign
185) double sign = 1.0;
186) if (*ptr == '+') {
187) sign = 1.0;
188) ++ptr;
189) } else if (*ptr == '-') {
190) sign = -1.0;
191) ++ptr;
192) }
193)
194) // read digits before dot
195) double value = 0.0;
196) while (*ptr >= '0' && *ptr <= '9') {
197) value = value * 10.0 + (double)(*ptr - '0');
198) ++ptr;
199) }
200)
201) // read dot and digits after it
202) double weight = 0.1;
203) if (*ptr == '.') {
204) ++ptr;
205)
206) /* read digits after dot */
207) while (*ptr >= '0' && *ptr <= '9') {
208) value += weight * (double)(*ptr - '0');
209) weight *= 0.1;
210) ++ptr;
211) }
212)
213) } // if (*ptr == '.')
214)
215) // merge sign into value
216) value *= sign;
217)
218) // read exponent
219) if (*ptr == 'E' || *ptr == 'e') {
220) ++ptr;
221)
222) /* read optional sign */
223) int exp_sign = 1;
224) if (*ptr == '+') {
225) exp_sign = 1;
226) ++ptr;
227) } else if (*ptr == '-') {
228) exp_sign = -1;
229) ++ptr;
230) }
231)
232) /* read digits */
233) int exp_value = 0;
234) while (*ptr >= '0' && *ptr <= '9') {
235) exp_value = exp_value * 10 + (int)(*ptr - '0');
236) ++ptr;
237) }
238)
239) /* merge exponent into value */
240) value *= pow(10.0, exp_sign * exp_value);
241)
242) } // if (*nptr == 'E' || *nptr == 'e')
243)
244) // skip trailing whitespace
245) while (isspace(*ptr)) {
246) ++ptr;
247) }
248)
249) // leftover characters -> error */
250) if (ptr == sz || *ptr != 0) {
251) std::stringstream msg;
252) msg << "invalid floating point value \"" << str << "\"";
253) throw std::runtime_error(msg.str());
254) }
255)
256) // return value
257) return value;
258) }
259)
260) /**
261) * @brief convert string to three doubles (decimal dot for any locale)
262) * @param[in] str string containing three comma-separated doubles
263) * @param[out] d1 first double parsed from string
264) * @param[out] d2 second double parsed from string
265) * @param[out] d3 third double parsed from string
266) * @throws std::exception in case of error
267) */
268) void Config::str2d3(std::string const &str,
269) double &d1, double &d2, double &d3)
270) {
271) std::vector<std::string> fields;
272) split_chr(str, ',', fields);
273) if (fields.size() != 3) {
274) std::stringstream msg;
275) msg << "expected three comma-separated floating point values, found \""
276) << str << "\"";
277) throw std::runtime_error(msg.str());
278) }
279) try {
280) d1 = str2d(fields[0]);
281) d2 = str2d(fields[1]);
282) d3 = str2d(fields[2]);
283) } catch (std::exception &ex) {
284) std::stringstream msg;
285) msg << "invalid floating point triplet \"" << str << "\": " << ex.what();
286) throw std::runtime_error(msg.str());
287) }
288) }
289)
|
complete implementation of...
Stefan Schuermans authored 7 years ago
|
290) /**
291) * @brief convert string to IPv4/port address
292) * @param[in] str string containing IPv4/port address
293) * @throws std::exception in case of error
294) */
295) void Config::str2addr(std::string const &str, struct sockaddr_in &addr)
296) {
297) // split address into IPv4 and port
298) std::vector<std::string> fields;
299) split_chr(str, ':', fields);
300) if (fields.size() != 2) {
301) std::stringstream msg;
302) msg << "expected \"<IPv4>:<port>\", found \"" << str << "\"";
303) throw std::runtime_error(msg.str());
304) }
305) std::string &strIPv4 = fields[0], &strPort = fields[1];
306)
307) // parse IPv4 address
308) if (! inet_aton(strIPv4.c_str(), &addr.sin_addr)) {
309) std::stringstream msg;
310) msg << "invalid IPv4 \"" << strIPv4 << "\"";
311) throw std::runtime_error(msg.str());
312) }
313)
314) // parse port
315) unsigned long port;
316) try {
317) port = str2ul(strPort);
318) if (port == 0 || port > 65535) {
319) throw std::runtime_error("port number out of range");
320) }
321) } catch (std::exception &ex) {
322) std::stringstream msg;
323) msg << "invalid port number \"" << strPort << "\": " << ex.what();
324) throw std::runtime_error(msg.str());
325) }
326) addr.sin_port = htons(port);
327)
328) // fin in remaining fields of address structure
329) addr.sin_family = AF_INET;
330) }
331)
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
332) /**
333) * @brief read config file
334) * @param[in] configFile name of config file
335) * @throws std::exception in case of error
336) */
337) void Config::readFile(std::string const &configFile)
338) {
339) // open file
340) std::ifstream cf(configFile.c_str(), std::ios::in);
341) if (! cf.is_open()) {
342) std::stringstream msg;
343) msg << "cannot open config file \"" << configFile << "\" for reading";
344) throw std::runtime_error(msg.str());
345) }
346)
347) // read lines and process them
348) std::string line;
349) size_t no;
350) for (no = 1; std::getline(cf, line); ++no) {
351) // process line
352) try {
353) procLine(line);
354) } catch (std::exception &ex) {
355) std::stringstream msg;
356) msg << "error in line " << no << " of config file \"" << configFile
357) << "\": " << ex.what();
358) throw std::runtime_error(msg.str());
359) }
360) }
361)
362) // close file
363) cf.close();
|
implement drawing pixels
Stefan Schuermans authored 7 years ago
|
364)
365) // update internal data
366) update();
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
367) }
368)
369) /**
370) * @brief process line from config file
371) * @param[in] line line to process
372) * @throws std::exception in case of error
373) */
374) void Config::procLine(std::string line)
375) {
376) // remove comment ("# ...")
377) size_t commentStart = line.find("#");
378) if (commentStart != std::string::npos) {
379) line.erase(commentStart);
380) }
381)
382) trim(line);
383)
384) // ignore empty lines
385) if (line.empty()) {
386) return;
387) }
388)
389) // split line at equal sign
390) size_t equalSign = line.find("=");
391) if (equalSign == std::string::npos) {
392) std::stringstream msg;
393) msg << "no equal sign found in \"" << line << "\"";
394) throw std::runtime_error(msg.str());
395) }
396) std::string setting = line.substr(0, equalSign);
397) std::string value = line.substr(equalSign + 1);
398) trim(setting);
399) trim(value);
400)
401) procSetting(setting, value);
402) }
403)
404) /**
405) * @brief process setting from config file
406) * @param[in] setting name of the setting
407) * @param[in] value value for setting
408) * @throws std::exception in case of error
409) */
410) void Config::procSetting(std::string const &setting, std::string const &value)
411) {
412) std::vector<std::string> setFields, valFields;
413) split(setting, setFields);
414) split(value, valFields);
415)
416) // empty setting
417) if (setFields.size() < 1) {
418) throw std::runtime_error("empty setting name");
419) }
420)
421) // distributor
422) if (setFields[0] == "distributor") {
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
423) proc_distributor(setFields, valFields);
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
424) }
425) // distributor address
426) else if (setFields[0] == "distributorAddr") {
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
427) proc_distributorAddr(setFields, valFields);
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
428) }
429) // mapping
430) else if (setFields[0] == "mapping") {
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
431) proc_mapping(setFields, valFields);
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
432) }
433) // output
434) else if (setFields[0] == "output") {
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
435) proc_output(setFields, valFields);
|
begin of config file parsing
Stefan Schuermans authored 7 years ago
|
436) }
437) // unknown setting
438) else {
439) std::stringstream msg;
440) msg << "unknown setting \"" << setting << "\"";
441) throw std::runtime_error(msg.str());
442) }
443) }
444)
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
445) /**
446) * @brief process distributor line from config file
447) * @param[in] setFields fields of the setting parts
448) * @param[in] valFields fields of the value part
449) * @throws std::exception in case of error
450) */
451) void Config::proc_distributor(std::vector<std::string> const &setFields,
452) std::vector<std::string> const &valFields)
453) {
454) // check number of setting fields
455) if (setFields.size() != 2) {
456) std::stringstream msg;
457) msg << "invalid \"distributor\" setting with " << setFields.size()
458) << " fields, expected \"distributor <distno>\"";
459) throw std::runtime_error(msg.str());
460) }
461)
462) // get and check distributor number
463) unsigned long distno;
464) try {
465) distno = str2ul(setFields[1]);
466) } catch (std::exception &ex) {
467) std::stringstream msg;
468) msg << "invalid distributor number \"" << setFields[1] << "\": "
469) << ex.what();
470) throw std::runtime_error(msg.str());
471) }
472) if (m_distriMap.find(distno) != m_distriMap.end()) {
473) std::stringstream msg;
474) msg << "duplicate \"distributor " << distno << "\" setting";
475) throw std::runtime_error(msg.str());
476) }
477)
478) // check number of value fields
479) if (valFields.size() != 1) {
480) std::stringstream msg;
481) msg << "invalid value for \"distributor " << distno << "\": "
482) << setFields.size() << " fields, expected \"<outputs>,<pixels>\"";
483) throw std::runtime_error(msg.str());
484) }
485)
486) // get and check outputs and pixels per output
487) unsigned long outputs, pixels;
488) try {
489) str2ul2(valFields[0], outputs, pixels);
490) if (outputs < 1) {
491) std::stringstream msg;
492) msg << "invalid number of outputs \"" << outputs << "\"";
493) throw std::runtime_error(msg.str());
494) }
495) if (pixels < 1) {
496) std::stringstream msg;
497) msg << "invalid number of pixels per output \"" << pixels << "\"";
498) throw std::runtime_error(msg.str());
499) }
500) } catch (std::exception &ex) {
501) std::stringstream msg;
502) msg << "invalid value for \"distributor " << distno << "\": "
503) << ex.what();
504) throw std::runtime_error(msg.str());
505) }
506)
507) // create distributor
508) m_distriMap[distno].init(distno, outputs, pixels);
509) }
510)
511) /**
512) * @brief process distributorAddr line from config file
513) * @param[in] setFields fields of the setting parts
514) * @param[in] valFields fields of the value part
515) * @throws std::exception in case of error
516) */
517) void Config::proc_distributorAddr(std::vector<std::string> const &setFields,
518) std::vector<std::string> const &valFields)
519) {
520) // check number of setting fields
521) if (setFields.size() != 2) {
522) std::stringstream msg;
523) msg << "invalid \"distributorAddr\" setting with " << setFields.size()
524) << " fields, expected \"distributorAddr <distno>\"";
525) throw std::runtime_error(msg.str());
526) }
527)
528) // get distributor
529) Distri &distri = getDistri(setFields[1]);
530)
531) // check number of value fields
532) if (valFields.size() != 1) {
533) std::stringstream msg;
534) msg << "invalid value for \"distributorAddr " << distri.getNo() << "\": "
535) << setFields.size() << " fields, expected \"<IPv4>:<port>\"";
536) throw std::runtime_error(msg.str());
537) }
538)
539) // parse address
|
complete implementation of...
Stefan Schuermans authored 7 years ago
|
540) struct sockaddr_in addr;
541) try {
542) str2addr(valFields[0], addr);
543) } catch (std::exception &ex) {
544) std::stringstream msg;
545) msg << "invalid value for \"mdistributorAddr " << distri.getNo() << "\": "
546) << ex.what();
547) throw std::runtime_error(msg.str());
548) }
549)
550) // set address
551) distri.setAddr(addr);
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
552) }
553)
554) /**
555) * @brief process mapping line from config file
556) * @param[in] setFields fields of the setting parts
557) * @param[in] valFields fields of the value part
558) * @throws std::exception in case of error
559) */
560) void Config::proc_mapping(std::vector<std::string> const &setFields,
561) std::vector<std::string> const &valFields)
562) {
563) // check number of setting fields
564) if (setFields.size() != 3) {
565) std::stringstream msg;
566) msg << "invalid \"mapping\" setting with " << setFields.size()
567) << " fields, expected \"mapping <distno> [red|green|blue]\"";
568) throw std::runtime_error(msg.str());
569) }
570)
571) // get distributor
572) Distri &distri = getDistri(setFields[1]);
573)
574) // get channel
575) std::string strColor = setFields[2];
576) Mapping::Channel channel;
577) if (strColor == "red" ) {
578) channel = Mapping::Red;
579) } else if (strColor == "green" ) {
580) channel = Mapping::Green;
581) } else if (strColor == "blue" ) {
582) channel = Mapping::Blue;
583) } else {
584) std::stringstream msg;
585) msg << "invalid \"mapping\" setting: unknown color \"" << strColor
586) << "\" fields, expected \"red\", \"green\" or \"blue\"";
587) throw std::runtime_error(msg.str());
588) }
589)
590) // check number of value fields
591) if (valFields.size() != 3) {
592) std::stringstream msg;
593) msg << "invalid value for \"mapping " << distri.getNo() << " "
594) << strColor << "\": " << setFields.size()
595) << " fields, expected \"<base> <factor> <gamma>\"";
596) throw std::runtime_error(msg.str());
597) }
598)
599) // parse value fields
600) double base, factor, gamma;
601) try {
602) base = str2d(valFields[0]);
603) } catch (std::exception &ex) {
604) std::stringstream msg;
605) msg << "invalid value for \"mapping " << distri.getNo() << " "
606) << strColor << "\": invalid value \"" << valFields[0]
607) << "\"for \"base\": " << ex.what();
608) throw std::runtime_error(msg.str());
609) }
610) try {
611) factor = str2d(valFields[1]);
612) } catch (std::exception &ex) {
613) std::stringstream msg;
614) msg << "invalid value for \"mapping " << distri.getNo() << " "
615) << strColor << "\": invalid value \"" << valFields[1]
616) << "\"for \"factor\": " << ex.what();
617) throw std::runtime_error(msg.str());
618) }
619) try {
620) gamma = str2d(valFields[2]);
621) if (gamma <= 0.0) {
622) throw std::runtime_error("gamma value must be positive");
623) }
624) } catch (std::exception &ex) {
625) std::stringstream msg;
626) msg << "invalid value for \"mapping " << distri.getNo() << " "
627) << strColor << "\": invalid value \"" << valFields[2]
628) << "\"for \"base\": " << ex.what();
629) throw std::runtime_error(msg.str());
630) }
631)
632) // set mapping of distributor
633) distri.setMapping(channel, Mapping(base, factor, gamma));
634) }
635)
636) /**
637) * @brief process output line from config file
638) * @param[in] setFields fields of the setting parts
639) * @param[in] valFields fields of the value part
640) * @throws std::exception in case of error
641) */
642) void Config::proc_output(std::vector<std::string> const &setFields,
643) std::vector<std::string> const &valFields)
644) {
645) // check number of setting fields
646) if (setFields.size() != 2) {
647) std::stringstream msg;
648) msg << "invalid \"output\" setting with " << setFields.size()
649) << " fields, expected \"output <distno>,<outno>\"";
650) throw std::runtime_error(msg.str());
651) }
652)
653) // parse distributor and output numbers
654) unsigned long distno, outno;
655) try {
656) str2ul2(setFields[1], distno, outno);
657) } catch (std::exception &ex) {
658) std::stringstream msg;
659) msg << "invalid output specifier \"" << setFields[1]
660) << "\": expected \"<distno>,<outno>\": " << ex.what();
661) throw std::runtime_error(msg.str());
662) }
663)
664) // get distributor
665) Distri &distri = getDistri(distno);
666)
667) // check output number
668) unsigned long outputs = distri.getOutputs();
669) if (outno > outputs) {
670) std::stringstream msg;
671) msg << "invalid output number " << outno << " for distributor " << distno
672) << ": only " << outputs << " outputs available";
673) throw std::runtime_error(msg.str());
674) }
675)
|
complete implementation of...
Stefan Schuermans authored 7 years ago
|
676) // add output to distributor
677) try {
678) distri.addOutput(outno);
679) } catch (std::exception &ex) {
680) std::stringstream msg;
681) msg << "cannot add output " << outno << " to distributor " << distno
682) << ": " << ex.what();
683) throw std::runtime_error(msg.str());
684) }
685)
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
686) // parse all pixels
687) std::vector<std::string>::const_iterator pix;
688) unsigned long p;
689) for (pix = valFields.begin(), p = 0; pix != valFields.end(); ++pix, ++p) {
690) // parse pixel description
691) double x, y, r;
692) try {
693) str2d3(*pix, x, y, r);
694) } catch (std::exception &ex) {
695) std::stringstream msg;
696) msg << "invalid pixel description \"" << *pix << "\" for pixel "
697) << p << " at output " << outno << " of distributor " << distno
698) << ": expected \"<x>,<y>,<r>\": " << ex.what();
699) throw std::runtime_error(msg.str());
700) }
701) // add pixel
|
complete implementation of...
Stefan Schuermans authored 7 years ago
|
702) try {
703) distri.addPixel(outno, Pixel(x, y, r));
704) } catch (std::exception &ex) {
705) std::stringstream msg;
706) msg << "cannot add pixel \"" << *pix << "\" (pixel "
707) << p << ") to output " << outno << " of distributor " << distno
708) << ": " << ex.what();
709) throw std::runtime_error(msg.str());
710) }
|
continue implementing confi...
Stefan Schuermans authored 7 years ago
|
711) } // for pixel
712) }
713)
714) /**
715) * @brief get distributor
716) * @param[in] strDistno distributor number as string
717) * @return reference to distributor object in map
718) * @throws std::exception in case of error
719) */
720) Distri & Config::getDistri(std::string const &strDistno)
721) {
722) unsigned long distno;
723) try {
724) distno = str2ul(strDistno);
725) } catch (std::exception &ex) {
726) std::stringstream msg;
727) msg << "invalid distributor number \"" << strDistno << "\": "
728) << ex.what();
729) throw std::runtime_error(msg.str());
730) }
731) return getDistri(distno);
732) }
733)
734) /**
735) * @brief get distributor
736) * @param[in] distno distributor number
737) * @return reference to distributor object in map
738) * @throws std::exception in case of error
739) */
740) Distri & Config::getDistri(unsigned long distno)
741) {
742) DistriMap::iterator distri = m_distriMap.find(distno);
743) if (distri == m_distriMap.end()) {
744) std::stringstream msg;
745) msg << "no distributor with number \"" << distno << "\" found";
746) throw std::runtime_error(msg.str());
747) }
748) return distri->second;
749) }
750)
|