You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
319 lines
11 KiB
319 lines
11 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkByteSwap.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkByteSwap.h"
|
|
#include <memory.h>
|
|
#include "vtkObjectFactory.h"
|
|
|
|
vtkCxxRevisionMacro(vtkByteSwap, "$Revision: 1.50 $");
|
|
vtkStandardNewMacro(vtkByteSwap);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkByteSwap::vtkByteSwap()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkByteSwap::~vtkByteSwap()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Define swap functions for each type size.
|
|
template <size_t s> struct vtkByteSwapper;
|
|
VTK_TEMPLATE_SPECIALIZE struct vtkByteSwapper<1>
|
|
{
|
|
static inline void Swap(void*) {}
|
|
};
|
|
VTK_TEMPLATE_SPECIALIZE struct vtkByteSwapper<2>
|
|
{
|
|
static inline void Swap(void* p)
|
|
{
|
|
char one_byte;
|
|
char* data = static_cast<char*>(p);
|
|
one_byte = data[0]; data[0] = data[1]; data[1] = one_byte;
|
|
}
|
|
};
|
|
VTK_TEMPLATE_SPECIALIZE struct vtkByteSwapper<4>
|
|
{
|
|
static inline void Swap(void* p)
|
|
{
|
|
char one_byte;
|
|
char* data = static_cast<char*>(p);
|
|
one_byte = data[0]; data[0] = data[3]; data[3] = one_byte;
|
|
one_byte = data[1]; data[1] = data[2]; data[2] = one_byte;
|
|
}
|
|
};
|
|
VTK_TEMPLATE_SPECIALIZE struct vtkByteSwapper<8>
|
|
{
|
|
static inline void Swap(void* p)
|
|
{
|
|
char one_byte;
|
|
char* data = static_cast<char*>(p);
|
|
one_byte = data[0]; data[0] = data[7]; data[7] = one_byte;
|
|
one_byte = data[1]; data[1] = data[6]; data[6] = one_byte;
|
|
one_byte = data[2]; data[2] = data[5]; data[5] = one_byte;
|
|
one_byte = data[3]; data[3] = data[4]; data[4] = one_byte;
|
|
}
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Define range swap functions.
|
|
template <class T> inline void vtkByteSwapRange(T* first, vtkIdType num)
|
|
{
|
|
// Swap one value at a time.
|
|
T* last = first + num;
|
|
for(T* p=first; p != last; ++p)
|
|
{
|
|
vtkByteSwapper<sizeof(T)>::Swap(p);
|
|
}
|
|
}
|
|
inline void vtkByteSwapRangeWrite(const char* first, vtkIdType num,
|
|
FILE* f, int)
|
|
{
|
|
// No need to swap segments of 1 byte.
|
|
fwrite(first, sizeof(char), num, f);
|
|
}
|
|
inline void vtkByteSwapRangeWrite(const signed char* first, vtkIdType num,
|
|
FILE* f, int)
|
|
{
|
|
// No need to swap segments of 1 byte.
|
|
fwrite(first, sizeof(signed char), num, f);
|
|
}
|
|
inline void vtkByteSwapRangeWrite(const unsigned char* first, vtkIdType num,
|
|
FILE* f, int)
|
|
{
|
|
// No need to swap segments of 1 byte.
|
|
fwrite(first, sizeof(unsigned char), num, f);
|
|
}
|
|
template <class T>
|
|
inline void vtkByteSwapRangeWrite(const T* first, vtkIdType num, FILE* f, long)
|
|
{
|
|
// Swap and write one value at a time. We do not need to do this in
|
|
// blocks because the file stream is already buffered.
|
|
const T* last = first + num;
|
|
for(const T* p=first; p != last; ++p)
|
|
{
|
|
T temp = *p;
|
|
vtkByteSwapper<sizeof(T)>::Swap(&temp);
|
|
fwrite(&temp, sizeof(temp), 1, f);
|
|
}
|
|
}
|
|
inline void vtkByteSwapRangeWrite(const char* first, vtkIdType num,
|
|
ostream* os, int)
|
|
{
|
|
// No need to swap segments of 1 byte.
|
|
os->write((char*)first, num*sizeof(char));
|
|
}
|
|
inline void vtkByteSwapRangeWrite(const signed char* first, vtkIdType num,
|
|
ostream* os, int)
|
|
{
|
|
// No need to swap segments of 1 byte.
|
|
os->write((char*)first, num*sizeof(signed char));
|
|
}
|
|
inline void vtkByteSwapRangeWrite(const unsigned char* first, vtkIdType num,
|
|
ostream* os, int)
|
|
{
|
|
// No need to swap segments of 1 byte.
|
|
os->write((char*)first, num*sizeof(unsigned char));
|
|
}
|
|
template <class T>
|
|
inline void vtkByteSwapRangeWrite(const T* first, vtkIdType num,
|
|
ostream* os, long)
|
|
{
|
|
// Swap and write one value at a time. We do not need to do this in
|
|
// blocks because the file stream is already buffered.
|
|
const T* last = first + num;
|
|
for(const T* p=first; p != last; ++p)
|
|
{
|
|
T temp = *p;
|
|
vtkByteSwapper<sizeof(T)>::Swap(&temp);
|
|
os->write((char*)&temp, sizeof(temp));
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Define swap functions for each endian-ness.
|
|
#if defined(VTK_WORDS_BIGENDIAN)
|
|
template <class T> inline void vtkByteSwapBE(T*) {}
|
|
template <class T> inline void vtkByteSwapBERange(T*, vtkIdType) {}
|
|
template <class T>
|
|
inline void vtkByteSwapBERangeWrite(const T* p, vtkIdType num, FILE* f)
|
|
{
|
|
fwrite(p, sizeof(T), num, f);
|
|
}
|
|
template <class T>
|
|
inline void vtkByteSwapBERangeWrite(const T* p, vtkIdType num, ostream* os)
|
|
{
|
|
os->write((char*)p, sizeof(T)*num);
|
|
}
|
|
template <class T> inline void vtkByteSwapLE(T* p)
|
|
{
|
|
vtkByteSwapper<sizeof(T)>::Swap(p);
|
|
}
|
|
template <class T> inline void vtkByteSwapLERange(T* p, vtkIdType num)
|
|
{
|
|
vtkByteSwapRange(p, num);
|
|
}
|
|
template <class T>
|
|
inline void vtkByteSwapLERangeWrite(const T* p, vtkIdType num, FILE* f)
|
|
{
|
|
vtkByteSwapRangeWrite(p, num, f, 1);
|
|
}
|
|
template <class T>
|
|
inline void vtkByteSwapLERangeWrite(const T* p, vtkIdType num, ostream* os)
|
|
{
|
|
vtkByteSwapRangeWrite(p, num, os, 1);
|
|
}
|
|
#else
|
|
template <class T> inline void vtkByteSwapBE(T* p)
|
|
{
|
|
vtkByteSwapper<sizeof(T)>::Swap(p);
|
|
}
|
|
template <class T> inline void vtkByteSwapBERange(T* p, vtkIdType num)
|
|
{
|
|
vtkByteSwapRange(p, num);
|
|
}
|
|
template <class T>
|
|
inline void vtkByteSwapBERangeWrite(const T* p, vtkIdType num, FILE* f)
|
|
{
|
|
vtkByteSwapRangeWrite(p, num, f, 1);
|
|
}
|
|
template <class T>
|
|
inline void vtkByteSwapBERangeWrite(const T* p, vtkIdType num, ostream* os)
|
|
{
|
|
vtkByteSwapRangeWrite(p, num, os, 1);
|
|
}
|
|
template <class T> inline void vtkByteSwapLE(T*) {}
|
|
template <class T> inline void vtkByteSwapLERange(T*, vtkIdType) {}
|
|
template <class T>
|
|
inline void vtkByteSwapLERangeWrite(const T* p, vtkIdType num, FILE* f)
|
|
{
|
|
fwrite(p, sizeof(T), num, f);
|
|
}
|
|
template <class T>
|
|
inline void vtkByteSwapLERangeWrite(const T* p, vtkIdType num, ostream* os)
|
|
{
|
|
os->write((char*)p, sizeof(T)*num);
|
|
}
|
|
#endif
|
|
|
|
//----------------------------------------------------------------------------
|
|
#define VTK_BYTE_SWAP_IMPL(T) \
|
|
void vtkByteSwap::SwapLE(T* p) { vtkByteSwapLE(p); } \
|
|
void vtkByteSwap::SwapBE(T* p) { vtkByteSwapBE(p); } \
|
|
void vtkByteSwap::SwapLERange(T* p, vtkIdType num) \
|
|
{ vtkByteSwapLERange(p, num); } \
|
|
void vtkByteSwap::SwapBERange(T* p, vtkIdType num) \
|
|
{ vtkByteSwapBERange(p, num); } \
|
|
void vtkByteSwap::SwapLERangeWrite(const T* p, vtkIdType num, FILE* file) \
|
|
{ vtkByteSwapLERangeWrite(p, num, file); } \
|
|
void vtkByteSwap::SwapBERangeWrite(const T* p, vtkIdType num, FILE* file) \
|
|
{ vtkByteSwapBERangeWrite(p, num, file); } \
|
|
void vtkByteSwap::SwapLERangeWrite(const T* p, vtkIdType num, ostream* os) \
|
|
{ vtkByteSwapLERangeWrite(p, num, os); } \
|
|
void vtkByteSwap::SwapBERangeWrite(const T* p, vtkIdType num, ostream* os) \
|
|
{ vtkByteSwapBERangeWrite(p, num, os); }
|
|
VTK_BYTE_SWAP_IMPL(float)
|
|
VTK_BYTE_SWAP_IMPL(double)
|
|
VTK_BYTE_SWAP_IMPL(char)
|
|
VTK_BYTE_SWAP_IMPL(short)
|
|
VTK_BYTE_SWAP_IMPL(int)
|
|
VTK_BYTE_SWAP_IMPL(long)
|
|
VTK_BYTE_SWAP_IMPL(signed char)
|
|
VTK_BYTE_SWAP_IMPL(unsigned char)
|
|
VTK_BYTE_SWAP_IMPL(unsigned short)
|
|
VTK_BYTE_SWAP_IMPL(unsigned int)
|
|
VTK_BYTE_SWAP_IMPL(unsigned long)
|
|
#if defined(VTK_IMPL_USE_LONG_LONG)
|
|
VTK_BYTE_SWAP_IMPL(long long)
|
|
VTK_BYTE_SWAP_IMPL(unsigned long long)
|
|
#endif
|
|
#if defined(VTK_IMPL_USE___INT64)
|
|
VTK_BYTE_SWAP_IMPL(__int64)
|
|
VTK_BYTE_SWAP_IMPL(unsigned __int64)
|
|
#endif
|
|
#undef VTK_BYTE_SWAP_IMPL
|
|
|
|
#if VTK_SIZEOF_SHORT == 2
|
|
typedef short vtkByteSwapType2;
|
|
#else
|
|
# error "..."
|
|
#endif
|
|
|
|
#if VTK_SIZEOF_INT == 4
|
|
typedef int vtkByteSwapType4;
|
|
#else
|
|
# error "..."
|
|
#endif
|
|
|
|
#if VTK_SIZEOF_DOUBLE == 8
|
|
typedef double vtkByteSwapType8;
|
|
#else
|
|
# error "..."
|
|
#endif
|
|
|
|
//----------------------------------------------------------------------------
|
|
#define VTK_BYTE_SWAP_SIZE(S) \
|
|
void vtkByteSwap::Swap##S##LE(void* p) \
|
|
{ vtkByteSwap::SwapLE(static_cast<vtkByteSwapType##S*>(p)); } \
|
|
void vtkByteSwap::Swap##S##BE(void* p) \
|
|
{ vtkByteSwap::SwapBE(static_cast<vtkByteSwapType##S*>(p)); } \
|
|
void vtkByteSwap::Swap##S##LERange(void* p, int n) \
|
|
{ vtkByteSwap::SwapLERange(static_cast<vtkByteSwapType##S*>(p), n); } \
|
|
void vtkByteSwap::Swap##S##BERange(void* p, int n) \
|
|
{ vtkByteSwap::SwapBERange(static_cast<vtkByteSwapType##S*>(p), n); } \
|
|
void vtkByteSwap::SwapWrite##S##LERange(const void* p, int n, FILE* f) \
|
|
{ vtkByteSwap::SwapLERangeWrite(static_cast<const vtkByteSwapType##S*>(p), \
|
|
n, f); } \
|
|
void vtkByteSwap::SwapWrite##S##BERange(const void* p, int n, FILE* f) \
|
|
{ vtkByteSwap::SwapBERangeWrite(static_cast<const vtkByteSwapType##S*>(p), \
|
|
n, f); } \
|
|
void vtkByteSwap::SwapWrite##S##LERange(const void* p, int n, ostream* os) \
|
|
{ vtkByteSwap::SwapLERangeWrite(static_cast<const vtkByteSwapType##S*>(p), \
|
|
n, os); } \
|
|
void vtkByteSwap::SwapWrite##S##BERange(const void* p, int n, ostream* os) \
|
|
{ vtkByteSwap::SwapBERangeWrite(static_cast<const vtkByteSwapType##S*>(p), \
|
|
n, os); }
|
|
VTK_BYTE_SWAP_SIZE(2)
|
|
VTK_BYTE_SWAP_SIZE(4)
|
|
VTK_BYTE_SWAP_SIZE(8)
|
|
#undef VTK_BYTE_SWAP_SIZE
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Swaps the bytes of a buffer. Uses an arbitrary word size, but
|
|
// assumes the word size is divisible by two.
|
|
void vtkByteSwap::SwapVoidRange(void *buffer, int numWords, int wordSize)
|
|
{
|
|
unsigned char temp, *out, *buf;
|
|
int idx1, idx2, inc, half;
|
|
|
|
half = wordSize / 2;
|
|
inc = wordSize - 1;
|
|
buf = (unsigned char *)(buffer);
|
|
|
|
for (idx1 = 0; idx1 < numWords; ++idx1)
|
|
{
|
|
out = buf + inc;
|
|
for (idx2 = 0; idx2 < half; ++idx2)
|
|
{
|
|
temp = *out;
|
|
*out = *buf;
|
|
*buf = temp;
|
|
++buf;
|
|
--out;
|
|
}
|
|
buf += half;
|
|
}
|
|
}
|
|
|