1 /* Copyright 2012 William Woodall and John Harrison */
4 #include "serial/serial.h"
7 #include "serial/impl/win.h"
9 #include "serial/impl/unix.h"
12 using std::invalid_argument;
14 using std::numeric_limits;
20 using serial::SerialExecption;
21 using serial::IOException;
22 using serial::bytesize_t;
23 using serial::parity_t;
24 using serial::stopbits_t;
25 using serial::flowcontrol_t;
27 class Serial::ScopedReadLock {
29 ScopedReadLock(SerialImpl *pimpl) : pimpl_(pimpl) {
30 this->pimpl_->readLock();
33 this->pimpl_->readUnlock();
36 // Disable copy constructors
37 ScopedReadLock(const ScopedReadLock&);
38 void operator=(const ScopedReadLock&);
39 const ScopedReadLock& operator=(ScopedReadLock);
44 class Serial::ScopedWriteLock {
46 ScopedWriteLock(SerialImpl *pimpl) : pimpl_(pimpl) {
47 this->pimpl_->writeLock();
50 this->pimpl_->writeUnlock();
53 // Disable copy constructors
54 ScopedWriteLock(const ScopedWriteLock&);
55 void operator=(const ScopedWriteLock&);
56 const ScopedWriteLock& operator=(ScopedWriteLock);
60 Serial::Serial (const string &port, uint32_t baudrate, serial::Timeout timeout,
61 bytesize_t bytesize, parity_t parity, stopbits_t stopbits,
62 flowcontrol_t flowcontrol)
63 : read_cache_(""), pimpl_(new SerialImpl (port, baudrate, bytesize, parity,
64 stopbits, flowcontrol))
66 pimpl_->setTimeout(timeout);
87 Serial::isOpen () const
89 return pimpl_->isOpen ();
95 return pimpl_->available ();
99 Serial::read_ (uint8_t *buffer, size_t size)
101 return this->pimpl_->read (buffer, size);
105 Serial::read (uint8_t *buffer, size_t size)
107 ScopedReadLock (this->pimpl_);
108 return this->pimpl_->read (buffer, size);
112 Serial::read (std::vector<uint8_t> &buffer, size_t size)
114 ScopedReadLock (this->pimpl_);
115 uint8_t *buffer_ = new uint8_t[size];
116 size_t bytes_read = this->pimpl_->read (buffer_, size);
117 buffer.insert (buffer.end (), buffer_, buffer_+bytes_read);
123 Serial::read (std::string &buffer, size_t size)
125 ScopedReadLock (this->pimpl_);
126 uint8_t *buffer_ = new uint8_t[size];
127 size_t bytes_read = this->pimpl_->read (buffer_, size);
128 buffer.append (reinterpret_cast<const char*>(buffer_), bytes_read);
134 Serial::read (size_t size)
137 this->read (buffer, size);
142 Serial::readline (string &buffer, size_t size, string eol)
144 ScopedReadLock (this->pimpl_);
145 size_t eol_len = eol.length ();
146 uint8_t *buffer_ = static_cast<uint8_t*>
147 (alloca (size * sizeof (uint8_t)));
148 size_t read_so_far = 0;
151 size_t bytes_read = this->read_ (buffer_ + read_so_far, 1);
152 read_so_far += bytes_read;
153 if (bytes_read == 0) {
154 break; // Timeout occured on reading 1 byte
156 if (string (reinterpret_cast<const char*>
157 (buffer_ + read_so_far - eol_len), eol_len) == eol) {
160 if (read_so_far == size) {
161 break; // Reached the maximum read length
164 buffer.append(reinterpret_cast<const char*> (buffer_), read_so_far);
169 Serial::readline (size_t size, string eol)
172 this->readline (buffer, size, eol);
177 Serial::readlines (size_t size, string eol)
179 ScopedReadLock (this->pimpl_);
180 std::vector<std::string> lines;
181 size_t eol_len = eol.length ();
182 uint8_t *buffer_ = static_cast<uint8_t*>
183 (alloca (size * sizeof (uint8_t)));
184 size_t read_so_far = 0;
185 size_t start_of_line = 0;
186 while (read_so_far < size) {
187 size_t bytes_read = this->read_ (buffer_+read_so_far, 1);
188 read_so_far += bytes_read;
189 if (bytes_read == 0) {
190 if (start_of_line != read_so_far) {
192 string (reinterpret_cast<const char*> (buffer_ + start_of_line),
193 read_so_far - start_of_line));
195 break; // Timeout occured on reading 1 byte
197 if (string (reinterpret_cast<const char*>
198 (buffer_ + read_so_far - eol_len), eol_len) == eol) {
201 string(reinterpret_cast<const char*> (buffer_ + start_of_line),
202 read_so_far - start_of_line));
203 start_of_line = read_so_far;
205 if (read_so_far == size) {
206 if (start_of_line != read_so_far) {
208 string(reinterpret_cast<const char*> (buffer_ + start_of_line),
209 read_so_far - start_of_line));
211 break; // Reached the maximum read length
218 Serial::write (const string &data)
220 ScopedWriteLock(this->pimpl_);
221 return this->write_ (reinterpret_cast<const uint8_t*>(data.c_str()),
226 Serial::write (const std::vector<uint8_t> &data)
228 ScopedWriteLock(this->pimpl_);
229 return this->write_ (&data[0], data.size());
233 Serial::write (const uint8_t *data, size_t size)
235 ScopedWriteLock(this->pimpl_);
236 return this->write_(data, size);
240 Serial::write_ (const uint8_t *data, size_t length)
242 return pimpl_->write (data, length);
246 Serial::setPort (const string &port)
248 ScopedReadLock(this->pimpl_);
249 ScopedWriteLock(this->pimpl_);
250 bool was_open = pimpl_->isOpen ();
251 if (was_open) close();
252 pimpl_->setPort (port);
253 if (was_open) open ();
257 Serial::getPort () const
259 return pimpl_->getPort ();
263 Serial::setTimeout (serial::Timeout &timeout)
265 pimpl_->setTimeout (timeout);
269 Serial::getTimeout () const {
270 return pimpl_->getTimeout ();
274 Serial::setBaudrate (uint32_t baudrate)
276 pimpl_->setBaudrate (baudrate);
280 Serial::getBaudrate () const
282 return uint32_t(pimpl_->getBaudrate ());
286 Serial::setBytesize (bytesize_t bytesize)
288 pimpl_->setBytesize (bytesize);
292 Serial::getBytesize () const
294 return pimpl_->getBytesize ();
298 Serial::setParity (parity_t parity)
300 pimpl_->setParity (parity);
304 Serial::getParity () const
306 return pimpl_->getParity ();
310 Serial::setStopbits (stopbits_t stopbits)
312 pimpl_->setStopbits (stopbits);
316 Serial::getStopbits () const
318 return pimpl_->getStopbits ();
322 Serial::setFlowcontrol (flowcontrol_t flowcontrol)
324 pimpl_->setFlowcontrol (flowcontrol);
328 Serial::getFlowcontrol () const
330 return pimpl_->getFlowcontrol ();
333 void Serial::flush ()
335 ScopedReadLock(this->pimpl_);
336 ScopedWriteLock(this->pimpl_);
338 read_cache_.clear ();
341 void Serial::flushInput ()
343 ScopedReadLock(this->pimpl_);
344 pimpl_->flushInput ();
347 void Serial::flushOutput ()
349 ScopedWriteLock(this->pimpl_);
350 pimpl_->flushOutput ();
351 read_cache_.clear ();
354 void Serial::sendBreak (int duration)
356 pimpl_->sendBreak (duration);
359 void Serial::setBreak (bool level)
361 pimpl_->setBreak (level);
364 void Serial::setRTS (bool level)
366 pimpl_->setRTS (level);
369 void Serial::setDTR (bool level)
371 pimpl_->setDTR (level);
374 bool Serial::waitForChange()
376 return pimpl_->waitForChange();
379 bool Serial::getCTS ()
381 return pimpl_->getCTS ();
384 bool Serial::getDSR ()
386 return pimpl_->getDSR ();
389 bool Serial::getRI ()
391 return pimpl_->getRI ();
394 bool Serial::getCD ()
396 return pimpl_->getCD ();