NCBI C++ ToolKit
ncbi_bswap.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CORELIB___NCBI_BSWAP__HPP
2 #define CORELIB___NCBI_BSWAP__HPP
3 /* $Id: ncbi_bswap.hpp 70460 2015-12-29 13:56:26Z ivanov $
4  * ===========================================================================
5  *
6  * PUBLIC DOMAIN NOTICE
7  * National Center for Biotechnology Information
8  *
9  * This software/database is a "United States Government Work" under the
10  * terms of the United States Copyright Act. It was written as part of
11  * the author's official duties as a United States Government employee and
12  * thus cannot be copyrighted. This software/database is freely available
13  * to the public for use. The National Library of Medicine and the U.S.
14  * Government have not placed any restriction on its use or reproduction.
15  *
16  * Although all reasonable efforts have been taken to ensure the accuracy
17  * and reliability of the software and data, the NLM and the U.S.
18  * Government do not and cannot warrant the performance or results that
19  * may be obtained by using this software or data. The NLM and the U.S.
20  * Government disclaim all warranties, express or implied, including
21  * warranties of performance, merchantability or fitness for any particular
22  * purpose.
23  *
24  * Please cite the author in any work or product based on this material.
25  *
26  * ===========================================================================
27  *
28  * Author: Anatoliy Kuznetsov, Kyrill Rotmistrovsky
29  *
30  * File Description: Byte swapping functions.
31  *
32  */
33 
34 #include <corelib/ncbistl.hpp>
35 #include <corelib/ncbitype.h>
36 
38 
39 /////////////////////////////////////////////////////////////////////////////
40 ///
41 /// CByteSwap --
42 ///
43 /// Class encapsulates byte swapping functions to convert between
44 /// big endian - little endian architectures
45 ///
46 /// Get and Put functions always do the byte swapping
47 /// (change the byte order). If the input is BIG ENDIAN it is
48 /// converted to LITTLE ENDIAN and vice versa.
49 /// This group of functions is used when we know upfront that the
50 /// incoming data were created on architecture with a different byte order
51 /// and byte swapping is necessary.
52 ///
53 ///
54 /// Use case:
55 ///
56 /// Usually it means sender writes all the data without conversion to network
57 /// byte order, instead adds a small characteristic word describing the
58 /// original byte order. Reader checks the byte order first and if it is
59 /// the same just interprets the data in the regular manner without any
60 /// conversion.
61 /// In most cases when the data does not cross the border we have no
62 /// performance impact (do not call CByteSwap::Get & Put methods).
63 /// Such "on demand" conversion scheme has potential performance advantage
64 /// over the unconditional conversion to network byte order.
65 ///
66 
67 class CByteSwap
68 {
69 public:
70  static Int2 GetInt2(const unsigned char* ptr);
71  static void PutInt2(unsigned char* ptr, Int2 value);
72  static Int4 GetInt4(const unsigned char* ptr);
73  static void PutInt4(unsigned char* ptr, Int4 value);
74  static Int8 GetInt8(const unsigned char* ptr);
75  static void PutInt8(unsigned char* ptr, Int8 value);
76  static float GetFloat(const unsigned char* ptr);
77  static void PutFloat(unsigned char* ptr, float value);
78  static double GetDouble(const unsigned char* ptr);
79  static void PutDouble(unsigned char* ptr, double value);
80 
81 private:
82  union UFloatInt4 {
83  float f;
85  };
86 
87  union UDoubleInt8 {
88  double d;
90  };
91 };
92 
93 
94 
95 inline
96 Int2 CByteSwap::GetInt2(const unsigned char* ptr)
97 {
98 #ifdef WORDS_BIGENDIAN
99  Int2 ret = (Int2)( (Int2(ptr[1]) << 8) | (Int2(ptr[0])) );
100 #else
101  Int2 ret = (Int2)( (Int2(ptr[0]) << 8) | (Int2(ptr[1])) );
102 #endif
103 
104  return ret;
105 }
106 
107 inline
108 void CByteSwap::PutInt2(unsigned char* ptr, Int2 value)
109 {
110 #ifdef WORDS_BIGENDIAN
111  ptr[1] = (unsigned char)(value >> 8);
112  ptr[0] = (unsigned char)(value);
113 #else
114  ptr[0] = (unsigned char)(value >> 8);
115  ptr[1] = (unsigned char)(value);
116 #endif
117 }
118 
119 
120 inline
121 Int4 CByteSwap::GetInt4(const unsigned char* ptr)
122 {
123 #ifdef WORDS_BIGENDIAN
124  Int4 ret = (Int4(ptr[3]) << 24) |
125  (Int4(ptr[2]) << 16) |
126  (Int4(ptr[1]) << 8) |
127  (Int4(ptr[0]));
128 #else
129  Int4 ret = (Int4(ptr[0]) << 24) |
130  (Int4(ptr[1]) << 16) |
131  (Int4(ptr[2]) << 8) |
132  (Int4(ptr[3]));
133 #endif
134  return ret;
135 }
136 
137 inline
138 void CByteSwap::PutInt4(unsigned char* ptr, Int4 value)
139 {
140 #ifdef WORDS_BIGENDIAN
141  ptr[3] = (unsigned char)(value >> 24);
142  ptr[2] = (unsigned char)(value >> 16);
143  ptr[1] = (unsigned char)(value >> 8);
144  ptr[0] = (unsigned char)(value);
145 #else
146  ptr[0] = (unsigned char)(value >> 24);
147  ptr[1] = (unsigned char)(value >> 16);
148  ptr[2] = (unsigned char)(value >> 8);
149  ptr[3] = (unsigned char)(value);
150 #endif
151 }
152 
153 inline
154 Int8 CByteSwap::GetInt8(const unsigned char* ptr)
155 {
156 #ifdef WORDS_BIGENDIAN
157  Int8 ret = (Int8(ptr[7]) << 56) |
158  (Int8(ptr[6]) << 48) |
159  (Int8(ptr[5]) << 40) |
160  (Int8(ptr[4]) << 32) |
161  (Int8(ptr[3]) << 24) |
162  (Int8(ptr[2]) << 16) |
163  (Int8(ptr[1]) << 8) |
164  (Int8(ptr[0]));
165 #else
166  Int8 ret = (Int8(ptr[0]) << 56) |
167  (Int8(ptr[1]) << 48) |
168  (Int8(ptr[2]) << 40) |
169  (Int8(ptr[3]) << 32) |
170  (Int8(ptr[4]) << 24) |
171  (Int8(ptr[5]) << 16) |
172  (Int8(ptr[6]) << 8) |
173  (Int8(ptr[7]));
174 #endif
175 
176  return ret;
177 }
178 
179 inline
180 void CByteSwap::PutInt8(unsigned char* ptr, Int8 value)
181 {
182 #ifdef WORDS_BIGENDIAN
183  ptr[7] = (unsigned char)(value >> 56);
184  ptr[6] = (unsigned char)(value >> 48);
185  ptr[5] = (unsigned char)(value >> 40);
186  ptr[4] = (unsigned char)(value >> 32);
187  ptr[3] = (unsigned char)(value >> 24);
188  ptr[2] = (unsigned char)(value >> 16);
189  ptr[1] = (unsigned char)(value >> 8);
190  ptr[0] = (unsigned char)(value);
191 #else
192  ptr[0] = (unsigned char)(value >> 56);
193  ptr[1] = (unsigned char)(value >> 48);
194  ptr[2] = (unsigned char)(value >> 40);
195  ptr[3] = (unsigned char)(value >> 32);
196  ptr[4] = (unsigned char)(value >> 24);
197  ptr[5] = (unsigned char)(value >> 16);
198  ptr[6] = (unsigned char)(value >> 8);
199  ptr[7] = (unsigned char)(value);
200 #endif
201 }
202 
203 
204 inline
205 float CByteSwap::GetFloat(const unsigned char* ptr)
206 {
207  UFloatInt4 u;
208  u.i = CByteSwap::GetInt4(ptr);
209  return u.f;
210 }
211 
212 inline
213 void CByteSwap::PutFloat(unsigned char* ptr, float value)
214 {
215  UFloatInt4 u;
216  u.f = value;
217  CByteSwap::PutInt4(ptr, u.i);
218 }
219 
220 
221 inline
222 double CByteSwap::GetDouble(const unsigned char* ptr)
223 {
224  UDoubleInt8 u;
225  u.i = CByteSwap::GetInt8(ptr);
226  return u.d;
227 }
228 
229 inline
230 void CByteSwap::PutDouble(unsigned char* ptr, double value)
231 {
232  UDoubleInt8 u;
233  u.d = value;
234  CByteSwap::PutInt8(ptr, u.i);
235 }
236 
237 
238 
240 
241 #endif /* NCBI_BSWAP__HPP */
CByteSwap –.
Definition: ncbi_bswap.hpp:68
static Int8 GetInt8(const unsigned char *ptr)
Definition: ncbi_bswap.hpp:154
static void PutFloat(unsigned char *ptr, float value)
Definition: ncbi_bswap.hpp:213
static void PutInt2(unsigned char *ptr, Int2 value)
Definition: ncbi_bswap.hpp:108
static double GetDouble(const unsigned char *ptr)
Definition: ncbi_bswap.hpp:222
static Int2 GetInt2(const unsigned char *ptr)
Definition: ncbi_bswap.hpp:96
static void PutDouble(unsigned char *ptr, double value)
Definition: ncbi_bswap.hpp:230
static void PutInt8(unsigned char *ptr, Int8 value)
Definition: ncbi_bswap.hpp:180
static Int4 GetInt4(const unsigned char *ptr)
Definition: ncbi_bswap.hpp:121
static float GetFloat(const unsigned char *ptr)
Definition: ncbi_bswap.hpp:205
static void PutInt4(unsigned char *ptr, Int4 value)
Definition: ncbi_bswap.hpp:138
char value[7]
Definition: config.c:431
int16_t Int2
2-byte (16-bit) signed integer
Definition: ncbitype.h:100
int32_t Int4
4-byte (32-bit) signed integer
Definition: ncbitype.h:102
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
The NCBI C++/STL use hints.
Defines Limits for the types used in NCBI C/C++ toolkit.
Modified on Thu Feb 29 12:23:54 2024 by modify_doxy.py rev. 669887