2b3458a3eb0ea293563a522f6519ef8467ed76dd
[libs/core.git] / source / io / serial.cpp
1 #include "serial.h"
2 #include "serial_private.h"
3
4 using namespace std;
5
6 namespace Msp {
7 namespace IO {
8
9 Serial::Serial(const string &descr):
10         reader(handle, 1024)
11 {
12         string::size_type comma = descr.find(',');
13         string port = descr.substr(0, comma);
14
15         platform_init(port);
16
17         if(comma!=string::npos)
18         {
19                 try
20                 {
21                         set_parameters(descr.substr(comma+1));
22                 }
23                 catch(...)
24                 {
25                         close();
26                         throw;
27                 }
28         }
29
30         set_events(P_INPUT);
31 }
32
33 Serial::~Serial()
34 {
35         close();
36 }
37
38 void Serial::close()
39 {
40         sys_close(handle);
41 }
42
43 void Serial::set_block(bool b)
44 {
45         adjust_mode(mode, M_NONBLOCK, !b);
46         sys_set_blocking(handle, b);
47 }
48
49 void Serial::set_baud_rate(unsigned rate)
50 {
51         DeviceState state;
52         state.get_from(handle);
53         state.set_baud_rate(rate);
54         state.apply_to(handle);
55 }
56
57 void Serial::set_data_bits(unsigned bits)
58 {
59         DeviceState state;
60         state.get_from(handle);
61         state.set_data_bits(bits);
62         state.apply_to(handle);
63 }
64
65 void Serial::set_parity(Parity par)
66 {
67         DeviceState state;
68         state.get_from(handle);
69         state.set_parity(par);
70         state.apply_to(handle);
71 }
72
73 void Serial::set_stop_bits(unsigned bits)
74 {
75         DeviceState state;
76         state.get_from(handle);
77         state.set_stop_bits(bits);
78         state.apply_to(handle);
79 }
80
81 void Serial::set_parameters(const string &params)
82 {
83         unsigned i;
84         for(i=0; i<params.size() && isdigit(params[i]); ++i) ;
85         if(i+4!=params.size() || params[i]!=',')
86                 throw invalid_argument("Serial::set_parameters");
87         if(params[i+1]<'5' || params[i+1]>'8')
88                 throw invalid_argument("Serial::set_parameters data_bits");
89         if(params[i+2]!='N' && params[i+2]!='E' && params[i+2]!='O')
90                 throw invalid_argument("Serial::set_parameters parity");
91         if(params[i+3]!='1' && params[i+3]!='2')
92                 throw invalid_argument("Serial::set_parameters stop_bits");
93
94         DeviceState state;
95         state.get_from(handle);
96         state.set_baud_rate(lexical_cast<unsigned>(params.substr(0, i)));
97         state.set_data_bits(params[i+1]-'0');
98         state.set_parity((params[i+2]=='E' ? EVEN : params[i+2]=='O' ? ODD : NONE));
99         state.set_stop_bits(params[i+3]-'0');
100         state.apply_to(handle);
101 }
102
103 unsigned Serial::do_write(const char *buf, unsigned size)
104 {
105         if(size==0)
106                 return 0;
107
108         return sys_write(handle, buf, size);
109 }
110
111 unsigned Serial::do_read(char *buf, unsigned size)
112 {
113         if(size==0)
114                 return 0;
115
116         unsigned ret = reader.read(buf, size);
117         if(ret==0)
118                 set_eof();
119
120         return ret;
121 }
122
123 } // namespace IO
124 } // namespace Msp