iostreams and serial ports help
Hi, I'm a newcomer to boost and having trouble determining if what I want to achieve is possible. I want some sort of boost::iostreams object wrapping a serial port so that it conforms to the usual interfaces - this would be extremely useful not only for its use, but also to enable injection of a stringstream instance as a mock object when testing. It seems that the likely candidate for this is file_descriptor but I'm not entirely sure. First off, file_descriptor refines SeekableDevice, which a serial port isn't - does this mean that I can't do it? After trying to compile I realised that a SeekableDevice provides read, write and seek functions, nothing else. Am I seriously misunderstanding the point of boost::iostreams? If I am then can anybody point me in a better direction? My ultimate requirement is a serial port access class that looks just like a C++/boost iostream. I cannot use C++ iostreams directly as I require access to file-descriptor which is not available. Anyone able to help a lost person please? TIA, --rob
Rob Desbois, le 18 janvier 2008 08:02:
After trying to compile I realised that a SeekableDevice provides read, write and seek functions, nothing else. Am I seriously misunderstanding the point of boost::iostreams?
A file_descriptor only implements the Device concept, it not an std::iostream. If you want an std::iostream, you wrap the Device in a boost::iostreams::stream which, as stated in its documentation: "performs i/o by delegating to a contained Device", and "derives from a specialization of std::basic_istream, std::basic_ostream or std::basic_iostream, depending on whether the underlying Device models Source, Sink or both." HTH, Éric Malenfant --------------------------------------------- If we were meant to fly, we wouldn't keep losing our luggage.
Eric,
Thanks, that does help.
Are you able to comment on whether I 'should' be doing this as regards the
non-blocking and non-seekable nature of a serial port?
Thanks,
Rob
On Jan 18, 2008 6:46 PM, Eric MALENFANT
Rob Desbois, le 18 janvier 2008 08:02:
After trying to compile I realised that a SeekableDevice provides read, write and seek functions, nothing else. Am I seriously misunderstanding the point of boost::iostreams?
A file_descriptor only implements the Device concept, it not an std::iostream. If you want an std::iostream, you wrap the Device in a boost::iostreams::stream which, as stated in its documentation: "performs i/o by delegating to a contained Device", and "derives from a specialization of std::basic_istream, std::basic_ostream or std::basic_iostream, depending on whether the underlying Device models Source, Sink or both."
HTH,
Éric Malenfant --------------------------------------------- If we were meant to fly, we wouldn't keep losing our luggage. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Rob Desbois Eml: rob.desbois@gmail.com Tel: 07946 705987 "There's a whale there's a whale there's a whale fish" he cried, and the whale was in full view. ...Then ooh welcome. Ahhh. Ooh mug welcome.
Rob, Like you, I feel like a relative newcomer to boost, though I have been playing around with various libraries to suit my needs for over a year. I looked at boost::asio. For some reason it is not listed under the boost documentation lists, but it does appear to be a boost approved library. It does address the issue of blocking and non-blocking. I got most of the way into making a serial port look and behave like an ftp socket. I know this is not the same as an iostream, but it may be what you want. Warning: you have to do a lot of learning/exploring before you can effectively use asio (though I found this is true of many boost libraries). There is a tutorial and plenty of examples. BobW
Rob Desbois, le 18 janvier 2008 08:02:
After trying to compile I realised that a SeekableDevice provides read, write and seek functions, nothing else. Am I seriously misunderstanding the point of
boost::iostreams?
On Jan 18, 2008 6:46 PM, Eric MALENFANT
wrote:
A file_descriptor only implements the Device concept, it not an std::iostream. If you want an std::iostream, you wrap the Device in a boost::iostreams::stream which, as stated in its documentation: "performs i/o by delegating to a contained Device", and "derives from a specialization of std::basic_istream, std::basic_ostream or std::basic_iostream, depending on whether the underlying Device models Source, Sink or both."
Rob Desbois, le 18 janvier 2008 13:58:
Are you able to comment on whether I 'should' be doing this as regards the non-blocking and non-seekable nature of a serial port?
The "seekability" should not be a problem. You could define a BidirectionalDevice as Jonathan suggests in another message. If you only need read (or write), you could even just define a Source (or Sink). The "blocking" side of things may be more trouble, depending on your needs. Boost.Iostreams offers minimal support for non-blocking strings: boost::iostreams::char_traits::would_block() can be used to indicate that a read or write attempt was interrupted but, unless I missed something, nothing allows the caller to wait for the blocking condition to be removed (like select() allows for non-blocking sockets, for example), so the caller has to poll the stream. As suggested by Bob Warren, Boost.Asio may offer an interesting alternative. Éric Malenfant --------------------------------------------- Amateur programmers think there are 1000 bytes in a kilobyte; Real Programmers think there are 1024 meters in a kilometer.
Jonathan - thank you, that's helped massively. I now have a serial_device
type along the lines you described :-)
Bob - thanks for the asio suggestion - I decided that it wasn't quite what
I'm looking for though.
Eric - I realised I actually configure the serial port as a blocking device
so it should be fine.
My final (I hope!) problem is in using a stream.
I cannot compile a program creating a stream object templated for my serial
device:
#include
int main(void) { boost::iostreams::stream
s; }
Compiling that with g++ 3.3.3 gives: test-stream.cpp: In function `int main()':
test-stream.cpp:5: error: invalid use of template `template
struct boost::iostreams::stream' test-stream.cpp:5: error: syntax error before `;' token
This is with Boost 1.34.1
Can any of you shed any light on this please?!
Thanks for all the help so far :-)
--rob
On Jan 21, 2008 3:09 PM, Eric MALENFANT
Rob Desbois, le 18 janvier 2008 08:02:
> > After trying to compile I realised that a SeekableDevice > provides read, write and seek functions, nothing else. > Am I seriously misunderstanding the point of boost::iostreams?
On Jan 18, 2008 6:46 PM, Eric MALENFANT
wrote: A file_descriptor only implements the Device concept, it not an std::iostream. If you want an std::iostream, you wrap the Device in a boost::iostreams::stream which, as stated in its documentation: "performs i/o by delegating to a contained Device", and "derives from a specialization of std::basic_istream, std::basic_ostream or std::basic_iostream, depending on whether the underlying Device models Source, Sink or both."
Rob Desbois, le 18 janvier 2008 13:58:
Are you able to comment on whether I 'should' be doing this as regards the non-blocking and non-seekable nature of a serial port?
The "seekability" should not be a problem. You could define a BidirectionalDevice as Jonathan suggests in another message. If you only need read (or write), you could even just define a Source (or Sink).
The "blocking" side of things may be more trouble, depending on your needs. Boost.Iostreams offers minimal support for non-blocking strings: boost::iostreams::char_traits::would_block() can be used to indicate that a read or write attempt was interrupted but, unless I missed something, nothing allows the caller to wait for the blocking condition to be removed (like select() allows for non-blocking sockets, for example), so the caller has to poll the stream. As suggested by Bob Warren, Boost.Asio may offer an interesting alternative.
Éric Malenfant --------------------------------------------- Amateur programmers think there are 1000 bytes in a kilobyte; Real Programmers think there are 1024 meters in a kilometer. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Rob Desbois Eml: rob.desbois@gmail.com Tel: 07946 705987 "There's a whale there's a whale there's a whale fish" he cried, and the whale was in full view. ...Then ooh welcome. Ahhh. Ooh mug welcome.
Hmm well I'm not entirely sure what I've done correctly now...but this seems
to work!
Another problem with the stream...but another thread would serve it well.
Thanks all for the help :-)
--rob
On Jan 22, 2008 5:12 PM, Rob Desbois
Jonathan - thank you, that's helped massively. I now have a serial_device type along the lines you described :-)
Bob - thanks for the asio suggestion - I decided that it wasn't quite what I'm looking for though.
Eric - I realised I actually configure the serial port as a blocking device so it should be fine.
My final (I hope!) problem is in using a stream. I cannot compile a program creating a stream object templated for my serial device:
#include
#include "serial_device.h"
int main(void) { boost::iostreams::stream
s; } Compiling that with g++ 3.3.3 gives:
test-stream.cpp: In function `int main()':
test-stream.cpp:5: error: invalid use of template `template
struct boost::iostreams::stream' test-stream.cpp:5: error: syntax error before `;' token This is with Boost 1.34.1 Can any of you shed any light on this please?!
Thanks for all the help so far :-) --rob
On Jan 21, 2008 3:09 PM, Eric MALENFANT < Eric.Malenfant@sagem-interstar.com> wrote:
Rob Desbois, le 18 janvier 2008 08:02:
> > After trying to compile I realised that a SeekableDevice > provides read, write and seek functions, nothing else. > Am I seriously misunderstanding the point of boost::iostreams?
On Jan 18, 2008 6:46 PM, Eric MALENFANT
wrote: A file_descriptor only implements the Device concept, it not an std::iostream. If you want an std::iostream, you wrap the Device in a boost::iostreams::stream which, as stated in its documentation: "performs i/o by delegating to a contained Device", and "derives from a specialization of std::basic_istream, std::basic_ostream or std::basic_iostream, depending on whether the underlying Device models Source, Sink or both."
Rob Desbois, le 18 janvier 2008 13:58:
Are you able to comment on whether I 'should' be doing this as regards the non-blocking and non-seekable nature of a serial port?
The "seekability" should not be a problem. You could define a BidirectionalDevice as Jonathan suggests in another message. If you only need read (or write), you could even just define a Source (or Sink).
The "blocking" side of things may be more trouble, depending on your needs. Boost.Iostreams offers minimal support for non-blocking strings: boost::iostreams::char_traits::would_block() can be used to indicate that a read or write attempt was interrupted but, unless I missed something, nothing allows the caller to wait for the blocking condition to be removed (like select() allows for non-blocking sockets, for example), so the caller has to poll the stream. As suggested by Bob Warren, Boost.Asio may offer an interesting alternative.
Éric Malenfant --------------------------------------------- Amateur programmers think there are 1000 bytes in a kilobyte; Real Programmers think there are 1024 meters in a kilometer. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Rob Desbois Eml: rob.desbois@gmail.com Tel: 07946 705987 "There's a whale there's a whale there's a whale fish" he cried, and the whale was in full view. ...Then ooh welcome. Ahhh. Ooh mug welcome.
-- Rob Desbois Eml: rob.desbois@gmail.com Tel: 07946 705987 "There's a whale there's a whale there's a whale fish" he cried, and the whale was in full view. ...Then ooh welcome. Ahhh. Ooh mug welcome.
Rob Desbois wrote:
Jonathan - thank you, that's helped massively. I now have a serial_device type along the lines you described :-)
Cool ;-) -- Jonathan Turkanis CodeRage http://www.coderage.com
Eric MALENFANT wrote:
Rob Desbois, le 18 janvier 2008 08:02:
After trying to compile I realised that a SeekableDevice provides read, write and seek functions, nothing else. Am I seriously misunderstanding the point of boost::iostreams?
A file_descriptor only implements the Device concept, it not an std::iostream. If you want an std::iostream, you wrap the Device in a boost::iostreams::stream which, as stated in its documentation: "performs i/o by delegating to a contained Device", and "derives from a specialization of std::basic_istream, std::basic_ostream or std::basic_iostream, depending on whether the underlying Device models Source, Sink or both."
Right. What you probably need to do is define your own device, SerialPort, which would not be a seekable device; instead, it might be a bidirectional device (http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.1). I must warn you in advance, however, that the C++ standard library iostream abstractions only works well for blocking I/O. I have a feeling that access to a serial port might be non-blocking, i.e., that a read or write might fail to process the requested number of character even though no error has occurred and EOF has not been reached. (See the brief discussions here (http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.1) and here (http://tinyurl.com/yoqrw5)) It has been on my todo list for some time to add to Boost.Iostreams some abstractions that will be useful with non-blocking devices, but I haven't done it yet. -- Jonathan Turkanis CodeRage http://www.coderage.com
participants (4)
-
Bob Warren
-
Eric MALENFANT
-
Jonathan Turkanis
-
Rob Desbois