@@ -54,13 +54,27 @@ class Concore{
5454#endif
5555
5656 public:
57+ enum class ReadStatus {
58+ SUCCESS,
59+ TIMEOUT,
60+ PARSE_ERROR,
61+ FILE_NOT_FOUND,
62+ RETRIES_EXCEEDED
63+ };
64+
65+ struct ReadResult {
66+ ReadStatus status;
67+ vector<double > data;
68+ };
69+
5770 double delay = 1 ;
5871 int retrycount = 0 ;
5972 double simtime;
6073 int maxtime = 100 ;
6174 map <string, int > iport;
6275 map <string, int > oport;
6376 map <string, string> params;
77+ ReadStatus last_read_status = ReadStatus::SUCCESS;
6478
6579 /* *
6680 * @brief Constructor for Concore class.
@@ -372,6 +386,14 @@ class Concore{
372386 return read_FM (port, name, initstr);
373387 }
374388
389+ ReadResult read_result (int port, string name, string initstr)
390+ {
391+ ReadResult result;
392+ result.data = read (port, name, initstr);
393+ result.status = last_read_status;
394+ return result;
395+ }
396+
375397 /* *
376398 * @brief Reads data from a specified port and name using the FM (File Method) communication protocol.
377399 * @param port The port number.
@@ -383,6 +405,7 @@ class Concore{
383405 chrono::milliseconds timespan ((int )(1000 *delay));
384406 this_thread::sleep_for (timespan);
385407 string ins;
408+ ReadStatus status = ReadStatus::SUCCESS;
386409 try {
387410 ifstream infile;
388411 infile.open (inpath+to_string (port)+" /" +name, ios::in);
@@ -393,10 +416,13 @@ class Concore{
393416 infile.close ();
394417 }
395418 else {
419+ status = ReadStatus::FILE_NOT_FOUND;
396420 throw 505 ;}
397421 }
398422 catch (...) {
399423 ins = initstr;
424+ if (status == ReadStatus::SUCCESS)
425+ status = ReadStatus::FILE_NOT_FOUND;
400426 }
401427
402428 int retry = 0 ;
@@ -424,14 +450,24 @@ class Concore{
424450 }
425451 retry++;
426452 }
453+ if ((int )ins.length ()==0 )
454+ status = ReadStatus::RETRIES_EXCEEDED;
427455 s += ins;
428456
429457 vector<double > inval = parser (ins);
430- if (inval.empty ())
458+ if (inval.empty ()) {
459+ if (status == ReadStatus::SUCCESS)
460+ status = ReadStatus::PARSE_ERROR;
431461 inval = parser (initstr);
432- if (inval.empty ())
462+ }
463+ if (inval.empty ()) {
464+ if (status == ReadStatus::SUCCESS)
465+ status = ReadStatus::PARSE_ERROR;
466+ last_read_status = status;
433467 return inval;
468+ }
434469 simtime = simtime > inval[0 ] ? simtime : inval[0 ];
470+ last_read_status = status;
435471
436472 // returning a string with data excluding simtime
437473 inval.erase (inval.begin ());
@@ -450,6 +486,7 @@ class Concore{
450486 chrono::milliseconds timespan ((int )(1000 *delay));
451487 this_thread::sleep_for (timespan);
452488 string ins = " " ;
489+ ReadStatus status = ReadStatus::SUCCESS;
453490 try {
454491 if (shmId_get != -1 ) {
455492 if (sharedData_get && sharedData_get[0 ] != ' \0 ' ) {
@@ -463,10 +500,13 @@ class Concore{
463500 }
464501 else
465502 {
503+ status = ReadStatus::FILE_NOT_FOUND;
466504 throw 505 ;
467505 }
468506 } catch (...) {
469507 ins = initstr;
508+ if (status == ReadStatus::SUCCESS)
509+ status = ReadStatus::FILE_NOT_FOUND;
470510 }
471511
472512 int retry = 0 ;
@@ -490,14 +530,24 @@ class Concore{
490530 }
491531 retry++;
492532 }
533+ if ((int )ins.length ()==0 )
534+ status = ReadStatus::RETRIES_EXCEEDED;
493535 s += ins;
494536
495537 vector<double > inval = parser (ins);
496- if (inval.empty ())
538+ if (inval.empty ()) {
539+ if (status == ReadStatus::SUCCESS)
540+ status = ReadStatus::PARSE_ERROR;
497541 inval = parser (initstr);
498- if (inval.empty ())
542+ }
543+ if (inval.empty ()) {
544+ if (status == ReadStatus::SUCCESS)
545+ status = ReadStatus::PARSE_ERROR;
546+ last_read_status = status;
499547 return inval;
548+ }
500549 simtime = simtime > inval[0 ] ? simtime : inval[0 ];
550+ last_read_status = status;
501551
502552 // returning a string with data excluding simtime
503553 inval.erase (inval.begin ());
@@ -674,15 +724,26 @@ class Concore{
674724 * @return a vector of double values
675725 */
676726 vector<double > read_ZMQ (string port_name, string name, string initstr) {
727+ ReadStatus status = ReadStatus::SUCCESS;
677728 auto it = zmq_ports.find (port_name);
678729 if (it == zmq_ports.end ()) {
679730 cerr << " read_ZMQ: port '" << port_name << " ' not initialized" << endl;
731+ status = ReadStatus::FILE_NOT_FOUND;
732+ last_read_status = status;
680733 return parser (initstr);
681734 }
682735 vector<double > inval = it->second ->recv_with_retry ();
683- if (inval.empty ())
736+ if (inval.empty ()) {
737+ status = ReadStatus::TIMEOUT;
684738 inval = parser (initstr);
685- if (inval.empty ()) return inval;
739+ }
740+ if (inval.empty ()) {
741+ if (status == ReadStatus::SUCCESS)
742+ status = ReadStatus::PARSE_ERROR;
743+ last_read_status = status;
744+ return inval;
745+ }
746+ last_read_status = status;
686747 simtime = simtime > inval[0 ] ? simtime : inval[0 ];
687748 s += port_name;
688749 inval.erase (inval.begin ());
@@ -736,6 +797,13 @@ class Concore{
736797 return read_ZMQ (port_name, name, initstr);
737798 }
738799
800+ ReadResult read_result (string port_name, string name, string initstr) {
801+ ReadResult result;
802+ result.data = read (port_name, name, initstr);
803+ result.status = last_read_status;
804+ return result;
805+ }
806+
739807 /* *
740808 * @brief deviate the write to ZMQ communication protocol when port identifier is a string key.
741809 * @param port_name The ZMQ port name.
0 commit comments