Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
311 lines (232 sloc) 5.24 KB
/*
* 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>
#include <HardwareSerial.h>
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){
//_serial.print("[PUT ");
//_serial.print(n);
//_serial.print("] ");
for(streamsize i=0;i<n;i++)
{
char_type c = s[i];
if ( c == '\n' )
_serial.print('\r');
_serial.print(c);
}
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("[OF]");
if ( (char_type)c == '\n' )
_serial.print('\r');
_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_);
sb.serial().println(__FUNCTION__);
}
/*
* 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