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

ArBasePacket.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
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 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArBasePacket.h"
00029 #include "ArLog.h"
00030 
00031 #include <stdio.h>
00032 
00039 AREXPORT ArBasePacket::ArBasePacket(ArTypes::UByte2 bufferSize, 
00040                                     ArTypes::UByte2 headerLength,
00041                                     char * buf,
00042                                     ArTypes::UByte2 footerLength) 
00043 {
00044   if (buf == NULL && bufferSize > 0) 
00045   {
00046     myOwnMyBuf = true;
00047     myBuf = new char[bufferSize];
00048   } 
00049   else 
00050   {
00051     myOwnMyBuf = false;
00052     myBuf = buf;
00053   }
00054   myHeaderLength = headerLength;
00055   myFooterLength = footerLength;
00056   myReadLength = myHeaderLength;
00057   myMaxLength = bufferSize;
00058   myLength = myHeaderLength;
00059   myIsValid = true;
00060 }
00061 
00062 AREXPORT ArBasePacket::~ArBasePacket()
00063 {
00064   if (myOwnMyBuf && myBuf != NULL)
00065     delete[] myBuf;
00066 }
00067 
00068 
00069 AREXPORT void ArBasePacket::setBuf(char *buf, ArTypes::UByte2 bufferSize)
00070 {
00071   if (myOwnMyBuf) 
00072   {
00073     delete[] myBuf;
00074     myOwnMyBuf = false;
00075   } 
00076   myBuf = buf;
00077   myMaxLength = bufferSize;
00078 }
00079 
00080 AREXPORT void ArBasePacket::setMaxLength(ArTypes::UByte2 bufferSize)
00081 {
00082   if (myMaxLength >= bufferSize)
00083     return;
00084   if (myOwnMyBuf) 
00085   {
00086     delete[] myBuf;
00087     myOwnMyBuf = false;
00088   } 
00089   myBuf = new char[bufferSize];
00090   myMaxLength = bufferSize;
00091   myOwnMyBuf = true;
00092 }
00093 
00094 AREXPORT bool ArBasePacket::setLength(ArTypes::UByte2 length)
00095 {
00096   if (myOwnMyBuf && length > myMaxLength)
00097     return false;
00098 
00099   myLength = length;
00100   return true;
00101 }
00102 
00103 AREXPORT void ArBasePacket::setReadLength(ArTypes::UByte2 readLength)
00104 {
00105   myReadLength = readLength;
00106 }
00107 
00108 AREXPORT bool ArBasePacket::setHeaderLength(ArTypes::UByte2 length)
00109 {
00110   if (myOwnMyBuf && length > myMaxLength)
00111     return false;
00112 
00113   myHeaderLength = length;
00114   return true;
00115 }
00116 
00122 AREXPORT void ArBasePacket::resetRead(void)
00123 {
00124   myReadLength = myHeaderLength;
00125   resetValid();
00126 }
00127 
00132 AREXPORT void ArBasePacket::empty(void)
00133 {
00134   myLength = myHeaderLength;
00135   resetValid();
00136 }
00137 
00138 AREXPORT bool ArBasePacket::isNextGood(int bytes)
00139 {
00140   if (bytes <= 0)
00141     return false;
00142 
00143   // make sure it comes in before the header
00144   if (myReadLength + bytes <= myLength - myFooterLength)
00145     return true;
00146 
00147   myIsValid = false;
00148 
00149   return false;
00150 }
00151 
00152 
00153 AREXPORT bool ArBasePacket::hasWriteCapacity(int bytes)
00154 {
00155   if (bytes < 0) {
00156     ArLog::log(ArLog::Normal, "ArBasePacket::hasWriteCapacity(%d) cannot write negative amount",
00157                bytes);
00158     return false;
00159   }
00160 
00161   // Make sure there's enough room in the packet 
00162   if ((myLength + bytes) <= myMaxLength) {
00163      return true;
00164   }
00165 
00166   myIsValid = false;
00167 
00168   return false;
00169 
00170 } // end method hasWriteCapacity
00171 
00172 
00178 AREXPORT bool ArBasePacket::isValid(void)
00179 {
00180   return myIsValid;
00181 
00182 } // end method isValid
00183 
00191 AREXPORT void ArBasePacket::resetValid()
00192 {
00193   myIsValid = true;
00194 }
00195 
00196 AREXPORT const char *ArBasePacket::getBuf(void)
00197 {
00198   return myBuf;
00199 }
00200 
00201 AREXPORT void ArBasePacket::byteToBuf(ArTypes::Byte val)
00202 {
00203   if (!hasWriteCapacity(1)) {
00204     return;
00205   }
00206 
00207   memcpy(myBuf+myLength, &val, 1);
00208   myLength += 1;
00209 }
00210 
00211 AREXPORT void ArBasePacket::byte2ToBuf(ArTypes::Byte2 val)
00212 {
00213   if (!hasWriteCapacity(2)) {
00214     return;
00215   }
00216 
00217   unsigned char c;
00218   c = (val >> 8) & 0xff;
00219   memcpy(myBuf+myLength+1, &c, 1);
00220   c = val & 0xff;
00221   memcpy(myBuf+myLength, &c, 1);
00222   myLength += 2;
00223 }
00224 
00225 AREXPORT void ArBasePacket::byte4ToBuf(ArTypes::Byte4 val)
00226 {
00227   if (!hasWriteCapacity(4)) {
00228     return;
00229   }
00230 
00231   unsigned char c;
00232   c = (val >> 24) & 0xff;
00233   memcpy(myBuf+myLength+3, &c, 1);
00234   c = (val >> 16) & 0xff;
00235   memcpy(myBuf+myLength+2, &c, 1);
00236   c = (val >> 8) & 0xff;
00237   memcpy(myBuf+myLength+1, &c, 1);
00238   c = val & 0xff;
00239   memcpy(myBuf+myLength, &c, 1);
00240   myLength += 4;
00241 
00242 }
00243 
00244 AREXPORT void ArBasePacket::uByteToBuf(ArTypes::UByte val)
00245 {
00246   if (!hasWriteCapacity(1)) {
00247     return;
00248   }
00249   memcpy(myBuf+myLength, &val, 1);
00250   myLength += 1;
00251 }
00252 
00253 AREXPORT void ArBasePacket::uByte2ToBuf(ArTypes::UByte2 val)
00254 {
00255   if (!hasWriteCapacity(2)) {
00256     return;
00257   }
00258   unsigned char c;
00259   c = (val >> 8) & 0xff;
00260   memcpy(myBuf+myLength+1, &c, 1);
00261   c = val & 0xff;
00262   memcpy(myBuf+myLength, &c, 1);
00263   myLength += 2;
00264 }
00265 
00266 AREXPORT void ArBasePacket::uByte4ToBuf(ArTypes::UByte4 val)
00267 {
00268   if (!hasWriteCapacity(4)) {
00269     return;
00270   }
00271   memcpy(myBuf+myLength, &val, 4);
00272   myLength += 4;
00273 }
00274 
00278 AREXPORT void ArBasePacket::strToBuf(const char *str)
00279 {
00280   if (str == NULL) {
00281     str = "";
00282   }
00283   ArTypes::UByte2 tempLen = strlen(str) + 1;
00284 
00285   if (!hasWriteCapacity(tempLen)) {
00286     return;
00287   }
00288 
00289   memcpy(myBuf+myLength, str, tempLen);
00290   myLength += tempLen;
00291 }
00292 
00300 AREXPORT void ArBasePacket::strNToBuf(const char *str, int length)
00301 {
00302   // Do not perform bounds checking because it breaks existing code.
00303 
00304   //byte4ToBuf(length);
00305   memcpy(myBuf+myLength, str, length);
00306   myLength+=length;
00307 
00308 }
00309 
00310 
00316 AREXPORT void ArBasePacket::strToBufPadded(const char *str, int length)
00317 {
00318   if (str == NULL) {
00319     str = "";
00320   }
00321   ArTypes::UByte2 tempLen = strlen(str);
00322 
00323   if (!hasWriteCapacity(length)) {
00324     return;
00325   }
00326 
00327   if (tempLen >= length) {
00328     memcpy(myBuf + myLength, str, length);
00329     myLength += length;
00330   }
00331   else // string is smaller than given length
00332   {
00333     memcpy(myBuf + myLength, str, tempLen);
00334     myLength += tempLen;
00335     memset(myBuf + myLength, 0, length - tempLen);
00336     myLength += length - tempLen;
00337   }
00338 }
00339 
00340 
00345 AREXPORT void ArBasePacket::dataToBuf(const char *data, int length)
00346 {
00347   if (data == NULL) {
00348     ArLog::log(ArLog::Normal, "ArBasePacket::dataToBuf(NULL, %d) cannot add from null address",
00349                length);
00350     return;
00351   }
00352 
00353   if (!hasWriteCapacity(length)) {
00354     return;
00355   }
00356 
00357   memcpy(myBuf+myLength, data, length);
00358   myLength+=length;
00359 
00360 }
00361 
00367 AREXPORT void ArBasePacket::dataToBuf(const unsigned char *data, int length)
00368 {
00369   if (data == NULL) {
00370     ArLog::log(ArLog::Normal, "ArBasePacket::dataToBuf(NULL, %d) cannot add from null address",
00371                length);
00372     return;
00373   }
00374 
00375   if (!hasWriteCapacity(length)) {
00376     return;
00377   }
00378 
00379   memcpy(myBuf+myLength, data, length);
00380   myLength+=length;
00381 
00382 }
00383 
00384 
00385 AREXPORT ArTypes::Byte ArBasePacket::bufToByte(void)
00386 {
00387   ArTypes::Byte ret=0;
00388 
00389   if (isNextGood(1))
00390   {
00391     memcpy(&ret, myBuf+myReadLength, 1);
00392     myReadLength+=1;
00393   }
00394 
00395   return(ret);
00396 }
00397 
00398 AREXPORT ArTypes::Byte2 ArBasePacket::bufToByte2(void)
00399 {
00400   ArTypes::Byte2 ret=0;
00401   unsigned char c1, c2;
00402 
00403   if (isNextGood(2))
00404   {
00405     memcpy(&c1, myBuf+myReadLength, 1);
00406     memcpy(&c2, myBuf+myReadLength+1, 1);
00407     ret = (c1 & 0xff) | (c2 << 8);
00408     myReadLength+=2;
00409   }
00410 
00411   return ret;
00412 }
00413 
00414 AREXPORT ArTypes::Byte4 ArBasePacket::bufToByte4(void)
00415 {
00416   ArTypes::Byte4 ret=0;
00417   unsigned char c1, c2, c3, c4;
00418 
00419   if (isNextGood(4))
00420   {
00421     memcpy(&c1, myBuf+myReadLength, 1);
00422     memcpy(&c2, myBuf+myReadLength+1, 1);
00423     memcpy(&c3, myBuf+myReadLength+2, 1);
00424     memcpy(&c4, myBuf+myReadLength+3, 1);
00425     ret = (c1 & 0xff) | (c2 << 8) | (c3 << 16) | (c4 << 24);
00426     myReadLength+=4;
00427   }
00428 
00429   return ret;
00430 }
00431 
00432 AREXPORT ArTypes::UByte ArBasePacket::bufToUByte(void)
00433 {
00434   ArTypes::UByte ret=0;
00435 
00436   if (isNextGood(1))
00437   {
00438     memcpy(&ret, myBuf+myReadLength, 1);
00439     myReadLength+=1;
00440   }
00441 
00442   return(ret);
00443 }
00444 
00445 AREXPORT ArTypes::UByte2 ArBasePacket::bufToUByte2(void)
00446 {
00447   ArTypes::UByte2 ret=0;
00448   unsigned char c1, c2;
00449 
00450   if (isNextGood(2))
00451   {
00452     memcpy(&c1, myBuf+myReadLength, 1);
00453     memcpy(&c2, myBuf+myReadLength+1, 1);
00454     ret = (c1 & 0xff) | (c2 << 8);
00455     myReadLength+=2;
00456   }
00457 
00458   return ret;
00459 }
00460 
00461 AREXPORT ArTypes::UByte4 ArBasePacket::bufToUByte4(void)
00462 {
00463   ArTypes::Byte4 ret=0;
00464   unsigned char c1, c2, c3, c4;
00465 
00466   if (isNextGood(4))
00467   {
00468     memcpy(&c1, myBuf+myReadLength, 1);
00469     memcpy(&c2, myBuf+myReadLength+1, 1);
00470     memcpy(&c3, myBuf+myReadLength+2, 1);
00471     memcpy(&c4, myBuf+myReadLength+3, 1);
00472     ret = (c1 & 0xff) | (c2 << 8) | (c3 << 16) | (c4 << 24);
00473     myReadLength+=4;
00474   }
00475 
00476   return ret;
00477 }
00478 
00487 AREXPORT void ArBasePacket::bufToStr(char *buf, int len)
00488 {
00489    if (buf == NULL) {
00490     ArLog::log(ArLog::Normal, "ArBasePacket::bufToStr(NULL, %d) cannot write to null address",
00491                len);
00492     return;
00493   }
00494 
00495   int i;
00496 
00497   buf[0] = '\0';
00498   // see if we can read
00499   if (isNextGood(1))
00500   {
00501     // while we can read copy over those bytes
00502     for (i = 0; 
00503          isNextGood(1) && i < (len - 1) && myBuf[myReadLength] != '\0';
00504          ++myReadLength, ++i) {
00505       buf[i] = myBuf[myReadLength];
00506     }
00507     // if we stopped because of a null then copy that one too
00508     if (myBuf[myReadLength] == '\0')
00509     {
00510       buf[i] = myBuf[myReadLength];
00511       myReadLength++;
00512     }
00513     else if (i >= (len - 1)) { 
00514 
00515       // Otherwise, if we stopped reading because the output buffer was full,
00516       // then attempt to flush the rest of the string from the packet
00517 
00518       // This is a bit redundant with the code below, but wanted to log the  
00519       // string for debugging
00520       myBuf[len - 1] = '\0';
00521 
00522       ArLog::log(ArLog::Normal, "ArBasePacket::bufToStr(buf, %d) output buf is not large enough for packet string %s",
00523                  len, myBuf);
00524 
00525       while (isNextGood(1) && (myBuf[myReadLength] != '\0')) {
00526         myReadLength++;
00527       }
00528       if (myBuf[myReadLength] == '\0') {
00529         myReadLength++;
00530       }
00531     } // end else if output buffer filled before null-terminator
00532   } // end if something to read
00533 
00534   // Make absolutely sure that the string is null-terminated...
00535   buf[len - 1] = '\0';
00536 
00537 }
00538 
00545 AREXPORT void ArBasePacket::bufToData(char *data, int length)
00546 {
00547   if (data == NULL) {
00548     ArLog::log(ArLog::Normal, "ArBasePacket::bufToData(NULL, %d) cannot write to null address",
00549                length);
00550     return;
00551   }
00552   if (isNextGood(length))
00553   {
00554     memcpy(data, myBuf+myReadLength, length);
00555     myReadLength += length;
00556   }
00557 }
00558 
00559 
00568 AREXPORT void ArBasePacket::bufToData(unsigned char *data, int length)
00569 {
00570   if (data == NULL) {
00571     ArLog::log(ArLog::Normal, "ArBasePacket::bufToData(NULL, %d) cannot write to null address",
00572                length);
00573     return;
00574   }
00575   if (isNextGood(length))
00576   {
00577     memcpy(data, myBuf+myReadLength, length);
00578     myReadLength += length;
00579   }
00580 }
00581 
00582 
00588 AREXPORT void ArBasePacket::duplicatePacket(ArBasePacket *packet)
00589 {
00590   myLength = packet->getLength();
00591   myReadLength = packet->getReadLength();
00592   memcpy(myBuf, packet->getBuf(), myLength);
00593 }
00594 
00595 AREXPORT void ArBasePacket::log(void)
00596 {
00597   int i;
00598   ArLog::log(ArLog::Terse, "Packet: (length = %i)", myLength);
00599   for (i = 0; i < myLength; i++)
00600     ArLog::log(ArLog::Terse, "  [%03i] % 5d\t0x%x\t%s", i,(unsigned char) myBuf[i],
00601         (unsigned char) myBuf[i], 
00602         i == 0 ? "[header0]" :
00603           i == 1 ? "[header1]" :
00604             i == 2 ? "[packet data length]" :
00605               i == 3 ? "[packet id]" :
00606                 i == (myLength - 2) ? "[first checksum byte]" :
00607                   i == (myLength - 1) ? "[second checksum byte]" :
00608                     ""
00609     );
00610   ArLog::log(ArLog::Terse, "\n");
00611 }
00612 
00613 AREXPORT void ArBasePacket::printHex(void)
00614 {
00615   int i;
00616   ArLog::log(ArLog::Terse, "Packet: (length = %i)", myLength);
00617   for (i = 0; i < myLength; i++)
00618     ArLog::log(ArLog::Terse, "  [%i] 0x%x ", i,(unsigned char) myBuf[i]);
00619   ArLog::log(ArLog::Terse, "\n");
00620 }
00621 

Generated on Tue Feb 20 10:51:39 2007 for Aria by  doxygen 1.4.0