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 #include "conduit_endianness.hpp"
11 
12 //-----------------------------------------------------------------------------
13 // -- begin conduit:: --
14 //-----------------------------------------------------------------------------
15 namespace conduit
16 {
17 
18 //-----------------------------------------------------------------------------
19 // -- begin conduit::Endianness --
20 //-----------------------------------------------------------------------------
21 ///
22 /// class: conduit::Endianness
23 ///
24 /// description:
25 ///  Class for endian info and conversation.
26 ///
27 //-----------------------------------------------------------------------------
28 
29 //---------------------------------------------------------------------------//
30 index_t
machine_default()31 Endianness::machine_default()
32 {
33     union{uint8  vbyte; uint32 vuint;} test;
34     test.vuint = 1;
35     if(test.vbyte ^ 1)
36         return BIG_ID;
37     else
38         return LITTLE_ID;
39 }
40 
41 //---------------------------------------------------------------------------//
42 bool
machine_is_little_endian()43 Endianness::machine_is_little_endian()
44 {
45     return machine_default() == LITTLE_ID;
46 }
47 
48 //---------------------------------------------------------------------------//
49 bool
machine_is_big_endian()50 Endianness::machine_is_big_endian()
51 {
52     return machine_default() == BIG_ID;
53 }
54 
55 
56 //-----------------------------------------------------------------------------
57 /// Enum id to string and string to enum id helpers.
58 //-----------------------------------------------------------------------------
59 
60 //---------------------------------------------------------------------------//
61 index_t
name_to_id(const std::string & name)62 Endianness::name_to_id(const std::string &name)
63 {
64     if(name == "big")
65         return BIG_ID;
66     else if(name =="little")
67         return LITTLE_ID;
68     return DEFAULT_ID;
69 
70 }
71 
72 //---------------------------------------------------------------------------//
73 std::string
id_to_name(index_t endianness)74 Endianness::id_to_name(index_t endianness)
75 {
76     std::string res = "default";
77     if(endianness == BIG_ID)
78         res = "big";
79     else if(endianness == LITTLE_ID)
80         res = "little";
81     return res;
82 };
83 
84 //-----------------------------------------------------------------------------
85 /// Helpers for endianness transforms
86 //-----------------------------------------------------------------------------
87 
88 //---------------------------------------------------------------------------//
89 void
swap16(void * data)90 Endianness::swap16(void *data)
91 {
92     uint8 tmp = *((uint8*)data);
93     ((uint8*)data)[0] = ((uint8*)data)[1];
94     ((uint8*)data)[1] = tmp;
95 }
96 
97 //---------------------------------------------------------------------------//
98 void
swap16(void * src,void * dest)99 Endianness::swap16(void *src,void *dest)
100 {
101     ((uint8*)dest)[0] = ((uint8*)src)[1];
102     ((uint8*)dest)[1] = ((uint8*)src)[0];
103 }
104 
105 //---------------------------------------------------------------------------//
106 void
swap32(void * data)107 Endianness::swap32(void *data)
108 {
109     union{uint8 vbytes[4]; uint32 vdata;} swp;
110 
111     swp.vbytes[3] = ((uint8*)data)[0];
112     swp.vbytes[2] = ((uint8*)data)[1];
113     swp.vbytes[1] = ((uint8*)data)[2];
114     swp.vbytes[0] = ((uint8*)data)[3];
115 
116     *((uint32*)data) = swp.vdata;
117 }
118 
119 //---------------------------------------------------------------------------//
120 void
swap32(void * src,void * dest)121 Endianness::swap32(void *src,void *dest)
122 {
123     ((uint8*)dest)[0] = ((uint8*)src)[3];
124     ((uint8*)dest)[1] = ((uint8*)src)[2];
125     ((uint8*)dest)[2] = ((uint8*)src)[1];
126     ((uint8*)dest)[3] = ((uint8*)src)[0];
127 }
128 
129 //---------------------------------------------------------------------------//
130 void
swap64(void * data)131 Endianness::swap64(void *data)
132 {
133     union{uint8 vbytes[8]; uint64 vdata;} swp;
134 
135     swp.vbytes[7] = ((uint8*)data)[0];
136     swp.vbytes[6] = ((uint8*)data)[1];
137     swp.vbytes[5] = ((uint8*)data)[2];
138     swp.vbytes[4] = ((uint8*)data)[3];
139     swp.vbytes[3] = ((uint8*)data)[4];
140     swp.vbytes[2] = ((uint8*)data)[5];
141     swp.vbytes[1] = ((uint8*)data)[6];
142     swp.vbytes[0] = ((uint8*)data)[7];
143 
144     *((uint64*)data) = swp.vdata;
145 }
146 
147 //---------------------------------------------------------------------------//
148 void
swap64(void * src,void * dest)149 Endianness::swap64(void *src,void *dest)
150 {
151     ((uint8*)dest)[0] = ((uint8*)src)[7];
152     ((uint8*)dest)[1] = ((uint8*)src)[6];
153     ((uint8*)dest)[2] = ((uint8*)src)[5];
154     ((uint8*)dest)[3] = ((uint8*)src)[4];
155     ((uint8*)dest)[4] = ((uint8*)src)[3];
156     ((uint8*)dest)[5] = ((uint8*)src)[2];
157     ((uint8*)dest)[6] = ((uint8*)src)[1];
158     ((uint8*)dest)[7] = ((uint8*)src)[0];
159 
160 }
161 
162 
163 }
164 //-----------------------------------------------------------------------------
165 // -- begin conduit:: --
166 //-----------------------------------------------------------------------------
167 
168