Endian.h

Go to the documentation of this file.
00001 /*
00002  * The information in this file is
00003  * Copyright(c) 2007 Ball Aerospace & Technologies Corporation
00004  * and is subject to the terms and conditions of the
00005  * GNU Lesser General Public License Version 2.1
00006  * The license text is available from   
00007  * http://www.gnu.org/licenses/lgpl.html
00008  */
00009 
00010 #ifndef ENDIAN_H
00011 #define ENDIAN_H
00012 
00013 #include "ComplexData.h"
00014 #include "TypesFile.h"
00015 
00016 /**
00017  *  A class to perform byte-swapping operations.
00018  *
00019  *  The Endian class provides a capability to perform byte-swapping of data
00020  *  values based on the endian type of the system.  An Endian object should be
00021  *  created with the target endian type.  The swapping methods can then be
00022  *  called to swap data values to the target type.  If the target type is the
00023  *  same as the system, no swapping is performed.
00024  *
00025  *  @see        EndianType
00026  */
00027 class Endian
00028 {
00029 public:
00030    /**
00031     *  Creates an Endian object of a given endian type.
00032     *
00033     *  @param   endian
00034     *           The endian type for the object.  This type is used as the
00035     *           target endian type for the byte-swapping methods.  If the given
00036     *           type is the same as the system type the byte-swapping methods
00037     *           can still be called, but no swapping is performed.
00038     *
00039     *  @see     EndianType
00040     */
00041    Endian(EndianType endian);
00042 
00043    /**
00044     *  Creates an Endian object which will always swap.
00045     *
00046     *  @see     EndianType
00047     */
00048    Endian();
00049 
00050    /**
00051     *  Destroys the Endian object.
00052     */
00053    ~Endian();
00054 
00055    /**
00056     *  Returns the endian type of <em>this</em>.
00057     *
00058     *  @return  The endian type.
00059     *
00060     *  @see     getSystemEndian()
00061     */
00062    EndianType getEndian() const;
00063 
00064    /**
00065     *  Queries the endian type of <em>this</em> for EndianType::BIG_ENDIAN_ORDER.
00066     *
00067     *  @return  Returns true if the endian type is EndianType::BIG_ENDIAN_ORDER,
00068     *           otherwise returns false.
00069     */
00070    bool isBigEndian() const;
00071 
00072    /**
00073     *  Queries the endian type of <em>this</em> for EndianType::LITTLE_ENDIAN_ORDER.
00074     *
00075     *  @return  Returns true if the endian type is EndianType::LITTLE_ENDIAN_ORDER,
00076     *           otherwise returns false.
00077     */
00078    bool isLittleEndian() const;
00079 
00080    /**
00081     *  Swaps the bytes of a single data value.
00082     *
00083     *  This method performs in-place byte swapping of a single data value
00084     *  by modifying the given element.  If the original value should not be
00085     *  overwritten, use the swapValue() method instead.
00086     *
00087     *  @param   value
00088     *           A reference to the data value to swap.
00089     *
00090     *  @return  Returns true if byte swapping was actually performed.  Returns
00091     *           false if no byte swapping is necessary because the endian type
00092     *           is already the same as the system.
00093     *
00094     *  @see     swapValue(const T &amp;), swapBuffer(T *,size_t)
00095     */
00096    template <class T>
00097    bool swapValue(T& value) const
00098    {
00099       return swapBuffer(&value, 1);
00100    }
00101 
00102    /**
00103     *  Swaps the bytes of a single data value.
00104     *
00105     *  This method performs byte swapping of a single data value and returns
00106     *  the swapped value.  The original data element is not modified. For
00107     *  performance reasons, if the original data element can be overwritten,
00108     *  use the swapValue() method instead.
00109     *
00110     *  @param   value
00111     *           A data value to swap.  The value is not modified.
00112     *
00113     *  @return  Returns the swapped data value.  If no swapping is necessary, a
00114     *           copy of the original data value is returned.
00115     *
00116     *  @see     swapValue(T &amp;)
00117     */
00118    template <class T>
00119    T swapValue(const T& value) const
00120    {
00121       T newValue = value;
00122       swapValue(newValue);
00123 
00124       return newValue;
00125    }
00126 
00127    /**
00128     *  Swaps the bytes of data elements in an array.
00129     *
00130     *  This method swaps the bytes of data elements in an array if the endian
00131     *  type of the system is different than the endian type of <em>this</em>.
00132     *
00133     *  This method is provided as a convenience if the data type is known.
00134     *
00135     *  @param   pBuffer
00136     *           A pointer to the data to be byte swapped.
00137     *  @param   count
00138     *           The number of items in the array to byte swap.
00139     *
00140     *  @return  Returns true if byte swapping was actually performed.  Returns
00141     *           false if no byte swapping is necessary because the endian type
00142     *           is already the same as the system.
00143     *
00144     *  @see     swapBuffer(void *,size_t,size_t), swapValue(T &amp;)
00145     */
00146    template <class T>
00147    bool swapBuffer(T* pBuffer, size_t count) const
00148    {
00149       return swapBuffer(pBuffer, sizeof(T), count);
00150    }
00151 
00152    /**
00153     * This override has the same behavior as the templated
00154     * function of the same name.
00155     *
00156     * It is needed because the template definition is incorrect
00157     * for complex data.
00158     *
00159     * @param pBuffer
00160     *        The FloatComplex buffer to swap
00161     * @param count
00162     *        The number of elements in pBuffer to swap
00163     *
00164     *  @return  Returns true if byte swapping was actually performed.  Returns
00165     *           false if no byte swapping is necessary because the endian type
00166     *           is already the same as the system.
00167     */
00168    bool swapBuffer(FloatComplex* pBuffer, size_t count) const
00169    {
00170       return swapBuffer(pBuffer, sizeof(float), 2*count);
00171    }
00172 
00173    /**
00174     * This override has the same behavior as the templated
00175     * function of the same name.
00176     *
00177     * It is needed because the template definition is incorrect
00178     * for complex data.
00179     *
00180     * @param pBuffer
00181     *        The IntegerComplex buffer to swap
00182     * @param count
00183     *        The number of elements in pBuffer to swap
00184     *
00185     *  @return  Returns true if byte swapping was actually performed.  Returns
00186     *           false if no byte swapping is necessary because the endian type
00187     *           is already the same as the system.
00188     */
00189    bool swapBuffer(IntegerComplex* pBuffer, size_t count) const
00190    {
00191       return swapBuffer(pBuffer, sizeof(short), 2*count);
00192    }
00193 
00194    /**
00195     *  Swaps the bytes of data elements in an array.
00196     *
00197     *  This method swaps the bytes of data elements in an array if the endian
00198     *  type of the system is different than endian type of <em>this</em>.
00199     *
00200     *  @param   pBuffer
00201     *           A pointer to the data to be byte swapped.
00202     *  @param   dataSize
00203     *           The size of each element in the array.
00204     *  @param   count
00205     *           The number of items in the array to byte swap.
00206     *
00207     *  @return  Returns true if byte swapping was actually performed.  Returns
00208     *           false if no byte swapping is necessary because the endian type
00209     *           is already the same as the system.
00210     *
00211     *  @see     swapBuffer(T *,size_t), swapValue(T &amp;)
00212     */
00213    bool swapBuffer(void* pBuffer, size_t dataSize, size_t count) const
00214    {
00215       if ((pBuffer == NULL) || (mSystemType == mType))
00216       {
00217          return false;
00218       }
00219 
00220       for (size_t i = 0; i < count; ++i)
00221       {
00222          unsigned char* pData = reinterpret_cast<unsigned char*>(pBuffer) + (i * dataSize);
00223          for (size_t j = 0; j < dataSize / 2; ++j)
00224          {
00225             size_t index = dataSize - j - 1;
00226 
00227             unsigned char byteData = pData[j];
00228             pData[j] = pData[index];
00229             pData[index] = byteData;
00230          }
00231       }
00232 
00233       return true;
00234    }
00235 
00236    /**
00237     *  Returns the endian type of the system.
00238     *
00239     *  This value is used in the byte-swapping methods to determine whether
00240     *  the data values should be swapped or not.
00241     *
00242     *  @return  The system endian type.
00243     *
00244     *  @see     getEndian()
00245     */
00246    static EndianType getSystemEndian();
00247 
00248 private:
00249    EndianType mType;
00250    EndianType mSystemType;
00251 };
00252 
00253 #endif

Software Development Kit - Opticks 4.9.0 Build 16218