1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 /*=========================================================================
19  *
20  *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21  *
22  *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23  *
24  *  For complete copyright, license and disclaimer of warranty information
25  *  please refer to the NOTICE file at the top of the ITK source tree.
26  *
27  *=========================================================================*/
28 #ifndef itkByteSwapper_h
29 #define itkByteSwapper_h
30 
31 #include "itkObject.h"
32 #include "itkObjectFactory.h"
33 #include "itkIntTypes.h"
34 
35 namespace itk
36 {
37 /** \class ByteSwapper
38  * \brief Perform machine dependent byte swapping.
39  *
40  * ByteSwapper is used by I/O classes to perform machine dependent byte
41  * swapping. Byte swapping is often used when reading or writing binary
42  * files. Files can either be Big Endian (BE) or Little Endian (LE).
43  *
44  * \ingroup IOFilters
45  * \ingroup OSSystemObjects
46  * \ingroup ITKCommon
47  */
48 
49 template< typename T >
50 class ITK_TEMPLATE_EXPORT ByteSwapper:public Object
51 {
52 public:
53   ITK_DISALLOW_COPY_AND_ASSIGN(ByteSwapper);
54 
55   /** Standard class type aliases. */
56   using Self = ByteSwapper;
57   using Superclass = Object;
58   using Pointer = SmartPointer< Self >;
59   using ConstPointer = SmartPointer< const Self >;
60 
61   /** Work around MSVC bug (including ByteSwapper.h in a templated class). */
62   using OStreamType = std::ostream;
63 
64   /** Run-time type information (and related methods). */
65   itkTypeMacro(ByteSwapper, Object);
66 
67   /** Query the machine Endian-ness. */
68   static bool SystemIsBigEndian();
69 
SystemIsBE()70   static bool SystemIsBE() { return SystemIsBigEndian(); }
71   static bool SystemIsLittleEndian();
72 
SystemIsLE()73   static bool SystemIsLE() { return SystemIsLittleEndian(); }
74 
75   /** Generic swap method handles type T. The swapping is
76    * done in-place. 2, 4 and 8 byte swapping
77    * can be handled. Single byte types are not swapped;
78    * others raise an exception. The method is used to
79    * swap to and from Big Endian. */
80   static void SwapFromSystemToBigEndian(T *p);
81 
82   /** Type for representing large buffers, including those in 64bits
83    * architectures */
84   using BufferSizeType = SizeValueType;
85 
86   /** Generic swap method handles type T. The swapping is
87    * done in-place. 2, 4 and 8 byte swapping
88    * can be handled. Single byte types are not swapped;
89    * others raise an exception. The method is used to
90    * swap to and from Big Endian. */
91   static void SwapRangeFromSystemToBigEndian(T *p, BufferSizeType num);
92 
93   /** Generic swap method handles type T. The data is
94    * swapped and written (in binary) to the ostream
95    * given. A total of num values of type T are written
96    * and swapped. 2, 4 and 8 byte swapping
97    * can be handled. Single byte types are not swapped;
98    * others raise an exception. The method is used to
99    * swap to and from Big Endian. */
100   static void SwapWriteRangeFromSystemToBigEndian(T *p, int num,
101                                                   OStreamType *fp);
102 
103   /** Generic swap method handles type T. The swapping is
104    * done in-place. 2, 4 and 8 byte swapping
105    * can be handled. Single byte types are not swapped;
106    * others raise an exception. The method is used to
107    * swap to and from Little Endian. */
108   static void SwapFromSystemToLittleEndian(T *p);
109 
110   /** Generic swap method handles type T. The swapping is
111    * done in-place. 2, 4 and 8 byte swapping
112    * can be handled. Single byte types are not swapped;
113    * others raise an exception. The method is used to
114    * swap to and from Little Endian. */
115   static void SwapRangeFromSystemToLittleEndian(T *p, BufferSizeType num);
116 
117   /** Generic swap method handles type T. The data is
118    * swapped and written (in binary) to the ostream
119    * given. A total of num values of type T are written
120    * and swapped. 2, 4 and 8 byte swapping
121    * can be handled. Single byte types are not swapped;
122    * others raise an exception. The method is used to
123    * swap to and from Little Endian. */
124   static void SwapWriteRangeFromSystemToLittleEndian(T *p, int num,
125                                                      OStreamType *fp);
126 
127 protected:
128   ByteSwapper() = default;
129   ~ByteSwapper() override = default;
130 
131   /** Swap 2 bytes. */
132   static void Swap2(void *p);
133 
134   /** Swap a range of two-byte words. Num is the number of two-byte
135    * words to swap. */
136   static void Swap2Range(void *p, BufferSizeType num);
137 
138   /** Swap and write a range of two-byte words. Num is the number of two-byte
139    * words to swap and write. */
140   static void SwapWrite2Range(void *p, BufferSizeType num, OStreamType *fp);
141 
142   /** Swap four bytes. */
143   static void Swap4(void *p);
144 
145   /** Swap a range of four-byte words. Num is the number of four-byte words
146    * to swap. */
147   static void Swap4Range(void *p, BufferSizeType num);
148 
149   /** Swap and write a range of four-byte words. Num is the number of four-byte
150    * words to swap and write. */
151   static void SwapWrite4Range(void *p, BufferSizeType num, OStreamType *fp);
152 
153   /** Swap 8 bytes. */
154   static void Swap8(void *p);
155 
156   /** Swap a range of 8-byte words. Num is the number of four-byte words
157    * to swap. */
158   static void Swap8Range(void *p, BufferSizeType num);
159 
160   /** Swap and write a range of 8-byte words. Num is the number of four-byte
161    * words to swap and write. */
162   static void SwapWrite8Range(void *p, BufferSizeType num, OStreamType *fp);
163 };
164 } // end namespace itk
165 
166 #ifndef ITK_MANUAL_INSTANTIATION
167 #include "itkByteSwapper.hxx"
168 #endif
169 
170 #endif
171