bug-commoncpp
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Patch: Serial Port Interactive Mode Buffering Improved


From: Conrad T. Pino
Subject: Patch: Serial Port Interactive Mode Buffering Improved
Date: Wed, 7 Sep 2005 12:10:24 -0700

This patch modifies the following files:

        demo/serialecho.cpp
        demo/serialecho.h
        demo/serialmain.cpp

        include/cc++/serial.h

        src/serial.cpp

This patch is committed on "dev-bcb6-arm" branch between revision
tags "dev-bcb6-arm-0050" and "dev-bcb6-arm-0051".

Index: demo/serialecho.cpp
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/demo/serialecho.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- demo/serialecho.cpp 23 Apr 2005 22:08:01 -0000      1.1.1.1
+++ demo/serialecho.cpp 7 Sep 2005 19:01:20 -0000       1.1.1.1.2.1
@@ -28,45 +28,56 @@
 using namespace std;
 
 SerialEcho::SerialEcho(const char *device, 
+                       unsigned long speed,
+                       int char_bits,
+                       Parity parity,
+                       int stop_bits,
+                       Flow flow,
                        int priority, int stacksize) :
   TTYSession( device, priority, stacksize ) {
 
   cout << "Creating SerialEcho" << endl;
 
-  if (!(*this)) {
+  if (!isOpen()) {
     throw xError();
     ::exit(1);
   } else {
     cout << "modem ready" << endl;
   }
 
-  interactive(false);
+  interactive(true);
 
-  if (setSpeed(38400)) cout << getErrorString() << endl;
-  if (setCharBits(8)) cout << getErrorString() << endl;
-  if (setParity(Serial::parityNone)) cout << getErrorString() << endl;
-  if (setStopBits(1)) cout << getErrorString() << endl;
-  if (setFlowControl(Serial::flowHard)) cout << getErrorString() << endl;
+  if (setSpeed(speed)) cout << getErrorString() << endl;
+  if (setCharBits(char_bits)) cout << getErrorString() << endl;
+  if (setParity(parity)) cout << getErrorString() << endl;
+  if (setStopBits(stop_bits)) cout << getErrorString() << endl;
+  if (setFlowControl(flow)) cout << getErrorString() << endl;
+
+//  setPacketInput(16,100);
 
   cout << "config done" << endl;
 }
 
 void SerialEcho::run() {
-  char* s = new char[getBufferSize()];
-
   cout << "start monitor" << endl;
 
-  while (s[0] != 'X') {
-    while (isPending(Serial::pendingInput)) {
-      cout.put( TTYStream::get() );
-    } 
-    sleep(500);
+#if 0
+//FILE *fout = fopen("serial.out", "wt");
+  FILE *fout = stdout;
+  while (isPending(pendingInput)) {
+    fputc( TTYStream::get(), fout );
+    if ( ! isPending( pendingInput, 0 ) ) fflush( fout );
   }
+#else
+  int data;
+  while ( ( data = TTYStream::get() ) ) {
+    cout.put( data );
+    if ( ! isPending( pendingInput, 0 ) ) cout.flush();
+  } 
+#endif
 
   cout << "end of monitor" << endl;
 
-  delete [] s;
-  
   exit();
 }
 
Index: demo/serialecho.h
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/demo/serialecho.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- demo/serialecho.h   23 Apr 2005 22:08:01 -0000      1.1.1.1
+++ demo/serialecho.h   7 Sep 2005 19:01:20 -0000       1.1.1.1.2.1
@@ -18,7 +18,7 @@
 #ifndef SERIALECHO_H
 #define SERIALECHO_H
 
-#include <cc++/common.h>
+#include <cc++/serial.h>
 
 #ifdef CCXX_NAMESPACES
 using namespace std;
@@ -28,7 +28,12 @@ using namespace ost;
 class SerialEcho : public TTYSession {
  public:
 
-  SerialEcho(const char *device,  
+  SerialEcho(const char *device, 
+             unsigned long speed = 38400,
+             int char_bits = 8,
+             Parity parity = parityNone,
+             int stop_bits = 1,
+             Flow flow = flowHard,
              int priority = 0, int stacksize = 0);
 
   // Exception classes
Index: demo/serialmain.cpp
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/demo/serialmain.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- demo/serialmain.cpp 23 Apr 2005 22:08:01 -0000      1.1.1.1
+++ demo/serialmain.cpp 7 Sep 2005 19:01:20 -0000       1.1.1.1.2.1
@@ -29,16 +29,60 @@
 
 int main(int argc, char **argv)
 {
+  const char *device = "/dev/modem2";
+  unsigned long speed = 38400;
+  int char_bits = 8;
+  Serial::Parity parity = Serial::parityNone;
+  int stop_bits = 1;
+  Serial::Flow flow = Serial::flowHard;
+
+  if ( argc > 1 ) device = argv[ 1 ];
+  if ( argc > 2 ) speed = atol( argv[ 2 ] );
+  if ( argc > 3 ) char_bits = atoi( argv[ 3 ] );
+  if ( argc > 4 )
+    switch ( *argv[ 4 ] ) {
+    case 'e':
+    case 'E':
+      parity = Serial::parityEven;
+      break;
+    case 'o':
+    case 'O':
+      parity = Serial::parityOdd;
+      break;
+    default:
+      parity = Serial::parityNone;
+      break;
+       }
+  if ( argc > 5 ) stop_bits = atoi( argv[ 5 ] );
+  if ( argc > 6 )
+    switch ( *argv[ 6 ] ) {
+    case 'b':
+    case 'B':
+      flow = Serial::flowBoth;
+      break;
+    case 'h':
+    case 'H':
+      flow = Serial::flowHard;
+      break;
+    case 's':
+    case 'S':
+      flow = Serial::flowSoft;
+      break;
+    default:
+      flow = Serial::flowNone;
+      break;
+       }
+
   cout << "Serial Echo to TCP Sessions" << endl;
   SerialEcho *modem;
   try {
-    modem = new SerialEcho("/dev/modem2");
+    modem = new SerialEcho(device, speed, char_bits, parity, stop_bits, flow);
   } catch (SerialEcho::xError *e) {
     cout << "Modem Error; aborting" << endl;
     ::exit(1);
   } catch (Serial *e) {
     cout << "Serial Error: " 
-         << modem->getErrorString() 
+         << e->getErrorString()
          << "; aborting" 
          << endl;
     ::exit(1);
@@ -46,7 +90,7 @@ int main(int argc, char **argv)
 
   char* b = new char[modem->getBufferSize()];
 
-  cout << "Modem code:" << modem->start() << endl;
+  cout << "Modem start code: " << modem->start() << endl;
 
   while (cin >> b, b[0]) {
 
@@ -64,4 +108,3 @@ int main(int argc, char **argv)
 }
 
 /**  2000 by TeleDynamics Communications Inc - address@hidden/
-
Index: include/cc++/serial.h
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/include/cc++/serial.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- include/cc++/serial.h       23 Apr 2005 22:08:11 -0000      1.1.1.1
+++ include/cc++/serial.h       7 Sep 2005 19:01:20 -0000       1.1.1.1.2.1
@@ -143,7 +143,7 @@ public:
 
 private:
        Error errid;
-       char *errstr;
+       const char *errstr;
 
        struct
        {
@@ -160,11 +160,10 @@ private:
        void initSerial(void);
 
 protected:
+       size_t getsize;
 
        HANDLE  dev;
 
-       int bufsize;
-
        /**
         * Opens the serial device.
         *
@@ -179,6 +178,13 @@ protected:
        void            close(void);
 
        /**
+        * Tests if the serial device is open.
+        *
+        */
+       inline bool     isOpen(void) const
+               {return dev != INVALID_HANDLE_VALUE;}
+
+       /**
         * Reads from serial device.
         *
         * @param Data  Point to character buffer to receive data.  Buffers MUST
@@ -202,7 +208,7 @@ protected:
         * @param error defined serial error id.
         * @param errstr string or message to optionally pass.
         */
-       Error error(Error error, char *errstr = NULL);
+       Error error(const Error error, const char *errstr = NULL);
 
        /**
         * This service is used to thow application defined serial
@@ -210,7 +216,7 @@ protected:
         *
         * @param errstr string or message to pass.
         */
-       inline void error(char *err)
+       inline void error(const char *err)
                {error(errExtended, err);};
 
 
@@ -254,17 +260,17 @@ protected:
        /**
         * Used to flush the input waiting queue.
         */
-       void flushInput(void);
+       virtual void flushInput(void);
 
        /**
         * Used to flush any pending output data.
         */
-       void flushOutput(void);
+       virtual void flushOutput(void);
 
        /**
         * Used to wait until all output has been sent.
         */
-       void waitOutput(void);
+       virtual void waitOutput(void);
 
        /**
         * Used as the default destructor for ending serial I/O
@@ -378,7 +384,7 @@ public:
         *
         * @return string for error message.
         */
-       inline char *getErrorString(void)
+       inline const char *getErrorString(void)
                {return errstr;};
 
        /**
@@ -388,8 +394,7 @@ public:
         *
         * @return number of bytes used for buffering.
         */
-       inline int getBufferSize(void)
-               {return bufsize;};
+       virtual size_t getBufferSize(void);
 
        /**
         * Get the status of pending operations.  This can be used to
@@ -427,12 +432,12 @@ public:
 class __EXPORT TTYStream : protected std::streambuf, public Serial, public 
std::iostream
 {
 private:
-       int doallocate();
-
        friend TTYStream& crlf(TTYStream&);
        friend TTYStream& lfcr(TTYStream&);
 
 protected:
+       size_t bufsize;
+
        char *gbuf, *pbuf;
        timeout_t timeout;
 
@@ -455,6 +460,21 @@ protected:
        void endStream(void);
 
        /**
+        * Used to flush the input waiting queue.
+        */
+       virtual void flushInput(void);
+
+       /**
+        * Used to flush any pending output data.
+        */
+       virtual void flushOutput(void);
+
+       /**
+        * Used to wait until all output has been sent.
+        */
+       virtual void waitOutput(void);
+
+       /**
         * This streambuf method is used to load the input buffer
         * through the established tty serial port.
         *
Index: src/serial.cpp
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/src/serial.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- src/serial.cpp      23 Apr 2005 22:08:24 -0000      1.1.1.1
+++ src/serial.cpp      7 Sep 2005 19:01:20 -0000       1.1.1.1.2.1
@@ -130,11 +130,7 @@ Serial::Serial(const char *fname)
 
        open(fname);
 
-#ifdef WIN32
-       if(dev == INVALID_HANDLE_VALUE)
-#else
-       if(dev < 0)
-#endif
+       if(!isOpen())
        {
                error(errOpenFailed);
                return;
@@ -154,9 +150,7 @@ Serial::Serial(const char *fname)
     CommTimeOuts.WriteTotalTimeoutConstant = 1000;
 
     SetCommTimeouts(dev, &CommTimeOuts) ;
-
 #else
-       
        if(!isatty(dev))
        {
                Serial::close();
@@ -206,7 +200,6 @@ void Serial::initConfig(void)
     attr->fParity = true;
 
     SetCommState(dev, attr);
-
 #else
        struct termios *attr = (struct termios *)current;
        struct termios *orig = (struct termios *)original;
@@ -275,34 +268,61 @@ void Serial::initSerial(void)
 
 void Serial::endSerial(void)
 {
+       if(isOpen())
+       {
+               if(original)
 #ifdef WIN32
-       if(dev == INVALID_HANDLE_VALUE && original)
-               SetCommState(dev, (DCB *)original);
+                       SetCommState(dev, (DCB *)original);
+#else
+                       tcsetattr(dev, TCSANOW, (struct termios *)original);
+#endif
+               Serial::close();
+       }
 
        if(current)
+       {
+#ifdef WIN32
                delete (DCB *)current;
+#else
+               delete (struct termios *)original;
+#endif
+               current = NULL;
+       }
 
        if(original)
+       {
+#ifdef WIN32
                delete (DCB *)original;
 #else
-       if(dev < 0 && original)
-               tcsetattr(dev, TCSANOW, (struct termios *)original);
-
-       if(current)
-               delete (struct termios *)current;
-
-       if(original)
                delete (struct termios *)original;
 #endif
-       Serial::close();
-
-       current = NULL;
-       original = NULL;
-
+               original = NULL;
+       }
 }
 
-Serial::Error Serial::error(Error err, char *errs)
+Serial::Error Serial::error(const Error err, const char *errs)
 {
+       static const char * errorStrings[ ] =
+       {
+               "errSuccess",
+               "errOpenNoTty",
+               "errOpenFailed",
+               "errSpeedInvalid",
+               "errFlowInvalid",
+               "errParityInvalid",
+               "errCharsizeInvalid",
+               "errStopbitsInvalid",
+               "errOptionInvalid",
+               "errResourceFailure",
+               "errOutput",
+               "errInput",
+               "errTimeout",
+               "errExtended"
+       };
+
+       if(!errs)
+               errs = errorStrings[ err ];
+
        errid = err;
        errstr = errs;
        if(!err)
@@ -336,13 +356,13 @@ int Serial::setPacketInput(int size, uns
        return 0;
 #else
 
-#ifdef _PC_MAX_INPUT
-       int max = fpathconf(dev, _PC_MAX_INPUT);
-#else
-       int max = MAX_INPUT;
-#endif
+       size_t max = getBufferSize();
+
        struct termios *attr = (struct termios *)current;
 
+       if(size < 0)
+               size = 1;
+
        if(size > max)
                size = max;
 
@@ -351,7 +371,7 @@ int Serial::setPacketInput(int size, uns
        attr->c_cc[VTIME] = btimer;
        attr->c_lflag &= ~ICANON;
        tcsetattr(dev, TCSANOW, attr);
-       bufsize = size;
+       getsize = size;
        return size;
 #endif
 }
@@ -362,7 +382,6 @@ int Serial::setLineInput(char newline, c
        //      Still to be done......
        return 0;
 #else
-
        struct termios *attr = (struct termios *)current;
        attr->c_cc[VMIN] = attr->c_cc[VTIME] = 0;
        attr->c_cc[VEOL] = newline;
@@ -370,13 +389,12 @@ int Serial::setLineInput(char newline, c
        attr->c_lflag |= ICANON;
        tcsetattr(dev, TCSANOW, attr);
 #ifdef _PC_MAX_CANON
-       bufsize = fpathconf(dev, _PC_MAX_CANON);
+       getsize = fpathconf(dev, _PC_MAX_CANON);
 #else
-       bufsize = MAX_CANON;
+       getsize = MAX_CANON;
 #endif
-       return bufsize;
+       return getsize;
 #endif
-
 }
 
 void Serial::flushInput(void)
@@ -400,7 +418,7 @@ void Serial::flushOutput(void)
 void Serial::waitOutput(void)
 {
 #ifdef WIN32
-
+       FlushFileBuffers(dev);
 #else
        tcdrain(dev);
 #endif
@@ -410,7 +428,7 @@ Serial &Serial::operator=(const Serial &
 {
        Serial::close();
 
-       if(ser.dev < 0)
+       if(!ser.isOpen())
                return *this;
 
 #ifdef WIN32
@@ -435,12 +453,11 @@ Serial &Serial::operator=(const Serial &
 
 void Serial::open(const char * fname)
 {
-
 #ifndef        WIN32
        int cflags = O_RDWR | O_NDELAY;
        dev = ::open(fname, cflags);
-       if(dev > -1)
-               initConfig();
+       if(dev < 0)
+               dev = INVALID_HANDLE_VALUE;
 #else
     // open COMM device
     dev = CreateFile(fname,
@@ -450,21 +467,20 @@ void Serial::open(const char * fname)
                     OPEN_EXISTING,
                     FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL | 
FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING,
                     NULL);
-       if(dev != INVALID_HANDLE_VALUE)
-               initConfig();
 #endif
+       if(isOpen())
+               initConfig();
 }
 
 #ifdef WIN32
 int Serial::aRead(char * Data, const int Length)
 {
-
        unsigned long   dwLength = 0, dwError, dwReadLength;
        COMSTAT cs;
     OVERLAPPED ol;
     
     // Return zero if handle is invalid
-    if(dev == INVALID_HANDLE_VALUE)
+    if(!isOpen())
         return 0;
 
     // Read max length or only what is available
@@ -552,29 +568,6 @@ void Serial::close()
        dev = INVALID_HANDLE_VALUE;     
 }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 /*
 const int iAsync::getTimeOuts(unsigned long & readTimeout, unsigned long & 
writeTimeout)
 {
@@ -687,14 +680,12 @@ Serial::Error Serial::setSpeed(unsigned 
        }
 
 #ifdef WIN32
-
        DCB             * dcb = (DCB *)current;
     dcb->DCBlength = sizeof(DCB);
     GetCommState(dev, dcb);
 
     dcb->BaudRate = rate;
     SetCommState(dev, dcb) ;
-
 #else
        struct termios *attr = (struct termios *)current;
        cfsetispeed(attr, rate);
@@ -706,14 +697,23 @@ Serial::Error Serial::setSpeed(unsigned 
 
 Serial::Error Serial::setFlowControl(Flow flow)
 {
-#ifdef WIN32
+       switch(flow)
+       {
+       case flowSoft:
+       case flowBoth:
+       case flowHard:
+       case flowNone:
+               break;
+       default:
+               return error(errFlowInvalid);
+       }
 
+#ifdef WIN32
        DCB * attr = (DCB *)current;
     attr->XonChar = ASCII_XON;
     attr->XoffChar = ASCII_XOFF;
     attr->XonLim = 100;
     attr->XoffLim = 100;
-
        switch(flow)
        {
        case flowSoft:
@@ -727,18 +727,12 @@ Serial::Error Serial::setFlowControl(Flo
                break;
        case flowNone:
                break;
-       default:
-               return error(errFlowInvalid);
        }
-
        SetCommState(dev, attr);
 #else
-
        struct termios *attr = (struct termios *)current;
-       
        attr->c_cflag &= ~CRTSCTS;
        attr->c_iflag &= ~(IXON | IXANY | IXOFF);
- 
        switch(flow)
        {
        case flowSoft:
@@ -751,20 +745,24 @@ Serial::Error Serial::setFlowControl(Flo
                break;
        case flowNone:
                break;
-       default:
-               return error(errFlowInvalid);
        }                                                                       
-       
        tcsetattr(dev, TCSANOW, attr);
-
 #endif
        return errSuccess;
 }
 
 Serial::Error Serial::setStopBits(int bits)
 {
-#ifdef WIN32
+       switch(bits)
+       {
+       case 1:
+       case 2:
+               break;
+       default:
+               return error(errStopbitsInvalid);
+       }
 
+#ifdef WIN32
        DCB * attr = (DCB *)current;
        switch(bits)
        {
@@ -774,15 +772,11 @@ Serial::Error Serial::setStopBits(int bi
        case 2:
                attr->StopBits = TWOSTOPBITS;
                break;
-       default:
-               return error(errStopbitsInvalid);
        }
-
        SetCommState(dev, attr);
 #else
        struct termios *attr = (struct termios *)current;
        attr->c_cflag &= ~CSTOPB;
-
        switch(bits)
        {
        case 1:
@@ -790,8 +784,6 @@ Serial::Error Serial::setStopBits(int bi
        case 2:
                attr->c_cflag |= CSTOPB;
                break;
-       default:
-               return error(errStopbitsInvalid);
        }
        tcsetattr(dev, TCSANOW, attr);
 #endif
@@ -800,25 +792,24 @@ Serial::Error Serial::setStopBits(int bi
 
 Serial::Error Serial::setCharBits(int bits)
 {
-#ifdef WIN32
-
-       DCB * attr = (DCB *)current;
        switch(bits)
        {
        case 5:
        case 6:
        case 7:
        case 8:
-               attr->ByteSize = bits;
                break;
        default:
                return error(errCharsizeInvalid);
        }
+
+#ifdef WIN32
+       DCB * attr = (DCB *)current;
+       attr->ByteSize = bits;
        SetCommState(dev, attr);
 #else
        struct termios *attr = (struct termios *)current;
        attr->c_cflag &= ~CSIZE;
-
        switch(bits)
        {
        case 5:
@@ -833,8 +824,6 @@ Serial::Error Serial::setCharBits(int bi
        case 8:
                attr->c_cflag |= CS8;
                break;
-       default:
-               return error(errCharsizeInvalid);
        }
        tcsetattr(dev, TCSANOW, attr);
 #endif
@@ -843,8 +832,17 @@ Serial::Error Serial::setCharBits(int bi
 
 Serial::Error Serial::setParity(Parity parity)
 {
-#ifdef WIN32
+       switch(parity)
+       {
+       case parityEven:
+       case parityOdd:
+       case parityNone:
+               break;
+       default:
+               return error(errParityInvalid);
+       }
 
+#ifdef WIN32
        DCB * attr = (DCB *)current;
        switch(parity)
        {
@@ -857,14 +855,11 @@ Serial::Error Serial::setParity(Parity p
        case parityNone:
                attr->Parity = NOPARITY;
                break;
-       default:
-               return error(errParityInvalid);
        }
        SetCommState(dev, attr);
 #else
        struct termios *attr = (struct termios *)current;
        attr->c_cflag &= ~(PARENB | PARODD);
-
        switch(parity)
        {
        case parityEven:
@@ -875,8 +870,6 @@ Serial::Error Serial::setParity(Parity p
                break;
        case parityNone:
                break;
-       default:
-               return error(errParityInvalid);
        }
        tcsetattr(dev, TCSANOW, attr);
 #endif
@@ -920,6 +913,20 @@ void Serial::toggleDTR(timeout_t millise
 #endif
 }
 
+size_t Serial::getBufferSize(void)
+{
+       size_t maxsize;
+#ifdef _PC_MAX_INPUT
+       if(isOpen())
+               maxsize = fpathconf(dev, _PC_MAX_INPUT);
+       else
+               maxsize = pathconf("/dev/tty", _PC_MAX_INPUT);
+#else
+       maxsize = MAX_INPUT;
+#endif
+       return maxsize;
+}
+
 bool Serial::isPending(Pending pending, timeout_t timeout)
 {
 #ifdef WIN32
@@ -992,7 +999,7 @@ bool Serial::isPending(Pending pending, 
        switch(pending)
        {
        case pendingInput:
-               pfd.events = POLLIN;
+               pfd.events = POLLIN | POLLPRI;
                break;
        case pendingOutput:
                pfd.events = POLLOUT;
@@ -1020,7 +1027,6 @@ bool Serial::isPending(Pending pending, 
 
        if(pfd.revents & pfd.events)
                return true;
-
 #else
        struct timeval tv;
        fd_set grp;
@@ -1080,7 +1086,7 @@ TTYStream::TTYStream(const char *filenam
        gbuf = pbuf = NULL;
        timeout = to;
 
-       if(INVALID_HANDLE_VALUE != dev)
+       if(isOpen())
                allocate();
 }
 
@@ -1111,6 +1117,9 @@ void TTYStream::endStream(void)
        if(bufsize)
                sync();
 
+       setg(NULL, NULL, NULL);
+       setp(NULL, NULL);
+
        if(gbuf)
        {
                delete[] gbuf;
@@ -1127,14 +1136,12 @@ void TTYStream::endStream(void)
 
 void TTYStream::allocate(void)
 {
-       if(INVALID_HANDLE_VALUE == dev)
+       if(!isOpen())
                return;
 
-#ifdef _PC_MAX_INPUT
-       bufsize = fpathconf(dev, _PC_MAX_INPUT);
-#else
-       bufsize = MAX_INPUT;
-#endif
+       bufsize = getBufferSize();
+       if(!getsize)
+               getsize = bufsize;
 
        gbuf = new char[bufsize];
        pbuf = new char[bufsize];
@@ -1155,119 +1162,110 @@ void TTYStream::allocate(void)
        setp(pbuf, pbuf + bufsize);
 }
 
-int TTYStream::doallocate()
+void TTYStream::flushInput(void)
 {
-       if(bufsize)
-               return 0;
-       
-       allocate();
-       return 1;
+       if(gbuf)
+               setg(gbuf, gbuf + bufsize, gbuf + bufsize);
+
+       Serial::flushInput();
 }
 
-void TTYStream::interactive(bool iflag)
+void TTYStream::flushOutput(void)
 {
-#ifdef WIN32
-       if(dev == INVALID_HANDLE_VALUE)
-#else
-       if(dev < 0)
-#endif
-               return;
+       if(pbuf)
+               setp(pbuf, pbuf + bufsize);
 
-       if(bufsize >= 1)
-               endStream();
+       Serial::flushOutput();
+}
 
-       if(iflag)
-       {
-               // setting to unbuffered mode
+void TTYStream::waitOutput(void)
+{
+//     while(overflow(EOF) == EOF);
+       overflow(EOF);
 
-               bufsize = 1;
-               gbuf = new char[bufsize];
+       Serial::waitOutput();
+}
 
-#if !(defined(STLPORT) || defined(__KCC))
-#if defined(__GNUC__) && (__GNUC__ < 3)
-               setb(0,0);
-#endif 
-#endif
-               setg(gbuf, gbuf+bufsize, gbuf+bufsize);
-               setp(pbuf, pbuf);
+void TTYStream::interactive(bool iflag)
+{
+       if(!isOpen())
                return;
-       }
 
-       if(bufsize < 2)
-               allocate();
+       // interactive is 1 else standard size
+       getsize = iflag ? 1 : getBufferSize();
 }
 
 int TTYStream::uflow(void)
 {
-       int rlen;
-       unsigned char ch;
+       int ch = underflow();
+
+       if(ch != EOF && gptr())
+               gbump(1);
+
+       return (unsigned char)ch;
+}
 
-       if(bufsize < 2)
+int TTYStream::underflow(void)
+{
+       ssize_t rlen;
+
+       if(!gptr())
        {
-               if(timeout)
+               if(timeout && !Serial::isPending(pendingInput, timeout))
                {
-                       if(Serial::isPending(pendingInput, timeout))
-                               rlen = aRead((char *)&ch, 1);
-                       else
-                               rlen = -1;
+                       setstate(failbit);
+                       error(errTimeout);
+                       return EOF;
                }
-               else
-                       rlen = aRead((char *)&ch, 1);
+
+               unsigned char ch;
+
+               rlen = aRead((char *)&ch, 1);
                if(rlen < 1)
                {
                        if(rlen < 0)
-                               clear(ios::failbit | rdstate());
+                       {
+                               setstate(failbit);
+                               error(errInput);
+                       }
                        return EOF;
                }
                return ch;
        }
-       else
-       {
-               ch = underflow();
-               gbump(1);
-               return ch;
-       }
-}
-
-int TTYStream::underflow(void)
-{
-       ssize_t rlen = 1;
-
-       if(!gptr())
-               return EOF;
 
        if(gptr() < egptr())
                return (unsigned char)*gptr();
 
-       rlen = (ssize_t)((gbuf + bufsize) - eback());
        if(timeout && !Serial::isPending(pendingInput, timeout))
-               rlen = -1;
-       else
-               rlen = aRead((char *)eback(), rlen);
+       {
+               setstate(failbit);
+               error(errTimeout);
+               return EOF;
+       }
 
+       if(getsize < 1)
+               return EOF;
+
+       rlen = aRead(gbuf, getsize);
        if(rlen < 1)
        {
                if(rlen < 0)
                {
-                       clear(ios::failbit | rdstate());
+                       setstate(failbit);
                        error(errInput);
                }
                return EOF;
        }
 
-       setg(eback(), eback(), eback() + rlen);
+       setg(gbuf, gbuf, gbuf + rlen);
        return (unsigned char) *gptr();
 }
 
 int TTYStream::sync(void)
 {
-       if(bufsize > 1 && pbase() && ((pptr() - pbase()) > 0))
-       {
-               overflow(0);
-               waitOutput();
-               setp(pbuf, pbuf + bufsize);
-       }
-       setg(gbuf, gbuf + bufsize, gbuf + bufsize);
+       waitOutput();
+       flushOutput();
+       flushInput();
        return 0;
 }
 
@@ -1276,7 +1274,7 @@ int TTYStream::overflow(int c)
        unsigned char ch;
        ssize_t rlen, req;
 
-       if(bufsize < 2)
+       if(!pbase())
        {
                if(c == EOF)
                        return 0;
@@ -1286,15 +1284,15 @@ int TTYStream::overflow(int c)
                if(rlen < 1)
                {
                        if(rlen < 0)
-                               clear(ios::failbit | rdstate());
+                       {
+                               setstate(failbit);
+                               error(errOutput);
+                       }
                        return EOF;
                }
-               else
-                       return c;
-       }
 
-       if(!pbase())
-               return EOF;
+               return c;
+       }
 
        req = (ssize_t)(pptr() - pbase());
        if(req)
@@ -1303,31 +1301,41 @@ int TTYStream::overflow(int c)
                if(rlen < 1)
                {
                        if(rlen < 0)
-                               clear(ios::failbit | rdstate());
+                       {
+                               setstate(failbit);
+                               error(errOutput);
+                       }
                        return EOF;
                }
                req -= rlen;
        }
-       
+
        if(req)
 //             memmove(pptr(), pptr() + rlen, req);
                memmove(pbuf, pbuf + rlen, req);
        setp(pbuf + req, pbuf + bufsize);
 
-       if(c != EOF)
-       {
-               *pptr() = (unsigned char)c;
-               pbump(1);
-       }
+       if(c == EOF)
+               return 0;
+
+       *pptr() = (unsigned char)c;
+       pbump(1);
+
        return c;
 }
 
 bool TTYStream::isPending(Pending pending, timeout_t timer)
 {
-//     if(pending == pendingInput && in_avail())
-//             return true;
-//     else if(pending == pendingOutput)
-//             flush();
+       switch ( pending )
+       {
+       case pendingInput:
+               if(in_avail())
+                       return true;
+               break;
+       case pendingOutput:
+               flush();
+               break;
+       }
 
        return Serial::isPending(pending, timer);
 }
@@ -1352,11 +1360,7 @@ TTYStream()
 
 void ttystream::close(void)
 {
-#ifdef WIN32
-       if (INVALID_HANDLE_VALUE == dev)
-#else
-       if(dev < 0)
-#endif
+       if (!isOpen())
                return;
 
        endStream();
@@ -1372,7 +1376,7 @@ void ttystream::open(const char *name)
        size_t namelen;
        long opt;
 
-       if (INVALID_HANDLE_VALUE != dev)
+       if (isOpen())
        {
                restore();
                close();
@@ -1408,7 +1412,7 @@ void ttystream::open(const char *name)
        
        Serial::open(pathname);
 
-       if(INVALID_HANDLE_VALUE == dev)
+       if(!isOpen())
        {
                error(errOpenFailed);
                return;
@@ -1492,6 +1496,7 @@ Thread(pri, stack), TTYStream(filename)
 TTYSession::~TTYSession()
 {
        terminate();
+       endStream();
        endSerial();
 }
 
@@ -1508,11 +1513,7 @@ detect_disconnect(true)
        next = prev = NULL;
        service = NULL;
 
-#ifdef WIN32
-       if(INVALID_HANDLE_VALUE != dev)
-#else
-       if(dev > -1)
-#endif
+       if(isOpen())
        {
                setError(false);
                service = svc;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]