byte_array.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  * Copyright (c) 2011, Southwest Research Institute
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are met:
00009  *
00010  *       * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *       * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *       * Neither the name of the Southwest Research Institute, nor the names
00016  *       of its contributors may be used to endorse or promote products derived
00017  *       from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00023  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029  * POSSIBILITY OF SUCH DAMAGE.
00030  */
00031 #ifdef ROS
00032 #include "simple_message/byte_array.h"
00033 #include "simple_message/simple_serialize.h"
00034 #include "simple_message/log_wrapper.h"
00035 #endif
00036 
00037 #ifdef MOTOPLUS
00038 #include "motoPlus.h"
00039 #include "byte_array.h"
00040 #include "simple_serialize.h"
00041 #include "log_wrapper.h"
00042 #endif
00043 
00044 #include "string.h"
00045 
00046 namespace industrial
00047 {
00048 namespace byte_array
00049 {
00050 
00051 using namespace industrial::simple_serialize;
00052 using namespace industrial::shared_types;
00053 using namespace industrial::byte_array;
00054 
00055 ByteArray::ByteArray(void)
00056 {
00057   this->init();
00058 #ifdef BYTE_SWAPPING
00059   LOG_COMM("Byte swapping enabled");
00060 #endif
00061 }
00062 
00063 ByteArray::~ByteArray(void)
00064 {
00065 }
00066 
00067 void ByteArray::init()
00068 {
00069   memset(&(buffer_[0]), 0, this->MAX_SIZE);
00070   this->setBufferSize(0);
00071 }
00072 
00073 bool ByteArray::init(const char* buffer, const shared_int byte_size)
00074 {
00075   bool rtn;
00076 
00077   if (this->MAX_SIZE >= byte_size)
00078   {
00079     LOG_COMM("Initializing buffer to size: %d", byte_size);
00080     this->load((void*)buffer, byte_size);
00081     rtn = true;
00082   }
00083   else
00084   {
00085     LOG_ERROR("Failed to initialize byte array, buffer size: %u greater than max: %u",
00086               byte_size, this->getMaxBufferSize());
00087     rtn = false;
00088   }
00089   return rtn;
00090 }
00091 
00092 void ByteArray::copyFrom(ByteArray & buffer)
00093 {
00094   if (buffer.getBufferSize() != 0)
00095   {
00096     this->setBufferSize(buffer.getBufferSize());
00097     memcpy(this->getRawDataPtr(), buffer.getRawDataPtr(), this->buffer_size_);
00098   }
00099   else
00100   {
00101     LOG_WARN("Byte array copy not performed, buffer to copy is empty");
00102   }
00103 }
00104 
00105 
00106 #ifdef BYTE_SWAPPING
00107 void ByteArray::swap(void *value, shared_int byteSize)
00108 {
00109   LOG_COMM("Executing byte swapping");
00110 
00111   LOG_COMM("Value (swapping-input): %u", (unsigned int)(*(unsigned int*)value));
00112   for (unsigned int i = 0; i < byteSize / 2; i++)
00113   {
00114     unsigned int endIndex = byteSize - i - 1;
00115     char endByte = ((char*)value)[endIndex];
00116     unsigned int endInt = endByte;
00117 
00118     unsigned int beginIndex = i;
00119     char beginByte = ((char*)value)[beginIndex];
00120     unsigned int beginInt = beginByte;
00121 
00122     LOG_COMM("Swap beginIndex i: %u, endIndex: %u, begin[]: %u, end[]: %u",
00123              beginIndex, endIndex, beginInt, endInt);
00124     ((char*)value)[endIndex] = beginByte;
00125     ((char*)value)[beginIndex] = endByte;
00126   }
00127   LOG_COMM("Value (swapping-output): %u", (unsigned int)(*(unsigned int*)value));
00128 
00129 }
00130 #endif
00131 
00132 char* ByteArray::getRawDataPtr()
00133 {
00134   return &this->buffer_[0];
00135 }
00136 
00137 /****************************************************************
00138  // load(*)
00139  //
00140  // Methods for loading various data types.
00141  //
00142  */
00143 bool ByteArray::load(shared_bool value)
00144 {
00145   return this->load(&value, sizeof(shared_bool));
00146 }
00147 
00148 bool ByteArray::load(shared_real value)
00149 {
00150 #ifdef BYTE_SWAPPING
00151   LOG_COMM("Value (loading-input): %f", value);
00152   this->swap(&value, sizeof(shared_real));
00153   LOG_COMM("Value (loading-output): %f", value);
00154 #endif
00155 
00156   return this->load(&value, sizeof(shared_real));
00157 }
00158 
00159 bool ByteArray::load(shared_int value)
00160 {
00161 #ifdef BYTE_SWAPPING
00162   LOG_COMM("Value (loading-input): %d", value);
00163   this->swap(&value, sizeof(shared_int));
00164   LOG_COMM("Value (loading-output): %d", value);
00165 #endif
00166 
00167   return this->load(&value, sizeof(shared_int));
00168 }
00169 
00170 bool ByteArray::load(simple_serialize::SimpleSerialize &value)
00171 {
00172   LOG_COMM("Executing byte array load through simple serialize");
00173   return value.load(this);
00174 }
00175 
00176 bool ByteArray::load(ByteArray &value)
00177 {
00178   LOG_COMM("Executing byte array load through byte array");
00179   return this->load(value.getRawDataPtr(), value.getBufferSize());
00180 }
00181 
00182 bool ByteArray::load(void* value, const shared_int byte_size)
00183 {
00184 
00185   bool rtn;
00186   // Get the load pointer before extending the buffer.
00187   char* loadPtr;
00188 
00189   LOG_COMM("Executing byte array load through void*, size: %d", byte_size);
00190   // Check inputs
00191   if (NULL == value)
00192   {
00193     LOG_ERROR("NULL point passed into load method");
00194     return false;
00195   }
00196 
00197   loadPtr = this->getLoadPtr();
00198 
00199   if (this->extendBufferSize(byte_size))
00200   {
00201     memcpy(loadPtr, value, byte_size);
00202     rtn = true;
00203   }
00204   else
00205   {
00206     LOG_ERROR("Failed to load byte array");
00207     rtn = false;
00208   }
00209 
00210   return rtn;
00211 }
00212 
00213 /****************************************************************
00214  // unload(*)
00215  //
00216  // Methods for unloading various data types.  Unloading data shortens
00217  // the internal buffer.  The resulting memory that holds the data is
00218  // lost.
00219  //
00220  */
00221 bool ByteArray::unload(shared_bool & value)
00222 {
00223   shared_bool rtn = this->unload(&value, sizeof(shared_bool));
00224   return rtn;
00225 
00226 }
00227 
00228 bool ByteArray::unload(shared_real &value)
00229 {
00230   bool rtn = this->unload(&value, sizeof(shared_real));
00231 
00232 #ifdef BYTE_SWAPPING
00233   LOG_COMM("Value (unloading-input): %f", value);
00234   this->swap(&value, sizeof(shared_real));
00235   LOG_COMM("Value (unloading-output): %f", value);
00236 #endif
00237 
00238   return rtn;
00239 }
00240 
00241 bool ByteArray::unload(shared_int &value)
00242 {
00243   bool rtn = this->unload(&value, sizeof(shared_int));
00244 
00245 #ifdef BYTE_SWAPPING
00246   LOG_COMM("Value (unloading-input): %d", value);
00247   this->swap(&value, sizeof(shared_int));
00248   LOG_COMM("Value (unloading-output): %d", value);
00249 #endif
00250   return rtn;
00251 }
00252 
00253 bool ByteArray::unload(simple_serialize::SimpleSerialize &value)
00254 {
00255   LOG_COMM("Executing byte array unload through simple serialize");
00256   return value.unload(this);
00257 }
00258 
00259 bool ByteArray::unload(ByteArray &value, const shared_int byte_size)
00260 {
00261   LOG_COMM("Executing byte array unload through byte array");
00262   char* unloadPtr = this->getUnloadPtr(byte_size);
00263   bool rtn;
00264 
00265   if (NULL != unloadPtr)
00266   {
00267     if (this->shortenBufferSize(byte_size))
00268     {
00269 
00270       rtn = value.load(unloadPtr, byte_size);
00271       rtn = true;
00272     }
00273     else
00274     {
00275       LOG_ERROR("Failed to shorten array");
00276       rtn = false;
00277     }
00278   }
00279   else
00280   {
00281     LOG_ERROR("Unload pointer returned NULL");
00282     rtn = false;
00283   }
00284 
00285   return rtn;
00286 }
00287 
00288 bool ByteArray::unload(void* value, shared_int byteSize)
00289 {
00290   bool rtn;
00291   char* unloadPtr;
00292 
00293   LOG_COMM("Executing byte array unload through void*, size: %d", byteSize);
00294   // Check inputs
00295   if (NULL == value)
00296   {
00297     LOG_ERROR("NULL point passed into unload method");
00298     return false;
00299   }
00300 
00301   unloadPtr = this->getUnloadPtr(byteSize);
00302 
00303   if (NULL != unloadPtr)
00304   {
00305 
00306     if (this->shortenBufferSize(byteSize))
00307     {
00308       memcpy(value, unloadPtr, byteSize);
00309       rtn = true;
00310     }
00311     else
00312     {
00313       LOG_ERROR("Failed to shorten array");
00314       rtn = false;
00315     }
00316   }
00317   else
00318   {
00319     LOG_ERROR("Unload pointer returned NULL");
00320     rtn = false;
00321   }
00322 
00323   return rtn;
00324 }
00325 
00326 
00327 
00328 /****************************************************************
00329  // unloadFront(*)
00330  //
00331  // Methods for unloading various data types.  Unloading data shortens
00332  // the internal buffer and requires a memmove.  These functions should
00333  // be used sparingly, as they are expensive.
00334  //
00335  */
00336 bool ByteArray::unloadFront(industrial::shared_types::shared_real &value)
00337 {
00338   bool rtn = this->unloadFront(&value, sizeof(shared_real));
00339 
00340 #ifdef BYTE_SWAPPING
00341   LOG_COMM("Value (unloading-input): %f", value);
00342   this->swap(&value, sizeof(shared_real));
00343   LOG_COMM("Value (unloading-output): %f", value);
00344 #endif
00345   return rtn;
00346 }
00347 
00348 bool ByteArray::unloadFront(industrial::shared_types::shared_int &value)
00349 {
00350   bool rtn = this->unloadFront(&value, sizeof(shared_int));
00351 
00352 #ifdef BYTE_SWAPPING
00353   LOG_COMM("Value (unloading-input): %d", value);
00354   this->swap(&value, sizeof(shared_int));
00355   LOG_COMM("Value (unloading-output): %d", value);
00356 #endif
00357   return rtn;
00358 }
00359 bool ByteArray::unloadFront(void* value, const industrial::shared_types::shared_int byteSize)
00360 {
00361   bool rtn;
00362   char* unloadPtr = NULL;
00363   char* nextPtr = NULL;
00364   shared_int sizeRemain;
00365 
00366   // Check inputs
00367   if (NULL == value)
00368   {
00369     LOG_ERROR("NULL point passed into unload method");
00370     return false;
00371   }
00372 
00373   unloadPtr = &this->buffer_[0];
00374 
00375   if (NULL != unloadPtr)
00376   {
00377     nextPtr = unloadPtr + byteSize;
00378     sizeRemain = this->getBufferSize() - byteSize;
00379 
00380     LOG_DEBUG("Unloading: %d bytes, %d bytes remain", byteSize, sizeRemain);
00381     if (this->shortenBufferSize(byteSize))
00382     {
00383       LOG_COMM("Preparing to copy value");
00384       memcpy(value, unloadPtr, byteSize);
00385       LOG_COMM("Value is unloaded, performing move");
00386       memmove(unloadPtr, nextPtr, sizeRemain);
00387       LOG_COMM("Move operation completed");
00388       rtn = true;
00389     }
00390     else
00391     {
00392       LOG_ERROR("Failed to shorten array");
00393       rtn = false;
00394     }
00395   }
00396   else
00397   {
00398     LOG_ERROR("Unload pointer returned NULL");
00399     rtn = false;
00400   }
00401 
00402   return rtn;
00403 }
00404 
00405 unsigned int ByteArray::getBufferSize()
00406 {
00407   return this->buffer_size_;
00408 }
00409 
00410 unsigned int ByteArray::getMaxBufferSize()
00411 {
00412   return this->MAX_SIZE;
00413 }
00414 
00415 
00416 bool ByteArray::isByteSwapEnabled()
00417 {
00418 #ifdef BYTE_SWAPPING
00419   return true;
00420 #endif
00421   return false;
00422 }
00423 
00424 bool ByteArray::setBufferSize(shared_int size)
00425 {
00426   bool rtn;
00427 
00428   if (this->MAX_SIZE >= size)
00429   {
00430     this->buffer_size_ = size;
00431     rtn = true;
00432   }
00433   else
00434   {
00435     LOG_ERROR("Set buffer size: %u, larger than MAX:, %u", size, this->MAX_SIZE);
00436     rtn = false;
00437   }
00438 
00439   return rtn;
00440 
00441 }
00442 
00443 bool ByteArray::extendBufferSize(shared_int size)
00444 {
00445   unsigned int newSize;
00446 
00447   newSize = this->getBufferSize() + size;
00448   return this->setBufferSize(newSize);
00449 
00450 }
00451 
00452 bool ByteArray::shortenBufferSize(shared_int size)
00453 {
00454   unsigned int newSize;
00455   bool rtn;
00456 
00457   // If the buffer is not larger than the size it is shortened by
00458   // we fail.  This is checked here (as opposed to setBufferSize)
00459   // because setBufferSize assumes a unsigned argument and therefore
00460   // wouldn't catch a negative size.
00461   if (size <= (shared_int)this->getBufferSize())
00462   {
00463     newSize = this->getBufferSize() - size;
00464     rtn = this->setBufferSize(newSize);
00465   }
00466   else
00467   {
00468     LOG_ERROR("Failed to shorten buffer by %u bytes, buffer too small, %u bytes", size, this->getBufferSize());
00469     rtn = false;
00470   }
00471 
00472   return rtn;
00473 
00474 }
00475 
00476 char* ByteArray::getLoadPtr()
00477 {
00478 
00479   return &this->buffer_[this->buffer_size_];
00480 }
00481 
00482 char* ByteArray::getUnloadPtr(shared_int byteSize)
00483 {
00484   char* rtn;
00485 
00486   if (byteSize <= (shared_int)this->getBufferSize())
00487   {
00488     rtn = this->getLoadPtr() - byteSize;
00489   }
00490   else
00491   {
00492     LOG_ERROR("Get unload pointer failed, buffer size: %d, smaller than byte size: %d",
00493               this->getBufferSize(), byteSize);
00494     rtn = NULL;
00495   }
00496 
00497   return rtn;
00498 }
00499 
00500 } // namespace byte_array
00501 } // namespace industrial


simple_message
Author(s): Shaun Edwards
autogenerated on Mon Oct 6 2014 00:54:17