Owl Positioning System: a Wi-Fi-based, infrastructure-centred indoor positioning system. http://owlps.pu-pm.univ-fcomte.fr/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

csvstringreader.cc 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * This file is part of the Owl Positioning System (OwlPS) project.
  3. * It is subject to the copyright notice and license terms in the
  4. * COPYRIGHT.t2t file found in the top-level directory of this
  5. * distribution and at
  6. * https://code.lm7.fr/mcy/owlps/src/master/COPYRIGHT.t2t
  7. * No part of the OwlPS Project, including this file, may be copied,
  8. * modified, propagated, or distributed except according to the terms
  9. * contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be
  10. * distributed along with this file, either separately or by replacing
  11. * this notice by the COPYRIGHT.t2t file's contents.
  12. */
  13. #include "csvstringreader.hh"
  14. #include "point3d.hh"
  15. #include <iostream>
  16. using namespace std ;
  17. using boost::tokenizer ;
  18. using boost::escaped_list_separator ;
  19. using boost::lexical_cast ;
  20. using boost::bad_lexical_cast ;
  21. /* *** Constructors *** */
  22. CSVStringReader::
  23. CSVStringReader(const std::string &_str, const char _separator):
  24. separator(_separator), current_token(nullptr), current_field_nb(0)
  25. {
  26. set_str(_str) ;
  27. }
  28. CSVStringReader::~CSVStringReader()
  29. {
  30. delete current_token ;
  31. }
  32. /* *** Accessors *** */
  33. /**
  34. * @returns `false` in case of error (EOF, etc.), `true` else.
  35. */
  36. void CSVStringReader::set_str(const string &_str)
  37. {
  38. str = _str ;
  39. delete current_token ;
  40. // Split read string into fields (semicolon-separated)
  41. current_token = new tokenizer<escaped_list_separator<char> >(
  42. str, escaped_list_separator<char>('\\', separator, '\"')) ;
  43. token_iterator = current_token->begin() ;
  44. current_field_nb = 0 ;
  45. }
  46. /* *** Operations *** */
  47. bool CSVStringReader::read_timestamp(Timestamp &t)
  48. {
  49. string timestamp_str ;
  50. uint_fast32_t time_s, time_ns ;
  51. if (! read_field(timestamp_str))
  52. return false ;
  53. tokenizer<escaped_list_separator<char> > tok(
  54. timestamp_str, escaped_list_separator<char>('\\', '.', '\"')) ;
  55. auto tok_iter = tok.begin() ;
  56. if (tok_iter == tok.end())
  57. return false ;
  58. try
  59. {
  60. time_s = lexical_cast<uint_fast32_t>(*tok_iter) ;
  61. }
  62. catch (bad_lexical_cast &e)
  63. {
  64. print_error_cast() ;
  65. return false ;
  66. }
  67. ++tok_iter ;
  68. if (tok_iter == tok.end())
  69. return false ;
  70. try
  71. {
  72. time_ns = lexical_cast<uint_fast32_t>(*tok_iter) ;
  73. }
  74. catch (bad_lexical_cast &e)
  75. {
  76. print_error_cast() ;
  77. return false ;
  78. }
  79. t = Timestamp(time_s, time_ns) ;
  80. return true ;
  81. }
  82. /**
  83. * The first field (X) can start with an opening parenthesis, and the
  84. * last one (Z) can finish with a closing parenthesis.
  85. *
  86. * @param[out] p The variable in which the read Point3D will be stored.
  87. * It is left untouched if a full Point3D cannot be read successfuly.
  88. *
  89. * @returns `true` if the Point3D was read successfuly.
  90. * @returns `false` in case of error.
  91. */
  92. bool CSVStringReader::read_point3d(Point3D &p)
  93. {
  94. float coord[3] ;
  95. for (unsigned int i = 0 ; i < 3 ; ++i)
  96. {
  97. if (token_iterator == current_token->end())
  98. return false ;
  99. ++current_field_nb ;
  100. string field = *token_iterator ;
  101. if (field.empty())
  102. return false ;
  103. /* Handle a leading '(' and a trailing ')' */
  104. if (i == 0 && field.front() == '(')
  105. field.erase(field.begin()) ;
  106. if (i == 2 && field.back() == ')')
  107. field.pop_back() ;
  108. try
  109. {
  110. coord[i] = lexical_cast<float>(field) ;
  111. }
  112. catch (bad_lexical_cast &e)
  113. {
  114. print_error_cast() ;
  115. return false ;
  116. }
  117. ++token_iterator ;
  118. }
  119. p.set_coordinates(coord) ;
  120. return true ;
  121. }
  122. void CSVStringReader::print_error_cast() const
  123. {
  124. cerr
  125. << "Bad value \"" << *token_iterator
  126. << "\" at field #" << current_field_nb
  127. << ", of CSV string \"" << str << "\"!" << endl ;
  128. }