1 // Copyright (c) Lawrence Livermore National Security, LLC and other Conduit
2 // Project developers. See top-level LICENSE AND COPYRIGHT files for dates and
3 // other details. No copyright assignment is required to contribute to Conduit.
4 
5 //-----------------------------------------------------------------------------
6 ///
7 /// file: conduit_endianness.cpp
8 ///
9 //-----------------------------------------------------------------------------
10 
11 #include "conduit.hpp"
12 
13 #include <iostream>
14 #include "gtest/gtest.h"
15 
16 using namespace conduit;
17 
18 
19 //-----------------------------------------------------------------------------
TEST(conduit_endianness,endianness_ids_and_names)20 TEST(conduit_endianness, endianness_ids_and_names)
21 {
22     if(Endianness::machine_is_big_endian())
23     {
24         EXPECT_TRUE(Endianness::machine_default() == Endianness::BIG_ID);
25     }
26 
27     if(Endianness::machine_is_little_endian())
28     {
29         EXPECT_TRUE(Endianness::machine_default() == Endianness::LITTLE_ID);
30     }
31 
32     EXPECT_EQ(Endianness::name_to_id("big"),Endianness::BIG_ID );
33     EXPECT_EQ(Endianness::name_to_id("little"),Endianness::LITTLE_ID );
34 
35     EXPECT_EQ(Endianness::id_to_name(Endianness::BIG_ID),"big");
36     EXPECT_EQ(Endianness::id_to_name(Endianness::LITTLE_ID),"little");
37 
38 }
39 
40 //-----------------------------------------------------------------------------
TEST(conduit_endianness,simple_1)41 TEST(conduit_endianness, simple_1)
42 {
43     union{uint8  vbytes[4]; uint32 vuint;} test;
44     std::string machine_endian = Endianness::id_to_name(Endianness::machine_default());
45     std::cout << "[host is " << machine_endian << "]" << std::endl;
46 
47     if(Endianness::machine_default() == Endianness::BIG_ID)
48     {
49         test.vbytes[0] =  0xff;
50         test.vbytes[1] =  0xff;
51         test.vbytes[2] =  0xff;
52         test.vbytes[3] =  0xfe;
53 
54         EXPECT_EQ(0xfffffffe,test.vuint);
55     }
56     else
57     {
58         test.vbytes[0] =  0xfe;
59         test.vbytes[1] =  0xff;
60         test.vbytes[2] =  0xff;
61         test.vbytes[3] =  0xff;
62 
63         EXPECT_EQ(0xfffffffe,test.vuint);
64     }
65 }
66 
67 //-----------------------------------------------------------------------------
TEST(conduit_endianness,swap_inplace)68 TEST(conduit_endianness, swap_inplace)
69 {
70     union{uint8  vbytes[2]; uint16 vuint16;} test16;
71     union{uint8  vbytes[4]; uint32 vuint32;} test32;
72     union{uint8  vbytes[8]; uint64 vuint64;} test64;
73 
74     if(Endianness::machine_default() == Endianness::BIG_ID)
75     {
76 
77         test16.vbytes[0] =  0x02;
78         test16.vbytes[1] =  0x01;
79 
80         Endianness::swap16(&test16.vuint16);
81         EXPECT_EQ(0x0102,test16.vuint16);
82 
83         test32.vbytes[0] =  0x04;
84         test32.vbytes[1] =  0x03;
85         test32.vbytes[2] =  0x02;
86         test32.vbytes[3] =  0x01;
87 
88         Endianness::swap32(&test32.vuint32);
89         EXPECT_EQ(0x01020304,test32.vuint32);
90 
91         test64.vbytes[0] =  0x08;
92         test64.vbytes[1] =  0x07;
93         test64.vbytes[2] =  0x06;
94         test64.vbytes[3] =  0x05;
95         test64.vbytes[4] =  0x04;
96         test64.vbytes[5] =  0x03;
97         test64.vbytes[6] =  0x02;
98         test64.vbytes[7] =  0x01;
99 
100         Endianness::swap64(&test64.vuint64);
101         EXPECT_EQ(0x0102030405060708,test64.vuint64);
102     }
103     else
104     {
105         test16.vbytes[0] =  0x01;
106         test16.vbytes[1] =  0x02;
107 
108         Endianness::swap16(&test16.vuint16);
109         EXPECT_EQ(0x0102,test16.vuint16);
110 
111         test32.vbytes[0] =  0x01;
112         test32.vbytes[1] =  0x02;
113         test32.vbytes[2] =  0x03;
114         test32.vbytes[3] =  0x04;
115 
116         Endianness::swap32(&test32.vuint32);
117         EXPECT_EQ(0x01020304,test32.vuint32);
118 
119         test64.vbytes[0] =  0x01;
120         test64.vbytes[1] =  0x02;
121         test64.vbytes[2] =  0x03;
122         test64.vbytes[3] =  0x04;
123         test64.vbytes[4] =  0x05;
124         test64.vbytes[5] =  0x06;
125         test64.vbytes[6] =  0x07;
126         test64.vbytes[7] =  0x08;
127 
128         Endianness::swap64(&test64.vuint64);
129         EXPECT_EQ(0x0102030405060708,test64.vuint64);
130 
131     }
132 }
133 
134 //-----------------------------------------------------------------------------
TEST(conduit_endianness,swap_to)135 TEST(conduit_endianness, swap_to)
136 {
137     union{uint8  vbytes[2]; uint16 vuint16;} src_test16;
138     union{uint8  vbytes[4]; uint32 vuint32;} src_test32;
139     union{uint8  vbytes[8]; uint64 vuint64;} src_test64;
140 
141     uint16 dest_test16;
142     uint32 dest_test32;
143     uint64 dest_test64;
144 
145     if(Endianness::machine_default() == Endianness::BIG_ID)
146     {
147 
148         src_test16.vbytes[0] =  0x02;
149         src_test16.vbytes[1] =  0x01;
150 
151         Endianness::swap16(&src_test16.vuint16,
152                            &dest_test16);
153 
154         EXPECT_EQ(0x0102,dest_test16);
155 
156         src_test32.vbytes[0] =  0x04;
157         src_test32.vbytes[1] =  0x03;
158         src_test32.vbytes[2] =  0x02;
159         src_test32.vbytes[3] =  0x01;
160 
161         Endianness::swap32(&src_test32.vuint32,
162                            &dest_test32);
163 
164         EXPECT_EQ(0x01020304,dest_test32);
165 
166         src_test64.vbytes[0] =  0x08;
167         src_test64.vbytes[1] =  0x07;
168         src_test64.vbytes[2] =  0x06;
169         src_test64.vbytes[3] =  0x05;
170         src_test64.vbytes[4] =  0x04;
171         src_test64.vbytes[5] =  0x03;
172         src_test64.vbytes[6] =  0x02;
173         src_test64.vbytes[7] =  0x01;
174 
175         Endianness::swap64(&src_test64.vuint64,
176                            &dest_test64);
177 
178         EXPECT_EQ(0x0102030405060708,dest_test64);
179     }
180     else
181     {
182         src_test16.vbytes[0] =  0x01;
183         src_test16.vbytes[1] =  0x02;
184 
185         Endianness::swap16(&src_test16.vuint16,
186                            &dest_test16);
187         EXPECT_EQ(0x0102,dest_test16);
188 
189         src_test32.vbytes[0] =  0x01;
190         src_test32.vbytes[1] =  0x02;
191         src_test32.vbytes[2] =  0x03;
192         src_test32.vbytes[3] =  0x04;
193 
194         Endianness::swap32(&src_test32.vuint32,
195                            &dest_test32);
196 
197         EXPECT_EQ(0x01020304,dest_test32);
198 
199         src_test64.vbytes[0] =  0x01;
200         src_test64.vbytes[1] =  0x02;
201         src_test64.vbytes[2] =  0x03;
202         src_test64.vbytes[3] =  0x04;
203         src_test64.vbytes[4] =  0x05;
204         src_test64.vbytes[5] =  0x06;
205         src_test64.vbytes[6] =  0x07;
206         src_test64.vbytes[7] =  0x08;
207 
208         Endianness::swap64(&src_test64.vuint64,
209                            &dest_test64);
210         EXPECT_EQ(0x0102030405060708,dest_test64);
211     }
212 }
213 
214 //-----------------------------------------------------------------------------
TEST(conduit_endianness,node_swap)215 TEST(conduit_endianness, node_swap)
216 {
217     union{uint8  vbytes[2]; uint16 vuint16;} test16;
218     union{uint8  vbytes[4]; uint32 vuint32;} test32;
219     union{uint8  vbytes[8]; uint64 vuint64;} test64;
220 
221     Node n;
222 
223     if(Endianness::machine_default() == Endianness::BIG_ID)
224     {
225         test16.vbytes[0] =  0x02;
226         test16.vbytes[1] =  0x01;
227 
228         n["test16"].set_external(&test16.vuint16,1);
229         /// no swap if types match (machine default will be BIG_ID)
230         n["test16"].endian_swap(Endianness::DEFAULT_ID);
231         EXPECT_EQ(0x0201,test16.vuint16);
232         /// no swap if types match (machine default will be BIG_ID)
233         n["test16"].endian_swap(Endianness::BIG_ID);
234         EXPECT_EQ(0x0201,test16.vuint16);
235         /// swap
236         n["test16"].endian_swap(Endianness::LITTLE_ID);
237         EXPECT_EQ(0x0102,test16.vuint16);
238 
239         test32.vbytes[0] =  0x04;
240         test32.vbytes[1] =  0x03;
241         test32.vbytes[2] =  0x02;
242         test32.vbytes[3] =  0x01;
243 
244         n["test32"].set_external(&test32.vuint32,1);
245         n["test32"].endian_swap(Endianness::LITTLE_ID);
246         EXPECT_EQ(0x01020304,test32.vuint32);
247 
248         test64.vbytes[0] =  0x08;
249         test64.vbytes[1] =  0x07;
250         test64.vbytes[2] =  0x06;
251         test64.vbytes[3] =  0x05;
252         test64.vbytes[4] =  0x04;
253         test64.vbytes[5] =  0x03;
254         test64.vbytes[6] =  0x02;
255         test64.vbytes[7] =  0x01;
256 
257         n["test64"].set_external(&test64.vuint64,1);
258         n["test64"].endian_swap(Endianness::LITTLE_ID);
259         EXPECT_EQ(0x0102030405060708,test64.vuint64);
260 
261         // swap all back back so we can do a full test on n
262         n["test16"].endian_swap(Endianness::BIG_ID);
263         n["test32"].endian_swap(Endianness::BIG_ID);
264         n["test64"].endian_swap(Endianness::BIG_ID);
265 
266         // full swap via n
267         n.endian_swap(Endianness::LITTLE_ID);
268 
269         EXPECT_EQ(0x0102,test16.vuint16);
270         EXPECT_EQ(0x01020304,test32.vuint32);
271         EXPECT_EQ(0x0102030405060708,test64.vuint64);
272 
273     }
274     else
275     {
276         test16.vbytes[0] =  0x01;
277         test16.vbytes[1] =  0x02;
278 
279         n["test16"].set_external(&test16.vuint16,1);
280         /// no swap if types match (machine default will be LITTLE_ID)
281         n["test16"].endian_swap(Endianness::DEFAULT_ID);
282         EXPECT_EQ(0x0201,test16.vuint16);
283         /// no swap if types match (machine default will be LITTLE_ID)
284         n["test16"].endian_swap(Endianness::LITTLE_ID);
285         EXPECT_EQ(0x0201,test16.vuint16);
286         /// swap
287         n["test16"].endian_swap(Endianness::BIG_ID);
288         EXPECT_EQ(0x0102,test16.vuint16);
289 
290         test32.vbytes[0] =  0x01;
291         test32.vbytes[1] =  0x02;
292         test32.vbytes[2] =  0x03;
293         test32.vbytes[3] =  0x04;
294 
295         n["test32"].set_external(&test32.vuint32,1);
296         n["test32"].endian_swap(Endianness::BIG_ID);
297         EXPECT_EQ(0x01020304,test32.vuint32);
298 
299         test64.vbytes[0] =  0x01;
300         test64.vbytes[1] =  0x02;
301         test64.vbytes[2] =  0x03;
302         test64.vbytes[3] =  0x04;
303         test64.vbytes[4] =  0x05;
304         test64.vbytes[5] =  0x06;
305         test64.vbytes[6] =  0x07;
306         test64.vbytes[7] =  0x08;
307 
308         n["test64"].set_external(&test64.vuint64,1);
309         n["test64"].endian_swap(Endianness::BIG_ID);
310         EXPECT_EQ(0x0102030405060708,test64.vuint64);
311 
312         // swap all back back so we can do a full test on n
313         n["test16"].endian_swap(Endianness::LITTLE_ID);
314         n["test32"].endian_swap(Endianness::LITTLE_ID);
315         n["test64"].endian_swap(Endianness::LITTLE_ID);
316         n.endian_swap(Endianness::BIG_ID);
317 
318         // full swap via n
319         EXPECT_EQ(0x0102,test16.vuint16);
320         EXPECT_EQ(0x01020304,test32.vuint32);
321         EXPECT_EQ(0x0102030405060708,test64.vuint64);
322 
323     }
324 }
325 
326 //-----------------------------------------------------------------------------
TEST(conduit_endianness,node_swap_using_explicit_funcs)327 TEST(conduit_endianness, node_swap_using_explicit_funcs)
328 {
329     union{uint8  vbytes[2]; uint16 vuint16;} test16;
330     union{uint8  vbytes[4]; uint32 vuint32;} test32;
331     union{uint8  vbytes[8]; uint64 vuint64;} test64;
332 
333     Node n;
334 
335     if(Endianness::machine_default() == Endianness::BIG_ID)
336     {
337         test16.vbytes[0] =  0x02;
338         test16.vbytes[1] =  0x01;
339 
340         n["test16"].set_external(&test16.vuint16,
341                                  1, // num ele
342                                  0, // offset
343                                  2, // stride
344                                  2, // elem_bytes
345                                  Endianness::LITTLE_ID); // set not match
346 
347         n["test16"].endian_swap_to_machine_default();
348         EXPECT_EQ(0x0102,test16.vuint16);
349 
350         test32.vbytes[0] =  0x04;
351         test32.vbytes[1] =  0x03;
352         test32.vbytes[2] =  0x02;
353         test32.vbytes[3] =  0x01;
354 
355         n["test32"].set_external(&test32.vuint32,
356                                  1, // num ele
357                                  0, // offset
358                                  4, // stride
359                                  4, // elem_bytes
360                                  Endianness::LITTLE_ID); // set not match
361 
362         n["test32"].endian_swap_to_machine_default();
363         EXPECT_EQ(0x01020304,test32.vuint32);
364 
365         test64.vbytes[0] =  0x08;
366         test64.vbytes[1] =  0x07;
367         test64.vbytes[2] =  0x06;
368         test64.vbytes[3] =  0x05;
369         test64.vbytes[4] =  0x04;
370         test64.vbytes[5] =  0x03;
371         test64.vbytes[6] =  0x02;
372         test64.vbytes[7] =  0x01;
373 
374         n["test64"].set_external(&test64.vuint64,
375                                  1, // num ele
376                                  0, // offset
377                                  8, // stride
378                                  8, // elem_bytes
379                                  Endianness::LITTLE_ID); // set not match
380 
381         n["test64"].endian_swap_to_machine_default();
382         EXPECT_EQ(0x0102030405060708,test64.vuint64);
383 
384         // swap all back back so we can do a full test on n
385         n["test16"].endian_swap_to_little();
386         n["test32"].endian_swap_to_little();
387         n["test64"].endian_swap_to_little();
388         // full swap via n
389         n.endian_swap_to_big();
390 
391         EXPECT_EQ(0x0102,test16.vuint16);
392         EXPECT_EQ(0x01020304,test32.vuint32);
393         EXPECT_EQ(0x0102030405060708,test64.vuint64);
394 
395     }
396     else
397     {
398         test16.vbytes[0] =  0x01;
399         test16.vbytes[1] =  0x02;
400 
401         n["test16"].set_external(&test16.vuint16,
402                                  1, // num ele
403                                  0, // offset
404                                  2, // stride
405                                  2, // elem_bytes
406                                  Endianness::BIG_ID); // set not match
407 
408         /// swap
409         n["test16"].endian_swap_to_machine_default();
410         EXPECT_EQ(0x0102,test16.vuint16);
411 
412         test32.vbytes[0] =  0x01;
413         test32.vbytes[1] =  0x02;
414         test32.vbytes[2] =  0x03;
415         test32.vbytes[3] =  0x04;
416 
417         n["test32"].set_external(&test32.vuint32,
418                                  1, // num ele
419                                  0, // offset
420                                  4, // stride
421                                  4, // elem_bytes
422                                  Endianness::BIG_ID); // set not match
423 
424         n["test32"].endian_swap_to_machine_default();
425         EXPECT_EQ(0x01020304,test32.vuint32);
426 
427         test64.vbytes[0] =  0x01;
428         test64.vbytes[1] =  0x02;
429         test64.vbytes[2] =  0x03;
430         test64.vbytes[3] =  0x04;
431         test64.vbytes[4] =  0x05;
432         test64.vbytes[5] =  0x06;
433         test64.vbytes[6] =  0x07;
434         test64.vbytes[7] =  0x08;
435 
436         n["test64"].set_external(&test64.vuint64,
437                                  1, // num ele
438                                  0, // offset
439                                  8, // stride
440                                  8, // elem_bytes
441                                  Endianness::BIG_ID); // set not match
442 
443 
444 
445         n["test64"].endian_swap_to_machine_default();
446         EXPECT_EQ(0x0102030405060708,test64.vuint64);
447 
448         // swap all back back so we can do a full test on n
449         n["test16"].endian_swap_to_big();
450         n["test32"].endian_swap_to_big();
451         n["test64"].endian_swap_to_big();
452 
453         // full swap via n
454         n.endian_swap_to_little();
455 
456         EXPECT_EQ(0x0102,test16.vuint16);
457         EXPECT_EQ(0x01020304,test32.vuint32);
458         EXPECT_EQ(0x0102030405060708,test64.vuint64);
459 
460 
461     }
462 }
463 
464 
465