Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

ArSocket.cpp

00001 /*
00002 ActivMedia Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004,2005 ActivMedia Robotics, LLC
00004 
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 ActivMedia Robotics for information about a commercial version of ARIA at 
00022 robots@activmedia.com or 
00023 ActivMedia Robotics, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 
00025 */
00026 
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include "ArSocket.h"
00030 #include "ArLog.h"
00031 
00032 void ArSocket::internalInit(void)
00033 {
00034   myCloseFunctor = NULL;
00035   myStringAutoEcho = true;
00036   myStringEcho = false;
00037   myStringPosLast = 0;
00038   myStringPos = 0;
00039   myStringGotComplete = false;
00040   myStringBufEmpty[0] = '\0';
00041   myStringGotEscapeChars = false;
00042   myStringHaveEchoed = false;
00043   sprintf(myIPString, "none");
00044 }
00045 
00046 int ArSocket::recvFrom(void *msg, int len, sockaddr_in *sin)
00047 {
00048 
00049 #ifdef WIN32
00050   int i=sizeof(sockaddr_in);
00051 #else
00052   socklen_t i=sizeof(sockaddr_in);
00053 #endif
00054   int ret;
00055   ret = ::recvfrom(myFD, (char*)msg, len, 0, (struct sockaddr*)sin, &i);
00056   return ret;
00057 }
00058 
00059 /*
00060    This cannot write more than 512 number of bytes
00061    @param str the string to write to the socket
00062    @return number of bytes written
00063 **/
00064 int ArSocket::writeString(const char *str, ...)
00065 {
00066   char buf[1200];
00067   int len;
00068   va_list ptr;
00069   va_start(ptr, str);
00070   vsnprintf(buf, sizeof(buf), str, ptr);
00071   va_end(ptr);
00072   if (myLogWriteStrings)
00073     ArLog::log(ArLog::Normal, "Sent to %s: %s", getIPString(), buf);
00074   len = strlen(buf);
00075   buf[len] = '\n';
00076   len++;
00077   buf[len] = '\r';
00078   len++;
00079   return write(buf, len);
00080 }
00081 
00082 void ArSocket::setIPString(void)
00083 {
00084   unsigned char *bytes;
00085   bytes = (unsigned char *)inAddr();
00086   if (bytes != NULL)
00087     sprintf(myIPString, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
00088 }
00089 
00090 
00101 char *ArSocket::readString(void)
00102 {
00103   size_t i;
00104   int n;
00105   myStringBufEmpty[0] = '\0';
00106   
00107   // read one byte at a time
00108   for (i = myStringPos; i < sizeof(myStringBuf); i++)
00109   {
00110     
00111     n = read(&myStringBuf[i], 1);
00112     if (n > 0)
00113     {
00114       if (i == 0 && myStringBuf[i] < 0)
00115       {
00116         myStringGotEscapeChars = true;
00117       }
00118       if (myStringBuf[i] == '\n' || myStringBuf[i] == '\r')
00119       {
00120         if (i != 0)
00121           myStringGotComplete = true;
00122         myStringBuf[i] = '\0';
00123         myStringPos = 0;
00124         myStringPosLast = 0;
00125         // if we have leading escape characters get rid of them
00126         if (myStringBuf[0] < 0)
00127         {
00128           int ei;
00129           myStringGotEscapeChars = true;
00130           // increment out the escape chars
00131           for (ei = 0; 
00132                myStringBuf[ei] < 0 || (ei > 0 && myStringBuf[ei - 1] < 0); 
00133                ei++);
00134           // okay now return the good stuff
00135           doStringEcho();
00136           return &myStringBuf[ei];
00137         }
00138         // if we don't return what we got
00139         doStringEcho();
00140         return myStringBuf;
00141       }
00142       // if its not an ending character but was good keep going
00143       else
00144         continue;
00145     }
00146     // failed
00147     else if (n == 0)
00148     {
00149       return NULL;
00150     }
00151     else // which means (n < 0)
00152     {
00153 #ifdef WIN32
00154       if (WSAGetLastError() == WSAEWOULDBLOCK)
00155       {
00156         myStringPos = i;
00157         doStringEcho();
00158         return myStringBufEmpty;
00159       }
00160 #endif
00161 #ifndef WIN32
00162       if (errno == EAGAIN)
00163       {
00164         myStringPos = i;
00165         doStringEcho();
00166         return myStringBufEmpty;
00167       }
00168 #endif
00169       perror("Error in reading from network");
00170       return NULL;
00171     }
00172   }
00173   // if they want a 0 length string
00174   ArLog::log(ArLog::Normal, "Some trouble in ArSocket::readString");
00175   writeString("String too long");
00176   return NULL;
00177 }
00178 
00179 void ArSocket::doStringEcho(void)
00180 {
00181   size_t to;
00182 
00183   if (!myStringAutoEcho && !myStringEcho)
00184     return;
00185 
00186   // if we're echoing complete thel ines
00187   if (myStringHaveEchoed && myStringGotComplete)
00188   {
00189     write("\n\r", 2);
00190     myStringGotComplete = false;
00191   }
00192 
00193   // if there's nothing to send we don't need to send it
00194   if (myStringPosLast == myStringPos)
00195     return;
00196   
00197   // we probably don't need it if its doing escape chars
00198   if (myStringAutoEcho && myStringGotEscapeChars)
00199     return;
00200 
00201   myStringHaveEchoed = true;
00202   to = strchr(myStringBuf, '\0') - myStringBuf;
00203   write(&myStringBuf[myStringPosLast], myStringPos - myStringPosLast);
00204   myStringPosLast = myStringPos;
00205 }

Generated on Wed Oct 19 12:56:37 2005 for Aria by  doxygen 1.4.0