Re: Using streams/strings to parse data.
HMS Surprise wrote:
I am reading data from a USB device using readFile:
BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
This is working OK but I want to start taking advantage of more C++
capabilities such as the way it handles streams and strings. The GPS
sentences read in start with '$' and end with 0x0D 0x0A. However the
device was apparently first implemented as RS-232 and then ported to
USB as there may be any number of nulls in the stream. Thus the
'sentences' may not start at the beginning of the buffer and since
each bufferful is 32 bytes some of the 80 byte 'sentences' may span
three buffers.
Question 1:
Is there an existing sstream function that can convert an array of
characters that may have embedded nulls into a string object.
<sstream> is a header declaring stringstreams, and those just operate or
strings, they don't introduce any new functionality for them. Now, as far
as strings are concerned, they don't care if there are null characters
embedded, they still work the same. The only exceptions are the ctor and
assignment op taking a 'char const*'.
Since Readfile tells me how many bytes were copied into the buffer, is
there something in sstream that works similar to cin.getc or
cin.getline that can ignore multiple characters?
'std::cin' is an istream. In <sstream>, you have class istringstream, which
is derived from class istream.
Is it possible to intermix a series of gets and appends to a string
object? In other words I want to use the string object as a FIFO,each
time I access this function I want to append more characters to the
string and then pull complete sentence from the front end?
Possible, yes, performant, maybe not. But with the sizes you mentioned the
performance will hardly present a bottleneck.
I am more familiar with the Nucleus OS than with Windows and VC++.
Could question 3 be performed across two threads, where one is
appending and the other is extracting?
Yes, but I'd rather use a single thread that assembles the full
packages/sentences and then forwards them. That way you don't have to touch
the data twice.
Of course I would use semaphores.
I'd suggest CRITICAL_SECTION (see MSDN). Semaphores are error-prone and the
full win32 mutexes are overkill if they are not used for inter-process
communication.
I would appreciate it if you could point me to some documentation on
VC++ threads.
Use msdn.microsoft.com, CreateThread as a starting point.
Finally, I wouldn't try to concentrate too much on the methods. First, I
would define how I want my data. Probably, I'd take it stripped of all the
packaging overhead, i.e. without the $ and 0x0d, 0x0a. In order to parse
this, if it contains text, I would use stringstreams, just for the
transport, I would use std::strings then. If it is some non-textual data, I
would use std::vector instead or maybe some custom made buffer type.
Reading from the device and assembling those sentences is done in one
module, handling them in another. Those modules can be represented by
threads, but they don't have to.
[...]and very C like code to do this ( at least it has c++ comments).
C99 has // comments, too. ;)
Uli