Advertisement
Garey

serial.h

Nov 26th, 2018
608
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 22.97 KB | None | 0 0
  1. /*!
  2.  * \file serial/serial.h
  3.  * \author  Stf Kolev <inkyz@gmail.com>
  4.  * \version 0.1
  5.  *
  6.  * Copyright (c) 2018 Stf Kolev
  7.  *
  8.  * \section DESCRIPTION
  9.  *
  10.  * This provides a cross platform interface for interacting with Serial Ports.
  11.  */
  12.  
  13. #ifndef SERIAL_H
  14. #define SERIAL_H
  15.  
  16. #include <limits>
  17. #include <vector>
  18. #include <string>
  19. #include <cstring>
  20. #include <sstream>
  21. #include <exception>
  22. #include <stdexcept>
  23. #include <serial/v8stdint.h>
  24.  
  25. #define THROW(exceptionClass, message) throw exceptionClass(__FILE__, \
  26. __LINE__, (message) )
  27.  
  28. namespace serial {
  29.    
  30.     /*!
  31.      * Enumeration defines the possible bytesizes for the serial port.
  32.      */
  33.     typedef enum {
  34.         fivebits = 5,
  35.         sixbits = 6,
  36.         sevenbits = 7,
  37.         eightbits = 8,
  38.     } bytesize_t;
  39.  
  40.     /*!
  41.      * Enumeration defines the possible parity types for the serial port.
  42.      */
  43.     typedef enum {
  44.         parity_none = 0,
  45.         parity_odd = 1,
  46.         parity_even = 2,
  47.         parity_mark = 3,
  48.         parity_space = 4,
  49.     } parity_t;
  50.  
  51.     /*!
  52.      * Enumeration defines the possible stopbit types for the serial port.
  53.      */
  54.     typedef enum {
  55.         stopbits_one = 1,
  56.         stopbits_two = 2,
  57.         stopbits_one_point_five
  58.     } stopbits_t;
  59.  
  60.     /*!
  61.      * Enumeration defines the possible flowcontrol types for the serial port.
  62.      */
  63.     typedef enum {
  64.         flowcontrol_none = 0,
  65.         flowcontrol_software,
  66.         flowcontrol_hardware
  67.     } flowcontrol_t;
  68.  
  69.     /*!
  70.      * Structure for setting the timeout of the serial port, times are
  71.      * in milliseconds.
  72.      *
  73.      * In order to disable the interbyte timeout, set it to Timeout::max()
  74.      */
  75.     struct Timeout {
  76.         #ifdef max
  77.         #undef max
  78.         #endif
  79.  
  80.         static uint32_t max() { return std::numeric_limits<uint32_t>::max(); }
  81.  
  82.         /*!
  83.          * Convenience function to generate Timeout structs using a
  84.          * single absolute timeout.
  85.          *
  86.          * \param timeout A long that defines the time in milliseconds until a
  87.          * timeout occurs after a call to read or write is made.
  88.          *
  89.          * \return Timeout struct that represents this simple timeout provided.
  90.          */
  91.         static Timeout simpleTimeout(uint32_t timeout) {
  92.             return Timeout(max(), timeout, 0, timeout, 0);
  93.         }
  94.  
  95.         /*! Number of milliseconds between bytes received to timeout on. */
  96.         uint32_t inter_byte_timeout;
  97.  
  98.         /*! A constant number of milliseconds to wait after calling read. */
  99.         uint32_t read_timeout_constant;
  100.  
  101.         /*! A multiplier against the number of requested bytes to wait after
  102.          *  calling read.
  103.          */
  104.         uint32_t  read_timeout_multiplier;
  105.  
  106.         /*! A constant number of milliseconds to wait after calling write. */
  107.         uint32_t write_timeout_constant;
  108.  
  109.         /*! A multiplier against the number of requested bytes to wait after
  110.          *  calling write.
  111.          */
  112.         uint32_t write_timeout_multiplier;
  113.  
  114.         explicit Timeout(uint32_t inter_byte_timeout_ = 0,
  115.                          uint32_t read_timeout_constant_ = 0,
  116.                          uint32_t read_timeout_multiplier_ = 0,
  117.                          uint32_t write_timeout_constant_ = 0,
  118.                          uint32_t write_timeout_multiplier_ = 0,
  119.             ) : inter_byte_timeout(inter_byte_timeout_),
  120.                 read_timeout_constant(read_timeout_constant_),
  121.                 read_timeout_multiplier(read_timeout_multiplier_),
  122.                 write_timeout_constant(write_timeout_constant_),
  123.                 write_timeout_multiplier(write_timeout_multiplier_)
  124.             {};
  125.     };
  126.  
  127.     /*!
  128.      * Class that provides portable serial port interface.
  129.      */
  130.     class Serial {
  131.     public:
  132.         /*!
  133.          * Creates a Serial object and opens port if a port is specified,
  134.          * otherwise it remains closed until serial::Serial::open is called.
  135.          *
  136.          * \param port A std::string containing the address of the serial port,
  137.          *        which would be something like 'COM1' on windows and '/dev/tty50'
  138.          *        on Linux.
  139.          *
  140.          * \param baudrate An unsigned 32-bit integer that represents the baudrate.
  141.          *
  142.          * \param timeout a serial::Timeout struct that defines the timeout
  143.          *        conditions for the serial ports. \see serial::Timeout
  144.          *
  145.          * \param bytesize The size of each byte in the serial transmission of data,
  146.          *        default is eightbits, possible values are: fivebits, sixbits, sevenbits,
  147.          *        eightbits
  148.          *
  149.          * \param parity Method of parity, default is parity_none, possible values are:
  150.          *        parity_none, parity_odd, parity_even
  151.          *
  152.          * \param stopbits Number of stop bits used, default is stopbits_one,
  153.          *        possible values: stopbits_one, stopbits_one_point_five,
  154.          *        stopbits_two
  155.          *
  156.          * \param flowcontrol Type of flowcontrol used, default is
  157.          *        flowcontrol_none, possible values are: flowcontrol_none,
  158.          *        flowcontrol_software, flowcontrol_hardware
  159.          *
  160.          * \throw serial::PortNotOpenedException
  161.          * \throw serial::IOException
  162.          * \throw std::invalid_argument
  163.          */
  164.         Serial(const std::string &port = "",
  165.                uint32_t baudrate = 9600,
  166.                Timeout timeout = Timeout(),
  167.                bytesize_t bytesize = eightbits,
  168.                parity_t parity = parity_none,
  169.                stopbits_t stopbits = stopbits_one,
  170.                flowcontrol_t flowcontrol = flowcontrol_none
  171.         );
  172.  
  173.         /*! Destructor */
  174.         virtual ~Serial();
  175.  
  176.         /*!
  177.          * Opens the serial port as long as the port is set and the port isn't
  178.          * already open.
  179.          *
  180.          * If port is provided to the constructor then explicit call to open
  181.          * is not needed.
  182.          *
  183.          * \see serial::Serial
  184.          *
  185.          * \throw std::invalid_argument
  186.          * \throw serial::SerialException
  187.          * \throw serial::IOException
  188.          */
  189.         auto open() -> void;
  190.  
  191.         /*! Closes the serial port. */
  192.         auto close() -> void;
  193.  
  194.         /*! Retrieves the number of characters in the buffer .*/
  195.         std::size_t available();
  196.  
  197.         /*! Block until there is serial data to read or read_timeout_constant
  198.          * number of milliseconds have elapsed. The return value is true when
  199.          * the function exits with the port in a readable state, false otherwise
  200.          * (due to timeout  or select interruption)
  201.          */
  202.         auto waitReadable() -> bool;
  203.  
  204.         /*! Blocks for a period of time corresponding to the transmission time of
  205.          * count characters at present serial settings. This may be used in con-
  206.          * juction with waitReadable() to read larger blocks of data from the
  207.          * port.
  208.          */
  209.         auto waiteByteTimes(std::size_t count) -> void;
  210.  
  211.         /*! Read a given amount of bytes from the serial port into a given buffer.
  212.          *
  213.          * The read function will return in one of three cases:
  214.          *  * The number of requested bytes was read.
  215.          *    * In this case the number of bytes requested will match the size_t
  216.          *      returned by read.
  217.          *  * A timeout occured, in this case the number of bytes read will not
  218.          *    match the amount requested, but no exception will be thrown. One of
  219.          *    two possible timeouts occured:
  220.          *    * The inter byte timeout expired, this means the number of
  221.          *      milliseconds elapsed between receiving bytes from serial port
  222.          *      exceeded the inter byte timeout.
  223.          *    * The total timeout expired, which is calculated by multiplying the
  224.          *      read timeout multiplier by the number of requested bytes and then
  225.          *      added to the read timeout constant. If that total number of
  226.          *      milliseconds elapses after the initial call to read a timeout will
  227.          *      occur.
  228.          *  * An exception occured, in this case an actual exception will occur.
  229.          *
  230.          * \param buffer An uint8_t array of at least the requested size.
  231.          * \param size A std::size_t defining how many bytes to be read.
  232.          *
  233.          * \return A std::size_t representing the number of bytes read as a result
  234.          *         of the call to read.
  235.          *
  236.          * \throw serial::PortNotOpenedException
  237.          * \throw serial::SerialException
  238.          */
  239.         auto read(uint8_t *buffer, std::size_t size) -> std::size_t;
  240.  
  241.         /*! Read a given amount of bytes from the serial port into the buffer
  242.          *
  243.          * \param buffer A reference to std::vector of uint8_t.
  244.          * \param size A size_t defining how many bytes to be read.
  245.          *
  246.          * \return A std::size_t representing the number of bytes read as a result
  247.          *         of the call to read.
  248.          *
  249.          * \throw serial::PortNotOpenedException
  250.          * \throw serial::SerialException
  251.          */
  252.         auto read(std::vector<uint8_t> &buffer, std::size_t size = 1) -> std::size_t;
  253.  
  254.         /*! Read a given amount of bytes from the serial port into the buffer
  255.          *
  256.          * \param buffer A reference to std::string.
  257.          * \param size A size_t defining how many bytes to be read.
  258.          *
  259.          * \return A std::size_t representing the number of bytes read as a result
  260.          *         of the call to read.
  261.          *
  262.          * \throw serial::PortNotOpenedException
  263.          * \throw serial::SerialException
  264.          */
  265.         auto read(std::string &buffer, std::size_t size = 1)->std::size_t;
  266.  
  267.         /*! Read a given amount of bytes from the serial port and return a string
  268.          * containing the data.
  269.          *
  270.          * \param size A std::size_t defining how many bytes to be read.
  271.          *
  272.          * \return A std::string containing the data read from the port.
  273.          *
  274.          * \throw serial::PortNotOpenedException
  275.          * \throw serial::SerialException
  276.          */
  277.         auto read(std::size_t size = 1) -> std::string;
  278.  
  279.         /*! Reads a line or until a given delimiter has been processed.
  280.          *
  281.          * Reads from the serial port until a single line has been read.
  282.          *
  283.          * \param buffer A std::string reference used to be stored data.
  284.          * \param size A std::size defining the maximum length of the line.
  285.          *        Defaults to 65536 or (2^16).
  286.          * \param eol A std::string to match against for the EOL.
  287.          *
  288.          * \return A std::size_t representing the number of bytes read.
  289.          *
  290.          * \throw serial::PortNotOpenedException
  291.          * \throw serial::SerialException
  292.          */
  293.         auto readline(std::string &buffer, std::size_t size = 65536, std::string eol = '\n') -> std::size_t;
  294.  
  295.         /*! Reads in a line or until a given delimiter has been processed.
  296.          *
  297.          * Reads from the serial port until a single line has been read.
  298.          *
  299.          * \param size size A std::size defining the maximum length of the line.
  300.          *        Defaults to 65536 or (2^16)
  301.          * \param eol A std::string to match against for the EOL.
  302.          *
  303.          * \return A std::string containing the line.
  304.          *
  305.          * \throw serial::PortNotOpenedException
  306.          * \throw serial::SerialException
  307.          */
  308.         auto readline(std::size_t size = 65536, std::string eol = '\n') -> std::string;
  309.  
  310.         /*! Reads in multiple lines until the serial port times out.
  311.          *
  312.          * This requires a timeout > 0 before it can be run. It will read until a
  313.          * timeout occurs and returns list of strings.
  314.          *
  315.          * \param size A std::size defining the maximum length of combined lines.
  316.          *        Defaults to 65536 or (2^16)
  317.          * \param eol A std::string to match against for the EOL.
  318.          *
  319.          * \return A std::vector of std::string containing the lines.
  320.          *
  321.          * \throw serial::PortNotOpenedException
  322.          * \throw serial::SerialException
  323.          */
  324.         auto readlines(std::size_t size = 65536, std::string eol = '\n') -> std::vector<std::string>;
  325.  
  326.         /*! Write a string to the serial port.
  327.          *
  328.          * \param data A const reference containing the data to be written
  329.          *        to the serial port.
  330.          * \param size A std::size_t defining the number of bytes to be written
  331.          *        from the given data buffer.
  332.          *
  333.          * \return A std::size_t representing the number of bytes actually written
  334.          *         to the serial port.
  335.          *
  336.          * \throw serial::PortNotOpenedException
  337.          * \throw serial::SerialException
  338.          * \throw serial::IOException
  339.          */
  340.         auto write(const uint8_t *data, std::size_t size) -> std::size_t;
  341.  
  342.         /*! Write a string to the serial port.
  343.          *
  344.          * \param data A const reference containing the data to be written to
  345.          *        the serial port.
  346.          *
  347.          * \return A std::size_t representing the number of bytes actually written
  348.          *         to the serial port.
  349.          *
  350.          * \throw serial::PortNotOpenedException
  351.          * \throw serial::SerialException
  352.          * \throw serial::IOException
  353.          */
  354.         auto write(const std::vector<uint8_t> &data) -> std::size_t;
  355.  
  356.         /*! Writes a string to the serial port.
  357.          *
  358.          * \param data A const reference containing the data to be written to
  359.          *        the serial port.
  360.          *
  361.          * \return A std::size_t representing the number of bytes actually written
  362.          *         to the serial port.
  363.          *
  364.          * \throw serial::PortNotOpenedException
  365.          * \throw serial::SerialException
  366.          * \throw serial::IOException
  367.          */
  368.         auto write(const std::string &data) -> std::size_t;
  369.  
  370.         /*! Sets the serial port identifier.
  371.          *
  372.          * \param port A const std::string reference containing the address of the
  373.          *        serial port, which would be something like 'COM1' on windows and '/dev/tty50'
  374.          *        on Linux.
  375.          *
  376.          * \throw std::invalid_argument
  377.          */
  378.         auto setPort(const std::string &port);
  379.  
  380.         /*! Gets the serial port identifier.
  381.          *
  382.          * \see serial::setPort
  383.          *
  384.          * \throw std::invalid_argument
  385.          */
  386.         auto getPort() -> std::string const;
  387.        
  388.         /*! Sets the timeout for reads and writes using the Timeout struct
  389.          *
  390.          * There are two timeout conditions described here:
  391.          *  * The inter byte timeout:
  392.          *    * The inter_byte_timeout component of the serial::Timeout defines the
  393.          *      maximum amount of time, in milliseconds, between receiving bytes on
  394.          *      the serial port that can pass before a timeout occurs. Setting this
  395.          *      to zero will prevent inter byte timeouts from occurring.
  396.          *  * Total time timeout:
  397.          *      * The constant and multiplier component of this timeout condition,
  398.          *        for both read and write, are defined in serial::Timeout. This
  399.          *        timeout occurs if the total time since the read and write call
  400.          *        was made exceeds the specified time in milliseconds.
  401.          *      * The limit is defined by multiplying the multiplier component by
  402.          *        the number of requested bytes and adding that product to the
  403.          *        constant component. In this way if you want a read call, for example,
  404.          *        to timeout after exactly one second regardless of the number of bytes
  405.          *        you asked for then set the read_timeout_constant component of
  406.          *        serial::Timeout to 1000 and the read_timeout_multiplier to zero. This
  407.          *        timeout condition can be used in conjuction with the inter byte timeout
  408.          *        condition without any problems, timeout will simply occur when one of the
  409.          *        two conditions is met. This allows users to have maximum control over the
  410.          *        trade-off between responsiveness and efficiency.
  411.          *
  412.          * Read and write functions will return in one of three cases. When the
  413.          * reading or writing is complete, when a timeout occurs, or when an
  414.          * exception occurs.
  415.          *
  416.          * A timeout of 0 enables non-blocking mode.
  417.          *
  418.          * \param timeout A serial::Timeout struct containing the inter
  419.          *        byte timeout, and the read and write timeout constants
  420.          *        and multipliers.
  421.          *
  422.          * \see serial::Timeout
  423.          */
  424.         auto setTimeout(Timeout &timeout) -> void;
  425.  
  426.         /*! Sets the timeout for reads and writes. */
  427.         auto setTimeout(uint32_t inter_byte_timeout,
  428.                         uint32_t read_timeout_constant,
  429.                         uint32_t read_timeout_multiplier,
  430.                         uint32_t write_timeout_constant,
  431.                         uint32_t write_timeout_multiplier) -> void {
  432.             Timeout timeout(inter_byte_timeout,
  433.                 read_timeout_constant,
  434.                 read_timeout_multiplier,
  435.                 write_timeout_constant,
  436.                 write_timeout_multiplier);
  437.  
  438.             return setTimeout(timeout);
  439.         };
  440.         /*! Gets the timeout for reads in seconds.
  441.          *
  442.          * \return A serial::Timeout struct containing the inter_byte_timeout, and read
  443.          * and write timeout constants and multipliers.
  444.          *
  445.          * \see serial::setTimeout
  446.          */
  447.         auto getTimeout() -> Timeout const;
  448.  
  449.         /*! Sets the baudrate of the serial port.
  450.          *
  451.          * Possible baudrates depends on the system, but some safe baudrates include:
  452.          * 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 56000,
  453.          * 57600, 115200
  454.          * Some other baudrates that are supported by comports:
  455.          * 120000, 153600, 230400, 256000, 500000, 921600
  456.          *
  457.          * \param baudrate An integer that sets the baudrate for the serial port.
  458.          *
  459.          * \throw std::invalid_argument
  460.          */
  461.         auto setBaudrate(uint32_t baudrate) -> void;
  462.  
  463.         /*! Gets the baudrate for the serial port.
  464.          *
  465.          * \return An integer that sets the baudrate for the serial port.
  466.          *
  467.          * \see serial::setBaudrate
  468.          *
  469.          * \throw std::invalid_argument
  470.          */
  471.         auto getBaudrate() -> uint32_t;
  472.  
  473.         /*! Sets the bytesize for the serial port.
  474.          *
  475.          * \param bytesize Size of each byte in the serial transmission of data,
  476.          *        default is eightbits, possible values are: fivebits, sixbits,
  477.          *        sevenbits, eightbits
  478.          *
  479.          * \throw std::invalid_argument
  480.          */
  481.         auto setBytesize(bytesize_t bytesize) -> void;
  482.  
  483.         /*! Gets the bytesize for the serial port.
  484.          *
  485.          * \see serial::setBytesize
  486.          *
  487.          * \throw std::invalid_argument
  488.          */
  489.         auto getBytesize() -> bytesize_t const;
  490.  
  491.         /*! Sets the parity for the serial port.
  492.         *
  493.         * \param parity Method of parity, default is parity_none, possible values
  494.         * are:   parity_none, parity_odd, parity_even
  495.         *
  496.         * \throw std::invalid_argument
  497.         */
  498.         auto setParity(parity_t parity) -> void;
  499.  
  500.         /*! Gets the parity for the serial port.
  501.         *
  502.         * \see serial::setParity
  503.         *
  504.         * \throw std::invalid_argument
  505.         */
  506.         auto getParity() -> parity_t const;
  507.  
  508.         /*! Sets the stop bits for the serial port.
  509.         *
  510.         * \param stopbits Number of stop bits used, default is stopbits_one,
  511.         * possible values are: stopbits_one, stopbits_one_point_five, stopbits_two
  512.         *
  513.         * \throw std::invalid_argument
  514.         */
  515.         auto setStopbits(stopbits_t stopbits) -> void;
  516.  
  517.         /*! Gets the stop bits for the serial port.
  518.         *
  519.         * \see serial::setStopbits
  520.         *
  521.         * \throw std::invalid_argument
  522.         */
  523.         auto getStopbits() -> stopbits_t const;
  524.  
  525.         /*! Sets the flow control for the serial port.
  526.         *
  527.         * \param flowcontrol Type of flowcontrol used, default is flowcontrol_none,
  528.         * possible values are: flowcontrol_none, flowcontrol_software,
  529.         * flowcontrol_hardware
  530.         *
  531.         * \throw std::invalid_argument
  532.         */
  533.         auto setFlowcontrol(flowcontrol_t flowcontrol) -> void;
  534.  
  535.         /*! Gets the flow control for the serial port.
  536.         *
  537.         * \see serial::setFlowcontrol
  538.         *
  539.         * \throw std::invalid_argument
  540.         */
  541.         auto getFlowcontrol() -> flowcontrol_t const;
  542.  
  543.         /*! Flush the output and input buffer. */
  544.         auto flush() -> void;
  545.  
  546.         /*! Flush only the input buffer. */
  547.         auto flushInput() -> void;
  548.  
  549.         /*! Flush only the output buffer. */
  550.         auto flushOutput() -> void;
  551.  
  552.         /*! Sends the RS-232 break signal.
  553.         *
  554.         * \see tcsendbreak(3)
  555.         */
  556.         auto sendBreak(int duration) -> void;
  557.  
  558.         /*! Set the break condition to the given level. Defaults to true. */
  559.         auto setBreak(bool level = true) -> void;
  560.  
  561.         /*! Set the RTS handshaking line to the given level. Defaults to true. */
  562.         auto setRTS(bool level = true) -> void;
  563.  
  564.         /*! Set the DTR handshaking line to the given level. Defaults to true. */
  565.         auto setDTR(bool level = true) -> void;
  566.  
  567.         /*! Blocks until CTS, DSR, RI, CD changes or something interrupts it.
  568.         *
  569.         * Can throw an exception if an error occurs while waiting.
  570.         * You can check the status of CTS, DSR, RI and CD once this returns.
  571.         * Use TIOCMIWAIT via ioctl if available (mostly only on Linux) with a
  572.         * resolution of less than +-1ms and as good as  +-0.2ms. Otherwise a
  573.         * polling method is used which can give +-2ms.
  574.         *
  575.         * \return Returns true if one of the lines changed, false if something else
  576.         * occured.
  577.         *
  578.         * \throw SerialException
  579.         */
  580.         auto waitForChange() -> bool;
  581.  
  582.         /*! Returns the current status of the CTS line. */
  583.         auto getCTS() -> bool;
  584.  
  585.         /*! Returns the current status of the DSR line. */
  586.         auto getDSR() -> bool;
  587.  
  588.         /*! Returns the current status of the RI line. */
  589.         auto getRI() -> bool;
  590.  
  591.         /*! Returns the current status of the CD line. */
  592.         auto getCD() -> bool;
  593.  
  594.     private:
  595.         // Disable copy constructors
  596.         Serial(const Serial &);
  597.         Serial& operator=(const Serial&);
  598.  
  599.         // Pimpl idiom, d_pointer
  600.         class SerialImpl;
  601.         class ScopedWriteLock;
  602.  
  603.         // Read common functions
  604.         auto read_(uint8_t *buffer, std::size_t size) -> std::size_t;
  605.  
  606.         // Write common functions
  607.         auto write_(const uint8_t *data, std::size_t size) -> std::size_t;
  608.     };
  609.  
  610.     class SerialException : public std::exception {
  611.     private:
  612.         // Disable copy constructors
  613.         SerialException& operator=(const SerialException &);
  614.         std::string e_what_;
  615.  
  616.     public:
  617.         SerialException(const char *description) {
  618.             std::stringstream ss;
  619.             ss << "SerialException: " << description << " failed.";
  620.             this->e_what_ = ss.str();
  621.         }
  622.  
  623.         SerialException(const SerialException& other) : e_what_(other.e_what_) {};
  624.  
  625.         virtual ~SerialException() throw() {};
  626.  
  627.         virtual inline auto what() const throw() -> const char* {
  628.             return e_what_.c_str();
  629.         }
  630.     };
  631.  
  632.     class IOException : public std::exception {
  633.     private:
  634.         // Disable copy constructor
  635.         IOException& operator=(const IOException &);
  636.  
  637.         std::string file_;
  638.         std::string e_what_;
  639.  
  640.         int line_;
  641.         int errno_;
  642.  
  643.     public:
  644.         explicit IOException(std::string filename, int line, int errnum)
  645.             : file_(file), line_(line), errno_(errnum) {
  646.             std::stringstream ss;
  647. #if defined(_WIN32) && !defined(__MINGW32__)
  648.             char error_str[1024];
  649.             strerror_s(error_str, 1024, errnum);
  650. #else
  651.             char *error_str = strerror(errnum);
  652. #endif
  653.             ss << "IO Exception (" << this->errno_ << "): " << error_str;
  654.             ss << < ", file " << this->file_ << ", line " << this->line_ << ".";
  655.  
  656.             this->e_what_ = ss.str();
  657.         }
  658.        
  659.         explicit IOException(std::string file, int line, const char* description)
  660.             : file_(file), line_(line), errno_(0) {
  661.             std::stringstream ss;
  662.  
  663.             ss << "IO Exception: " << description;
  664.             ss << ", file " << this->file_ << ", line " << this->line_ << ".";
  665.            
  666.             this->e_what_ = ss.str();
  667.         }
  668.        
  669.         virtual IOException() throw() {};
  670.         IOException(const IOException &other) : line_(other.line_), e_what_(other.e_what_), errno_(other.errno_) {};
  671.  
  672.         inline auto getErrorNumber() -> int const {
  673.             return this->errno_;
  674.         }
  675.  
  676.         virtual inline auto what() const throw() -> const char* {
  677.             return this->e_what_.c_str();
  678.         }
  679.     };
  680.  
  681.     class PortNotOpenedException : std::exception {
  682.     private:
  683.         // Disable copy constructor
  684.         const PortNotOpenedException& operator=(const PortNotOpenedException&);
  685.         std::string e_what_;
  686.  
  687.     public:
  688.         PortNotOpenedException(const  char* description) {
  689.             std::stringstream ss;
  690.  
  691.             ss << "PortNotOpenedException " << description << " failed.";
  692.             this->e_what_ = ss.str();
  693.         }
  694.  
  695.         explicit PortNotOpenedException(const PortNotOpenedException& other) : e_what_(other.e_what_) {};
  696.  
  697.         virtual ~PortNotOpenedException() throw() {};
  698.         virtual inline auto what() const throw() -> const char* {
  699.             return this->e_what_.c_str();
  700.         }
  701.     };
  702.  
  703.     /*!
  704.     * Structure that describes a serial device.
  705.     */
  706.     struct PortInfo {
  707.         /*! Address of the serial port (this can be passed to the constructor of Serial) */
  708.         std::string port;
  709.  
  710.         /*! Human readable description of serial device if available. */
  711.         std::string description;
  712.  
  713.         /*! Hardware ID (e.g. VID:PID of USB serial devices) or "n\a" if not available. */
  714.         std::string hardware_id;
  715.     };
  716.  
  717.     /*! Lists the serial ports available on the system.
  718.      *
  719.      * Returns a vector of available serial ports, each represented
  720.      * by a serial::PortInfo data structure.
  721.      *
  722.      * \return vector of serial::PortInfo
  723.      */
  724.     std::vector<PortInfo> list_ports();
  725.  
  726. } // namespace serial
  727.  
  728. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement