1 // Copyright 2019 Peter Dimov
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 
6 #include <boost/endian/conversion.hpp>
7 #include <boost/core/lightweight_test.hpp>
8 #include <boost/config.hpp>
9 #include <boost/cstdint.hpp>
10 #include <cstddef>
11 #include <ostream>
12 #include <iomanip>
13 
14 class byte_span
15 {
16 private:
17 
18     unsigned char const * p_;
19     std::size_t n_;
20 
21 public:
22 
byte_span(unsigned char const * p,std::size_t n)23     byte_span( unsigned char const * p, std::size_t n ): p_( p ), n_( n )
24     {
25     }
26 
byte_span(unsigned char const (& a)[N])27     template<std::size_t N> explicit byte_span( unsigned char const (&a)[ N ] ): p_( a ), n_( N )
28     {
29     }
30 
operator ==(byte_span const & r) const31     bool operator==( byte_span const& r ) const
32     {
33         if( n_ != r.n_ ) return false;
34 
35         for( std::size_t i = 0; i < n_; ++i )
36         {
37             if( p_[ i ] != r.p_[ i ] ) return false;
38         }
39 
40         return true;
41     }
42 
operator <<(std::ostream & os,byte_span s)43     friend std::ostream& operator<<( std::ostream& os, byte_span s )
44     {
45         if( s.n_ == 0 ) return os;
46 
47         os << std::hex << std::setfill( '0' ) << std::uppercase;
48 
49         os << std::setw( 2 ) << +s.p_[ 0 ];
50 
51         for( std::size_t i = 1; i < s.n_; ++i )
52         {
53             os << ':' << std::setw( 2 ) << +s.p_[ i ];
54         }
55 
56         os << std::dec << std::setfill( ' ' ) << std::nouppercase;;
57 
58         return os;
59     }
60 };
61 
test_1()62 template<class T> void test_1()
63 {
64     {
65         unsigned char v[] = { 0xAA, 0xAA };
66 
67         boost::endian::endian_store<T, 1, boost::endian::order::little>( v, 0x01 );
68 
69         unsigned char w[] = { 0x01, 0xAA };
70 
71         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
72     }
73 
74     {
75         unsigned char v[] = { 0xAA, 0xAA };
76 
77         boost::endian::endian_store<T, 1, boost::endian::order::big>( v, 0x01 );
78 
79         unsigned char w[] = { 0x01, 0xAA };
80 
81         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
82     }
83 }
84 
test_2()85 template<class T> void test_2()
86 {
87     {
88         unsigned char v[] = { 0xAA, 0xAA, 0xAA };
89 
90         boost::endian::endian_store<T, 2, boost::endian::order::little>( v, 0x0102 );
91 
92         unsigned char w[] = { 0x02, 0x01, 0xAA };
93 
94         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
95     }
96 
97     {
98         unsigned char v[] = { 0xAA, 0xAA, 0xAA };
99 
100         boost::endian::endian_store<T, 2, boost::endian::order::big>( v, 0x0102 );
101 
102         unsigned char w[] = { 0x01, 0x02, 0xAA };
103 
104         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
105     }
106 }
107 
test_3()108 template<class T> void test_3()
109 {
110     {
111         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA };
112 
113         boost::endian::endian_store<T, 3, boost::endian::order::little>( v, 0x010203 );
114 
115         unsigned char w[] = { 0x03, 0x02, 0x01, 0xAA };
116 
117         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
118     }
119 
120     {
121         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA };
122 
123         boost::endian::endian_store<T, 3, boost::endian::order::big>( v, 0x010203 );
124 
125         unsigned char w[] = { 0x01, 0x02, 0x03, 0xAA };
126 
127         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
128     }
129 }
130 
test_4()131 template<class T> void test_4()
132 {
133     {
134         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
135 
136         boost::endian::endian_store<T, 4, boost::endian::order::little>( v, 0x01020304 );
137 
138         unsigned char w[] = { 0x04, 0x03, 0x02, 0x01, 0xAA };
139 
140         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
141     }
142 
143     {
144         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
145 
146         boost::endian::endian_store<T, 4, boost::endian::order::big>( v, 0x01020304 );
147 
148         unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0xAA };
149 
150         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
151     }
152 }
153 
test_5()154 template<class T> void test_5()
155 {
156     {
157         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
158 
159         boost::endian::endian_store<T, 5, boost::endian::order::little>( v, 0x0102030405 );
160 
161         unsigned char w[] = { 0x05, 0x04, 0x03, 0x02, 0x01, 0xAA };
162 
163         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
164     }
165 
166     {
167         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
168 
169         boost::endian::endian_store<T, 5, boost::endian::order::big>( v, 0x0102030405 );
170 
171         unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0xAA };
172 
173         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
174     }
175 }
176 
test_6()177 template<class T> void test_6()
178 {
179     {
180         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
181 
182         boost::endian::endian_store<T, 6, boost::endian::order::little>( v, 0x010203040506 );
183 
184         unsigned char w[] = { 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0xAA };
185 
186         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
187     }
188 
189     {
190         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
191 
192         boost::endian::endian_store<T, 6, boost::endian::order::big>( v, 0x010203040506 );
193 
194         unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xAA };
195 
196         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
197     }
198 }
199 
test_7()200 template<class T> void test_7()
201 {
202     {
203         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
204 
205         boost::endian::endian_store<T, 7, boost::endian::order::little>( v, 0x01020304050607 );
206 
207         unsigned char w[] = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0xAA };
208 
209         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
210     }
211 
212     {
213         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
214 
215         boost::endian::endian_store<T, 7, boost::endian::order::big>( v, 0x01020304050607 );
216 
217         unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xAA };
218 
219         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
220     }
221 }
222 
test_8()223 template<class T> void test_8()
224 {
225     {
226         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
227 
228         boost::endian::endian_store<T, 8, boost::endian::order::little>( v, 0x0102030405060708 );
229 
230         unsigned char w[] = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0xAA };
231 
232         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
233     }
234 
235     {
236         unsigned char v[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
237 
238         boost::endian::endian_store<T, 8, boost::endian::order::big>( v, 0x0102030405060708 );
239 
240         unsigned char w[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xAA };
241 
242         BOOST_TEST_EQ( byte_span( v ), byte_span( w ) );
243     }
244 }
245 
main()246 int main()
247 {
248     // 1
249 
250     test_1<boost::int8_t>();
251     test_1<boost::uint8_t>();
252 
253     test_1<boost::int16_t>();
254     test_1<boost::uint16_t>();
255 
256     test_1<boost::int32_t>();
257     test_1<boost::uint32_t>();
258 
259     test_1<boost::int64_t>();
260     test_1<boost::uint64_t>();
261 
262     // 2
263 
264     test_2<boost::int16_t>();
265     test_2<boost::uint16_t>();
266 
267     test_2<boost::int32_t>();
268     test_2<boost::uint32_t>();
269 
270     test_2<boost::int64_t>();
271     test_2<boost::uint64_t>();
272 
273     // 3
274 
275     test_3<boost::int32_t>();
276     test_3<boost::uint32_t>();
277 
278     test_3<boost::int64_t>();
279     test_3<boost::uint64_t>();
280 
281     // 4
282 
283     test_4<boost::int32_t>();
284     test_4<boost::uint32_t>();
285 
286     test_4<boost::int64_t>();
287     test_4<boost::uint64_t>();
288 
289     // 5
290 
291     test_5<boost::int64_t>();
292     test_5<boost::uint64_t>();
293 
294     // 6
295 
296     test_6<boost::int64_t>();
297     test_6<boost::uint64_t>();
298 
299     // 7
300 
301     test_7<boost::int64_t>();
302     test_7<boost::uint64_t>();
303 
304     // 8
305 
306     test_8<boost::int64_t>();
307     test_8<boost::uint64_t>();
308 
309     return boost::report_errors();
310 }
311