]>
Commit | Line | Data |
---|---|---|
1 | /**************************************************************************** | |
2 | ** | |
3 | ** Copyright (C) 2017 Intel Corporation | |
4 | ** | |
5 | ** Permission is hereby granted, free of charge, to any person obtaining a copy | |
6 | ** of this software and associated documentation files (the "Software"), to deal | |
7 | ** in the Software without restriction, including without limitation the rights | |
8 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
9 | ** copies of the Software, and to permit persons to whom the Software is | |
10 | ** furnished to do so, subject to the following conditions: | |
11 | ** | |
12 | ** The above copyright notice and this permission notice shall be included in | |
13 | ** all copies or substantial portions of the Software. | |
14 | ** | |
15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
18 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
21 | ** THE SOFTWARE. | |
22 | ** | |
23 | ****************************************************************************/ | |
24 | ||
25 | #ifndef CBORINTERNAL_P_H | |
26 | #define CBORINTERNAL_P_H | |
27 | ||
28 | #include "compilersupport_p.h" | |
29 | ||
30 | #ifndef CBOR_NO_FLOATING_POINT | |
31 | # include <float.h> | |
32 | # include <math.h> | |
33 | #else | |
34 | # ifndef CBOR_NO_HALF_FLOAT_TYPE | |
35 | # define CBOR_NO_HALF_FLOAT_TYPE 1 | |
36 | # endif | |
37 | #endif | |
38 | ||
39 | #ifndef CBOR_NO_HALF_FLOAT_TYPE | |
40 | # ifdef __F16C__ | |
41 | # include <immintrin.h> | |
42 | static inline unsigned short encode_half(double val) | |
43 | { | |
44 | return _cvtss_sh((float)val, 3); | |
45 | } | |
46 | static inline double decode_half(unsigned short half) | |
47 | { | |
48 | return _cvtsh_ss(half); | |
49 | } | |
50 | # else | |
51 | /* software implementation of float-to-fp16 conversions */ | |
52 | static inline unsigned short encode_half(double val) | |
53 | { | |
54 | uint64_t v; | |
55 | int sign, exp, mant; | |
56 | memcpy(&v, &val, sizeof(v)); | |
57 | sign = v >> 63 << 15; | |
58 | exp = (v >> 52) & 0x7ff; | |
59 | mant = v << 12 >> 12 >> (53-11); /* keep only the 11 most significant bits of the mantissa */ | |
60 | exp -= 1023; | |
61 | if (exp == 1024) { | |
62 | /* infinity or NaN */ | |
63 | exp = 16; | |
64 | mant >>= 1; | |
65 | } else if (exp >= 16) { | |
66 | /* overflow, as largest number */ | |
67 | exp = 15; | |
68 | mant = 1023; | |
69 | } else if (exp >= -14) { | |
70 | /* regular normal */ | |
71 | } else if (exp >= -24) { | |
72 | /* subnormal */ | |
73 | mant |= 1024; | |
74 | mant >>= -(exp + 14); | |
75 | exp = -15; | |
76 | } else { | |
77 | /* underflow, make zero */ | |
78 | return 0; | |
79 | } | |
80 | ||
81 | /* safe cast here as bit operations above guarantee not to overflow */ | |
82 | return (unsigned short)(sign | ((exp + 15) << 10) | mant); | |
83 | } | |
84 | ||
85 | /* this function was copied & adapted from RFC 7049 Appendix D */ | |
86 | static inline double decode_half(unsigned short half) | |
87 | { | |
88 | int exp = (half >> 10) & 0x1f; | |
89 | int mant = half & 0x3ff; | |
90 | double val; | |
91 | if (exp == 0) val = ldexp(mant, -24); | |
92 | else if (exp != 31) val = ldexp(mant + 1024, exp - 25); | |
93 | else val = mant == 0 ? INFINITY : NAN; | |
94 | return half & 0x8000 ? -val : val; | |
95 | } | |
96 | # endif | |
97 | #endif /* CBOR_NO_HALF_FLOAT_TYPE */ | |
98 | ||
99 | #ifndef CBOR_INTERNAL_API | |
100 | # define CBOR_INTERNAL_API | |
101 | #endif | |
102 | ||
103 | #ifndef CBOR_PARSER_MAX_RECURSIONS | |
104 | # define CBOR_PARSER_MAX_RECURSIONS 1024 | |
105 | #endif | |
106 | ||
107 | /* | |
108 | * CBOR Major types | |
109 | * Encoded in the high 3 bits of the descriptor byte | |
110 | * See http://tools.ietf.org/html/rfc7049#section-2.1 | |
111 | */ | |
112 | typedef enum CborMajorTypes { | |
113 | UnsignedIntegerType = 0U, | |
114 | NegativeIntegerType = 1U, | |
115 | ByteStringType = 2U, | |
116 | TextStringType = 3U, | |
117 | ArrayType = 4U, | |
118 | MapType = 5U, /* a.k.a. object */ | |
119 | TagType = 6U, | |
120 | SimpleTypesType = 7U | |
121 | } CborMajorTypes; | |
122 | ||
123 | /* | |
124 | * CBOR simple and floating point types | |
125 | * Encoded in the low 8 bits of the descriptor byte when the | |
126 | * Major Type is 7. | |
127 | */ | |
128 | typedef enum CborSimpleTypes { | |
129 | FalseValue = 20, | |
130 | TrueValue = 21, | |
131 | NullValue = 22, | |
132 | UndefinedValue = 23, | |
133 | SimpleTypeInNextByte = 24, /* not really a simple type */ | |
134 | HalfPrecisionFloat = 25, /* ditto */ | |
135 | SinglePrecisionFloat = 26, /* ditto */ | |
136 | DoublePrecisionFloat = 27, /* ditto */ | |
137 | Break = 31 | |
138 | } CborSimpleTypes; | |
139 | ||
140 | enum { | |
141 | SmallValueBitLength = 5U, | |
142 | SmallValueMask = (1U << SmallValueBitLength) - 1, /* 31 */ | |
143 | Value8Bit = 24U, | |
144 | Value16Bit = 25U, | |
145 | Value32Bit = 26U, | |
146 | Value64Bit = 27U, | |
147 | IndefiniteLength = 31U, | |
148 | ||
149 | MajorTypeShift = SmallValueBitLength, | |
150 | MajorTypeMask = (int) (~0U << MajorTypeShift), | |
151 | ||
152 | BreakByte = (unsigned)Break | (SimpleTypesType << MajorTypeShift) | |
153 | }; | |
154 | ||
155 | CBOR_INTERNAL_API CborError CBOR_INTERNAL_API_CC _cbor_value_extract_number(const uint8_t **ptr, const uint8_t *end, uint64_t *len); | |
156 | CBOR_INTERNAL_API CborError CBOR_INTERNAL_API_CC _cbor_value_prepare_string_iteration(CborValue *it); | |
157 | CBOR_INTERNAL_API CborError CBOR_INTERNAL_API_CC _cbor_value_get_string_chunk(const CborValue *value, const void **bufferptr, | |
158 | size_t *len, CborValue *next); | |
159 | ||
160 | ||
161 | #endif /* CBORINTERNAL_P_H */ |