|
From: <bo...@us...> - 2008-04-30 05:42:38
|
Revision: 132
http://gearbox.svn.sourceforge.net/gearbox/?rev=132&view=rev
Author: borax00
Date: 2008-04-29 22:42:43 -0700 (Tue, 29 Apr 2008)
Log Message:
-----------
fixed readUntil, _changed_serial_API_ !!!
Modified Paths:
--------------
gearbox/trunk/src/gbxserialacfr/serial.cpp
gearbox/trunk/src/gbxserialacfr/serial.h
gearbox/trunk/src/gbxserialacfr/test/serialloopbacktest.cpp
gearbox/trunk/submitted/gbxgarminacfr/driver.cpp
Modified: gearbox/trunk/src/gbxserialacfr/serial.cpp
===================================================================
--- gearbox/trunk/src/gbxserialacfr/serial.cpp 2008-04-30 01:36:20 UTC (rev 131)
+++ gearbox/trunk/src/gbxserialacfr/serial.cpp 2008-04-30 05:42:43 UTC (rev 132)
@@ -64,10 +64,6 @@
namespace {
- //Used for calls to waitForDataOrTimeout()
- enum{TIMED_OUT=-1, GOT_DATA};
-
-
// Converts an integer baud-rate into a c-style '#define'd baudrate
int cBaudrate( int baudRate )
{
@@ -623,10 +619,8 @@
}
-
-
-int
-Serial::readUntil(void *buf, int count, char termchar)
+int
+Serial::readStringUntil( std::string &str, char termchar )
{
if ( debugLevel_ > 0 ){
cout<<"TRACE(serial.cpp): "<<__func__<<"(): ";
@@ -637,55 +631,109 @@
}
}
- // There must be at least room for a terminating char and NULL terminator!
- assert (count >= 2);
+ // clear the string
+ str="";
- char* dataPtr = static_cast<char*>(buf);
- const char* bufPtr = static_cast<char*>(buf);
- char nextChar = 0;
-
- do {
- // Check for buf overrun Must leave room for NULL terminator
- if ( dataPtr >= bufPtr + (count - 1) )
+ while ( true )
+ {
+ // Read at most a single character
+ char c;
+ int ret = ::read( portFd_, &c, 1 );
+ if ( ret == 1 )
{
- stringstream ss;
- ss << "Serial::"<<__func__<<": Not enough room in buffer";
- throw SerialException( ss.str() );
+ str += c;
+ if ( c == termchar )
+ return str.size();
}
-
- int ret = ::read( portFd_, &nextChar, 1 );
- if (ret == 1)
+ else if ( ret == 0 )
{
- *(dataPtr++) = nextChar; //got data let's store it...
+ // Nothing to read yet
+ if ( ( timeoutsEnabled() && waitForDataOrTimeout() == TIMED_OUT ) ||
+ !timeoutsEnabled() )
+ {
+ // Timed out
+ return -1;
+ }
}
- else
+ else // ret==-1: error
{
- // If timeouts enabled and no data, wait and then go again
- if( timeoutsEnabled() && (ret == -1) && (errno == EAGAIN) )
+ if ( timeoutsEnabled() && errno == EAGAIN )
{
- if(waitForDataOrTimeout() == GOT_DATA)
- {
- continue;
- }else{
- *dataPtr = 0x00; // Timed out. terminate string just incase it's used anyway
+ if ( waitForDataOrTimeout() == TIMED_OUT )
return -1;
- }
}
+ else
+ {
+ stringstream ss;
+ ss << "Serial::"<<__func__<<"(): "<<strerror(errno);
+ throw SerialException( ss.str() );
+ }
+ }
+ }
+ return str.size();
+}
- // If we get here then it was a more serious error
- stringstream ss;
- ss << "Serial::"<<__func__<<"(): "<<strerror(errno);
- throw SerialException( ss.str() );
- }
+// int
+// Serial::readUntil(void *buf, int count, char termchar)
+// {
+// if ( debugLevel_ > 0 ){
+// cout<<"TRACE(serial.cpp): "<<__func__<<"(): ";
+// if(timeoutsEnabled()){
+// cout << "timeouts enabled"<<endl;
+// }else{
+// cout << "timeouts not enabled"<<endl;
+// }
+// }
+
+// // There must be at least room for a terminating char and NULL terminator!
+// assert (count >= 2);
+
+// char* dataPtr = static_cast<char*>(buf);
+// const char* bufPtr = static_cast<char*>(buf);
+// char nextChar = 0;
+
+// do {
+// // Check for buf overrun Must leave room for NULL terminator
+// if ( dataPtr >= bufPtr + (count - 1) )
+// {
+// stringstream ss;
+// ss << "Serial::"<<__func__<<": Not enough room in buffer";
+// throw SerialException( ss.str() );
+// }
+
+// int ret = ::read( portFd_, &nextChar, 1 );
+// if (ret == 1)
+// {
+// *(dataPtr++) = nextChar; //got data let's store it...
+// }
+// else
+// {
+// // If timeouts enabled and no data, wait and then go again
+// if( timeoutsEnabled() && (ret == -1) && (errno == EAGAIN) )
+// {
+// if( waitForDataOrTimeout() == DATA_AVAILABLE )
+// {
+// continue;
+// }else{
+// *dataPtr = 0x00; // Timed out. terminate string just incase it's used anyway
+// return -1;
+// }
+// }
+
+// // If we get here then it was a more serious error
+// stringstream ss;
+// ss << "Serial::"<<__func__<<"(): "<<strerror(errno);
+// throw SerialException( ss.str() );
+// }
- } while (nextChar != termchar);
+// } while (nextChar != termchar);
- // It's a string. It must be NULL terminated...
- *dataPtr = 0x00;
+// // It's a string. It must be NULL terminated...
+// *dataPtr = 0x00;
- // Return the number of chars not including the NULL
- return ( (int) (dataPtr - bufPtr) );
-}
+// // Return the number of chars not including the NULL
+// return ( (int) (dataPtr - bufPtr) );
+// }
int
@@ -706,7 +754,8 @@
int
Serial::bytesAvailableWait()
{
- if ( waitForDataOrTimeout() == TIMED_OUT){
+ if ( waitForDataOrTimeout() == TIMED_OUT )
+ {
return -1;
}
@@ -714,7 +763,7 @@
}
-int
+Serial::WaitStatus
Serial::waitForDataOrTimeout()
{
fd_set rfds;
@@ -736,7 +785,7 @@
throw SerialException( ss.str() );
}
- return GOT_DATA;
+ return DATA_AVAILABLE;
}
Modified: gearbox/trunk/src/gbxserialacfr/serial.h
===================================================================
--- gearbox/trunk/src/gbxserialacfr/serial.h 2008-04-30 01:36:20 UTC (rev 131)
+++ gearbox/trunk/src/gbxserialacfr/serial.h 2008-04-30 05:42:43 UTC (rev 132)
@@ -94,16 +94,9 @@
//!
int readFull(void *buf, int count);
- //! Reads up to @c count bytes-1 (including @c termchar), terminated by @c termchar.
- //! Returns the number of bytes read.
- //! After reading the data, the string will be NULL terminated.
+ //! Reads a string into @str, up to and including the first instance of @termchar
+ //! Returns the number of bytes read (or '-1' on timeout).
//!
- //! Example: if you expect to read the string "1234\n", you need something like:
- //! char buf[6];
- //! serial.readUntil( buf, 6, '\n' );
- //!
- //! where the two extra characters are for the "\n" and the terminating "\0".
- //!
//! If timeouts are not enabled we might block forever, waiting for the number of bytes we want or an error.
//!
//! If timeouts are enabled we won't block more than the timeout specified.
@@ -111,12 +104,12 @@
//! NOTE: The timeout applies for each individual read() call. We might have to make lots of them,
//! so the total time for which this function blocks might be longer than the specified timeout.
//!
- int readUntil(void *buf, int count, char termchar);
+ int readStringUntil( std::string &str, char termchar );
//! Short-hand for "readUntil(buf,count,'\n');"
//! Reads everything up to and including the '\n'.
- int readLine(void *buf, int count)
- { return readUntil(buf,count,'\n'); }
+ int readLine( std::string &str )
+ { return readStringUntil(str,'\n'); }
//! Returns the number of bytes available for reading (non-blocking).
int bytesAvailable();
@@ -155,9 +148,11 @@
// Utility function to wait up to the timeout for data to appear.
// Returns:
- // TIMED_OUT: timed out
- // GOT_DATA : data available
- int waitForDataOrTimeout(void);
+ enum WaitStatus {
+ TIMED_OUT,
+ DATA_AVAILABLE,
+ };
+ WaitStatus waitForDataOrTimeout(void);
// Opens a device @c dev.
void open(int flags=0);
Modified: gearbox/trunk/src/gbxserialacfr/test/serialloopbacktest.cpp
===================================================================
--- gearbox/trunk/src/gbxserialacfr/test/serialloopbacktest.cpp 2008-04-30 01:36:20 UTC (rev 131)
+++ gearbox/trunk/src/gbxserialacfr/test/serialloopbacktest.cpp 2008-04-30 05:42:43 UTC (rev 132)
@@ -46,12 +46,12 @@
for ( uint i=0; i < NUM_CHARS; i++ )
{
int stringI = i % (stringList.size());
- std::string theString = stringList[stringI]+"\n";
+ std::string sendString = stringList[stringI]+"\n";
- serial.writeString( theString );
+ serial.writeString( sendString );
- char buf[ theString.size()+1 ];
- int ret = serial.readLine( buf, theString.size()+1 );
+ std::string receiveString;
+ int ret = serial.readLine( receiveString );
if ( ret < 0 )
{
cout << "ERROR(serialloopbacktest.cpp): Read timed out!" << endl;
@@ -66,15 +66,15 @@
exit(1);
}
- if ( !strcmp( buf, theString.c_str() ) )
+ if ( sendString == receiveString )
{
- cout<<"Wrote and read: " << theString << endl;
+ cout<<"Wrote and read: " << sendString << endl;
}
else
{
cout << "ERROR(serialloopbacktest.cpp): Strings didn't match!!" << endl;
- cout << "ERROR(serialloopbacktest.cpp): Wrote: '" << theString <<"'"<< endl;
- cout << "ERROR(serialloopbacktest.cpp): Read: '" << buf <<"'"<< endl;
+ cout << "ERROR(serialloopbacktest.cpp): Wrote: '" << sendString <<"'"<< endl;
+ cout << "ERROR(serialloopbacktest.cpp): Read: '" << receiveString <<"'"<< endl;
cout<<"TRACE(serialloopbacktest.cpp): test FAILED" << endl;
exit(1);
Modified: gearbox/trunk/submitted/gbxgarminacfr/driver.cpp
===================================================================
--- gearbox/trunk/submitted/gbxgarminacfr/driver.cpp 2008-04-30 01:36:20 UTC (rev 131)
+++ gearbox/trunk/submitted/gbxgarminacfr/driver.cpp 2008-04-30 05:42:43 UTC (rev 132)
@@ -150,7 +150,7 @@
Driver::readFrame(Data& GpsData)
{
- char serial_data[1024];
+ string serial_data;
int gpsMsgNotYetGotFrameCount = 0;
//How many messages are we looking for to make our frame
@@ -164,7 +164,7 @@
// This will block up to the timeout
tracer_.debug( "Driver::read(): calling serial_->readLine()", 10 );
- int ret = serial_->readLine(serial_data,1024);
+ int ret = serial_->readLine(serial_data);
tracer_.debug( serial_data, 10 );
// timeOfRead_ = IceUtil::Time::now();
@@ -193,7 +193,7 @@
static int nmeaExceptionCount =0;
try{
//This throws if it cannot find the * to deliminate the checksum field
- nmeaMessage_.setSentence(serial_data,gbxgpsutilacfr::TestChecksum);
+ nmeaMessage_.setSentence(serial_data.c_str(),gbxgpsutilacfr::TestChecksum);
}
catch (gbxgpsutilacfr::NmeaException &e){
//Don't throw if only occasional messages are missing the checksums
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|