serial.cc
Go to the documentation of this file.
1 /* Copyright 2012 William Woodall and John Harrison */
2 #include <algorithm>
3 
4 #if !defined(_WIN32) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
5 # include <alloca.h>
6 #endif
7 
8 #if defined (__MINGW32__)
9 # define alloca __builtin_alloca
10 #endif
11 
12 #include "serial/serial.h"
13 
14 #ifdef _WIN32
15 #include "serial/impl/win.h"
16 #else
17 #include "serial/impl/unix.h"
18 #endif
19 
20 using std::invalid_argument;
21 using std::min;
22 using std::numeric_limits;
23 using std::vector;
24 using std::size_t;
25 using std::string;
26 
27 using serial::Serial;
30 using serial::bytesize_t;
31 using serial::parity_t;
32 using serial::stopbits_t;
34 
36 public:
37  ScopedReadLock(SerialImpl *pimpl) : pimpl_(pimpl) {
38  this->pimpl_->readLock();
39  }
41  this->pimpl_->readUnlock();
42  }
43 private:
44  // Disable copy constructors
47 
49 };
50 
52 public:
53  ScopedWriteLock(SerialImpl *pimpl) : pimpl_(pimpl) {
54  this->pimpl_->writeLock();
55  }
57  this->pimpl_->writeUnlock();
58  }
59 private:
60  // Disable copy constructors
64 };
65 
66 Serial::Serial (const string &port, uint32_t baudrate, serial::Timeout timeout,
67  bytesize_t bytesize, parity_t parity, stopbits_t stopbits,
68  flowcontrol_t flowcontrol)
69  : pimpl_(new SerialImpl (port, baudrate, bytesize, parity,
70  stopbits, flowcontrol))
71 {
73 }
74 
75 Serial::~Serial ()
76 {
77  delete pimpl_;
78 }
79 
80 void
81 Serial::open ()
82 {
83  pimpl_->open ();
84 }
85 
86 void
87 Serial::close ()
88 {
89  pimpl_->close ();
90 }
91 
92 bool
93 Serial::isOpen () const
94 {
95  return pimpl_->isOpen ();
96 }
97 
98 size_t
99 Serial::available ()
100 {
101  return pimpl_->available ();
102 }
103 
104 bool
105 Serial::waitReadable ()
106 {
107  serial::Timeout timeout(pimpl_->getTimeout ());
108  return pimpl_->waitReadable(timeout.read_timeout_constant);
109 }
110 
111 void
112 Serial::waitByteTimes (size_t count)
113 {
114  pimpl_->waitByteTimes(count);
115 }
116 
117 size_t
118 Serial::read_ (uint8_t *buffer, size_t size)
119 {
120  return this->pimpl_->read (buffer, size);
121 }
122 
123 size_t
124 Serial::read (uint8_t *buffer, size_t size)
125 {
126  ScopedReadLock lock(this->pimpl_);
127  return this->pimpl_->read (buffer, size);
128 }
129 
130 size_t
131 Serial::read (std::vector<uint8_t> &buffer, size_t size)
132 {
133  ScopedReadLock lock(this->pimpl_);
134  uint8_t *buffer_ = new uint8_t[size];
135  size_t bytes_read = 0;
136 
137  try {
138  bytes_read = this->pimpl_->read (buffer_, size);
139  }
140  catch (const std::exception &e) {
141  delete[] buffer_;
142  throw;
143  }
144 
145  buffer.insert (buffer.end (), buffer_, buffer_+bytes_read);
146  delete[] buffer_;
147  return bytes_read;
148 }
149 
150 size_t
151 Serial::read (std::string &buffer, size_t size)
152 {
153  ScopedReadLock lock(this->pimpl_);
154  uint8_t *buffer_ = new uint8_t[size];
155  size_t bytes_read = 0;
156  try {
157  bytes_read = this->pimpl_->read (buffer_, size);
158  }
159  catch (const std::exception &e) {
160  delete[] buffer_;
161  throw;
162  }
163  buffer.append (reinterpret_cast<const char*>(buffer_), bytes_read);
164  delete[] buffer_;
165  return bytes_read;
166 }
167 
168 string
169 Serial::read (size_t size)
170 {
171  std::string buffer;
172  this->read (buffer, size);
173  return buffer;
174 }
175 
176 size_t
177 Serial::readline (string &buffer, size_t size, string eol)
178 {
179  ScopedReadLock lock(this->pimpl_);
180  size_t eol_len = eol.length ();
181  uint8_t *buffer_ = static_cast<uint8_t*>
182  (alloca (size * sizeof (uint8_t)));
183  size_t read_so_far = 0;
184  while (true)
185  {
186  size_t bytes_read = this->read_ (buffer_ + read_so_far, 1);
187  read_so_far += bytes_read;
188  if (bytes_read == 0) {
189  break; // Timeout occured on reading 1 byte
190  }
191  if(read_so_far < eol_len) continue;
192  if (string (reinterpret_cast<const char*>
193  (buffer_ + read_so_far - eol_len), eol_len) == eol) {
194  break; // EOL found
195  }
196  if (read_so_far == size) {
197  break; // Reached the maximum read length
198  }
199  }
200  buffer.append(reinterpret_cast<const char*> (buffer_), read_so_far);
201  return read_so_far;
202 }
203 
204 string
205 Serial::readline (size_t size, string eol)
206 {
207  std::string buffer;
208  this->readline (buffer, size, eol);
209  return buffer;
210 }
211 
212 vector<string>
213 Serial::readlines (size_t size, string eol)
214 {
215  ScopedReadLock lock(this->pimpl_);
216  std::vector<std::string> lines;
217  size_t eol_len = eol.length ();
218  uint8_t *buffer_ = static_cast<uint8_t*>
219  (alloca (size * sizeof (uint8_t)));
220  size_t read_so_far = 0;
221  size_t start_of_line = 0;
222  while (read_so_far < size) {
223  size_t bytes_read = this->read_ (buffer_+read_so_far, 1);
224  read_so_far += bytes_read;
225  if (bytes_read == 0) {
226  if (start_of_line != read_so_far) {
227  lines.push_back (
228  string (reinterpret_cast<const char*> (buffer_ + start_of_line),
229  read_so_far - start_of_line));
230  }
231  break; // Timeout occured on reading 1 byte
232  }
233  if(read_so_far < eol_len) continue;
234  if (string (reinterpret_cast<const char*>
235  (buffer_ + read_so_far - eol_len), eol_len) == eol) {
236  // EOL found
237  lines.push_back(
238  string(reinterpret_cast<const char*> (buffer_ + start_of_line),
239  read_so_far - start_of_line));
240  start_of_line = read_so_far;
241  }
242  if (read_so_far == size) {
243  if (start_of_line != read_so_far) {
244  lines.push_back(
245  string(reinterpret_cast<const char*> (buffer_ + start_of_line),
246  read_so_far - start_of_line));
247  }
248  break; // Reached the maximum read length
249  }
250  }
251  return lines;
252 }
253 
254 size_t
255 Serial::write (const string &data)
256 {
257  ScopedWriteLock lock(this->pimpl_);
258  return this->write_ (reinterpret_cast<const uint8_t*>(data.c_str()),
259  data.length());
260 }
261 
262 size_t
263 Serial::write (const std::vector<uint8_t> &data)
264 {
265  ScopedWriteLock lock(this->pimpl_);
266  return this->write_ (&data[0], data.size());
267 }
268 
269 size_t
270 Serial::write (const uint8_t *data, size_t size)
271 {
272  ScopedWriteLock lock(this->pimpl_);
273  return this->write_(data, size);
274 }
275 
276 size_t
277 Serial::write_ (const uint8_t *data, size_t length)
278 {
279  return pimpl_->write (data, length);
280 }
281 
282 void
283 Serial::setPort (const string &port)
284 {
285  ScopedReadLock rlock(this->pimpl_);
286  ScopedWriteLock wlock(this->pimpl_);
287  bool was_open = pimpl_->isOpen ();
288  if (was_open) close();
289  pimpl_->setPort (port);
290  if (was_open) open ();
291 }
292 
293 string
294 Serial::getPort () const
295 {
296  return pimpl_->getPort ();
297 }
298 
299 void
300 Serial::setTimeout (serial::Timeout &timeout)
301 {
302  pimpl_->setTimeout (timeout);
303 }
304 
306 Serial::getTimeout () const {
307  return pimpl_->getTimeout ();
308 }
309 
310 void
311 Serial::setBaudrate (uint32_t baudrate)
312 {
313  pimpl_->setBaudrate (baudrate);
314 }
315 
316 uint32_t
317 Serial::getBaudrate () const
318 {
319  return uint32_t(pimpl_->getBaudrate ());
320 }
321 
322 void
323 Serial::setBytesize (bytesize_t bytesize)
324 {
325  pimpl_->setBytesize (bytesize);
326 }
327 
329 Serial::getBytesize () const
330 {
331  return pimpl_->getBytesize ();
332 }
333 
334 void
335 Serial::setParity (parity_t parity)
336 {
337  pimpl_->setParity (parity);
338 }
339 
340 parity_t
341 Serial::getParity () const
342 {
343  return pimpl_->getParity ();
344 }
345 
346 void
347 Serial::setStopbits (stopbits_t stopbits)
348 {
349  pimpl_->setStopbits (stopbits);
350 }
351 
353 Serial::getStopbits () const
354 {
355  return pimpl_->getStopbits ();
356 }
357 
358 void
359 Serial::setFlowcontrol (flowcontrol_t flowcontrol)
360 {
361  pimpl_->setFlowcontrol (flowcontrol);
362 }
363 
365 Serial::getFlowcontrol () const
366 {
367  return pimpl_->getFlowcontrol ();
368 }
369 
370 void Serial::flush ()
371 {
372  ScopedReadLock rlock(this->pimpl_);
373  ScopedWriteLock wlock(this->pimpl_);
374  pimpl_->flush ();
375 }
376 
377 void Serial::flushInput ()
378 {
379  ScopedReadLock lock(this->pimpl_);
380  pimpl_->flushInput ();
381 }
382 
383 void Serial::flushOutput ()
384 {
385  ScopedWriteLock lock(this->pimpl_);
386  pimpl_->flushOutput ();
387 }
388 
389 void Serial::sendBreak (int duration)
390 {
391  pimpl_->sendBreak (duration);
392 }
393 
394 void Serial::setBreak (bool level)
395 {
396  pimpl_->setBreak (level);
397 }
398 
399 void Serial::setRTS (bool level)
400 {
401  pimpl_->setRTS (level);
402 }
403 
404 void Serial::setDTR (bool level)
405 {
406  pimpl_->setDTR (level);
407 }
408 
409 bool Serial::waitForChange()
410 {
411  return pimpl_->waitForChange();
412 }
413 
414 bool Serial::getCTS ()
415 {
416  return pimpl_->getCTS ();
417 }
418 
419 bool Serial::getDSR ()
420 {
421  return pimpl_->getDSR ();
422 }
423 
424 bool Serial::getRI ()
425 {
426  return pimpl_->getRI ();
427 }
428 
429 bool Serial::getCD ()
430 {
431  return pimpl_->getCD ();
432 }
serial::parity_t
parity_t
Definition: serial.h:66
unix.h
serial::Serial::SerialImpl::writeLock
void writeLock()
Definition: unix.cc:1067
serial::Serial::SerialImpl::setTimeout
void setTimeout(Timeout &timeout)
Definition: unix.cc:728
serial::Serial::ScopedWriteLock::~ScopedWriteLock
~ScopedWriteLock()
Definition: serial.cc:56
serial::Serial::ScopedReadLock::pimpl_
SerialImpl * pimpl_
Definition: serial.cc:48
serial::Serial::ScopedReadLock
Definition: serial.cc:35
serial::Serial::ScopedReadLock::operator=
const ScopedReadLock & operator=(ScopedReadLock)
serial::IOException
Definition: serial.h:690
serial::bytesize_t
bytesize_t
Definition: serial.h:56
serial::Serial::ScopedWriteLock::operator=
const ScopedWriteLock & operator=(ScopedWriteLock)
python_serial_test.timeout
timeout
Definition: python_serial_test.py:10
serial::Serial::SerialImpl::readLock
void readLock()
Definition: unix.cc:1049
serial::Serial::SerialImpl
Definition: unix.h:66
serial::Serial::ScopedReadLock::ScopedReadLock
ScopedReadLock(SerialImpl *pimpl)
Definition: serial.cc:37
serial::Serial::SerialImpl::readUnlock
void readUnlock()
Definition: unix.cc:1058
serial::Serial::ScopedReadLock::~ScopedReadLock
~ScopedReadLock()
Definition: serial.cc:40
serial::Serial
Definition: serial.h:147
serial.h
win.h
serial::Serial::SerialImpl::writeUnlock
void writeUnlock()
Definition: unix.cc:1076
serial::flowcontrol_t
flowcontrol_t
Definition: serial.h:86
serial::Serial::ScopedWriteLock
Definition: serial.cc:51
serial::stopbits_t
stopbits_t
Definition: serial.h:77
serial::Serial::ScopedWriteLock::ScopedWriteLock
ScopedWriteLock(SerialImpl *pimpl)
Definition: serial.cc:53
serial::SerialException
Definition: serial.h:672
serial::Timeout
Definition: serial.h:98
serial::Serial::ScopedWriteLock::pimpl_
SerialImpl * pimpl_
Definition: serial.cc:63


serial
Author(s): William Woodall , John Harrison
autogenerated on Wed Mar 9 2022 03:10:03