How to efficiently convert baudrate from int to speed_t?

Viewed 4326

The functions cfsetospeed and cfsetispeed take baud rate as type speed_t:

int cfsetispeed(struct termios *termios_p, speed_t speed);
int cfsetospeed(struct termios *termios_p, speed_t speed);

The type speed_t is basically an integer, but casting is not a solution, as can be seen from the baudrate definitions in termios.h:

#define B0  0x00000000
#define B50 0x00000001
#define B75 0x00000002
// ...
#define B9600   0x0000000d
#define B19200  0x0000000e
#define B38400  0x0000000f

When I process user input (e.g. from file), I convert a string such as "9600" to integer 9600, and then to B9600. I'm basically looking for a generic way to convert the following:

// 0 -> B0
// 50 -> B50
// 75 -> B75
// ...
// 9600 -> B9600 
// 19200 -> B19200
// 38400 -> B38400

One way to convert from int (such as 9600) to speed_t (such as B9600) is a switch-case structure. Is there a better way to achieve this?

2 Answers

You need a lookup table, but not a naive one:

#include <stdio.h>    
#include <termios.h>       

struct
{
  int rawrate;
  int termiosrate;
} conversiontable[] =
{
  {0, B0},
  {50, B50},
  {75, B75},
  // you need to complete the table with B110 to B38400
};

int convertbaudrate(int rawrate)
{
  for (int i = 0; i < sizeof(conversiontable) / sizeof(conversiontable[0]); i++)
  {
    if (conversiontable[i].rawrate == rawrate)
    {
      return conversiontable[i].termiosrate;
    }
  }

  return -1;    // invalid baud rate
}

int main()
{
  printf("%d -> %d\n", 50, convertbaudrate(50));
  printf("%d -> %d\n", 75, convertbaudrate(75));
}

That should autoexplain. If not, please comment.

Related