TsByteSwapUtils.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 // Unit-Test TerraLib
21 #include "TsByteSwapUtils.h"
22 
23 #include <terralib/common.h>
25 
26 // STL
27 #include <cstdlib>
28 #include <string>
29 #include <vector>
30 
31 // Boost
32 #include <boost/lexical_cast.hpp>
33 #include <boost/property_tree/json_parser.hpp>
34 #include <boost/foreach.hpp>
35 
36 // http://www.boost.org/doc/libs/1_43_0/libs/integer/test/cstdint_test.cpp
37 
38 /*
39 Int16: 2 bytes
40 Int32 and int: 4 bytes
41 Int64 : 8 bytes
42 
43 Type Capacity
44 Min/Max Value
45 Int 16 -32,768 / 32,767
46 Int 32 -2,147,483,648 / 2,147,483,647
47 Int 64 -9,223,372,036,854,775,808 / 9,223,372,036,854,775,807
48 
49 */
50 
52 
54 {
55 }
56 
58 {
59 }
60 
62 {
63  char input_letter[] = "AB";
64  te::common::Swap2Bytes(input_letter);
65  std::cout << "Input AB " << input_letter << std::endl;
66  CPPUNIT_ASSERT(strncmp(input_letter, "BA", 2 ) == 0);
67 
68  char input_num[] = "12";
69  te::common::Swap2Bytes(input_num);
70  std::cout << "Input 12" << input_num << std::endl;
71  CPPUNIT_ASSERT(strncmp(input_num, "21", 2 ) == 0);
72 
73  char input_symb[] = "!@";
74  te::common::Swap2Bytes(input_symb);
75  std::cout << "Input !@ " << input_symb << std::endl;
76  CPPUNIT_ASSERT(strncmp(input_symb, "@!", 2 ) == 0);
77 
78 }
79 
81 {
82  char input_letter[] = "ABCD";
83  te::common::Swap4Bytes(input_letter);
84  std::cout << "Input ABCD=" << input_letter << std::endl;
85  CPPUNIT_ASSERT(strncmp(input_letter, "DCBA", 4 ) == 0);
86 
87  char input_num[] = "1234";
88  te::common::Swap4Bytes(input_num);
89  std::cout << "Input 1234=" << input_num << std::endl;
90  CPPUNIT_ASSERT(strncmp(input_num, "4321", 4 ) == 0);
91 
92  char input_symb[] = "!@#$";
93  te::common::Swap4Bytes(input_symb);
94  std::cout << "Input !@#$= " << input_symb << std::endl;
95  CPPUNIT_ASSERT(strncmp(input_symb, "$#@!", 4 ) == 0);
96 }
97 
99 {
100  char input_letter[] = "ABCDabcdefghij";
101  int len = strlen(input_letter);
102  te::common::SwapBytes(input_letter);
103  std::cout << " Input ABCDabcdefghij " << input_letter << std::endl;
104  CPPUNIT_ASSERT_MESSAGE("SwapBytes of n bytes (ABCDabcdefghij) is not working!", strncmp(input_letter, "jihgfedcbaDCBA", len ) == 0);
105 
106  char input_num[] = "12345678";
107  te::common::SwapBytes(input_num);
108  std::cout << " Input 12345678 " << input_num << std::endl;
109  CPPUNIT_ASSERT(strncmp(input_num, "87654321", 8 ) == 0);
110 
111  char input_symb[] = "!@#$%&*(";
112  te::common::SwapBytes(input_symb);
113  std::cout << " Input !@#$%&*( " << input_symb << std::endl;
114  CPPUNIT_ASSERT(strncmp(input_symb, "(*&%$#@!", 8 ) == 0);
115 }
116 
118 {
119  char input_letter[] = "ABCDabcd";
120  te::common::Swap8Bytes(input_letter);
121  std::cout << " Input ABCDabcd " << input_letter << std::endl;
122  CPPUNIT_ASSERT(strncmp(input_letter, "dcbaDCBA", 8 ) == 0);
123 
124  char input_num[] = "12345678";
125  te::common::Swap8Bytes(input_num);
126  std::cout << " Input 12345678 " << input_num << std::endl;
127  CPPUNIT_ASSERT(strncmp(input_num, "87654321", 8 ) == 0);
128 
129  char input_symb[] = "!@#$%&*(";
130  te::common::Swap8Bytes(input_symb);
131  std::cout << " Input !@#$%&*( " << input_symb << std::endl;
132  CPPUNIT_ASSERT(strncmp(input_symb, "(*&%$#@!", 8 ) == 0);
133 }
134 
136 {
137  //boost::int16_t int16 = INT16_C(-32767);
138  //Int 16 -32768 to 32767
139  boost::int16_t i16min = -32768;
140  boost::int16_t i16min_swap2 = -32768;
141  boost::int16_t i16max = 32767;
142  boost::int16_t i16max_swap2 = 32767;
143  boost::int16_t i16med = 32767/2;
144  boost::int16_t i16med_swap2 = 32767/2;
145  int ss;
146 
147  //Swap bytes 2x and the result must be equal the input.
148  std::cout << " Input min " << i16min << std::endl;
149  ss = sizeof(i16min);
150  te::common::SwapBytes(i16min);
151  std::cout << " Input swap " << i16min << std::endl;
152  te::common::SwapBytes(i16min);
153  std::cout << " Swap again " << i16min << std::endl;
154 
155  CPPUNIT_ASSERT(i16min == i16min_swap2);
156 
157  std::cout << " Input max " << i16max << std::endl;
158  ss = sizeof(i16max);
159  te::common::SwapBytes(i16max);
160  std::cout << " Input swap " << i16max << std::endl;
161  te::common::SwapBytes(i16max);
162  std::cout << " Swap again " << i16max << std::endl;
163  CPPUNIT_ASSERT(i16max == i16max_swap2);
164 
165  std::cout << " Input med " << i16med << std::endl;
166  ss = sizeof(i16med);
167  te::common::SwapBytes(i16med);
168  std::cout << " Input swap " << i16med << std::endl;
169  te::common::SwapBytes(i16med);
170  std::cout << "Swap again " << i16med << std::endl;
171  CPPUNIT_ASSERT(i16med == i16med_swap2);
172 }
173 
175 {
176  //boost::int32_t int32 = INT32_C(-2147483647);
177  //Int 32 -2,147,483,648 to 2,147,483,647
178  boost::int32_t i32min = -2147483647; //-2147483648;
179  //if -2147483648 is used ...warning C4146: unary minus operator applied to unsigned type, result still unsigned
180  boost::int32_t i32min_swap2 = -2147483647; //-2147483648;
181  boost::int32_t i32max = 2147483683;
182  boost::int32_t i32max_swap2 = 2147483683;
183  boost::int32_t i32med = 2147483683/2;
184  boost::int32_t i32med_swap2 = 2147483683/2;
185 
186  //Swap bytes 2x and the result must be equal the input.
187  CPPUNIT_ASSERT(sizeof(i32min) == 4);
188 
189  te::common::SwapBytes(i32min);
190  te::common::SwapBytes(i32min);
191  CPPUNIT_ASSERT(i32min == i32min_swap2);
192 
193  te::common::SwapBytes(i32max);
194  te::common::SwapBytes(i32max);
195  CPPUNIT_ASSERT(i32max == i32max_swap2);
196 
197  te::common::SwapBytes(i32med);
198  te::common::SwapBytes(i32med);
199  CPPUNIT_ASSERT(i32med == i32med_swap2);
200 }
201 
203 {
204  // boost::uint32_t uint32 = UINT32_C(4294967295);
205  // uint32 type 0 to 4294967295
206  boost::uint32_t ui32max = 4294967295;
207  boost::uint32_t ui32max_swap2 = 4294967295;
208  boost::uint32_t ui32med = 4294967295/2;
209  boost::uint32_t ui32med_swap2 = 4294967295/2;
210 
211  //Swap bytes 2x and the result must be equal the input.
212  CPPUNIT_ASSERT(sizeof(ui32max) == 4);
213 
214  te::common::SwapBytes(ui32max);
215  te::common::SwapBytes(ui32max);
216  CPPUNIT_ASSERT(ui32max == ui32max_swap2);
217 
218  te::common::SwapBytes(ui32med);
219  te::common::SwapBytes(ui32med);
220  CPPUNIT_ASSERT(ui32med == ui32med_swap2);
221 }
222 
224 {
225  // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
226 
227  float fl = 10.25f ;
228  float fl_swap2 = 10.25f ;
231  CPPUNIT_ASSERT(fl == fl_swap2);
232 
233  float fl1 = 4.2038954e-045f ;
234  float fl1_swap2 = 4.2038954e-045f;
237  CPPUNIT_ASSERT(fl1 == fl1_swap2);
238 
239  float fl2 = 1.99999976f ;
240  float fl2_swap2 = 1.99999976f;
243  CPPUNIT_ASSERT(fl2 == fl2_swap2);
244 
245  float fl3 = +1.4012985e-045f ;
246  float fl3_swap2 = +1.4012985e-045f;
249  CPPUNIT_ASSERT(fl3 == fl3_swap2);
250 
251  float fl5 = (float)0xFFFFFFFD ;
252  float fl5_swap2 = (float)0xFFFFFFFD ;
255  CPPUNIT_ASSERT(fl5 == fl5_swap2);
256 
257  float fl6 = (float)(-3) ;
258  float fl6_swap2 = (float)(-3) ;
261  CPPUNIT_ASSERT(fl6 == fl6_swap2);
262 
263 /*
264 http://processing.org/reference/float.html
265 Data type for floating-point numbers, a number that has a decimal point.
266 Floats are not precise, so avoid adding small values (such as 0.0001)
267 may not always increment because of rounding error.
268 If you want to increment a value in small intervals, use an int,
269 and divide by a float value before using it. (See above example.)
270 
271 Floating-point numbers can be as large as 3.40282347E+38 and as
272 low as -3.40282347E+38. They are stored as 32 bits (4 bytes) of
273 information. The float data type is inherited from Java.
274 
275 float f = 0;
276 for (int i = 0 ; i < 100000; i++) {
277  f = f + 0.0001; // Bad idea! See below.
278 }
279 
280 for (int i = 0; i < 100000; i++) {
281  // The variable 'f' will work better here, less affected by rounding
282  float f = i / 1000.0; // Count by thousandths
283 }
284 
285 */
286  float f; float f_orig;
287  for (int i = 1000000000; i > 0; i--)
288  {
289  //The variable 'f' will work better here, less affected by rounding
290  f = (float)(i / 100000.0);
291  f_orig = (float)(i / 100000.0 );
294  CPPUNIT_ASSERT(f == f_orig);
295  i-=5000;
296  }
297 }
298 
300 {
301  //http://stackoverflow.com/questions/4738768/printing-double-without-losing-precision?rq=1
302  double d = 3.1415926535897932384626433832795 ; // 3.1415926535897931;
303  double dorig = 3.1415926535897932384626433832795 ; // 3.1415926535897931;
304  CPPUNIT_ASSERT(sizeof(d) == 8) ;
305 
306  std::cout.precision(52); //16 ok
307  //std::cout << "Pi: " << std::cout.fixed << d <<std::endl;
308  //std::cout << "Pi: " << d <<std::endl;
311  CPPUNIT_ASSERT(d == dorig) ;
312 
313  //2^-52 + 300300300300
314  double d_52 = 300300300300 +0.0000000000000002220446049250313080847263336181640625 ;
315  double dorig_52 = 300300300300 + 0.0000000000000002220446049250313080847263336181640625 ;
316  te::common::SwapBytes(d_52);
317  te::common::SwapBytes(d_52);
318  CPPUNIT_ASSERT(d_52 == dorig_52) ;
319  //std::cout << "d_52: " << d_52 << std::endl;
320 
321  double p;// 2^i
322  double p_orig;
323  double base = 2;
324  for (int i = 52; i > 0; i--)
325  {
326  p = pow(base,-i) ;
327  p_orig = pow(base,-i) ;
328  //std::cout << "Pi: " << boost::lexical_cast<std::string>(p) << std::endl;
329  //std::cout << "double 2^-" << i << " = " << std::cout.fixed << p << std::endl;
332  //std::cout << "double 2^-" << i << "swaped twice" << " = " << std::cout.fixed << p <<std::endl;
333  CPPUNIT_ASSERT(p == p_orig);
334  }
335 }
void tcSwapBytes()
Test Case: Swap an array of n-bytes.
Utility functions to swap bytes: double, int and unsigned int.
void tcSwapBytes_float()
Test Case: Swap 4 bytes (float).
void Swap8Bytes(char *v)
It swaps an array of eight bytes in local.
void tcSwap2Bytes()
Test Case: Swap an array of 2 bytes -sizeof(<type>)== 2.
void Swap2Bytes(T &v)
It swaps two bytes in local.
Definition: ByteSwapUtils.h:51
Test suite for ByteSwapUtils.
void Swap4Bytes(T &v)
It swaps four bytes in local.
Definition: ByteSwapUtils.h:82
static te::dt::DateTime d(2010, 8, 9, 15, 58, 39)
Test suite for ByteSwapUtils.
te::gm::Polygon * p
void tcSwapBytes_buint32()
Test Case: Swap 4 bytes (boost::uint32).
void tcSwap4Bytes()
Test Case: Swap an array of 4 bytes.
CPPUNIT_TEST_SUITE_REGISTRATION(TsByteSwapUtils)
void tcSwapBytes_bint16()
Test Case: Swap 2 bytes (boost::int16).
This file contains include headers for the TerraLib Common Runtime module.
void tcSwapBytes_bint32()
Test Case: Swap 4 bytes (boost::int32).
void tcSwap8Bytes()
Test Case: Swap an array of 8-bytesr.
void tcSwapBytes_double()
Test Case: Swap 8 bytes (double).
void SwapBytes(T &v)
It swaps the bytes in local.