/* Blinker
   Copyright 2011-2019 Stefan Schuermans <stefan@blinkenarea.org>
   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
   a blinkenarea.org project */

#include <sstream>
#include <string>

#include "SerCfg.h"
#include "StringParser.h"

namespace Blinker {

/// constructor
SerCfg::SerCfg():
  m_baud(9600),
  m_data(8),
  m_parity(ParityNone),
  m_stop(1)
{
}

/**
 * @brief parse from string format
 * @param[in] str string format
 * @return if parsing was successful
 */
bool SerCfg::fromStr(const std::string &str)
{
  StringParser parser(str);
  unsigned int baud, data, stop;
  char parityChr;

  if (!parser.uintMin(1, baud) ||
      !parser.fixChr(','))
    return false;
  if (parser.uintMin(1, data)) { // data bits, parity
    if (!parser.fixChr(',') ||
        !parser.oneChrOf("nNeEoO", parityChr))
      return false;
  } else { // parity, data bits
    if (!parser.oneChrOf("nNeEoO", parityChr) ||
        !parser.fixChr(',') ||
        !parser.uintMin(1, data))
      return false;
  }
  if (!parser.fixChr(',') ||
      !parser.uintMin(1, stop) ||
      !parser.isDone())
    return false;
  m_baud = baud;
  m_data = data;
  switch (parityChr) {
    case 'n': case 'N': m_parity = ParityNone; break;
    case 'e': case 'E': m_parity = ParityEven; break;
    case 'o': case 'O': m_parity = ParityOdd; break;
  }
  m_stop = stop;
  return true;
}

/**
 * @brief convert to string format
 * @return string format
 */
std::string SerCfg::toStr() const
{
  std::stringstream strm;
  strm << m_baud << "," << m_data << ",";
  switch (m_parity) {
    case ParityNone: strm << "N"; break;
    case ParityEven: strm << "E"; break;
    case ParityOdd:  strm << "O"; break;
  }
  strm << "," << m_stop;
  return strm.str();
}

} // namespace Blinker

