294 lines
4.9 KiB
Plaintext
294 lines
4.9 KiB
Plaintext
|
/*
|
||
|
* serstream
|
||
|
* Implementation of input/output streams for the Arduino serial classes
|
||
|
*
|
||
|
* Created on: 2 Jan 2011
|
||
|
* Author: Andy Brown
|
||
|
*
|
||
|
* http://andybrown.me.uk/ws/terms-and-conditions
|
||
|
*/
|
||
|
|
||
|
#ifndef __810370EC_AD69_4ef7_91F5_B1AA16F14712
|
||
|
#define __810370EC_AD69_4ef7_91F5_B1AA16F14712
|
||
|
|
||
|
#include <basic_definitions>
|
||
|
|
||
|
#include <stl_config.h>
|
||
|
#include <iosfwd>
|
||
|
#include <ios>
|
||
|
#include <istream>
|
||
|
#include <ostream>
|
||
|
#include <iostream>
|
||
|
|
||
|
|
||
|
namespace std
|
||
|
{
|
||
|
/*
|
||
|
* basic_serialbuf implements an unbuffered basic_streambuf as a backing buffer
|
||
|
* for the IO classes
|
||
|
*/
|
||
|
|
||
|
template <class charT, class traits, class Tserial>
|
||
|
class basic_serialbuf : public basic_streambuf<charT,traits>
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
/*
|
||
|
* Types used here
|
||
|
*/
|
||
|
|
||
|
typedef charT char_type;
|
||
|
typedef typename traits::int_type int_type;
|
||
|
|
||
|
/*
|
||
|
* constructor - wraps an existing Tserial class instance
|
||
|
*/
|
||
|
|
||
|
explicit basic_serialbuf(Tserial& serial_,ios_base::openmode which_ = ios_base::in | ios_base::out)
|
||
|
: _serial(serial_)
|
||
|
{
|
||
|
basic_streambuf<charT,traits>::openedFor = which_;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Required to maintain the chain
|
||
|
*/
|
||
|
|
||
|
virtual ~basic_serialbuf() { }
|
||
|
|
||
|
/*
|
||
|
* Get a reference to the wrapped object
|
||
|
*/
|
||
|
|
||
|
Tserial& serial() { return _serial; }
|
||
|
|
||
|
protected:
|
||
|
|
||
|
/*
|
||
|
* Get how many bytes available
|
||
|
*/
|
||
|
|
||
|
virtual int showmanyc(){
|
||
|
return _serial.available();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Read up to n chars
|
||
|
*/
|
||
|
|
||
|
virtual streamsize xsgetn(char_type* c, streamsize n) {
|
||
|
|
||
|
streamsize i = 0;
|
||
|
char_type data;
|
||
|
|
||
|
while((data=_serial.read())!=-1 && i < n ) {
|
||
|
c[i] = data;
|
||
|
++i;
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Write up to n chars
|
||
|
*/
|
||
|
|
||
|
virtual streamsize xsputn(const char_type* s, streamsize n){
|
||
|
|
||
|
for(streamsize i=0;i<n;i++)
|
||
|
_serial.print(s[i]);
|
||
|
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* write a single char
|
||
|
*/
|
||
|
|
||
|
virtual int_type overflow (int_type c = traits::eof()) {
|
||
|
if(!traits::eq_int_type(c,traits::eof()))
|
||
|
_serial.print((char_type)c);
|
||
|
|
||
|
return traits::not_eof(c);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* peek at a char where possible
|
||
|
*/
|
||
|
|
||
|
virtual int_type underflow(){
|
||
|
if(_serial.available())
|
||
|
return _serial.peek();
|
||
|
else
|
||
|
return traits::eof();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Read a char where possible
|
||
|
*/
|
||
|
|
||
|
virtual int_type uflow(){
|
||
|
if(_serial.available())
|
||
|
return _serial.read();
|
||
|
else
|
||
|
return traits::eof();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Our wrapped arduino class
|
||
|
*/
|
||
|
|
||
|
Tserial _serial;
|
||
|
};
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Input stream
|
||
|
*/
|
||
|
|
||
|
template <class charT, class traits, class Tserial> class basic_iserialstream
|
||
|
: public basic_istream<charT,traits>
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
/*
|
||
|
* Types used here
|
||
|
*/
|
||
|
|
||
|
typedef charT char_type;
|
||
|
|
||
|
/*
|
||
|
* Constructor - default the serial object to #1
|
||
|
* Mega users can explicity initialise with one of
|
||
|
* the others
|
||
|
*/
|
||
|
|
||
|
explicit basic_iserialstream(Tserial& serial_)
|
||
|
: basic_ios<charT, traits>(&sb), basic_istream<charT,traits>(&sb), sb(serial_,ios_base::in)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Required to maintain the chain
|
||
|
*/
|
||
|
|
||
|
virtual ~basic_iserialstream() { }
|
||
|
|
||
|
/*
|
||
|
* Initialise the baud rate
|
||
|
*/
|
||
|
|
||
|
void begin(long speed_) {
|
||
|
sb.serial().begin(speed_);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* The wrapped object
|
||
|
*/
|
||
|
|
||
|
private:
|
||
|
basic_serialbuf<charT,traits,Tserial> sb;
|
||
|
};
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Output stream
|
||
|
*/
|
||
|
|
||
|
template <class charT, class traits, class Tserial> class basic_oserialstream
|
||
|
: public basic_ostream<charT,traits>
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
/*
|
||
|
* Types used here
|
||
|
*/
|
||
|
|
||
|
typedef charT char_type;
|
||
|
|
||
|
/*
|
||
|
* Constructor - default the serial object to #1
|
||
|
* Mega users can explicity initialise with one of
|
||
|
* the others
|
||
|
*/
|
||
|
|
||
|
explicit basic_oserialstream(Tserial& serial_)
|
||
|
: basic_ios<charT, traits>(&sb), basic_ostream<charT,traits>(&sb), sb(serial_,ios_base::out)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Required to maintain the chain
|
||
|
*/
|
||
|
|
||
|
virtual ~basic_oserialstream() { }
|
||
|
|
||
|
/*
|
||
|
* Initialise the baud rate
|
||
|
*/
|
||
|
|
||
|
void begin(long speed_) {
|
||
|
sb.serial().begin(speed_);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* The wrapped object
|
||
|
*/
|
||
|
|
||
|
private:
|
||
|
basic_serialbuf<charT,traits,Tserial> sb;
|
||
|
};
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Input/output stream
|
||
|
*/
|
||
|
|
||
|
template <class charT, class traits, class Tserial> class basic_ioserialstream
|
||
|
: public basic_iostream<charT,traits>
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
/*
|
||
|
* Types used here
|
||
|
*/
|
||
|
|
||
|
typedef charT char_type;
|
||
|
|
||
|
/*
|
||
|
* Constructor - default the serial object to #1
|
||
|
* Mega users can explicity initialise with one of
|
||
|
* the others
|
||
|
*/
|
||
|
|
||
|
explicit basic_ioserialstream(Tserial& serial_)
|
||
|
: basic_ios<charT, traits>(&sb), basic_iostream<charT,traits>(&sb), sb(serial_,ios_base::in | ios_base::out)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Required to maintain the chain
|
||
|
*/
|
||
|
|
||
|
virtual ~basic_ioserialstream(){ }
|
||
|
|
||
|
/*
|
||
|
* Initialise the baud rate
|
||
|
*/
|
||
|
|
||
|
void begin(long speed_) {
|
||
|
sb.serial().begin(speed_);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* The wrapped object
|
||
|
*/
|
||
|
|
||
|
private:
|
||
|
basic_serialbuf<charT, traits, Tserial> sb;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|