1 | // SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later |
2 | // Copyright 2011, SIL International, All rights reserved. |
3 | /* |
4 | Description: |
5 | A set of fast template based decoders for decoding values of any C integer |
6 | type up to long int size laid out with most significant byte first or least |
7 | significant byte first (aka big endian or little endian). These are CPU |
8 | byte order agnostic and will function the same regardless of the CPUs native |
9 | byte order. |
10 | |
11 | Being template based means if the either le or be class is not used then |
12 | template code of unused functions will not be instantiated by the compiler |
13 | and thus shouldn't cause any overhead. |
14 | */ |
15 | |
16 | #include <cstddef> |
17 | |
18 | #pragma once |
19 | |
20 | |
21 | class be |
22 | { |
23 | template<int S> |
24 | inline static unsigned long int _peek(const unsigned char * p) { |
25 | return _peek<S/2>(p) << (S/2)*8 | _peek<S/2>(p+S/2); |
26 | } |
27 | public: |
28 | template<typename T> |
29 | inline static T peek(const void * p) { |
30 | return T(_peek<sizeof(T)>(static_cast<const unsigned char *>(p))); |
31 | } |
32 | |
33 | template<typename T> |
34 | inline static T read(const unsigned char * &p) { |
35 | const T r = T(_peek<sizeof(T)>(p)); |
36 | p += sizeof r; |
37 | return r; |
38 | } |
39 | |
40 | template<typename T> |
41 | inline static T swap(const T x) { |
42 | return T(_peek<sizeof(T)>(reinterpret_cast<const unsigned char *>(&x))); |
43 | } |
44 | |
45 | template<typename T> |
46 | inline static void skip(const unsigned char * &p, size_t n=1) { |
47 | p += sizeof(T)*n; |
48 | } |
49 | }; |
50 | |
51 | template<> |
52 | inline unsigned long int be::_peek<1>(const unsigned char * p) { return *p; } |
53 | |
54 | |
55 | class le |
56 | { |
57 | template<int S> |
58 | inline static unsigned long int _peek(const unsigned char * p) { |
59 | return _peek<S/2>(p) | _peek<S/2>(p+S/2) << (S/2)*8; |
60 | } |
61 | public: |
62 | template<typename T> |
63 | inline static T peek(const void * p) { |
64 | return T(_peek<sizeof(T)>(static_cast<const unsigned char *>(p))); |
65 | } |
66 | |
67 | template<typename T> |
68 | inline static T read(const unsigned char * &p) { |
69 | const T r = T(_peek<sizeof(T)>(p)); |
70 | p += sizeof r; |
71 | return r; |
72 | } |
73 | |
74 | template<typename T> |
75 | inline static T swap(const T x) { |
76 | return T(_peek<sizeof(T)>(reinterpret_cast<const unsigned char *>(&x))); |
77 | } |
78 | |
79 | template<typename T> |
80 | inline static void skip(const unsigned char * &p, size_t n=1) { |
81 | p += sizeof(T)*n; |
82 | } |
83 | }; |
84 | |
85 | template<> |
86 | inline unsigned long int le::_peek<1>(const unsigned char * p) { return *p; } |
87 | |