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 #ifndef FLATHEADERS
00032 #include "simple_message/byte_array.h"
00033 #include "simple_message/simple_serialize.h"
00034 #include "simple_message/log_wrapper.h"
00035 #else
00036 #include "byte_array.h"
00037 #include "simple_serialize.h"
00038 #include "log_wrapper.h"
00039 #endif
00040 
00041 #ifdef MOTOPLUS
00042 #include "motoPlus.h"
00043 #endif
00044 
00045 #include "string.h"
00046 
00047 namespace industrial
00048 {
00049 namespace byte_array
00050 {
00051 
00052 using namespace industrial::simple_serialize;
00053 using namespace industrial::shared_types;
00054 using namespace industrial::byte_array;
00055 
00056 ByteArray::ByteArray(void)
00057 {
00058   this->init();
00059 #ifdef BYTE_SWAPPING
00060   LOG_COMM("Byte swapping enabled");
00061 #endif
00062 }
00063 
00064 ByteArray::~ByteArray(void)
00065 {
00066 }
00067 
00068 void ByteArray::init()
00069 {
00070   memset(&(buffer_[0]), 0, this->MAX_SIZE);
00071   this->setBufferSize(0);
00072 }
00073 
00074 bool ByteArray::init(const char* buffer, const shared_int byte_size)
00075 {
00076   bool rtn;
00077 
00078   if (this->MAX_SIZE >= byte_size)
00079   {
00080     LOG_COMM("Initializing buffer to size: %d", byte_size);
00081     this->load((void*)buffer, byte_size);
00082     rtn = true;
00083   }
00084   else
00085   {
00086     LOG_ERROR("Failed to initialize byte array, buffer size: %u greater than max: %u",
00087               byte_size, this->getMaxBufferSize());
00088     rtn = false;
00089   }
00090   return rtn;
00091 }
00092 
00093 void ByteArray::copyFrom(ByteArray & buffer)
00094 {
00095   if (buffer.getBufferSize() != 0)
00096   {
00097     this->setBufferSize(buffer.getBufferSize());
00098     memcpy(this->getRawDataPtr(), buffer.getRawDataPtr(), this->buffer_size_);
00099   }
00100   else
00101   {
00102     LOG_WARN("Byte array copy not performed, buffer to copy is empty");
00103   }
00104 }
00105 
00106 
00107 #ifdef BYTE_SWAPPING
00108 void ByteArray::swap(void *value, shared_int byteSize)
00109 {
00110   LOG_COMM("Executing byte swapping");
00111 
00112   LOG_COMM("Value (swapping-input): %u", (unsigned int)(*(unsigned int*)value));
00113   for (unsigned int i = 0; i < byteSize / 2; i++)
00114   {
00115     unsigned int endIndex = byteSize - i - 1;
00116     char endByte = ((char*)value)[endIndex];
00117     unsigned int endInt = endByte;
00118 
00119     unsigned int beginIndex = i;
00120     char beginByte = ((char*)value)[beginIndex];
00121     unsigned int beginInt = beginByte;
00122 
00123     LOG_COMM("Swap beginIndex i: %u, endIndex: %u, begin[]: %u, end[]: %u",
00124              beginIndex, endIndex, beginInt, endInt);
00125     ((char*)value)[endIndex] = beginByte;
00126     ((char*)value)[beginIndex] = endByte;
00127   }
00128   LOG_COMM("Value (swapping-output): %u", (unsigned int)(*(unsigned int*)value));
00129 
00130 }
00131 #endif
00132 
00133 char* ByteArray::getRawDataPtr()
00134 {
00135   return &this->buffer_[0];
00136 }
00137 
00138 /****************************************************************
00139  // load(*)
00140  //
00141  // Methods for loading various data types.
00142  //
00143  */
00144 bool ByteArray::load(shared_bool value)
00145 {
00146   return this->load(&value, sizeof(shared_bool));
00147 }
00148 
00149 bool ByteArray::load(shared_real value)
00150 {
00151 #ifdef BYTE_SWAPPING
00152   LOG_COMM("Value (loading-input): %f", value);
00153   this->swap(&value, sizeof(shared_real));
00154   LOG_COMM("Value (loading-output): %f", value);
00155 #endif
00156 
00157   return this->load(&value, sizeof(shared_real));
00158 }
00159 
00160 bool ByteArray::load(shared_int value)
00161 {
00162 #ifdef BYTE_SWAPPING
00163   LOG_COMM("Value (loading-input): %d", value);
00164   this->swap(&value, sizeof(shared_int));
00165   LOG_COMM("Value (loading-output): %d", value);
00166 #endif
00167 
00168   return this->load(&value, sizeof(shared_int));
00169 }
00170 
00171 bool ByteArray::load(simple_serialize::SimpleSerialize &value)
00172 {
00173   LOG_COMM("Executing byte array load through simple serialize");
00174   return value.load(this);
00175 }
00176 
00177 bool ByteArray::load(ByteArray &value)
00178 {
00179   LOG_COMM("Executing byte array load through byte array");
00180   return this->load(value.getRawDataPtr(), value.getBufferSize());
00181 }
00182 
00183 bool ByteArray::load(void* value, const shared_int byte_size)
00184 {
00185 
00186   bool rtn;
00187   // Get the load pointer before extending the buffer.
00188   char* loadPtr;
00189 
00190   LOG_COMM("Executing byte array load through void*, size: %d", byte_size);
00191   // Check inputs
00192   if (NULL == value)
00193   {
00194     LOG_ERROR("NULL point passed into load method");
00195     return false;
00196   }
00197 
00198   loadPtr = this->getLoadPtr();
00199 
00200   if (this->extendBufferSize(byte_size))
00201   {
00202     memcpy(loadPtr, value, byte_size);
00203     rtn = true;
00204   }
00205   else
00206   {
00207     LOG_ERROR("Failed to load byte array");
00208     rtn = false;
00209   }
00210 
00211   return rtn;
00212 }
00213 
00214 /****************************************************************
00215  // unload(*)
00216  //
00217  // Methods for unloading various data types.  Unloading data shortens
00218  // the internal buffer.  The resulting memory that holds the data is
00219  // lost.
00220  //
00221  */
00222 bool ByteArray::unload(shared_bool & value)
00223 {
00224   shared_bool rtn = this->unload(&value, sizeof(shared_bool));
00225   return rtn;
00226 
00227 }
00228 
00229 bool ByteArray::unload(shared_real &value)
00230 {
00231   bool rtn = this->unload(&value, sizeof(shared_real));
00232 
00233 #ifdef BYTE_SWAPPING
00234   LOG_COMM("Value (unloading-input): %f", value);
00235   this->swap(&value, sizeof(shared_real));
00236   LOG_COMM("Value (unloading-output): %f", value);
00237 #endif
00238 
00239   return rtn;
00240 }
00241 
00242 bool ByteArray::unload(shared_int &value)
00243 {
00244   bool rtn = this->unload(&value, sizeof(shared_int));
00245 
00246 #ifdef BYTE_SWAPPING
00247   LOG_COMM("Value (unloading-input): %d", value);
00248   this->swap(&value, sizeof(shared_int));
00249   LOG_COMM("Value (unloading-output): %d", value);
00250 #endif
00251   return rtn;
00252 }
00253 
00254 bool ByteArray::unload(simple_serialize::SimpleSerialize &value)
00255 {
00256   LOG_COMM("Executing byte array unload through simple serialize");
00257   return value.unload(this);
00258 }
00259 
00260 bool ByteArray::unload(ByteArray &value, const shared_int byte_size)
00261 {
00262   LOG_COMM("Executing byte array unload through byte array");
00263   char* unloadPtr = this->getUnloadPtr(byte_size);
00264   bool rtn;
00265 
00266   if (NULL != unloadPtr)
00267   {
00268     if (this->shortenBufferSize(byte_size))
00269     {
00270 
00271       rtn = value.load(unloadPtr, byte_size);
00272       rtn = true;
00273     }
00274     else
00275     {
00276       LOG_ERROR("Failed to shorten array");
00277       rtn = false;
00278     }
00279   }
00280   else
00281   {
00282     LOG_ERROR("Unload pointer returned NULL");
00283     rtn = false;
00284   }
00285 
00286   return rtn;
00287 }
00288 
00289 bool ByteArray::unload(void* value, shared_int byteSize)
00290 {
00291   bool rtn;
00292   char* unloadPtr;
00293 
00294   LOG_COMM("Executing byte array unload through void*, size: %d", byteSize);
00295   // Check inputs
00296   if (NULL == value)
00297   {
00298     LOG_ERROR("NULL point passed into unload method");
00299     return false;
00300   }
00301 
00302   unloadPtr = this->getUnloadPtr(byteSize);
00303 
00304   if (NULL != unloadPtr)
00305   {
00306 
00307     if (this->shortenBufferSize(byteSize))
00308     {
00309       memcpy(value, unloadPtr, byteSize);
00310       rtn = true;
00311     }
00312     else
00313     {
00314       LOG_ERROR("Failed to shorten array");
00315       rtn = false;
00316     }
00317   }
00318   else
00319   {
00320     LOG_ERROR("Unload pointer returned NULL");
00321     rtn = false;
00322   }
00323 
00324   return rtn;
00325 }
00326 
00327 
00328 
00329 /****************************************************************
00330  // unloadFront(*)
00331  //
00332  // Methods for unloading various data types.  Unloading data shortens
00333  // the internal buffer and requires a memmove.  These functions should
00334  // be used sparingly, as they are expensive.
00335  //
00336  */
00337 bool ByteArray::unloadFront(industrial::shared_types::shared_real &value)
00338 {
00339   bool rtn = this->unloadFront(&value, sizeof(shared_real));
00340 
00341 #ifdef BYTE_SWAPPING
00342   LOG_COMM("Value (unloading-input): %f", value);
00343   this->swap(&value, sizeof(shared_real));
00344   LOG_COMM("Value (unloading-output): %f", value);
00345 #endif
00346   return rtn;
00347 }
00348 
00349 bool ByteArray::unloadFront(industrial::shared_types::shared_int &value)
00350 {
00351   bool rtn = this->unloadFront(&value, sizeof(shared_int));
00352 
00353 #ifdef BYTE_SWAPPING
00354   LOG_COMM("Value (unloading-input): %d", value);
00355   this->swap(&value, sizeof(shared_int));
00356   LOG_COMM("Value (unloading-output): %d", value);
00357 #endif
00358   return rtn;
00359 }
00360 bool ByteArray::unloadFront(void* value, const industrial::shared_types::shared_int byteSize)
00361 {
00362   bool rtn;
00363   char* unloadPtr = NULL;
00364   char* nextPtr = NULL;
00365   shared_int sizeRemain;
00366 
00367   // Check inputs
00368   if (NULL == value)
00369   {
00370     LOG_ERROR("NULL point passed into unload method");
00371     return false;
00372   }
00373 
00374   unloadPtr = &this->buffer_[0];
00375 
00376   if (NULL != unloadPtr)
00377   {
00378     nextPtr = unloadPtr + byteSize;
00379     sizeRemain = this->getBufferSize() - byteSize;
00380 
00381     LOG_DEBUG("Unloading: %d bytes, %d bytes remain", byteSize, sizeRemain);
00382     if (this->shortenBufferSize(byteSize))
00383     {
00384       LOG_COMM("Preparing to copy value");
00385       memcpy(value, unloadPtr, byteSize);
00386       LOG_COMM("Value is unloaded, performing move");
00387       memmove(unloadPtr, nextPtr, sizeRemain);
00388       LOG_COMM("Move operation completed");
00389       rtn = true;
00390     }
00391     else
00392     {
00393       LOG_ERROR("Failed to shorten array");
00394       rtn = false;
00395     }
00396   }
00397   else
00398   {
00399     LOG_ERROR("Unload pointer returned NULL");
00400     rtn = false;
00401   }
00402 
00403   return rtn;
00404 }
00405 
00406 unsigned int ByteArray::getBufferSize()
00407 {
00408   return this->buffer_size_;
00409 }
00410 
00411 unsigned int ByteArray::getMaxBufferSize()
00412 {
00413   return this->MAX_SIZE;
00414 }
00415 
00416 
00417 bool ByteArray::isByteSwapEnabled()
00418 {
00419 #ifdef BYTE_SWAPPING
00420   return true;
00421 #endif
00422   return false;
00423 }
00424 
00425 bool ByteArray::setBufferSize(shared_int size)
00426 {
00427   bool rtn;
00428 
00429   if (this->MAX_SIZE >= size)
00430   {
00431     this->buffer_size_ = size;
00432     rtn = true;
00433   }
00434   else
00435   {
00436     LOG_ERROR("Set buffer size: %u, larger than MAX:, %u", size, this->MAX_SIZE);
00437     rtn = false;
00438   }
00439 
00440   return rtn;
00441 
00442 }
00443 
00444 bool ByteArray::extendBufferSize(shared_int size)
00445 {
00446   unsigned int newSize;
00447 
00448   newSize = this->getBufferSize() + size;
00449   return this->setBufferSize(newSize);
00450 
00451 }
00452 
00453 bool ByteArray::shortenBufferSize(shared_int size)
00454 {
00455   unsigned int newSize;
00456   bool rtn;
00457 
00458   // If the buffer is not larger than the size it is shortened by
00459   // we fail.  This is checked here (as opposed to setBufferSize)
00460   // because setBufferSize assumes a unsigned argument and therefore
00461   // wouldn't catch a negative size.
00462   if (size <= (shared_int)this->getBufferSize())
00463   {
00464     newSize = this->getBufferSize() - size;
00465     rtn = this->setBufferSize(newSize);
00466   }
00467   else
00468   {
00469     LOG_ERROR("Failed to shorten buffer by %u bytes, buffer too small, %u bytes", size, this->getBufferSize());
00470     rtn = false;
00471   }
00472 
00473   return rtn;
00474 
00475 }
00476 
00477 char* ByteArray::getLoadPtr()
00478 {
00479 
00480   return &this->buffer_[this->buffer_size_];
00481 }
00482 
00483 char* ByteArray::getUnloadPtr(shared_int byteSize)
00484 {
00485   char* rtn;
00486 
00487   if (byteSize <= (shared_int)this->getBufferSize())
00488   {
00489     rtn = this->getLoadPtr() - byteSize;
00490   }
00491   else
00492   {
00493     LOG_ERROR("Get unload pointer failed, buffer size: %d, smaller than byte size: %d",
00494               this->getBufferSize(), byteSize);
00495     rtn = NULL;
00496   }
00497 
00498   return rtn;
00499 }
00500 
00501 } // namespace byte_array
00502 } // namespace industrial


simple_message
Author(s): Shaun Edwards
autogenerated on Fri Aug 28 2015 11:11:56