Merge lp:~thomas-voss/location-service/generalize-glue-code-for-agps-operation into lp:location-service/15.04
- generalize-glue-code-for-agps-operation
- Merge into 15.04
Status: | Superseded |
---|---|
Proposed branch: | lp:~thomas-voss/location-service/generalize-glue-code-for-agps-operation |
Merge into: | lp:location-service/15.04 |
Diff against target: |
4046 lines (+3470/-62) 34 files modified
3rd-party/boost/core/scoped_enum.hpp (+192/-0) 3rd-party/boost/endian/arithmetic.hpp (+413/-0) 3rd-party/boost/endian/buffers.hpp (+515/-0) 3rd-party/boost/endian/conversion.hpp (+487/-0) 3rd-party/boost/endian/detail/config.hpp (+62/-0) 3rd-party/boost/endian/detail/cover_operators.hpp (+142/-0) 3rd-party/boost/endian/detail/disable_warnings.hpp (+33/-0) 3rd-party/boost/endian/detail/disable_warnings_pop.hpp (+12/-0) 3rd-party/boost/endian/detail/intrinsic.hpp (+64/-0) 3rd-party/boost/endian/detail/lightweight_test.hpp (+223/-0) 3rd-party/boost/endian/endian.hpp (+19/-0) 3rd-party/boost/endian/std_pair.hpp (+38/-0) CMakeLists.txt (+3/-0) include/location_service/com/ubuntu/location/connectivity/manager.h (+21/-0) src/location_service/com/ubuntu/location/CMakeLists.txt (+8/-0) src/location_service/com/ubuntu/location/connectivity/ofono.h (+115/-1) src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp (+34/-2) src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h (+5/-1) src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt (+13/-10) src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp (+120/-30) src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h (+34/-5) src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp (+30/-0) src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h (+35/-4) src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp (+210/-0) src/location_service/com/ubuntu/location/providers/gps/sntp_client.h (+210/-0) src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp (+57/-0) src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h (+51/-0) src/location_service/com/ubuntu/location/service/runtime.h (+1/-1) src/location_service/com/ubuntu/location/service/runtime_tests.cpp (+1/-0) src/location_service/com/ubuntu/location/time_since_boot.cpp (+140/-0) src/location_service/com/ubuntu/location/time_since_boot.h (+35/-0) tests/CMakeLists.txt (+1/-0) tests/gps_provider_test.cpp (+42/-8) tests/sntp_client_test.cpp (+104/-0) |
To merge this branch: | bzr merge lp:~thomas-voss/location-service/generalize-glue-code-for-agps-operation |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phablet Team | Pending | ||
Review via email: mp+288690@code.launchpad.net |
This proposal has been superseded by a proposal from 2016-03-10.
Commit message
This is the first MP in a series to generalize AGPS behavior. Here, we wire up
incoming RIL-specific requests and respond to them by reaching out to our Ofono-based telephony stack.
Description of the change
This is the first MP in a series to generalize AGPS behavior. Here, we wire up
incoming RIL-specific requests and respond to them by reaching out to our Ofono-based telephony stack.
- 230. By Thomas Voß
-
Log individual imsi/msisdn callback invocations.
- 231. By Thomas Voß
-
Extend runtime test cases to cover agps use cases.
- 232. By Thomas Voß
-
Clean up event connections after each trial.
Adjust terminal output.
Unmerged revisions
- 232. By Thomas Voß
-
Clean up event connections after each trial.
Adjust terminal output. - 231. By Thomas Voß
-
Extend runtime test cases to cover agps use cases.
- 230. By Thomas Voß
-
Log individual imsi/msisdn callback invocations.
- 229. By Thomas Voß
-
Wire up ril request callbacks.
Preview Diff
1 | === added directory '3rd-party' | |||
2 | === added directory '3rd-party/boost' | |||
3 | === added directory '3rd-party/boost/core' | |||
4 | === added file '3rd-party/boost/core/scoped_enum.hpp' | |||
5 | --- 3rd-party/boost/core/scoped_enum.hpp 1970-01-01 00:00:00 +0000 | |||
6 | +++ 3rd-party/boost/core/scoped_enum.hpp 2016-03-10 19:55:08 +0000 | |||
7 | @@ -0,0 +1,192 @@ | |||
8 | 1 | // scoped_enum.hpp ---------------------------------------------------------// | ||
9 | 2 | |||
10 | 3 | // Copyright Beman Dawes, 2009 | ||
11 | 4 | // Copyright (C) 2011-2012 Vicente J. Botet Escriba | ||
12 | 5 | // Copyright (C) 2012 Anthony Williams | ||
13 | 6 | |||
14 | 7 | // Distributed under the Boost Software License, Version 1.0. | ||
15 | 8 | // See http://www.boost.org/LICENSE_1_0.txt | ||
16 | 9 | |||
17 | 10 | #ifndef BOOST_CORE_SCOPED_ENUM_HPP | ||
18 | 11 | #define BOOST_CORE_SCOPED_ENUM_HPP | ||
19 | 12 | |||
20 | 13 | #include <boost/config.hpp> | ||
21 | 14 | |||
22 | 15 | #ifdef BOOST_HAS_PRAGMA_ONCE | ||
23 | 16 | #pragma once | ||
24 | 17 | #endif | ||
25 | 18 | |||
26 | 19 | namespace boost | ||
27 | 20 | { | ||
28 | 21 | |||
29 | 22 | #ifdef BOOST_NO_CXX11_SCOPED_ENUMS | ||
30 | 23 | |||
31 | 24 | /** | ||
32 | 25 | * Meta-function to get the native enum type associated to an enum class or its emulation. | ||
33 | 26 | */ | ||
34 | 27 | template <typename EnumType> | ||
35 | 28 | struct native_type | ||
36 | 29 | { | ||
37 | 30 | /** | ||
38 | 31 | * The member typedef type names the native enum type associated to the scoped enum, | ||
39 | 32 | * which is it self if the compiler supports scoped enums or EnumType::enum_type if it is an emulated scoped enum. | ||
40 | 33 | */ | ||
41 | 34 | typedef typename EnumType::enum_type type; | ||
42 | 35 | }; | ||
43 | 36 | |||
44 | 37 | /** | ||
45 | 38 | * Casts a scoped enum to its underlying type. | ||
46 | 39 | * | ||
47 | 40 | * This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type. | ||
48 | 41 | * @param v A scoped enum. | ||
49 | 42 | * @returns The underlying type. | ||
50 | 43 | * @throws No-throws. | ||
51 | 44 | */ | ||
52 | 45 | template <typename UnderlyingType, typename EnumType> | ||
53 | 46 | UnderlyingType underlying_cast(EnumType v) | ||
54 | 47 | { | ||
55 | 48 | return v.get_underlying_value_(); | ||
56 | 49 | } | ||
57 | 50 | |||
58 | 51 | /** | ||
59 | 52 | * Casts a scoped enum to its native enum type. | ||
60 | 53 | * | ||
61 | 54 | * This function is useful to make programs portable when the scoped enum emulation can not be use where native enums can. | ||
62 | 55 | * | ||
63 | 56 | * EnumType the scoped enum type | ||
64 | 57 | * | ||
65 | 58 | * @param v A scoped enum. | ||
66 | 59 | * @returns The native enum value. | ||
67 | 60 | * @throws No-throws. | ||
68 | 61 | */ | ||
69 | 62 | template <typename EnumType> | ||
70 | 63 | inline | ||
71 | 64 | typename EnumType::enum_type native_value(EnumType e) | ||
72 | 65 | { | ||
73 | 66 | return e.get_native_value_(); | ||
74 | 67 | } | ||
75 | 68 | |||
76 | 69 | #else // BOOST_NO_CXX11_SCOPED_ENUMS | ||
77 | 70 | |||
78 | 71 | template <typename EnumType> | ||
79 | 72 | struct native_type | ||
80 | 73 | { | ||
81 | 74 | typedef EnumType type; | ||
82 | 75 | }; | ||
83 | 76 | |||
84 | 77 | template <typename UnderlyingType, typename EnumType> | ||
85 | 78 | UnderlyingType underlying_cast(EnumType v) | ||
86 | 79 | { | ||
87 | 80 | return static_cast<UnderlyingType>(v); | ||
88 | 81 | } | ||
89 | 82 | |||
90 | 83 | template <typename EnumType> | ||
91 | 84 | inline | ||
92 | 85 | EnumType native_value(EnumType e) | ||
93 | 86 | { | ||
94 | 87 | return e; | ||
95 | 88 | } | ||
96 | 89 | |||
97 | 90 | #endif // BOOST_NO_CXX11_SCOPED_ENUMS | ||
98 | 91 | } | ||
99 | 92 | |||
100 | 93 | |||
101 | 94 | #ifdef BOOST_NO_CXX11_SCOPED_ENUMS | ||
102 | 95 | |||
103 | 96 | #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS | ||
104 | 97 | |||
105 | 98 | #define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ | ||
106 | 99 | explicit operator underlying_type() const BOOST_NOEXCEPT { return get_underlying_value_(); } | ||
107 | 100 | |||
108 | 101 | #else | ||
109 | 102 | |||
110 | 103 | #define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR | ||
111 | 104 | |||
112 | 105 | #endif | ||
113 | 106 | |||
114 | 107 | /** | ||
115 | 108 | * Start a declaration of a scoped enum. | ||
116 | 109 | * | ||
117 | 110 | * @param EnumType The new scoped enum. | ||
118 | 111 | * @param UnderlyingType The underlying type. | ||
119 | 112 | */ | ||
120 | 113 | #define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType, UnderlyingType) \ | ||
121 | 114 | struct EnumType { \ | ||
122 | 115 | typedef void is_boost_scoped_enum_tag; \ | ||
123 | 116 | typedef UnderlyingType underlying_type; \ | ||
124 | 117 | EnumType() BOOST_NOEXCEPT {} \ | ||
125 | 118 | explicit EnumType(underlying_type v) BOOST_NOEXCEPT : v_(v) {} \ | ||
126 | 119 | underlying_type get_underlying_value_() const BOOST_NOEXCEPT { return v_; } \ | ||
127 | 120 | BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ | ||
128 | 121 | private: \ | ||
129 | 122 | underlying_type v_; \ | ||
130 | 123 | typedef EnumType self_type; \ | ||
131 | 124 | public: \ | ||
132 | 125 | enum enum_type | ||
133 | 126 | |||
134 | 127 | #define BOOST_SCOPED_ENUM_DECLARE_END2() \ | ||
135 | 128 | enum_type get_native_value_() const BOOST_NOEXCEPT { return enum_type(v_); } \ | ||
136 | 129 | friend bool operator ==(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \ | ||
137 | 130 | friend bool operator ==(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \ | ||
138 | 131 | friend bool operator ==(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \ | ||
139 | 132 | friend bool operator !=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=enum_type(rhs.v_); } \ | ||
140 | 133 | friend bool operator !=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=rhs; } \ | ||
141 | 134 | friend bool operator !=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs!=enum_type(rhs.v_); } \ | ||
142 | 135 | friend bool operator <(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<enum_type(rhs.v_); } \ | ||
143 | 136 | friend bool operator <(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<rhs; } \ | ||
144 | 137 | friend bool operator <(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<enum_type(rhs.v_); } \ | ||
145 | 138 | friend bool operator <=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=enum_type(rhs.v_); } \ | ||
146 | 139 | friend bool operator <=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=rhs; } \ | ||
147 | 140 | friend bool operator <=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<=enum_type(rhs.v_); } \ | ||
148 | 141 | friend bool operator >(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>enum_type(rhs.v_); } \ | ||
149 | 142 | friend bool operator >(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>rhs; } \ | ||
150 | 143 | friend bool operator >(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>enum_type(rhs.v_); } \ | ||
151 | 144 | friend bool operator >=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=enum_type(rhs.v_); } \ | ||
152 | 145 | friend bool operator >=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=rhs; } \ | ||
153 | 146 | friend bool operator >=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>=enum_type(rhs.v_); } \ | ||
154 | 147 | }; | ||
155 | 148 | |||
156 | 149 | #define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) \ | ||
157 | 150 | ; \ | ||
158 | 151 | EnumType(enum_type v) BOOST_NOEXCEPT : v_(v) {} \ | ||
159 | 152 | BOOST_SCOPED_ENUM_DECLARE_END2() | ||
160 | 153 | |||
161 | 154 | /** | ||
162 | 155 | * Starts a declaration of a scoped enum with the default int underlying type. | ||
163 | 156 | * | ||
164 | 157 | * @param EnumType The new scoped enum. | ||
165 | 158 | */ | ||
166 | 159 | #define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) \ | ||
167 | 160 | BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,int) | ||
168 | 161 | |||
169 | 162 | /** | ||
170 | 163 | * Name of the native enum type. | ||
171 | 164 | * | ||
172 | 165 | * @param EnumType The new scoped enum. | ||
173 | 166 | */ | ||
174 | 167 | #define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType::enum_type | ||
175 | 168 | /** | ||
176 | 169 | * Forward declares an scoped enum. | ||
177 | 170 | * | ||
178 | 171 | * @param EnumType The scoped enum. | ||
179 | 172 | */ | ||
180 | 173 | #define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) struct EnumType | ||
181 | 174 | |||
182 | 175 | #else // BOOST_NO_CXX11_SCOPED_ENUMS | ||
183 | 176 | |||
184 | 177 | #define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,UnderlyingType) enum class EnumType : UnderlyingType | ||
185 | 178 | #define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) enum class EnumType | ||
186 | 179 | #define BOOST_SCOPED_ENUM_DECLARE_END2() | ||
187 | 180 | #define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) ; | ||
188 | 181 | |||
189 | 182 | #define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType | ||
190 | 183 | #define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) enum class EnumType | ||
191 | 184 | |||
192 | 185 | #endif // BOOST_NO_CXX11_SCOPED_ENUMS | ||
193 | 186 | |||
194 | 187 | // Deprecated macros | ||
195 | 188 | #define BOOST_SCOPED_ENUM_START(name) BOOST_SCOPED_ENUM_DECLARE_BEGIN(name) | ||
196 | 189 | #define BOOST_SCOPED_ENUM_END BOOST_SCOPED_ENUM_DECLARE_END2() | ||
197 | 190 | #define BOOST_SCOPED_ENUM(name) BOOST_SCOPED_ENUM_NATIVE(name) | ||
198 | 191 | |||
199 | 192 | #endif // BOOST_CORE_SCOPED_ENUM_HPP | ||
200 | 0 | 193 | ||
201 | === added directory '3rd-party/boost/endian' | |||
202 | === added file '3rd-party/boost/endian/arithmetic.hpp' | |||
203 | --- 3rd-party/boost/endian/arithmetic.hpp 1970-01-01 00:00:00 +0000 | |||
204 | +++ 3rd-party/boost/endian/arithmetic.hpp 2016-03-10 19:55:08 +0000 | |||
205 | @@ -0,0 +1,413 @@ | |||
206 | 1 | // boost/endian/arithmetic.hpp -------------------------------------------------------// | ||
207 | 2 | |||
208 | 3 | // (C) Copyright Darin Adler 2000 | ||
209 | 4 | // (C) Copyright Beman Dawes 2006, 2009, 2014 | ||
210 | 5 | |||
211 | 6 | // Distributed under the Boost Software License, Version 1.0. | ||
212 | 7 | // See http://www.boost.org/LICENSE_1_0.txt | ||
213 | 8 | |||
214 | 9 | // See library home page at http://www.boost.org/libs/endian | ||
215 | 10 | |||
216 | 11 | //--------------------------------------------------------------------------------------// | ||
217 | 12 | |||
218 | 13 | // Original design developed by Darin Adler based on classes developed by Mark | ||
219 | 14 | // Borgerding. Four original class templates were combined into a single endian | ||
220 | 15 | // class template by Beman Dawes, who also added the unrolled_byte_loops sign | ||
221 | 16 | // partial specialization to correctly extend the sign when cover integer size | ||
222 | 17 | // differs from endian representation size. | ||
223 | 18 | |||
224 | 19 | // TODO: When a compiler supporting constexpr becomes available, try possible uses. | ||
225 | 20 | |||
226 | 21 | #ifndef BOOST_ENDIAN_ARITHMETIC_HPP | ||
227 | 22 | #define BOOST_ENDIAN_ARITHMETIC_HPP | ||
228 | 23 | |||
229 | 24 | #if defined(_MSC_VER) | ||
230 | 25 | # pragma warning(push) | ||
231 | 26 | # pragma warning(disable:4365) // conversion ... signed/unsigned mismatch | ||
232 | 27 | #endif | ||
233 | 28 | |||
234 | 29 | #ifdef BOOST_ENDIAN_LOG | ||
235 | 30 | # include <iostream> | ||
236 | 31 | #endif | ||
237 | 32 | |||
238 | 33 | #if defined(__BORLANDC__) || defined( __CODEGEARC__) | ||
239 | 34 | # pragma pack(push, 1) | ||
240 | 35 | #endif | ||
241 | 36 | |||
242 | 37 | #include <boost/config.hpp> | ||
243 | 38 | #include <boost/predef/detail/endian_compat.h> | ||
244 | 39 | #include <boost/endian/conversion.hpp> | ||
245 | 40 | #include <boost/endian/buffers.hpp> | ||
246 | 41 | #define BOOST_ENDIAN_MINIMAL_COVER_OPERATORS | ||
247 | 42 | #include <boost/endian/detail/cover_operators.hpp> | ||
248 | 43 | #undef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS | ||
249 | 44 | #include <boost/type_traits/is_signed.hpp> | ||
250 | 45 | #include <boost/cstdint.hpp> | ||
251 | 46 | #include <boost/static_assert.hpp> | ||
252 | 47 | #include <boost/core/scoped_enum.hpp> | ||
253 | 48 | #include <iosfwd> | ||
254 | 49 | #include <climits> | ||
255 | 50 | |||
256 | 51 | # if CHAR_BIT != 8 | ||
257 | 52 | # error Platforms with CHAR_BIT != 8 are not supported | ||
258 | 53 | # endif | ||
259 | 54 | |||
260 | 55 | # ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS | ||
261 | 56 | # define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03 | ||
262 | 57 | # else | ||
263 | 58 | # define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x | ||
264 | 59 | # endif | ||
265 | 60 | |||
266 | 61 | # if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS) | ||
267 | 62 | # define BOOST_ENDIAN_NO_CTORS | ||
268 | 63 | # endif | ||
269 | 64 | |||
270 | 65 | # ifndef BOOST_ENDIAN_EXPLICIT_CTORS | ||
271 | 66 | # define BOOST_ENDIAN_EXPLICIT_OPT | ||
272 | 67 | # else | ||
273 | 68 | # define BOOST_ENDIAN_EXPLICIT_OPT explicit | ||
274 | 69 | # endif | ||
275 | 70 | |||
276 | 71 | //---------------------------------- synopsis ----------------------------------------// | ||
277 | 72 | |||
278 | 73 | namespace boost | ||
279 | 74 | { | ||
280 | 75 | namespace endian | ||
281 | 76 | { | ||
282 | 77 | |||
283 | 78 | template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits, | ||
284 | 79 | BOOST_SCOPED_ENUM(align) A = align::no> | ||
285 | 80 | class endian_arithmetic; | ||
286 | 81 | |||
287 | 82 | // big endian signed integer aligned types | ||
288 | 83 | typedef endian_arithmetic<order::big, int8_t, 8, align::yes> big_int8_at; | ||
289 | 84 | typedef endian_arithmetic<order::big, int16_t, 16, align::yes> big_int16_at; | ||
290 | 85 | typedef endian_arithmetic<order::big, int32_t, 32, align::yes> big_int32_at; | ||
291 | 86 | typedef endian_arithmetic<order::big, int64_t, 64, align::yes> big_int64_at; | ||
292 | 87 | |||
293 | 88 | // big endian unsigned integer aligned types | ||
294 | 89 | typedef endian_arithmetic<order::big, uint8_t, 8, align::yes> big_uint8_at; | ||
295 | 90 | typedef endian_arithmetic<order::big, uint16_t, 16, align::yes> big_uint16_at; | ||
296 | 91 | typedef endian_arithmetic<order::big, uint32_t, 32, align::yes> big_uint32_at; | ||
297 | 92 | typedef endian_arithmetic<order::big, uint64_t, 64, align::yes> big_uint64_at; | ||
298 | 93 | |||
299 | 94 | // little endian signed integer aligned types | ||
300 | 95 | typedef endian_arithmetic<order::little, int8_t, 8, align::yes> little_int8_at; | ||
301 | 96 | typedef endian_arithmetic<order::little, int16_t, 16, align::yes> little_int16_at; | ||
302 | 97 | typedef endian_arithmetic<order::little, int32_t, 32, align::yes> little_int32_at; | ||
303 | 98 | typedef endian_arithmetic<order::little, int64_t, 64, align::yes> little_int64_at; | ||
304 | 99 | |||
305 | 100 | // little endian unsigned integer aligned types | ||
306 | 101 | typedef endian_arithmetic<order::little, uint8_t, 8, align::yes> little_uint8_at; | ||
307 | 102 | typedef endian_arithmetic<order::little, uint16_t, 16, align::yes> little_uint16_at; | ||
308 | 103 | typedef endian_arithmetic<order::little, uint32_t, 32, align::yes> little_uint32_at; | ||
309 | 104 | typedef endian_arithmetic<order::little, uint64_t, 64, align::yes> little_uint64_at; | ||
310 | 105 | |||
311 | 106 | // aligned native endian typedefs are not provided because | ||
312 | 107 | // <cstdint> types are superior for this use case | ||
313 | 108 | |||
314 | 109 | // big endian signed integer unaligned types | ||
315 | 110 | typedef endian_arithmetic<order::big, int_least8_t, 8> big_int8_t; | ||
316 | 111 | typedef endian_arithmetic<order::big, int_least16_t, 16> big_int16_t; | ||
317 | 112 | typedef endian_arithmetic<order::big, int_least32_t, 24> big_int24_t; | ||
318 | 113 | typedef endian_arithmetic<order::big, int_least32_t, 32> big_int32_t; | ||
319 | 114 | typedef endian_arithmetic<order::big, int_least64_t, 40> big_int40_t; | ||
320 | 115 | typedef endian_arithmetic<order::big, int_least64_t, 48> big_int48_t; | ||
321 | 116 | typedef endian_arithmetic<order::big, int_least64_t, 56> big_int56_t; | ||
322 | 117 | typedef endian_arithmetic<order::big, int_least64_t, 64> big_int64_t; | ||
323 | 118 | |||
324 | 119 | // big endian unsigned integer unaligned types | ||
325 | 120 | typedef endian_arithmetic<order::big, uint_least8_t, 8> big_uint8_t; | ||
326 | 121 | typedef endian_arithmetic<order::big, uint_least16_t, 16> big_uint16_t; | ||
327 | 122 | typedef endian_arithmetic<order::big, uint_least32_t, 24> big_uint24_t; | ||
328 | 123 | typedef endian_arithmetic<order::big, uint_least32_t, 32> big_uint32_t; | ||
329 | 124 | typedef endian_arithmetic<order::big, uint_least64_t, 40> big_uint40_t; | ||
330 | 125 | typedef endian_arithmetic<order::big, uint_least64_t, 48> big_uint48_t; | ||
331 | 126 | typedef endian_arithmetic<order::big, uint_least64_t, 56> big_uint56_t; | ||
332 | 127 | typedef endian_arithmetic<order::big, uint_least64_t, 64> big_uint64_t; | ||
333 | 128 | |||
334 | 129 | // little endian signed integer unaligned types | ||
335 | 130 | typedef endian_arithmetic<order::little, int_least8_t, 8> little_int8_t; | ||
336 | 131 | typedef endian_arithmetic<order::little, int_least16_t, 16> little_int16_t; | ||
337 | 132 | typedef endian_arithmetic<order::little, int_least32_t, 24> little_int24_t; | ||
338 | 133 | typedef endian_arithmetic<order::little, int_least32_t, 32> little_int32_t; | ||
339 | 134 | typedef endian_arithmetic<order::little, int_least64_t, 40> little_int40_t; | ||
340 | 135 | typedef endian_arithmetic<order::little, int_least64_t, 48> little_int48_t; | ||
341 | 136 | typedef endian_arithmetic<order::little, int_least64_t, 56> little_int56_t; | ||
342 | 137 | typedef endian_arithmetic<order::little, int_least64_t, 64> little_int64_t; | ||
343 | 138 | |||
344 | 139 | // little endian unsigned integer unaligned types | ||
345 | 140 | typedef endian_arithmetic<order::little, uint_least8_t, 8> little_uint8_t; | ||
346 | 141 | typedef endian_arithmetic<order::little, uint_least16_t, 16> little_uint16_t; | ||
347 | 142 | typedef endian_arithmetic<order::little, uint_least32_t, 24> little_uint24_t; | ||
348 | 143 | typedef endian_arithmetic<order::little, uint_least32_t, 32> little_uint32_t; | ||
349 | 144 | typedef endian_arithmetic<order::little, uint_least64_t, 40> little_uint40_t; | ||
350 | 145 | typedef endian_arithmetic<order::little, uint_least64_t, 48> little_uint48_t; | ||
351 | 146 | typedef endian_arithmetic<order::little, uint_least64_t, 56> little_uint56_t; | ||
352 | 147 | typedef endian_arithmetic<order::little, uint_least64_t, 64> little_uint64_t; | ||
353 | 148 | |||
354 | 149 | # ifdef BOOST_BIG_ENDIAN | ||
355 | 150 | // native endian signed integer unaligned types | ||
356 | 151 | typedef big_int8_t native_int8_t; | ||
357 | 152 | typedef big_int16_t native_int16_t; | ||
358 | 153 | typedef big_int24_t native_int24_t; | ||
359 | 154 | typedef big_int32_t native_int32_t; | ||
360 | 155 | typedef big_int40_t native_int40_t; | ||
361 | 156 | typedef big_int48_t native_int48_t; | ||
362 | 157 | typedef big_int56_t native_int56_t; | ||
363 | 158 | typedef big_int64_t native_int64_t; | ||
364 | 159 | |||
365 | 160 | // native endian unsigned integer unaligned types | ||
366 | 161 | typedef big_uint8_t native_uint8_t; | ||
367 | 162 | typedef big_uint16_t native_uint16_t; | ||
368 | 163 | typedef big_uint24_t native_uint24_t; | ||
369 | 164 | typedef big_uint32_t native_uint32_t; | ||
370 | 165 | typedef big_uint40_t native_uint40_t; | ||
371 | 166 | typedef big_uint48_t native_uint48_t; | ||
372 | 167 | typedef big_uint56_t native_uint56_t; | ||
373 | 168 | typedef big_uint64_t native_uint64_t; | ||
374 | 169 | # else | ||
375 | 170 | // native endian signed integer unaligned types | ||
376 | 171 | typedef little_int8_t native_int8_t; | ||
377 | 172 | typedef little_int16_t native_int16_t; | ||
378 | 173 | typedef little_int24_t native_int24_t; | ||
379 | 174 | typedef little_int32_t native_int32_t; | ||
380 | 175 | typedef little_int40_t native_int40_t; | ||
381 | 176 | typedef little_int48_t native_int48_t; | ||
382 | 177 | typedef little_int56_t native_int56_t; | ||
383 | 178 | typedef little_int64_t native_int64_t; | ||
384 | 179 | |||
385 | 180 | // native endian unsigned integer unaligned types | ||
386 | 181 | typedef little_uint8_t native_uint8_t; | ||
387 | 182 | typedef little_uint16_t native_uint16_t; | ||
388 | 183 | typedef little_uint24_t native_uint24_t; | ||
389 | 184 | typedef little_uint32_t native_uint32_t; | ||
390 | 185 | typedef little_uint40_t native_uint40_t; | ||
391 | 186 | typedef little_uint48_t native_uint48_t; | ||
392 | 187 | typedef little_uint56_t native_uint56_t; | ||
393 | 188 | typedef little_uint64_t native_uint64_t; | ||
394 | 189 | # endif | ||
395 | 190 | |||
396 | 191 | # ifdef BOOST_ENDIAN_DEPRECATED_NAMES | ||
397 | 192 | |||
398 | 193 | typedef order endianness; | ||
399 | 194 | typedef align alignment; | ||
400 | 195 | |||
401 | 196 | # ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES | ||
402 | 197 | template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits, | ||
403 | 198 | BOOST_SCOPED_ENUM(align) Align = align::no> | ||
404 | 199 | using endian = endian_arithmetic<Order, T, n_bits, Align>; | ||
405 | 200 | # endif | ||
406 | 201 | |||
407 | 202 | // unaligned big endian signed integer types | ||
408 | 203 | typedef endian_arithmetic< order::big, int_least8_t, 8 > big8_t; | ||
409 | 204 | typedef endian_arithmetic< order::big, int_least16_t, 16 > big16_t; | ||
410 | 205 | typedef endian_arithmetic< order::big, int_least32_t, 24 > big24_t; | ||
411 | 206 | typedef endian_arithmetic< order::big, int_least32_t, 32 > big32_t; | ||
412 | 207 | typedef endian_arithmetic< order::big, int_least64_t, 40 > big40_t; | ||
413 | 208 | typedef endian_arithmetic< order::big, int_least64_t, 48 > big48_t; | ||
414 | 209 | typedef endian_arithmetic< order::big, int_least64_t, 56 > big56_t; | ||
415 | 210 | typedef endian_arithmetic< order::big, int_least64_t, 64 > big64_t; | ||
416 | 211 | |||
417 | 212 | // unaligned big endian_arithmetic unsigned integer types | ||
418 | 213 | typedef endian_arithmetic< order::big, uint_least8_t, 8 > ubig8_t; | ||
419 | 214 | typedef endian_arithmetic< order::big, uint_least16_t, 16 > ubig16_t; | ||
420 | 215 | typedef endian_arithmetic< order::big, uint_least32_t, 24 > ubig24_t; | ||
421 | 216 | typedef endian_arithmetic< order::big, uint_least32_t, 32 > ubig32_t; | ||
422 | 217 | typedef endian_arithmetic< order::big, uint_least64_t, 40 > ubig40_t; | ||
423 | 218 | typedef endian_arithmetic< order::big, uint_least64_t, 48 > ubig48_t; | ||
424 | 219 | typedef endian_arithmetic< order::big, uint_least64_t, 56 > ubig56_t; | ||
425 | 220 | typedef endian_arithmetic< order::big, uint_least64_t, 64 > ubig64_t; | ||
426 | 221 | |||
427 | 222 | // unaligned little endian_arithmetic signed integer types | ||
428 | 223 | typedef endian_arithmetic< order::little, int_least8_t, 8 > little8_t; | ||
429 | 224 | typedef endian_arithmetic< order::little, int_least16_t, 16 > little16_t; | ||
430 | 225 | typedef endian_arithmetic< order::little, int_least32_t, 24 > little24_t; | ||
431 | 226 | typedef endian_arithmetic< order::little, int_least32_t, 32 > little32_t; | ||
432 | 227 | typedef endian_arithmetic< order::little, int_least64_t, 40 > little40_t; | ||
433 | 228 | typedef endian_arithmetic< order::little, int_least64_t, 48 > little48_t; | ||
434 | 229 | typedef endian_arithmetic< order::little, int_least64_t, 56 > little56_t; | ||
435 | 230 | typedef endian_arithmetic< order::little, int_least64_t, 64 > little64_t; | ||
436 | 231 | |||
437 | 232 | // unaligned little endian_arithmetic unsigned integer types | ||
438 | 233 | typedef endian_arithmetic< order::little, uint_least8_t, 8 > ulittle8_t; | ||
439 | 234 | typedef endian_arithmetic< order::little, uint_least16_t, 16 > ulittle16_t; | ||
440 | 235 | typedef endian_arithmetic< order::little, uint_least32_t, 24 > ulittle24_t; | ||
441 | 236 | typedef endian_arithmetic< order::little, uint_least32_t, 32 > ulittle32_t; | ||
442 | 237 | typedef endian_arithmetic< order::little, uint_least64_t, 40 > ulittle40_t; | ||
443 | 238 | typedef endian_arithmetic< order::little, uint_least64_t, 48 > ulittle48_t; | ||
444 | 239 | typedef endian_arithmetic< order::little, uint_least64_t, 56 > ulittle56_t; | ||
445 | 240 | typedef endian_arithmetic< order::little, uint_least64_t, 64 > ulittle64_t; | ||
446 | 241 | |||
447 | 242 | // unaligned native endian_arithmetic signed integer types | ||
448 | 243 | typedef endian_arithmetic< order::native, int_least8_t, 8 > native8_t; | ||
449 | 244 | typedef endian_arithmetic< order::native, int_least16_t, 16 > native16_t; | ||
450 | 245 | typedef endian_arithmetic< order::native, int_least32_t, 24 > native24_t; | ||
451 | 246 | typedef endian_arithmetic< order::native, int_least32_t, 32 > native32_t; | ||
452 | 247 | typedef endian_arithmetic< order::native, int_least64_t, 40 > native40_t; | ||
453 | 248 | typedef endian_arithmetic< order::native, int_least64_t, 48 > native48_t; | ||
454 | 249 | typedef endian_arithmetic< order::native, int_least64_t, 56 > native56_t; | ||
455 | 250 | typedef endian_arithmetic< order::native, int_least64_t, 64 > native64_t; | ||
456 | 251 | |||
457 | 252 | // unaligned native endian_arithmetic unsigned integer types | ||
458 | 253 | typedef endian_arithmetic< order::native, uint_least8_t, 8 > unative8_t; | ||
459 | 254 | typedef endian_arithmetic< order::native, uint_least16_t, 16 > unative16_t; | ||
460 | 255 | typedef endian_arithmetic< order::native, uint_least32_t, 24 > unative24_t; | ||
461 | 256 | typedef endian_arithmetic< order::native, uint_least32_t, 32 > unative32_t; | ||
462 | 257 | typedef endian_arithmetic< order::native, uint_least64_t, 40 > unative40_t; | ||
463 | 258 | typedef endian_arithmetic< order::native, uint_least64_t, 48 > unative48_t; | ||
464 | 259 | typedef endian_arithmetic< order::native, uint_least64_t, 56 > unative56_t; | ||
465 | 260 | typedef endian_arithmetic< order::native, uint_least64_t, 64 > unative64_t; | ||
466 | 261 | |||
467 | 262 | // aligned native endian_arithmetic typedefs are not provided because | ||
468 | 263 | // <cstdint> types are superior for this use case | ||
469 | 264 | |||
470 | 265 | typedef endian_arithmetic< order::big, int16_t, 16, align::yes > aligned_big16_t; | ||
471 | 266 | typedef endian_arithmetic< order::big, uint16_t, 16, align::yes > aligned_ubig16_t; | ||
472 | 267 | typedef endian_arithmetic< order::little, int16_t, 16, align::yes > aligned_little16_t; | ||
473 | 268 | typedef endian_arithmetic< order::little, uint16_t, 16, align::yes > aligned_ulittle16_t; | ||
474 | 269 | |||
475 | 270 | typedef endian_arithmetic< order::big, int32_t, 32, align::yes > aligned_big32_t; | ||
476 | 271 | typedef endian_arithmetic< order::big, uint32_t, 32, align::yes > aligned_ubig32_t; | ||
477 | 272 | typedef endian_arithmetic< order::little, int32_t, 32, align::yes > aligned_little32_t; | ||
478 | 273 | typedef endian_arithmetic< order::little, uint32_t, 32, align::yes > aligned_ulittle32_t; | ||
479 | 274 | |||
480 | 275 | typedef endian_arithmetic< order::big, int64_t, 64, align::yes > aligned_big64_t; | ||
481 | 276 | typedef endian_arithmetic< order::big, uint64_t, 64, align::yes > aligned_ubig64_t; | ||
482 | 277 | typedef endian_arithmetic< order::little, int64_t, 64, align::yes > aligned_little64_t; | ||
483 | 278 | typedef endian_arithmetic< order::little, uint64_t, 64, align::yes > aligned_ulittle64_t; | ||
484 | 279 | |||
485 | 280 | # endif | ||
486 | 281 | |||
487 | 282 | //---------------------------------- end synopsis ------------------------------------// | ||
488 | 283 | |||
489 | 284 | // endian class template specializations ---------------------------------------------// | ||
490 | 285 | |||
491 | 286 | // Specializations that represent unaligned bytes. | ||
492 | 287 | // Taking an integer type as a parameter provides a nice way to pass both | ||
493 | 288 | // the size and signness of the desired integer and get the appropriate | ||
494 | 289 | // corresponding integer type for the interface. | ||
495 | 290 | |||
496 | 291 | // unaligned integer big endian specialization | ||
497 | 292 | template <typename T, std::size_t n_bits> | ||
498 | 293 | class endian_arithmetic< order::big, T, n_bits, align::no > | ||
499 | 294 | : public endian_buffer< order::big, T, n_bits, align::no >, | ||
500 | 295 | cover_operators<endian_arithmetic<order::big, T, n_bits>, T> | ||
501 | 296 | { | ||
502 | 297 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | ||
503 | 298 | public: | ||
504 | 299 | typedef T value_type; | ||
505 | 300 | # ifndef BOOST_ENDIAN_NO_CTORS | ||
506 | 301 | endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT | ||
507 | 302 | BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT | ||
508 | 303 | { | ||
509 | 304 | # ifdef BOOST_ENDIAN_LOG | ||
510 | 305 | if ( endian_log ) | ||
511 | 306 | std::cout << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n"; | ||
512 | 307 | # endif | ||
513 | 308 | detail::store_big_endian<T, n_bits/8>(this->m_value, val); | ||
514 | 309 | } | ||
515 | 310 | # endif | ||
516 | 311 | endian_arithmetic& operator=(T val) BOOST_NOEXCEPT | ||
517 | 312 | { detail::store_big_endian<T, n_bits/8>(this->m_value, val); return *this; } | ||
518 | 313 | operator value_type() const BOOST_NOEXCEPT { return this->value(); } | ||
519 | 314 | }; | ||
520 | 315 | |||
521 | 316 | // unaligned little endian specialization | ||
522 | 317 | template <typename T, std::size_t n_bits> | ||
523 | 318 | class endian_arithmetic< order::little, T, n_bits, align::no > | ||
524 | 319 | : public endian_buffer< order::little, T, n_bits, align::no >, | ||
525 | 320 | cover_operators< endian_arithmetic< order::little, T, n_bits >, T > | ||
526 | 321 | { | ||
527 | 322 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | ||
528 | 323 | public: | ||
529 | 324 | typedef T value_type; | ||
530 | 325 | # ifndef BOOST_ENDIAN_NO_CTORS | ||
531 | 326 | endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT | ||
532 | 327 | BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT | ||
533 | 328 | { | ||
534 | 329 | # ifdef BOOST_ENDIAN_LOG | ||
535 | 330 | if ( endian_log ) | ||
536 | 331 | std::cout << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n"; | ||
537 | 332 | # endif | ||
538 | 333 | detail::store_little_endian<T, n_bits/8>(this->m_value, val); | ||
539 | 334 | } | ||
540 | 335 | # endif | ||
541 | 336 | endian_arithmetic& operator=(T val) BOOST_NOEXCEPT | ||
542 | 337 | { detail::store_little_endian<T, n_bits/8>(this->m_value, val); return *this; } | ||
543 | 338 | operator value_type() const BOOST_NOEXCEPT { return this->value(); } | ||
544 | 339 | }; | ||
545 | 340 | |||
546 | 341 | // align::yes specializations; only n_bits == 16/32/64 supported | ||
547 | 342 | |||
548 | 343 | // aligned big endian specialization | ||
549 | 344 | template <typename T, std::size_t n_bits> | ||
550 | 345 | class endian_arithmetic<order::big, T, n_bits, align::yes> | ||
551 | 346 | : public endian_buffer< order::big, T, n_bits, align::yes >, | ||
552 | 347 | cover_operators<endian_arithmetic<order::big, T, n_bits, align::yes>, T> | ||
553 | 348 | { | ||
554 | 349 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | ||
555 | 350 | BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); | ||
556 | 351 | public: | ||
557 | 352 | typedef T value_type; | ||
558 | 353 | # ifndef BOOST_ENDIAN_NO_CTORS | ||
559 | 354 | endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT | ||
560 | 355 | BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT | ||
561 | 356 | { | ||
562 | 357 | # ifdef BOOST_ENDIAN_LOG | ||
563 | 358 | if ( endian_log ) | ||
564 | 359 | std::cout << "big, aligned, " << n_bits << "-bits, construct(" << val << ")\n"; | ||
565 | 360 | # endif | ||
566 | 361 | this->m_value = ::boost::endian::native_to_big(val); | ||
567 | 362 | } | ||
568 | 363 | |||
569 | 364 | # endif | ||
570 | 365 | endian_arithmetic& operator=(T val) BOOST_NOEXCEPT | ||
571 | 366 | { | ||
572 | 367 | this->m_value = ::boost::endian::native_to_big(val); | ||
573 | 368 | return *this; | ||
574 | 369 | } | ||
575 | 370 | operator value_type() const BOOST_NOEXCEPT { return this->value(); } | ||
576 | 371 | }; | ||
577 | 372 | |||
578 | 373 | // aligned little endian specialization | ||
579 | 374 | template <typename T, std::size_t n_bits> | ||
580 | 375 | class endian_arithmetic<order::little, T, n_bits, align::yes> | ||
581 | 376 | : public endian_buffer< order::little, T, n_bits, align::yes >, | ||
582 | 377 | cover_operators<endian_arithmetic<order::little, T, n_bits, align::yes>, T> | ||
583 | 378 | { | ||
584 | 379 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | ||
585 | 380 | BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); | ||
586 | 381 | public: | ||
587 | 382 | typedef T value_type; | ||
588 | 383 | # ifndef BOOST_ENDIAN_NO_CTORS | ||
589 | 384 | endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT | ||
590 | 385 | BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT | ||
591 | 386 | { | ||
592 | 387 | # ifdef BOOST_ENDIAN_LOG | ||
593 | 388 | if ( endian_log ) | ||
594 | 389 | std::cout << "little, aligned, " << n_bits << "-bits, construct(" << val << ")\n"; | ||
595 | 390 | # endif | ||
596 | 391 | this->m_value = ::boost::endian::native_to_little(val); | ||
597 | 392 | } | ||
598 | 393 | # endif | ||
599 | 394 | endian_arithmetic& operator=(T val) BOOST_NOEXCEPT | ||
600 | 395 | { | ||
601 | 396 | this->m_value = ::boost::endian::native_to_little(val); | ||
602 | 397 | return *this; | ||
603 | 398 | } | ||
604 | 399 | operator value_type() const BOOST_NOEXCEPT { return this->value(); } | ||
605 | 400 | }; | ||
606 | 401 | |||
607 | 402 | } // namespace endian | ||
608 | 403 | } // namespace boost | ||
609 | 404 | |||
610 | 405 | #if defined(__BORLANDC__) || defined( __CODEGEARC__) | ||
611 | 406 | # pragma pack(pop) | ||
612 | 407 | #endif | ||
613 | 408 | |||
614 | 409 | #if defined(_MSC_VER) | ||
615 | 410 | # pragma warning(pop) | ||
616 | 411 | #endif | ||
617 | 412 | |||
618 | 413 | #endif // BOOST_ENDIAN_ARITHMETIC_HPP | ||
619 | 0 | 414 | ||
620 | === added file '3rd-party/boost/endian/buffers.hpp' | |||
621 | --- 3rd-party/boost/endian/buffers.hpp 1970-01-01 00:00:00 +0000 | |||
622 | +++ 3rd-party/boost/endian/buffers.hpp 2016-03-10 19:55:08 +0000 | |||
623 | @@ -0,0 +1,515 @@ | |||
624 | 1 | // boost/endian/buffers.hpp ----------------------------------------------------------// | ||
625 | 2 | |||
626 | 3 | // (C) Copyright Darin Adler 2000 | ||
627 | 4 | // (C) Copyright Beman Dawes 2006, 2009, 2014 | ||
628 | 5 | |||
629 | 6 | // Distributed under the Boost Software License, Version 1.0. | ||
630 | 7 | // See http://www.boost.org/LICENSE_1_0.txt | ||
631 | 8 | |||
632 | 9 | // See library home page at http://www.boost.org/libs/endian | ||
633 | 10 | |||
634 | 11 | //--------------------------------------------------------------------------------------// | ||
635 | 12 | |||
636 | 13 | // Original design developed by Darin Adler based on classes developed by Mark | ||
637 | 14 | // Borgerding. Four original class templates were combined into a single endian | ||
638 | 15 | // class template by Beman Dawes, who also added the unrolled_byte_loops sign | ||
639 | 16 | // partial specialization to correctly extend the sign when cover integer size | ||
640 | 17 | // differs from endian representation size. | ||
641 | 18 | |||
642 | 19 | // TODO: When a compiler supporting constexpr becomes available, try possible uses. | ||
643 | 20 | |||
644 | 21 | #ifndef BOOST_ENDIAN_BUFFERS_HPP | ||
645 | 22 | #define BOOST_ENDIAN_BUFFERS_HPP | ||
646 | 23 | |||
647 | 24 | #if defined(_MSC_VER) | ||
648 | 25 | # pragma warning(push) | ||
649 | 26 | # pragma warning(disable:4365) // conversion ... signed/unsigned mismatch | ||
650 | 27 | #endif | ||
651 | 28 | |||
652 | 29 | #ifdef BOOST_ENDIAN_LOG | ||
653 | 30 | # include <iostream> | ||
654 | 31 | #endif | ||
655 | 32 | |||
656 | 33 | #if defined(__BORLANDC__) || defined( __CODEGEARC__) | ||
657 | 34 | # pragma pack(push, 1) | ||
658 | 35 | #endif | ||
659 | 36 | |||
660 | 37 | #include <boost/config.hpp> | ||
661 | 38 | #include <boost/predef/detail/endian_compat.h> | ||
662 | 39 | #include <boost/endian/conversion.hpp> | ||
663 | 40 | #include <boost/type_traits/is_signed.hpp> | ||
664 | 41 | #include <boost/cstdint.hpp> | ||
665 | 42 | #include <boost/static_assert.hpp> | ||
666 | 43 | #include <boost/core/scoped_enum.hpp> | ||
667 | 44 | #include <iosfwd> | ||
668 | 45 | #include <climits> | ||
669 | 46 | |||
670 | 47 | # if CHAR_BIT != 8 | ||
671 | 48 | # error Platforms with CHAR_BIT != 8 are not supported | ||
672 | 49 | # endif | ||
673 | 50 | |||
674 | 51 | # ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS | ||
675 | 52 | # define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03 | ||
676 | 53 | # else | ||
677 | 54 | # define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x | ||
678 | 55 | # endif | ||
679 | 56 | |||
680 | 57 | # if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS) | ||
681 | 58 | # define BOOST_ENDIAN_NO_CTORS | ||
682 | 59 | # endif | ||
683 | 60 | |||
684 | 61 | //---------------------------------- synopsis ----------------------------------------// | ||
685 | 62 | |||
686 | 63 | namespace boost | ||
687 | 64 | { | ||
688 | 65 | namespace endian | ||
689 | 66 | { | ||
690 | 67 | |||
691 | 68 | BOOST_SCOPED_ENUM_START(align) | ||
692 | 69 | {no, yes | ||
693 | 70 | # ifdef BOOST_ENDIAN_DEPRECATED_NAMES | ||
694 | 71 | , unaligned = no, aligned = yes | ||
695 | 72 | # endif | ||
696 | 73 | }; BOOST_SCOPED_ENUM_END | ||
697 | 74 | |||
698 | 75 | template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits, | ||
699 | 76 | BOOST_SCOPED_ENUM(align) A = align::no> | ||
700 | 77 | class endian_buffer; | ||
701 | 78 | |||
702 | 79 | // aligned big endian signed integer buffers | ||
703 | 80 | typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at; | ||
704 | 81 | typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at; | ||
705 | 82 | typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at; | ||
706 | 83 | typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at; | ||
707 | 84 | |||
708 | 85 | // aligned big endian unsigned integer buffers | ||
709 | 86 | typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at; | ||
710 | 87 | typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at; | ||
711 | 88 | typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at; | ||
712 | 89 | typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at; | ||
713 | 90 | |||
714 | 91 | // aligned little endian signed integer buffers | ||
715 | 92 | typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at; | ||
716 | 93 | typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_at; | ||
717 | 94 | typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_at; | ||
718 | 95 | typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_at; | ||
719 | 96 | |||
720 | 97 | // aligned little endian unsigned integer buffers | ||
721 | 98 | typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_at; | ||
722 | 99 | typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at; | ||
723 | 100 | typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at; | ||
724 | 101 | typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at; | ||
725 | 102 | |||
726 | 103 | // aligned native endian typedefs are not provided because | ||
727 | 104 | // <cstdint> types are superior for this use case | ||
728 | 105 | |||
729 | 106 | // unaligned big endian signed integer buffers | ||
730 | 107 | typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t; | ||
731 | 108 | typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t; | ||
732 | 109 | typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t; | ||
733 | 110 | typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t; | ||
734 | 111 | typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t; | ||
735 | 112 | typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t; | ||
736 | 113 | typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t; | ||
737 | 114 | typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t; | ||
738 | 115 | |||
739 | 116 | // unaligned big endian unsigned integer buffers | ||
740 | 117 | typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t; | ||
741 | 118 | typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t; | ||
742 | 119 | typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t; | ||
743 | 120 | typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t; | ||
744 | 121 | typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t; | ||
745 | 122 | typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t; | ||
746 | 123 | typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t; | ||
747 | 124 | typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t; | ||
748 | 125 | |||
749 | 126 | // unaligned little endian signed integer buffers | ||
750 | 127 | typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t; | ||
751 | 128 | typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t; | ||
752 | 129 | typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t; | ||
753 | 130 | typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t; | ||
754 | 131 | typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t; | ||
755 | 132 | typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t; | ||
756 | 133 | typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t; | ||
757 | 134 | typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t; | ||
758 | 135 | |||
759 | 136 | // unaligned little endian unsigned integer buffers | ||
760 | 137 | typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t; | ||
761 | 138 | typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t; | ||
762 | 139 | typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t; | ||
763 | 140 | typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t; | ||
764 | 141 | typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t; | ||
765 | 142 | typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t; | ||
766 | 143 | typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t; | ||
767 | 144 | typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t; | ||
768 | 145 | |||
769 | 146 | # ifdef BOOST_BIG_ENDIAN | ||
770 | 147 | // unaligned native endian signed integer buffers | ||
771 | 148 | typedef big_int8_buf_t native_int8_buf_t; | ||
772 | 149 | typedef big_int16_buf_t native_int16_buf_t; | ||
773 | 150 | typedef big_int24_buf_t native_int24_buf_t; | ||
774 | 151 | typedef big_int32_buf_t native_int32_buf_t; | ||
775 | 152 | typedef big_int40_buf_t native_int40_buf_t; | ||
776 | 153 | typedef big_int48_buf_t native_int48_buf_t; | ||
777 | 154 | typedef big_int56_buf_t native_int56_buf_t; | ||
778 | 155 | typedef big_int64_buf_t native_int64_buf_t; | ||
779 | 156 | |||
780 | 157 | // unaligned native endian unsigned integer buffers | ||
781 | 158 | typedef big_uint8_buf_t native_uint8_buf_t; | ||
782 | 159 | typedef big_uint16_buf_t native_uint16_buf_t; | ||
783 | 160 | typedef big_uint24_buf_t native_uint24_buf_t; | ||
784 | 161 | typedef big_uint32_buf_t native_uint32_buf_t; | ||
785 | 162 | typedef big_uint40_buf_t native_uint40_buf_t; | ||
786 | 163 | typedef big_uint48_buf_t native_uint48_buf_t; | ||
787 | 164 | typedef big_uint56_buf_t native_uint56_buf_t; | ||
788 | 165 | typedef big_uint64_buf_t native_uint64_buf_t; | ||
789 | 166 | # else | ||
790 | 167 | // unaligned native endian signed integer buffers | ||
791 | 168 | typedef little_int8_buf_t native_int8_buf_t; | ||
792 | 169 | typedef little_int16_buf_t native_int16_buf_t; | ||
793 | 170 | typedef little_int24_buf_t native_int24_buf_t; | ||
794 | 171 | typedef little_int32_buf_t native_int32_buf_t; | ||
795 | 172 | typedef little_int40_buf_t native_int40_buf_t; | ||
796 | 173 | typedef little_int48_buf_t native_int48_buf_t; | ||
797 | 174 | typedef little_int56_buf_t native_int56_buf_t; | ||
798 | 175 | typedef little_int64_buf_t native_int64_buf_t; | ||
799 | 176 | |||
800 | 177 | // unaligned native endian unsigned integer buffers | ||
801 | 178 | typedef little_uint8_buf_t native_uint8_buf_t; | ||
802 | 179 | typedef little_uint16_buf_t native_uint16_buf_t; | ||
803 | 180 | typedef little_uint24_buf_t native_uint24_buf_t; | ||
804 | 181 | typedef little_uint32_buf_t native_uint32_buf_t; | ||
805 | 182 | typedef little_uint40_buf_t native_uint40_buf_t; | ||
806 | 183 | typedef little_uint48_buf_t native_uint48_buf_t; | ||
807 | 184 | typedef little_uint56_buf_t native_uint56_buf_t; | ||
808 | 185 | typedef little_uint64_buf_t native_uint64_buf_t; | ||
809 | 186 | # endif | ||
810 | 187 | |||
811 | 188 | // Stream inserter | ||
812 | 189 | template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T, | ||
813 | 190 | std::size_t n_bits, BOOST_SCOPED_ENUM(align) A> | ||
814 | 191 | std::basic_ostream<charT, traits>& | ||
815 | 192 | operator<<(std::basic_ostream<charT, traits>& os, | ||
816 | 193 | const endian_buffer<Order, T, n_bits, A>& x) | ||
817 | 194 | { | ||
818 | 195 | return os << x.value(); | ||
819 | 196 | } | ||
820 | 197 | |||
821 | 198 | // Stream extractor | ||
822 | 199 | template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T, | ||
823 | 200 | std::size_t n_bits, BOOST_SCOPED_ENUM(align) A> | ||
824 | 201 | std::basic_istream<charT, traits>& | ||
825 | 202 | operator>>(std::basic_istream<charT, traits>& is, | ||
826 | 203 | endian_buffer<Order, T, n_bits, A>& x) | ||
827 | 204 | { | ||
828 | 205 | T i; | ||
829 | 206 | if (is >> i) | ||
830 | 207 | x = i; | ||
831 | 208 | return is; | ||
832 | 209 | } | ||
833 | 210 | |||
834 | 211 | //---------------------------------- end synopsis ------------------------------------// | ||
835 | 212 | |||
836 | 213 | namespace detail | ||
837 | 214 | { | ||
838 | 215 | |||
839 | 216 | // Unrolled loops for loading and storing streams of bytes. | ||
840 | 217 | |||
841 | 218 | template <typename T, std::size_t n_bytes, | ||
842 | 219 | bool sign=boost::is_signed<T>::value > | ||
843 | 220 | struct unrolled_byte_loops | ||
844 | 221 | { | ||
845 | 222 | typedef unrolled_byte_loops<T, n_bytes - 1, sign> next; | ||
846 | 223 | |||
847 | 224 | static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT | ||
848 | 225 | { return static_cast<T>(*(bytes - 1) | (next::load_big(bytes - 1) << 8)); } | ||
849 | 226 | static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT | ||
850 | 227 | { return static_cast<T>(*bytes | (next::load_little(bytes + 1) << 8)); } | ||
851 | 228 | |||
852 | 229 | static void store_big(char* bytes, T value) BOOST_NOEXCEPT | ||
853 | 230 | { | ||
854 | 231 | *(bytes - 1) = static_cast<char>(value); | ||
855 | 232 | next::store_big(bytes - 1, static_cast<T>(value >> 8)); | ||
856 | 233 | } | ||
857 | 234 | static void store_little(char* bytes, T value) BOOST_NOEXCEPT | ||
858 | 235 | { | ||
859 | 236 | *bytes = static_cast<char>(value); | ||
860 | 237 | next::store_little(bytes + 1, static_cast<T>(value >> 8)); | ||
861 | 238 | } | ||
862 | 239 | }; | ||
863 | 240 | |||
864 | 241 | template <typename T> | ||
865 | 242 | struct unrolled_byte_loops<T, 1, false> | ||
866 | 243 | { | ||
867 | 244 | static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT | ||
868 | 245 | { return *(bytes - 1); } | ||
869 | 246 | static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT | ||
870 | 247 | { return *bytes; } | ||
871 | 248 | static void store_big(char* bytes, T value) BOOST_NOEXCEPT | ||
872 | 249 | { *(bytes - 1) = static_cast<char>(value); } | ||
873 | 250 | static void store_little(char* bytes, T value) BOOST_NOEXCEPT | ||
874 | 251 | { *bytes = static_cast<char>(value); } | ||
875 | 252 | |||
876 | 253 | }; | ||
877 | 254 | |||
878 | 255 | template <typename T> | ||
879 | 256 | struct unrolled_byte_loops<T, 1, true> | ||
880 | 257 | { | ||
881 | 258 | static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT | ||
882 | 259 | { return *reinterpret_cast<const signed char*>(bytes - 1); } | ||
883 | 260 | static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT | ||
884 | 261 | { return *reinterpret_cast<const signed char*>(bytes); } | ||
885 | 262 | static void store_big(char* bytes, T value) BOOST_NOEXCEPT | ||
886 | 263 | { *(bytes - 1) = static_cast<char>(value); } | ||
887 | 264 | static void store_little(char* bytes, T value) BOOST_NOEXCEPT | ||
888 | 265 | { *bytes = static_cast<char>(value); } | ||
889 | 266 | }; | ||
890 | 267 | |||
891 | 268 | template <typename T, std::size_t n_bytes> | ||
892 | 269 | inline | ||
893 | 270 | T load_big_endian(const void* bytes) BOOST_NOEXCEPT | ||
894 | 271 | { | ||
895 | 272 | return unrolled_byte_loops<T, n_bytes>::load_big | ||
896 | 273 | (static_cast<const unsigned char*>(bytes) + n_bytes); | ||
897 | 274 | } | ||
898 | 275 | |||
899 | 276 | template <typename T, std::size_t n_bytes> | ||
900 | 277 | inline | ||
901 | 278 | T load_little_endian(const void* bytes) BOOST_NOEXCEPT | ||
902 | 279 | { | ||
903 | 280 | # if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) | ||
904 | 281 | // On x86 (which is little endian), unaligned loads are permitted | ||
905 | 282 | if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this | ||
906 | 283 | // test and generate code only for the applicable return | ||
907 | 284 | // case since sizeof(T) and n_bytes are known at compile | ||
908 | 285 | // time. | ||
909 | 286 | { | ||
910 | 287 | return *reinterpret_cast<T const *>(bytes); | ||
911 | 288 | } | ||
912 | 289 | # endif | ||
913 | 290 | return unrolled_byte_loops<T, n_bytes>::load_little | ||
914 | 291 | (static_cast<const unsigned char*>(bytes)); | ||
915 | 292 | } | ||
916 | 293 | |||
917 | 294 | template <typename T, std::size_t n_bytes> | ||
918 | 295 | inline | ||
919 | 296 | void store_big_endian(void* bytes, T value) BOOST_NOEXCEPT | ||
920 | 297 | { | ||
921 | 298 | unrolled_byte_loops<T, n_bytes>::store_big | ||
922 | 299 | (static_cast<char*>(bytes) + n_bytes, value); | ||
923 | 300 | } | ||
924 | 301 | |||
925 | 302 | template <typename T, std::size_t n_bytes> | ||
926 | 303 | inline | ||
927 | 304 | void store_little_endian(void* bytes, T value) BOOST_NOEXCEPT | ||
928 | 305 | { | ||
929 | 306 | # if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) | ||
930 | 307 | // On x86 (which is little endian), unaligned stores are permitted | ||
931 | 308 | if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this | ||
932 | 309 | // test and generate code only for the applicable return | ||
933 | 310 | // case since sizeof(T) and n_bytes are known at compile | ||
934 | 311 | // time. | ||
935 | 312 | { | ||
936 | 313 | *reinterpret_cast<T *>(bytes) = value; | ||
937 | 314 | return; | ||
938 | 315 | } | ||
939 | 316 | # endif | ||
940 | 317 | unrolled_byte_loops<T, n_bytes>::store_little | ||
941 | 318 | (static_cast<char*>(bytes), value); | ||
942 | 319 | } | ||
943 | 320 | |||
944 | 321 | } // namespace detail | ||
945 | 322 | |||
946 | 323 | # ifdef BOOST_ENDIAN_LOG | ||
947 | 324 | bool endian_log(true); | ||
948 | 325 | # endif | ||
949 | 326 | |||
950 | 327 | // endian_buffer class template specializations --------------------------------------// | ||
951 | 328 | |||
952 | 329 | // Specializations that represent unaligned bytes. | ||
953 | 330 | // Taking an integer type as a parameter provides a nice way to pass both | ||
954 | 331 | // the size and signedness of the desired integer and get the appropriate | ||
955 | 332 | // corresponding integer type for the interface. | ||
956 | 333 | |||
957 | 334 | // Q: Should endian_buffer supply "value_type operator value_type() const noexcept"? | ||
958 | 335 | // A: No. The rationale for endian_buffers is to prevent high-cost hidden | ||
959 | 336 | // conversions. If an implicit conversion operator is supplied, hidden conversions | ||
960 | 337 | // can occur. | ||
961 | 338 | |||
962 | 339 | // unaligned big endian_buffer specialization | ||
963 | 340 | template <typename T, std::size_t n_bits> | ||
964 | 341 | class endian_buffer< order::big, T, n_bits, align::no > | ||
965 | 342 | { | ||
966 | 343 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | ||
967 | 344 | public: | ||
968 | 345 | typedef T value_type; | ||
969 | 346 | # ifndef BOOST_ENDIAN_NO_CTORS | ||
970 | 347 | endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT | ||
971 | 348 | explicit endian_buffer(T val) BOOST_NOEXCEPT | ||
972 | 349 | { | ||
973 | 350 | # ifdef BOOST_ENDIAN_LOG | ||
974 | 351 | if ( endian_log ) | ||
975 | 352 | std::cout << "big, unaligned, " | ||
976 | 353 | << n_bits << "-bits, construct(" << val << ")\n"; | ||
977 | 354 | # endif | ||
978 | 355 | detail::store_big_endian<T, n_bits/8>(m_value, val); | ||
979 | 356 | } | ||
980 | 357 | # endif | ||
981 | 358 | endian_buffer & operator=(T val) BOOST_NOEXCEPT | ||
982 | 359 | { | ||
983 | 360 | # ifdef BOOST_ENDIAN_LOG | ||
984 | 361 | if (endian_log) | ||
985 | 362 | std::cout << "big, unaligned, " << n_bits << "-bits, assign(" << val << ")\n"; | ||
986 | 363 | # endif | ||
987 | 364 | detail::store_big_endian<T, n_bits/8>(m_value, val); | ||
988 | 365 | return *this; | ||
989 | 366 | } | ||
990 | 367 | value_type value() const BOOST_NOEXCEPT | ||
991 | 368 | { | ||
992 | 369 | # ifdef BOOST_ENDIAN_LOG | ||
993 | 370 | if ( endian_log ) | ||
994 | 371 | std::cout << "big, unaligned, " << n_bits << "-bits, convert(" | ||
995 | 372 | << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n"; | ||
996 | 373 | # endif | ||
997 | 374 | return detail::load_big_endian<T, n_bits/8>(m_value); | ||
998 | 375 | } | ||
999 | 376 | const char* data() const BOOST_NOEXCEPT { return m_value; } | ||
1000 | 377 | protected: | ||
1001 | 378 | char m_value[n_bits/8]; | ||
1002 | 379 | }; | ||
1003 | 380 | |||
1004 | 381 | // unaligned little endian_buffer specialization | ||
1005 | 382 | template <typename T, std::size_t n_bits> | ||
1006 | 383 | class endian_buffer< order::little, T, n_bits, align::no > | ||
1007 | 384 | { | ||
1008 | 385 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | ||
1009 | 386 | public: | ||
1010 | 387 | typedef T value_type; | ||
1011 | 388 | # ifndef BOOST_ENDIAN_NO_CTORS | ||
1012 | 389 | endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT | ||
1013 | 390 | explicit endian_buffer(T val) BOOST_NOEXCEPT | ||
1014 | 391 | { | ||
1015 | 392 | # ifdef BOOST_ENDIAN_LOG | ||
1016 | 393 | if ( endian_log ) | ||
1017 | 394 | std::cout << "little, unaligned, " << n_bits << "-bits, construct(" | ||
1018 | 395 | << val << ")\n"; | ||
1019 | 396 | # endif | ||
1020 | 397 | detail::store_little_endian<T, n_bits/8>(m_value, val); | ||
1021 | 398 | } | ||
1022 | 399 | # endif | ||
1023 | 400 | endian_buffer & operator=(T val) BOOST_NOEXCEPT | ||
1024 | 401 | { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; } | ||
1025 | 402 | value_type value() const BOOST_NOEXCEPT | ||
1026 | 403 | { | ||
1027 | 404 | # ifdef BOOST_ENDIAN_LOG | ||
1028 | 405 | if ( endian_log ) | ||
1029 | 406 | std::cout << "little, unaligned, " << n_bits << "-bits, convert(" | ||
1030 | 407 | << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n"; | ||
1031 | 408 | # endif | ||
1032 | 409 | return detail::load_little_endian<T, n_bits/8>(m_value); | ||
1033 | 410 | } | ||
1034 | 411 | const char* data() const BOOST_NOEXCEPT { return m_value; } | ||
1035 | 412 | protected: | ||
1036 | 413 | char m_value[n_bits/8]; | ||
1037 | 414 | }; | ||
1038 | 415 | |||
1039 | 416 | // align::yes specializations; only n_bits == 16/32/64 supported | ||
1040 | 417 | |||
1041 | 418 | // aligned big endian_buffer specialization | ||
1042 | 419 | template <typename T, std::size_t n_bits> | ||
1043 | 420 | class endian_buffer<order::big, T, n_bits, align::yes> | ||
1044 | 421 | { | ||
1045 | 422 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | ||
1046 | 423 | BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); | ||
1047 | 424 | public: | ||
1048 | 425 | typedef T value_type; | ||
1049 | 426 | # ifndef BOOST_ENDIAN_NO_CTORS | ||
1050 | 427 | endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT | ||
1051 | 428 | explicit endian_buffer(T val) BOOST_NOEXCEPT | ||
1052 | 429 | { | ||
1053 | 430 | # ifdef BOOST_ENDIAN_LOG | ||
1054 | 431 | if ( endian_log ) | ||
1055 | 432 | std::cout << "big, aligned, " << n_bits | ||
1056 | 433 | << "-bits, construct(" << val << ")\n"; | ||
1057 | 434 | # endif | ||
1058 | 435 | m_value = ::boost::endian::native_to_big(val); | ||
1059 | 436 | } | ||
1060 | 437 | |||
1061 | 438 | # endif | ||
1062 | 439 | endian_buffer& operator=(T val) BOOST_NOEXCEPT | ||
1063 | 440 | { | ||
1064 | 441 | m_value = ::boost::endian::native_to_big(val); | ||
1065 | 442 | return *this; | ||
1066 | 443 | } | ||
1067 | 444 | //operator value_type() const BOOST_NOEXCEPT | ||
1068 | 445 | //{ | ||
1069 | 446 | // return ::boost::endian::big_to_native(m_value); | ||
1070 | 447 | //} | ||
1071 | 448 | value_type value() const BOOST_NOEXCEPT | ||
1072 | 449 | { | ||
1073 | 450 | # ifdef BOOST_ENDIAN_LOG | ||
1074 | 451 | if ( endian_log ) | ||
1075 | 452 | std::cout << "big, aligned, " << n_bits << "-bits, convert(" | ||
1076 | 453 | << ::boost::endian::big_to_native(m_value) << ")\n"; | ||
1077 | 454 | # endif | ||
1078 | 455 | return ::boost::endian::big_to_native(m_value); | ||
1079 | 456 | } | ||
1080 | 457 | const char* data() const BOOST_NOEXCEPT | ||
1081 | 458 | {return reinterpret_cast<const char*>(&m_value);} | ||
1082 | 459 | protected: | ||
1083 | 460 | T m_value; | ||
1084 | 461 | }; | ||
1085 | 462 | |||
1086 | 463 | // aligned little endian_buffer specialization | ||
1087 | 464 | template <typename T, std::size_t n_bits> | ||
1088 | 465 | class endian_buffer<order::little, T, n_bits, align::yes> | ||
1089 | 466 | { | ||
1090 | 467 | BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); | ||
1091 | 468 | BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); | ||
1092 | 469 | public: | ||
1093 | 470 | typedef T value_type; | ||
1094 | 471 | # ifndef BOOST_ENDIAN_NO_CTORS | ||
1095 | 472 | endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT | ||
1096 | 473 | explicit endian_buffer(T val) BOOST_NOEXCEPT | ||
1097 | 474 | { | ||
1098 | 475 | # ifdef BOOST_ENDIAN_LOG | ||
1099 | 476 | if ( endian_log ) | ||
1100 | 477 | std::cout << "little, aligned, " << n_bits | ||
1101 | 478 | << "-bits, construct(" << val << ")\n"; | ||
1102 | 479 | # endif | ||
1103 | 480 | m_value = ::boost::endian::native_to_little(val); | ||
1104 | 481 | } | ||
1105 | 482 | |||
1106 | 483 | # endif | ||
1107 | 484 | endian_buffer& operator=(T val) BOOST_NOEXCEPT | ||
1108 | 485 | { | ||
1109 | 486 | m_value = ::boost::endian::native_to_little(val); | ||
1110 | 487 | return *this; | ||
1111 | 488 | } | ||
1112 | 489 | value_type value() const BOOST_NOEXCEPT | ||
1113 | 490 | { | ||
1114 | 491 | # ifdef BOOST_ENDIAN_LOG | ||
1115 | 492 | if ( endian_log ) | ||
1116 | 493 | std::cout << "little, aligned, " << n_bits << "-bits, convert(" | ||
1117 | 494 | << ::boost::endian::little_to_native(m_value) << ")\n"; | ||
1118 | 495 | # endif | ||
1119 | 496 | return ::boost::endian::little_to_native(m_value); | ||
1120 | 497 | } | ||
1121 | 498 | const char* data() const BOOST_NOEXCEPT | ||
1122 | 499 | {return reinterpret_cast<const char*>(&m_value);} | ||
1123 | 500 | protected: | ||
1124 | 501 | T m_value; | ||
1125 | 502 | }; | ||
1126 | 503 | |||
1127 | 504 | } // namespace endian | ||
1128 | 505 | } // namespace boost | ||
1129 | 506 | |||
1130 | 507 | #if defined(__BORLANDC__) || defined( __CODEGEARC__) | ||
1131 | 508 | # pragma pack(pop) | ||
1132 | 509 | #endif | ||
1133 | 510 | |||
1134 | 511 | #if defined(_MSC_VER) | ||
1135 | 512 | # pragma warning(pop) | ||
1136 | 513 | #endif | ||
1137 | 514 | |||
1138 | 515 | #endif // BOOST_ENDIAN_BUFFERS_HPP | ||
1139 | 0 | 516 | ||
1140 | === added file '3rd-party/boost/endian/conversion.hpp' | |||
1141 | --- 3rd-party/boost/endian/conversion.hpp 1970-01-01 00:00:00 +0000 | |||
1142 | +++ 3rd-party/boost/endian/conversion.hpp 2016-03-10 19:55:08 +0000 | |||
1143 | @@ -0,0 +1,487 @@ | |||
1144 | 1 | // boost/endian/conversion.hpp -------------------------------------------------------// | ||
1145 | 2 | |||
1146 | 3 | // Copyright Beman Dawes 2010, 2011, 2014 | ||
1147 | 4 | |||
1148 | 5 | // Distributed under the Boost Software License, Version 1.0. | ||
1149 | 6 | // http://www.boost.org/LICENSE_1_0.txt | ||
1150 | 7 | |||
1151 | 8 | #ifndef BOOST_ENDIAN_CONVERSION_HPP | ||
1152 | 9 | #define BOOST_ENDIAN_CONVERSION_HPP | ||
1153 | 10 | |||
1154 | 11 | #include <boost/config.hpp> | ||
1155 | 12 | #include <boost/predef/detail/endian_compat.h> | ||
1156 | 13 | #include <boost/cstdint.hpp> | ||
1157 | 14 | #include <boost/endian/detail/intrinsic.hpp> | ||
1158 | 15 | #include <boost/core/scoped_enum.hpp> | ||
1159 | 16 | #include <boost/static_assert.hpp> | ||
1160 | 17 | #include <algorithm> | ||
1161 | 18 | #include <cstring> // for memcpy | ||
1162 | 19 | |||
1163 | 20 | //------------------------------------- synopsis ---------------------------------------// | ||
1164 | 21 | |||
1165 | 22 | namespace boost | ||
1166 | 23 | { | ||
1167 | 24 | namespace endian | ||
1168 | 25 | { | ||
1169 | 26 | #ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED | ||
1170 | 27 | BOOST_SCOPED_ENUM_START(order) | ||
1171 | 28 | { | ||
1172 | 29 | big, little, | ||
1173 | 30 | # ifdef BOOST_BIG_ENDIAN | ||
1174 | 31 | native = big | ||
1175 | 32 | # else | ||
1176 | 33 | native = little | ||
1177 | 34 | # endif | ||
1178 | 35 | }; BOOST_SCOPED_ENUM_END | ||
1179 | 36 | # define BOOST_ENDIAN_ORDER_ENUM_DEFINED | ||
1180 | 37 | #endif | ||
1181 | 38 | |||
1182 | 39 | //--------------------------------------------------------------------------------------// | ||
1183 | 40 | // // | ||
1184 | 41 | // return-by-value interfaces // | ||
1185 | 42 | // suggested by Phil Endecott // | ||
1186 | 43 | // // | ||
1187 | 44 | // user-defined types (UDTs) // | ||
1188 | 45 | // // | ||
1189 | 46 | // All return-by-value conversion function templates are required to be implemented in // | ||
1190 | 47 | // terms of an unqualified call to "endian_reverse(x)", a function returning the // | ||
1191 | 48 | // value of x with endianness reversed. This provides a customization point for any // | ||
1192 | 49 | // UDT that provides a "endian_reverse" free-function meeting the requirements. // | ||
1193 | 50 | // It must be defined in the same namespace as the UDT itself so that it will be found // | ||
1194 | 51 | // by argument dependent lookup (ADL). // | ||
1195 | 52 | // // | ||
1196 | 53 | //--------------------------------------------------------------------------------------// | ||
1197 | 54 | |||
1198 | 55 | // customization for exact-length arithmetic types. See doc/conversion.html/#FAQ | ||
1199 | 56 | inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT; | ||
1200 | 57 | inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT; | ||
1201 | 58 | inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT; | ||
1202 | 59 | inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT; | ||
1203 | 60 | inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT; | ||
1204 | 61 | inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT; | ||
1205 | 62 | inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT; | ||
1206 | 63 | inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT; | ||
1207 | 64 | |||
1208 | 65 | // reverse byte order unless native endianness is big | ||
1209 | 66 | template <class EndianReversible > | ||
1210 | 67 | inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT; | ||
1211 | 68 | // Returns: x if native endian order is big, otherwise endian_reverse(x) | ||
1212 | 69 | template <class EndianReversible > | ||
1213 | 70 | inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT; | ||
1214 | 71 | // Returns: x if native endian order is big, otherwise endian_reverse(x) | ||
1215 | 72 | |||
1216 | 73 | // reverse byte order unless native endianness is little | ||
1217 | 74 | template <class EndianReversible > | ||
1218 | 75 | inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT; | ||
1219 | 76 | // Returns: x if native endian order is little, otherwise endian_reverse(x) | ||
1220 | 77 | template <class EndianReversible > | ||
1221 | 78 | inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT; | ||
1222 | 79 | // Returns: x if native endian order is little, otherwise endian_reverse(x) | ||
1223 | 80 | |||
1224 | 81 | // generic conditional reverse byte order | ||
1225 | 82 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | ||
1226 | 83 | class EndianReversible> | ||
1227 | 84 | inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT; | ||
1228 | 85 | // Returns: If From == To have different values, from. | ||
1229 | 86 | // Otherwise endian_reverse(from). | ||
1230 | 87 | // Remarks: The From == To test, and as a consequence which form the return takes, is | ||
1231 | 88 | // is determined at compile time. | ||
1232 | 89 | |||
1233 | 90 | // runtime conditional reverse byte order | ||
1234 | 91 | template <class EndianReversible > | ||
1235 | 92 | inline EndianReversible conditional_reverse(EndianReversible from, | ||
1236 | 93 | BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) | ||
1237 | 94 | BOOST_NOEXCEPT; | ||
1238 | 95 | // Returns: from_order == to_order ? from : endian_reverse(from). | ||
1239 | 96 | |||
1240 | 97 | //------------------------------------------------------------------------------------// | ||
1241 | 98 | |||
1242 | 99 | |||
1243 | 100 | // Q: What happended to bswap, htobe, and the other synonym functions based on names | ||
1244 | 101 | // popularized by BSD, OS X, and Linux? | ||
1245 | 102 | // A: Turned out these may be implemented as macros on some systems. Ditto POSIX names | ||
1246 | 103 | // for such functionality. Since macros would cause endless problems with functions | ||
1247 | 104 | // of the same names, and these functions are just synonyms anyhow, they have been | ||
1248 | 105 | // removed. | ||
1249 | 106 | |||
1250 | 107 | |||
1251 | 108 | //------------------------------------------------------------------------------------// | ||
1252 | 109 | // // | ||
1253 | 110 | // reverse in place interfaces // | ||
1254 | 111 | // // | ||
1255 | 112 | // user-defined types (UDTs) // | ||
1256 | 113 | // // | ||
1257 | 114 | // All reverse in place function templates are required to be implemented in terms // | ||
1258 | 115 | // of an unqualified call to "endian_reverse_inplace(x)", a function reversing // | ||
1259 | 116 | // the endianness of x, which is a non-const reference. This provides a // | ||
1260 | 117 | // customization point for any UDT that provides a "reverse_inplace" free-function // | ||
1261 | 118 | // meeting the requirements. The free-function must be declared in the same // | ||
1262 | 119 | // namespace as the UDT itself so that it will be found by argument-dependent // | ||
1263 | 120 | // lookup (ADL). // | ||
1264 | 121 | // // | ||
1265 | 122 | //------------------------------------------------------------------------------------// | ||
1266 | 123 | |||
1267 | 124 | // reverse in place | ||
1268 | 125 | template <class EndianReversible> | ||
1269 | 126 | inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT; | ||
1270 | 127 | // Effects: x = endian_reverse(x) | ||
1271 | 128 | |||
1272 | 129 | // reverse in place unless native endianness is big | ||
1273 | 130 | template <class EndianReversibleInplace> | ||
1274 | 131 | inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | ||
1275 | 132 | // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x) | ||
1276 | 133 | template <class EndianReversibleInplace> | ||
1277 | 134 | inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | ||
1278 | 135 | // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x) | ||
1279 | 136 | |||
1280 | 137 | // reverse in place unless native endianness is little | ||
1281 | 138 | template <class EndianReversibleInplace> | ||
1282 | 139 | inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | ||
1283 | 140 | // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x); | ||
1284 | 141 | template <class EndianReversibleInplace> | ||
1285 | 142 | inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | ||
1286 | 143 | // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x); | ||
1287 | 144 | |||
1288 | 145 | // generic conditional reverse in place | ||
1289 | 146 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | ||
1290 | 147 | class EndianReversibleInplace> | ||
1291 | 148 | inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; | ||
1292 | 149 | |||
1293 | 150 | // runtime reverse in place | ||
1294 | 151 | template <class EndianReversibleInplace> | ||
1295 | 152 | inline void conditional_reverse_inplace(EndianReversibleInplace& x, | ||
1296 | 153 | BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) | ||
1297 | 154 | BOOST_NOEXCEPT; | ||
1298 | 155 | |||
1299 | 156 | //----------------------------------- end synopsis -------------------------------------// | ||
1300 | 157 | |||
1301 | 158 | namespace detail | ||
1302 | 159 | { | ||
1303 | 160 | // generic reverse function template implementation approach using std::reverse | ||
1304 | 161 | // suggested by Mathias Gaunard. Primary motivation for inclusion is to have an | ||
1305 | 162 | // independent implementation to test against. | ||
1306 | 163 | |||
1307 | 164 | template <class T> | ||
1308 | 165 | inline T std_endian_reverse(T x) BOOST_NOEXCEPT | ||
1309 | 166 | { | ||
1310 | 167 | T tmp(x); | ||
1311 | 168 | std::reverse( | ||
1312 | 169 | reinterpret_cast<unsigned char*>(&tmp), | ||
1313 | 170 | reinterpret_cast<unsigned char*>(&tmp) + sizeof(T)); | ||
1314 | 171 | return tmp; | ||
1315 | 172 | } | ||
1316 | 173 | |||
1317 | 174 | // conditional unaligned reverse copy, patterned after std::reverse_copy | ||
1318 | 175 | template <class T> | ||
1319 | 176 | inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT; | ||
1320 | 177 | template <class T> | ||
1321 | 178 | inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT; | ||
1322 | 179 | template <class T> | ||
1323 | 180 | inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT; | ||
1324 | 181 | template <class T> | ||
1325 | 182 | inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT; | ||
1326 | 183 | } // namespace detail | ||
1327 | 184 | |||
1328 | 185 | //--------------------------------------------------------------------------------------// | ||
1329 | 186 | // // | ||
1330 | 187 | // return-by-value implementation // | ||
1331 | 188 | // // | ||
1332 | 189 | // -- portable approach suggested by tymofey, with avoidance of undefined behavior // | ||
1333 | 190 | // as suggested by Giovanni Piero Deretta, with a further refinement suggested // | ||
1334 | 191 | // by Pyry Jahkola. // | ||
1335 | 192 | // -- intrinsic approach suggested by reviewers, and by David Stone, who provided // | ||
1336 | 193 | // his Boost licensed macro implementation (detail/intrinsic.hpp) // | ||
1337 | 194 | // // | ||
1338 | 195 | //--------------------------------------------------------------------------------------// | ||
1339 | 196 | |||
1340 | 197 | inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT | ||
1341 | 198 | { | ||
1342 | 199 | return x; | ||
1343 | 200 | } | ||
1344 | 201 | |||
1345 | 202 | inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT | ||
1346 | 203 | { | ||
1347 | 204 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | ||
1348 | 205 | return (static_cast<uint16_t>(x) << 8) | ||
1349 | 206 | | (static_cast<uint16_t>(x) >> 8); | ||
1350 | 207 | # else | ||
1351 | 208 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(static_cast<uint16_t>(x)); | ||
1352 | 209 | # endif | ||
1353 | 210 | } | ||
1354 | 211 | |||
1355 | 212 | inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT | ||
1356 | 213 | { | ||
1357 | 214 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | ||
1358 | 215 | uint32_t step16; | ||
1359 | 216 | step16 = static_cast<uint32_t>(x) << 16 | static_cast<uint32_t>(x) >> 16; | ||
1360 | 217 | return | ||
1361 | 218 | ((static_cast<uint32_t>(step16) << 8) & 0xff00ff00) | ||
1362 | 219 | | ((static_cast<uint32_t>(step16) >> 8) & 0x00ff00ff); | ||
1363 | 220 | # else | ||
1364 | 221 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(static_cast<uint32_t>(x)); | ||
1365 | 222 | # endif | ||
1366 | 223 | } | ||
1367 | 224 | |||
1368 | 225 | inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT | ||
1369 | 226 | { | ||
1370 | 227 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | ||
1371 | 228 | uint64_t step32, step16; | ||
1372 | 229 | step32 = static_cast<uint64_t>(x) << 32 | static_cast<uint64_t>(x) >> 32; | ||
1373 | 230 | step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | ||
1374 | 231 | | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; | ||
1375 | 232 | return static_cast<int64_t>((step16 & 0x00FF00FF00FF00FFULL) << 8 | ||
1376 | 233 | | (step16 & 0xFF00FF00FF00FF00ULL) >> 8); | ||
1377 | 234 | # else | ||
1378 | 235 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(static_cast<uint64_t>(x)); | ||
1379 | 236 | # endif | ||
1380 | 237 | } | ||
1381 | 238 | |||
1382 | 239 | inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT | ||
1383 | 240 | { | ||
1384 | 241 | return x; | ||
1385 | 242 | } | ||
1386 | 243 | |||
1387 | 244 | inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT | ||
1388 | 245 | { | ||
1389 | 246 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | ||
1390 | 247 | return (x << 8) | ||
1391 | 248 | | (x >> 8); | ||
1392 | 249 | # else | ||
1393 | 250 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x); | ||
1394 | 251 | # endif | ||
1395 | 252 | } | ||
1396 | 253 | |||
1397 | 254 | inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT | ||
1398 | 255 | { | ||
1399 | 256 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | ||
1400 | 257 | uint32_t step16; | ||
1401 | 258 | step16 = x << 16 | x >> 16; | ||
1402 | 259 | return | ||
1403 | 260 | ((step16 << 8) & 0xff00ff00) | ||
1404 | 261 | | ((step16 >> 8) & 0x00ff00ff); | ||
1405 | 262 | # else | ||
1406 | 263 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x); | ||
1407 | 264 | # endif | ||
1408 | 265 | } | ||
1409 | 266 | |||
1410 | 267 | inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT | ||
1411 | 268 | { | ||
1412 | 269 | # ifdef BOOST_ENDIAN_NO_INTRINSICS | ||
1413 | 270 | uint64_t step32, step16; | ||
1414 | 271 | step32 = x << 32 | x >> 32; | ||
1415 | 272 | step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | ||
1416 | 273 | | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; | ||
1417 | 274 | return (step16 & 0x00FF00FF00FF00FFULL) << 8 | ||
1418 | 275 | | (step16 & 0xFF00FF00FF00FF00ULL) >> 8; | ||
1419 | 276 | # else | ||
1420 | 277 | return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x); | ||
1421 | 278 | # endif | ||
1422 | 279 | } | ||
1423 | 280 | |||
1424 | 281 | template <class EndianReversible > | ||
1425 | 282 | inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT | ||
1426 | 283 | { | ||
1427 | 284 | # ifdef BOOST_BIG_ENDIAN | ||
1428 | 285 | return x; | ||
1429 | 286 | # else | ||
1430 | 287 | return endian_reverse(x); | ||
1431 | 288 | # endif | ||
1432 | 289 | } | ||
1433 | 290 | |||
1434 | 291 | template <class EndianReversible > | ||
1435 | 292 | inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT | ||
1436 | 293 | { | ||
1437 | 294 | # ifdef BOOST_BIG_ENDIAN | ||
1438 | 295 | return x; | ||
1439 | 296 | # else | ||
1440 | 297 | return endian_reverse(x); | ||
1441 | 298 | # endif | ||
1442 | 299 | } | ||
1443 | 300 | |||
1444 | 301 | template <class EndianReversible > | ||
1445 | 302 | inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT | ||
1446 | 303 | { | ||
1447 | 304 | # ifdef BOOST_LITTLE_ENDIAN | ||
1448 | 305 | return x; | ||
1449 | 306 | # else | ||
1450 | 307 | return endian_reverse(x); | ||
1451 | 308 | # endif | ||
1452 | 309 | } | ||
1453 | 310 | |||
1454 | 311 | template <class EndianReversible > | ||
1455 | 312 | inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT | ||
1456 | 313 | { | ||
1457 | 314 | # ifdef BOOST_LITTLE_ENDIAN | ||
1458 | 315 | return x; | ||
1459 | 316 | # else | ||
1460 | 317 | return endian_reverse(x); | ||
1461 | 318 | # endif | ||
1462 | 319 | } | ||
1463 | 320 | |||
1464 | 321 | namespace detail | ||
1465 | 322 | { | ||
1466 | 323 | // Primary template and specializations to support endian_reverse(). | ||
1467 | 324 | // See rationale in endian_reverse() below. | ||
1468 | 325 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | ||
1469 | 326 | class EndianReversible> | ||
1470 | 327 | class value_converter ; // primary template | ||
1471 | 328 | template <class T> class value_converter <order::big, order::big, T> | ||
1472 | 329 | {public: T operator()(T x) BOOST_NOEXCEPT {return x;}}; | ||
1473 | 330 | template <class T> class value_converter <order::little, order::little, T> | ||
1474 | 331 | {public: T operator()(T x) BOOST_NOEXCEPT {return x;}}; | ||
1475 | 332 | template <class T> class value_converter <order::big, order::little, T> | ||
1476 | 333 | {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}}; | ||
1477 | 334 | template <class T> class value_converter <order::little, order::big, T> | ||
1478 | 335 | {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}}; | ||
1479 | 336 | } | ||
1480 | 337 | |||
1481 | 338 | // generic conditional reverse | ||
1482 | 339 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | ||
1483 | 340 | class EndianReversible> | ||
1484 | 341 | inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT { | ||
1485 | 342 | // work around lack of function template partial specialization by instantiating | ||
1486 | 343 | // a function object of a class that is partially specialized on the two order | ||
1487 | 344 | // template parameters, and then calling its operator(). | ||
1488 | 345 | detail::value_converter <From, To, EndianReversible> tmp; | ||
1489 | 346 | return tmp(from); | ||
1490 | 347 | } | ||
1491 | 348 | |||
1492 | 349 | // runtime conditional reverse | ||
1493 | 350 | template <class EndianReversible > | ||
1494 | 351 | inline EndianReversible conditional_reverse(EndianReversible from, | ||
1495 | 352 | BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT | ||
1496 | 353 | { | ||
1497 | 354 | return from_order == to_order ? from : endian_reverse(from); | ||
1498 | 355 | } | ||
1499 | 356 | |||
1500 | 357 | //--------------------------------------------------------------------------------------// | ||
1501 | 358 | // reverse-in-place implementation // | ||
1502 | 359 | //--------------------------------------------------------------------------------------// | ||
1503 | 360 | |||
1504 | 361 | // reverse in place | ||
1505 | 362 | template <class EndianReversible> | ||
1506 | 363 | inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT | ||
1507 | 364 | { | ||
1508 | 365 | x = endian_reverse(x); | ||
1509 | 366 | } | ||
1510 | 367 | |||
1511 | 368 | template <class EndianReversibleInplace> | ||
1512 | 369 | # ifdef BOOST_BIG_ENDIAN | ||
1513 | 370 | inline void big_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} | ||
1514 | 371 | # else | ||
1515 | 372 | inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | ||
1516 | 373 | { endian_reverse_inplace(x); } | ||
1517 | 374 | # endif | ||
1518 | 375 | template <class EndianReversibleInplace> | ||
1519 | 376 | # ifdef BOOST_BIG_ENDIAN | ||
1520 | 377 | inline void native_to_big_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} | ||
1521 | 378 | # else | ||
1522 | 379 | inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | ||
1523 | 380 | { | ||
1524 | 381 | endian_reverse_inplace(x); | ||
1525 | 382 | } | ||
1526 | 383 | # endif | ||
1527 | 384 | |||
1528 | 385 | template <class EndianReversibleInplace> | ||
1529 | 386 | # ifdef BOOST_LITTLE_ENDIAN | ||
1530 | 387 | inline void little_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} | ||
1531 | 388 | # else | ||
1532 | 389 | inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | ||
1533 | 390 | { endian_reverse_inplace(x); } | ||
1534 | 391 | # endif | ||
1535 | 392 | template <class EndianReversibleInplace> | ||
1536 | 393 | # ifdef BOOST_LITTLE_ENDIAN | ||
1537 | 394 | inline void native_to_little_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} | ||
1538 | 395 | # else | ||
1539 | 396 | inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | ||
1540 | 397 | { | ||
1541 | 398 | endian_reverse_inplace(x); | ||
1542 | 399 | } | ||
1543 | 400 | # endif | ||
1544 | 401 | |||
1545 | 402 | namespace detail | ||
1546 | 403 | { | ||
1547 | 404 | // Primary template and specializations support generic | ||
1548 | 405 | // endian_reverse_inplace(). | ||
1549 | 406 | // See rationale in endian_reverse_inplace() below. | ||
1550 | 407 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | ||
1551 | 408 | class EndianReversibleInplace> | ||
1552 | 409 | class converter; // primary template | ||
1553 | 410 | template <class T> class converter<order::big, order::big, T> | ||
1554 | 411 | {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}}; | ||
1555 | 412 | template <class T> class converter<order::little, order::little, T> | ||
1556 | 413 | {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}}; | ||
1557 | 414 | template <class T> class converter<order::big, order::little, T> | ||
1558 | 415 | {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }}; | ||
1559 | 416 | template <class T> class converter<order::little, order::big, T> | ||
1560 | 417 | {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }}; | ||
1561 | 418 | } // namespace detail | ||
1562 | 419 | |||
1563 | 420 | // generic conditional reverse in place | ||
1564 | 421 | template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, | ||
1565 | 422 | class EndianReversibleInplace> | ||
1566 | 423 | inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT | ||
1567 | 424 | { | ||
1568 | 425 | // work around lack of function template partial specialization by instantiating | ||
1569 | 426 | // a function object of a class that is partially specialized on the two order | ||
1570 | 427 | // template parameters, and then calling its operator(). | ||
1571 | 428 | detail::converter<From, To, EndianReversibleInplace> tmp; | ||
1572 | 429 | tmp(x); // call operator () | ||
1573 | 430 | } | ||
1574 | 431 | |||
1575 | 432 | // runtime reverse in place | ||
1576 | 433 | template <class EndianReversibleInplace> | ||
1577 | 434 | inline void conditional_reverse_inplace(EndianReversibleInplace& x, | ||
1578 | 435 | BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) | ||
1579 | 436 | BOOST_NOEXCEPT | ||
1580 | 437 | { | ||
1581 | 438 | if (from_order != to_order) | ||
1582 | 439 | endian_reverse_inplace(x); | ||
1583 | 440 | } | ||
1584 | 441 | |||
1585 | 442 | |||
1586 | 443 | namespace detail | ||
1587 | 444 | { | ||
1588 | 445 | template <class T> | ||
1589 | 446 | inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT | ||
1590 | 447 | { | ||
1591 | 448 | # ifdef BOOST_BIG_ENDIAN | ||
1592 | 449 | std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T)); | ||
1593 | 450 | # else | ||
1594 | 451 | std::reverse_copy(reinterpret_cast<const char*>(&from), | ||
1595 | 452 | reinterpret_cast<const char*>(&from) + sizeof(T), to); | ||
1596 | 453 | # endif | ||
1597 | 454 | } | ||
1598 | 455 | template <class T> | ||
1599 | 456 | inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT | ||
1600 | 457 | { | ||
1601 | 458 | # ifdef BOOST_BIG_ENDIAN | ||
1602 | 459 | std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T)); | ||
1603 | 460 | # else | ||
1604 | 461 | std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to)); | ||
1605 | 462 | # endif | ||
1606 | 463 | } | ||
1607 | 464 | template <class T> | ||
1608 | 465 | inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT | ||
1609 | 466 | { | ||
1610 | 467 | # ifdef BOOST_LITTLE_ENDIAN | ||
1611 | 468 | std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T)); | ||
1612 | 469 | # else | ||
1613 | 470 | std::reverse_copy(reinterpret_cast<const char*>(&from), | ||
1614 | 471 | reinterpret_cast<const char*>(&from) + sizeof(T), to); | ||
1615 | 472 | # endif | ||
1616 | 473 | } | ||
1617 | 474 | template <class T> | ||
1618 | 475 | inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT | ||
1619 | 476 | { | ||
1620 | 477 | # ifdef BOOST_LITTLE_ENDIAN | ||
1621 | 478 | std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T)); | ||
1622 | 479 | # else | ||
1623 | 480 | std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to)); | ||
1624 | 481 | # endif | ||
1625 | 482 | } | ||
1626 | 483 | } // namespace detail | ||
1627 | 484 | } // namespace endian | ||
1628 | 485 | } // namespace boost | ||
1629 | 486 | |||
1630 | 487 | #endif // BOOST_ENDIAN_CONVERSION_HPP | ||
1631 | 0 | 488 | ||
1632 | === added directory '3rd-party/boost/endian/detail' | |||
1633 | === added file '3rd-party/boost/endian/detail/config.hpp' | |||
1634 | --- 3rd-party/boost/endian/detail/config.hpp 1970-01-01 00:00:00 +0000 | |||
1635 | +++ 3rd-party/boost/endian/detail/config.hpp 2016-03-10 19:55:08 +0000 | |||
1636 | @@ -0,0 +1,62 @@ | |||
1637 | 1 | // boost/endian/detail/config.hpp ----------------------------------------------------// | ||
1638 | 2 | |||
1639 | 3 | // Copyright Beman Dawes 2003, 2010 | ||
1640 | 4 | |||
1641 | 5 | // Distributed under the Boost Software License, Version 1.0. | ||
1642 | 6 | // See http://www.boost.org/LICENSE_1_0.txt | ||
1643 | 7 | |||
1644 | 8 | //--------------------------------------------------------------------------------------// | ||
1645 | 9 | |||
1646 | 10 | #ifndef BOOST_ENDIAN_CONFIG_HPP | ||
1647 | 11 | #define BOOST_ENDIAN_CONFIG_HPP | ||
1648 | 12 | |||
1649 | 13 | // This header implements separate compilation features as described in | ||
1650 | 14 | // http://www.boost.org/more/separate_compilation.html | ||
1651 | 15 | |||
1652 | 16 | #include <boost/config.hpp> | ||
1653 | 17 | #include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API | ||
1654 | 18 | |||
1655 | 19 | // throw an exception ----------------------------------------------------------------// | ||
1656 | 20 | // | ||
1657 | 21 | // Exceptions were originally thrown via boost::throw_exception(). | ||
1658 | 22 | // As throw_exception() became more complex, it caused user error reporting | ||
1659 | 23 | // to be harder to interpret, since the exception reported became much more complex. | ||
1660 | 24 | // The immediate fix was to throw directly, wrapped in a macro to make any later change | ||
1661 | 25 | // easier. | ||
1662 | 26 | |||
1663 | 27 | #define BOOST_ENDIAN_THROW(EX) throw EX | ||
1664 | 28 | |||
1665 | 29 | // enable dynamic linking -------------------------------------------------------------// | ||
1666 | 30 | |||
1667 | 31 | #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK) | ||
1668 | 32 | # if defined(BOOST_ENDIAN_SOURCE) | ||
1669 | 33 | # define BOOST_ENDIAN_DECL BOOST_SYMBOL_EXPORT | ||
1670 | 34 | # else | ||
1671 | 35 | # define BOOST_ENDIAN_DECL BOOST_SYMBOL_IMPORT | ||
1672 | 36 | # endif | ||
1673 | 37 | #else | ||
1674 | 38 | # define BOOST_ENDIAN_DECL | ||
1675 | 39 | #endif | ||
1676 | 40 | |||
1677 | 41 | // enable automatic library variant selection ----------------------------------------// | ||
1678 | 42 | |||
1679 | 43 | #if !defined(BOOST_ENDIAN_SOURCE) && !defined(BOOST_ALL_NO_LIB) \ | ||
1680 | 44 | && !defined(BOOST_ENDIAN_NO_LIB) | ||
1681 | 45 | // | ||
1682 | 46 | // Set the name of our library, this will get undef'ed by auto_link.hpp | ||
1683 | 47 | // once it's done with it: | ||
1684 | 48 | // | ||
1685 | 49 | #define BOOST_LIB_NAME boost_endian | ||
1686 | 50 | // | ||
1687 | 51 | // If we're importing code from a dll, then tell auto_link.hpp about it: | ||
1688 | 52 | // | ||
1689 | 53 | #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK) | ||
1690 | 54 | # define BOOST_DYN_LINK | ||
1691 | 55 | #endif | ||
1692 | 56 | // | ||
1693 | 57 | // And include the header that does the work: | ||
1694 | 58 | // | ||
1695 | 59 | #include <boost/config/auto_link.hpp> | ||
1696 | 60 | #endif // auto-linking disabled | ||
1697 | 61 | |||
1698 | 62 | #endif // BOOST_ENDIAN_CONFIG_HPP | ||
1699 | 0 | 63 | ||
1700 | === added file '3rd-party/boost/endian/detail/cover_operators.hpp' | |||
1701 | --- 3rd-party/boost/endian/detail/cover_operators.hpp 1970-01-01 00:00:00 +0000 | |||
1702 | +++ 3rd-party/boost/endian/detail/cover_operators.hpp 2016-03-10 19:55:08 +0000 | |||
1703 | @@ -0,0 +1,142 @@ | |||
1704 | 1 | // boost/endian/detail/cover_operators.hpp ----------------------------------// | ||
1705 | 2 | |||
1706 | 3 | // Copyright Darin Adler 2000 | ||
1707 | 4 | // Copyright Beman Dawes 2008 | ||
1708 | 5 | |||
1709 | 6 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
1710 | 7 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
1711 | 8 | |||
1712 | 9 | #ifndef BOOST_ENDIAN_COVER_OPERATORS_HPP | ||
1713 | 10 | #define BOOST_ENDIAN_COVER_OPERATORS_HPP | ||
1714 | 11 | |||
1715 | 12 | #if defined(_MSC_VER) | ||
1716 | 13 | # pragma warning(push) | ||
1717 | 14 | # pragma warning(disable:4365) // conversion ... signed/unsigned mismatch | ||
1718 | 15 | #endif | ||
1719 | 16 | |||
1720 | 17 | # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS | ||
1721 | 18 | # include <boost/operators.hpp> | ||
1722 | 19 | # endif | ||
1723 | 20 | |||
1724 | 21 | #include <boost/config.hpp> | ||
1725 | 22 | #include <iosfwd> | ||
1726 | 23 | |||
1727 | 24 | namespace boost | ||
1728 | 25 | { | ||
1729 | 26 | namespace endian | ||
1730 | 27 | { | ||
1731 | 28 | |||
1732 | 29 | //--------------------------------------------------------------------------------------// | ||
1733 | 30 | |||
1734 | 31 | // A class that adds arithmetic operators to an arithmetic cover class | ||
1735 | 32 | // | ||
1736 | 33 | // Uses the curiously recurring template pattern (CRTP). | ||
1737 | 34 | // | ||
1738 | 35 | // If the class being covered has a non-explicit conversion to an integer type | ||
1739 | 36 | // then a smaller number of cover operations are needed. Define the macro | ||
1740 | 37 | // BOOST_ENDIAN_MINIMAL_COVER_OPERATORS to indicate this. | ||
1741 | 38 | // | ||
1742 | 39 | // Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired. | ||
1743 | 40 | |||
1744 | 41 | //--------------------------------------------------------------------------------------// | ||
1745 | 42 | |||
1746 | 43 | template <class D, // D is the CRTP derived type, i.e. the cover class | ||
1747 | 44 | class ArithmeticT> | ||
1748 | 45 | class cover_operators | ||
1749 | 46 | # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS | ||
1750 | 47 | : boost::operators<D> | ||
1751 | 48 | # endif | ||
1752 | 49 | { | ||
1753 | 50 | // The other operations take advantage of the type conversion that's | ||
1754 | 51 | // built into unary +. | ||
1755 | 52 | |||
1756 | 53 | // Unary operations. | ||
1757 | 54 | friend ArithmeticT operator+(const D& x) BOOST_NOEXCEPT { return x; } | ||
1758 | 55 | # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS | ||
1759 | 56 | friend ArithmeticT operator-(const D& x) BOOST_NOEXCEPT { return -+x; } | ||
1760 | 57 | friend ArithmeticT operator~(const D& x) BOOST_NOEXCEPT { return ~+x; } | ||
1761 | 58 | friend ArithmeticT operator!(const D& x) BOOST_NOEXCEPT { return !+x; } | ||
1762 | 59 | |||
1763 | 60 | // The basic ordering operations. | ||
1764 | 61 | friend bool operator==(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x == y; } | ||
1765 | 62 | friend bool operator<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x < y; } | ||
1766 | 63 | # endif | ||
1767 | 64 | |||
1768 | 65 | // The basic arithmetic operations. | ||
1769 | 66 | friend D& operator+=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1770 | 67 | { return x = static_cast<ArithmeticT>(+x + y); } | ||
1771 | 68 | friend D& operator-=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1772 | 69 | { return x = static_cast<ArithmeticT>(+x - y); } | ||
1773 | 70 | friend D& operator*=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1774 | 71 | { return x = static_cast<ArithmeticT>(+x * y); } | ||
1775 | 72 | friend D& operator/=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1776 | 73 | { return x = static_cast<ArithmeticT>(+x / y); } | ||
1777 | 74 | friend D& operator%=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1778 | 75 | { return x = static_cast<ArithmeticT>(+x % y); } | ||
1779 | 76 | friend D& operator&=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1780 | 77 | { return x = static_cast<ArithmeticT>(+x & y); } | ||
1781 | 78 | friend D& operator|=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1782 | 79 | { return x = static_cast<ArithmeticT>(+x | y); } | ||
1783 | 80 | friend D& operator^=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1784 | 81 | { return x = static_cast<ArithmeticT>(+x ^ y); } | ||
1785 | 82 | friend D& operator<<=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1786 | 83 | { return x = static_cast<ArithmeticT>(+x << y); } | ||
1787 | 84 | friend D& operator>>=(D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1788 | 85 | { return x = static_cast<ArithmeticT>(+x >> y); } | ||
1789 | 86 | |||
1790 | 87 | // A few binary arithmetic operations not covered by operators base class. | ||
1791 | 88 | friend ArithmeticT operator<<(const D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1792 | 89 | { return static_cast<ArithmeticT>(+x << y); } | ||
1793 | 90 | friend ArithmeticT operator>>(const D& x, ArithmeticT y) BOOST_NOEXCEPT | ||
1794 | 91 | { return static_cast<ArithmeticT>(+x >> y); } | ||
1795 | 92 | |||
1796 | 93 | // Auto-increment and auto-decrement can be defined in terms of the | ||
1797 | 94 | // arithmetic operations. | ||
1798 | 95 | friend D& operator++(D& x) BOOST_NOEXCEPT { return x += 1; } | ||
1799 | 96 | friend D& operator--(D& x) BOOST_NOEXCEPT { return x -= 1; } | ||
1800 | 97 | |||
1801 | 98 | # ifdef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS | ||
1802 | 99 | friend D operator++(D& x, int) BOOST_NOEXCEPT | ||
1803 | 100 | { | ||
1804 | 101 | D tmp(x); | ||
1805 | 102 | x += 1; | ||
1806 | 103 | return tmp; | ||
1807 | 104 | } | ||
1808 | 105 | friend D operator--(D& x, int) BOOST_NOEXCEPT | ||
1809 | 106 | { | ||
1810 | 107 | D tmp(x); | ||
1811 | 108 | x -= 1; | ||
1812 | 109 | return tmp; | ||
1813 | 110 | } | ||
1814 | 111 | # endif | ||
1815 | 112 | |||
1816 | 113 | # ifndef BOOST_NO_IO_COVER_OPERATORS | ||
1817 | 114 | |||
1818 | 115 | // Stream inserter | ||
1819 | 116 | template <class charT, class traits> | ||
1820 | 117 | friend std::basic_ostream<charT, traits>& | ||
1821 | 118 | operator<<(std::basic_ostream<charT, traits>& os, const D& x) | ||
1822 | 119 | { | ||
1823 | 120 | return os << +x; | ||
1824 | 121 | } | ||
1825 | 122 | |||
1826 | 123 | // Stream extractor | ||
1827 | 124 | template <class charT, class traits> | ||
1828 | 125 | friend std::basic_istream<charT, traits>& | ||
1829 | 126 | operator>>(std::basic_istream<charT, traits>& is, D& x) | ||
1830 | 127 | { | ||
1831 | 128 | ArithmeticT i; | ||
1832 | 129 | if (is >> i) | ||
1833 | 130 | x = i; | ||
1834 | 131 | return is; | ||
1835 | 132 | } | ||
1836 | 133 | # endif | ||
1837 | 134 | }; | ||
1838 | 135 | } // namespace endian | ||
1839 | 136 | } // namespace boost | ||
1840 | 137 | |||
1841 | 138 | #if defined(_MSC_VER) | ||
1842 | 139 | # pragma warning(pop) | ||
1843 | 140 | #endif | ||
1844 | 141 | |||
1845 | 142 | #endif // BOOST_ENDIAN_COVER_OPERATORS_HPP | ||
1846 | 0 | 143 | ||
1847 | === added file '3rd-party/boost/endian/detail/disable_warnings.hpp' | |||
1848 | --- 3rd-party/boost/endian/detail/disable_warnings.hpp 1970-01-01 00:00:00 +0000 | |||
1849 | +++ 3rd-party/boost/endian/detail/disable_warnings.hpp 2016-03-10 19:55:08 +0000 | |||
1850 | @@ -0,0 +1,33 @@ | |||
1851 | 1 | // disable_warnings.hpp --------------------------------------------------------------// | ||
1852 | 2 | |||
1853 | 3 | // Copyright Beman Dawes 2011 | ||
1854 | 4 | |||
1855 | 5 | // Distributed under the Boost Software License, Version 1.0. | ||
1856 | 6 | // See http://www.boost.org/LICENSE_1_0.txt | ||
1857 | 7 | |||
1858 | 8 | //--------------------------------------------------------------------------------------// | ||
1859 | 9 | |||
1860 | 10 | #ifdef _MSC_VER | ||
1861 | 11 | |||
1862 | 12 | #ifndef _SCL_SECURE_NO_WARNINGS | ||
1863 | 13 | # define _SCL_SECURE_NO_WARNINGS | ||
1864 | 14 | #endif | ||
1865 | 15 | |||
1866 | 16 | #ifndef _CRT_SECURE_NO_WARNINGS | ||
1867 | 17 | # define _CRT_SECURE_NO_WARNINGS | ||
1868 | 18 | #endif | ||
1869 | 19 | |||
1870 | 20 | # pragma warning(push) | ||
1871 | 21 | |||
1872 | 22 | // triggered by boost/detail/lightweight_test.hpp | ||
1873 | 23 | # pragma warning( disable : 4640 ) // ... construction of local static object is not thread-safe | ||
1874 | 24 | |||
1875 | 25 | // triggered by Microsoft's own headers, so disable | ||
1876 | 26 | # pragma warning( disable : 4820 ) // padding added after data member | ||
1877 | 27 | # pragma warning( disable : 4548 ) // expression before comma has no effect | ||
1878 | 28 | # pragma warning( disable : 4668 ) // ... is not defined as a preprocessor macro | ||
1879 | 29 | # pragma warning( disable : 4514 ) // ... unreferenced inline function has been removed | ||
1880 | 30 | # pragma warning( disable : 4710 ) // ... function not inlined | ||
1881 | 31 | # pragma warning( disable : 4986 ) // ... exception specification does not match previous declaration | ||
1882 | 32 | # pragma warning( disable : 4711 ) // ... selected for automatic inline expansion | ||
1883 | 33 | #endif | ||
1884 | 0 | 34 | ||
1885 | === added file '3rd-party/boost/endian/detail/disable_warnings_pop.hpp' | |||
1886 | --- 3rd-party/boost/endian/detail/disable_warnings_pop.hpp 1970-01-01 00:00:00 +0000 | |||
1887 | +++ 3rd-party/boost/endian/detail/disable_warnings_pop.hpp 2016-03-10 19:55:08 +0000 | |||
1888 | @@ -0,0 +1,12 @@ | |||
1889 | 1 | // disable_warnings_pop.hpp ----------------------------------------------------------// | ||
1890 | 2 | |||
1891 | 3 | // Copyright Beman Dawes 2011 | ||
1892 | 4 | |||
1893 | 5 | // Distributed under the Boost Software License, Version 1.0. | ||
1894 | 6 | // See http://www.boost.org/LICENSE_1_0.txt | ||
1895 | 7 | |||
1896 | 8 | //--------------------------------------------------------------------------------------// | ||
1897 | 9 | |||
1898 | 10 | #ifdef _MSC_VER | ||
1899 | 11 | # pragma warning(push) | ||
1900 | 12 | #endif | ||
1901 | 0 | 13 | ||
1902 | === added file '3rd-party/boost/endian/detail/intrinsic.hpp' | |||
1903 | --- 3rd-party/boost/endian/detail/intrinsic.hpp 1970-01-01 00:00:00 +0000 | |||
1904 | +++ 3rd-party/boost/endian/detail/intrinsic.hpp 2016-03-10 19:55:08 +0000 | |||
1905 | @@ -0,0 +1,64 @@ | |||
1906 | 1 | // endian/detail/intrinsic.hpp -------------------------------------------------------// | ||
1907 | 2 | |||
1908 | 3 | // Copyright (C) 2012 David Stone | ||
1909 | 4 | // Copyright Beman Dawes 2013 | ||
1910 | 5 | |||
1911 | 6 | // Distributed under the Boost Software License, Version 1.0. | ||
1912 | 7 | // http://www.boost.org/LICENSE_1_0.txt | ||
1913 | 8 | |||
1914 | 9 | #ifndef BOOST_ENDIAN_INTRINSIC_HPP | ||
1915 | 10 | #define BOOST_ENDIAN_INTRINSIC_HPP | ||
1916 | 11 | |||
1917 | 12 | // Allow user to force BOOST_ENDIAN_NO_INTRINSICS in case they aren't available for a | ||
1918 | 13 | // particular platform/compiler combination. Please report such platform/compiler | ||
1919 | 14 | // combinations to the Boost mailing list. | ||
1920 | 15 | #ifndef BOOST_ENDIAN_NO_INTRINSICS | ||
1921 | 16 | |||
1922 | 17 | #ifndef __has_builtin // Optional of course | ||
1923 | 18 | #define __has_builtin(x) 0 // Compatibility with non-clang compilers | ||
1924 | 19 | #endif | ||
1925 | 20 | |||
1926 | 21 | // GCC and Clang recent versions provide intrinsic byte swaps via builtins | ||
1927 | 22 | #if (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) \ | ||
1928 | 23 | || (defined(__GNUC__ ) && \ | ||
1929 | 24 | (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) | ||
1930 | 25 | # define BOOST_ENDIAN_INTRINSIC_MSG "__builtin_bswap16, etc." | ||
1931 | 26 | // prior to 4.8, gcc did not provide __builtin_bswap16 on some platforms so we emulate it | ||
1932 | 27 | // see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624 | ||
1933 | 28 | // Clang has a similar problem, but their feature test macros make it easier to detect | ||
1934 | 29 | # if (defined(__clang__) && __has_builtin(__builtin_bswap16)) \ | ||
1935 | 30 | || (defined(__GNUC__) &&(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) | ||
1936 | 31 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) __builtin_bswap16(x) | ||
1937 | 32 | # else | ||
1938 | 33 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) __builtin_bswap32((x) << 16) | ||
1939 | 34 | # endif | ||
1940 | 35 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) __builtin_bswap32(x) | ||
1941 | 36 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) __builtin_bswap64(x) | ||
1942 | 37 | |||
1943 | 38 | // Linux systems provide the byteswap.h header, with | ||
1944 | 39 | #elif defined(__linux__) | ||
1945 | 40 | // don't check for obsolete forms defined(linux) and defined(__linux) on the theory that | ||
1946 | 41 | // compilers that predefine only these are so old that byteswap.h probably isn't present. | ||
1947 | 42 | # define BOOST_ENDIAN_INTRINSIC_MSG "byteswap.h bswap_16, etc." | ||
1948 | 43 | # include <byteswap.h> | ||
1949 | 44 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) bswap_16(x) | ||
1950 | 45 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) bswap_32(x) | ||
1951 | 46 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) bswap_64(x) | ||
1952 | 47 | |||
1953 | 48 | #elif defined(_MSC_VER) | ||
1954 | 49 | // Microsoft documents these as being compatible since Windows 95 and specificly | ||
1955 | 50 | // lists runtime library support since Visual Studio 2003 (aka 7.1). | ||
1956 | 51 | # define BOOST_ENDIAN_INTRINSIC_MSG "cstdlib _byteswap_ushort, etc." | ||
1957 | 52 | # include <cstdlib> | ||
1958 | 53 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) _byteswap_ushort(x) | ||
1959 | 54 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) _byteswap_ulong(x) | ||
1960 | 55 | # define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) _byteswap_uint64(x) | ||
1961 | 56 | #else | ||
1962 | 57 | # define BOOST_ENDIAN_NO_INTRINSICS | ||
1963 | 58 | # define BOOST_ENDIAN_INTRINSIC_MSG "no byte swap intrinsics" | ||
1964 | 59 | #endif | ||
1965 | 60 | |||
1966 | 61 | #elif !defined(BOOST_ENDIAN_INTRINSIC_MSG) | ||
1967 | 62 | # define BOOST_ENDIAN_INTRINSIC_MSG "no byte swap intrinsics" | ||
1968 | 63 | #endif // BOOST_ENDIAN_NO_INTRINSICS | ||
1969 | 64 | #endif // BOOST_ENDIAN_INTRINSIC_HPP | ||
1970 | 0 | 65 | ||
1971 | === added file '3rd-party/boost/endian/detail/lightweight_test.hpp' | |||
1972 | --- 3rd-party/boost/endian/detail/lightweight_test.hpp 1970-01-01 00:00:00 +0000 | |||
1973 | +++ 3rd-party/boost/endian/detail/lightweight_test.hpp 2016-03-10 19:55:08 +0000 | |||
1974 | @@ -0,0 +1,223 @@ | |||
1975 | 1 | // boost/endian/detail/lightweight_test.hpp --------------------------------------------// | ||
1976 | 2 | |||
1977 | 3 | #ifndef BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP | ||
1978 | 4 | #define BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP | ||
1979 | 5 | |||
1980 | 6 | // MS compatible compilers support #pragma once | ||
1981 | 7 | |||
1982 | 8 | #if defined(_MSC_VER) | ||
1983 | 9 | # pragma once | ||
1984 | 10 | #endif | ||
1985 | 11 | |||
1986 | 12 | // | ||
1987 | 13 | // Copyright (c) 2002, 2009, 2014 Peter Dimov | ||
1988 | 14 | // Copyright (2) Beman Dawes 2010, 2011, 2015 | ||
1989 | 15 | // Copyright (3) Ion Gaztanaga 2013 | ||
1990 | 16 | // | ||
1991 | 17 | // Distributed under the Boost Software License, Version 1.0. | ||
1992 | 18 | // See http://www.boost.org/LICENSE_1_0.txt | ||
1993 | 19 | // | ||
1994 | 20 | |||
1995 | 21 | #include <boost/assert.hpp> | ||
1996 | 22 | #include <boost/current_function.hpp> | ||
1997 | 23 | #include <boost/core/no_exceptions_support.hpp> | ||
1998 | 24 | #include <cstring> // for memcmp | ||
1999 | 25 | #include <iostream> | ||
2000 | 26 | |||
2001 | 27 | // IDE's like Visual Studio perform better if output goes to std::cout or | ||
2002 | 28 | // some other stream, so allow user to configure output stream: | ||
2003 | 29 | #ifndef BOOST_LIGHTWEIGHT_TEST_OSTREAM | ||
2004 | 30 | # define BOOST_LIGHTWEIGHT_TEST_OSTREAM std::cerr | ||
2005 | 31 | #endif | ||
2006 | 32 | |||
2007 | 33 | namespace boost | ||
2008 | 34 | { | ||
2009 | 35 | namespace endian | ||
2010 | 36 | { | ||
2011 | 37 | namespace detail | ||
2012 | 38 | { | ||
2013 | 39 | |||
2014 | 40 | struct report_errors_reminder | ||
2015 | 41 | { | ||
2016 | 42 | bool called_report_errors_function; | ||
2017 | 43 | |||
2018 | 44 | report_errors_reminder() : called_report_errors_function(false) {} | ||
2019 | 45 | |||
2020 | 46 | ~report_errors_reminder() | ||
2021 | 47 | { | ||
2022 | 48 | BOOST_ASSERT(called_report_errors_function); // verify report_errors() was called | ||
2023 | 49 | } | ||
2024 | 50 | }; | ||
2025 | 51 | |||
2026 | 52 | inline report_errors_reminder& report_errors_remind() | ||
2027 | 53 | { | ||
2028 | 54 | static report_errors_reminder r; | ||
2029 | 55 | return r; | ||
2030 | 56 | } | ||
2031 | 57 | |||
2032 | 58 | inline int & test_errors() | ||
2033 | 59 | { | ||
2034 | 60 | static int x = 0; | ||
2035 | 61 | report_errors_remind(); | ||
2036 | 62 | return x; | ||
2037 | 63 | } | ||
2038 | 64 | |||
2039 | 65 | inline void test_failed_impl(char const * expr, char const * file, int line, char const * function) | ||
2040 | 66 | { | ||
2041 | 67 | BOOST_LIGHTWEIGHT_TEST_OSTREAM | ||
2042 | 68 | << file << "(" << line << "): test '" << expr << "' failed in function '" | ||
2043 | 69 | << function << "'" << std::endl; | ||
2044 | 70 | ++test_errors(); | ||
2045 | 71 | } | ||
2046 | 72 | |||
2047 | 73 | inline void error_impl(char const * msg, char const * file, int line, char const * function) | ||
2048 | 74 | { | ||
2049 | 75 | BOOST_LIGHTWEIGHT_TEST_OSTREAM | ||
2050 | 76 | << file << "(" << line << "): " << msg << " in function '" | ||
2051 | 77 | << function << "'" << std::endl; | ||
2052 | 78 | ++test_errors(); | ||
2053 | 79 | } | ||
2054 | 80 | |||
2055 | 81 | inline void throw_failed_impl(char const * excep, char const * file, int line, char const * function) | ||
2056 | 82 | { | ||
2057 | 83 | BOOST_LIGHTWEIGHT_TEST_OSTREAM | ||
2058 | 84 | << file << "(" << line << "): Exception '" << excep << "' not thrown in function '" | ||
2059 | 85 | << function << "'" << std::endl; | ||
2060 | 86 | ++test_errors(); | ||
2061 | 87 | } | ||
2062 | 88 | |||
2063 | 89 | template<class T, class U> inline void test_eq_impl( char const * expr1, char const * expr2, | ||
2064 | 90 | char const * file, int line, char const * function, T const & t, U const & u ) | ||
2065 | 91 | { | ||
2066 | 92 | if( t == u ) | ||
2067 | 93 | { | ||
2068 | 94 | report_errors_remind(); | ||
2069 | 95 | } | ||
2070 | 96 | else | ||
2071 | 97 | { | ||
2072 | 98 | BOOST_LIGHTWEIGHT_TEST_OSTREAM | ||
2073 | 99 | << file << "(" << line << "): test '" << expr1 << " == " << expr2 | ||
2074 | 100 | << "' failed in function '" << function << "': " | ||
2075 | 101 | << "'" << t << "' != '" << u << "'" << std::endl; | ||
2076 | 102 | ++test_errors(); | ||
2077 | 103 | } | ||
2078 | 104 | } | ||
2079 | 105 | |||
2080 | 106 | template<class T, class U> inline void test_ne_impl( char const * expr1, char const * expr2, | ||
2081 | 107 | char const * file, int line, char const * function, T const & t, U const & u ) | ||
2082 | 108 | { | ||
2083 | 109 | if( t != u ) | ||
2084 | 110 | { | ||
2085 | 111 | report_errors_remind(); | ||
2086 | 112 | } | ||
2087 | 113 | else | ||
2088 | 114 | { | ||
2089 | 115 | BOOST_LIGHTWEIGHT_TEST_OSTREAM | ||
2090 | 116 | << file << "(" << line << "): test '" << expr1 << " != " << expr2 | ||
2091 | 117 | << "' failed in function '" << function << "': " | ||
2092 | 118 | << "'" << t << "' == '" << u << "'" << std::endl; | ||
2093 | 119 | ++test_errors(); | ||
2094 | 120 | } | ||
2095 | 121 | } | ||
2096 | 122 | |||
2097 | 123 | template <class T> | ||
2098 | 124 | std::string to_hex(const T& x) | ||
2099 | 125 | { | ||
2100 | 126 | const char hex[] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; | ||
2101 | 127 | std::string tmp; | ||
2102 | 128 | const unsigned char* p = reinterpret_cast<const unsigned char*>(&x); | ||
2103 | 129 | const unsigned char* e = p + sizeof(T); | ||
2104 | 130 | |||
2105 | 131 | for (; p < e; ++p) | ||
2106 | 132 | { | ||
2107 | 133 | tmp += hex[*p >> 4]; // high-order nibble | ||
2108 | 134 | tmp += hex[*p & 0x0f]; // low-order nibble | ||
2109 | 135 | } | ||
2110 | 136 | return tmp; | ||
2111 | 137 | } | ||
2112 | 138 | |||
2113 | 139 | template<class T, class U> inline bool test_memcmp_eq_impl(char const * expr1, | ||
2114 | 140 | char const * expr2, char const * file, int line, char const * function, T const & t, | ||
2115 | 141 | U const & u) | ||
2116 | 142 | { | ||
2117 | 143 | BOOST_ASSERT(sizeof(T) == sizeof(U)); | ||
2118 | 144 | if (sizeof(T) == sizeof(U) | ||
2119 | 145 | && std::memcmp(&t, &u, sizeof(T)) == 0) | ||
2120 | 146 | { | ||
2121 | 147 | report_errors_remind(); | ||
2122 | 148 | return true; | ||
2123 | 149 | } | ||
2124 | 150 | else | ||
2125 | 151 | { | ||
2126 | 152 | BOOST_LIGHTWEIGHT_TEST_OSTREAM | ||
2127 | 153 | << file << "(" << line << "): test 'std::memcmp(" << expr1 << ", " << expr2 | ||
2128 | 154 | << ") == 0' fails in function '" << function << "': " | ||
2129 | 155 | << " with values '" << to_hex(t) << "' and '" << to_hex(u) << "'" << std::endl; | ||
2130 | 156 | ++test_errors(); | ||
2131 | 157 | return false; | ||
2132 | 158 | } | ||
2133 | 159 | } | ||
2134 | 160 | |||
2135 | 161 | } // namespace detail | ||
2136 | 162 | |||
2137 | 163 | inline int report_errors() | ||
2138 | 164 | { | ||
2139 | 165 | boost::endian::detail::report_errors_remind().called_report_errors_function = true; | ||
2140 | 166 | |||
2141 | 167 | int errors = boost::endian::detail::test_errors(); | ||
2142 | 168 | |||
2143 | 169 | if( errors == 0 ) | ||
2144 | 170 | { | ||
2145 | 171 | BOOST_LIGHTWEIGHT_TEST_OSTREAM | ||
2146 | 172 | << "No errors detected." << std::endl; | ||
2147 | 173 | return 0; | ||
2148 | 174 | } | ||
2149 | 175 | else | ||
2150 | 176 | { | ||
2151 | 177 | BOOST_LIGHTWEIGHT_TEST_OSTREAM | ||
2152 | 178 | << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl; | ||
2153 | 179 | return 1; | ||
2154 | 180 | } | ||
2155 | 181 | } | ||
2156 | 182 | |||
2157 | 183 | } // namespace endian | ||
2158 | 184 | } // namespace boost | ||
2159 | 185 | |||
2160 | 186 | ////////////////////////////////////////////////////////////////////////////////////////// | ||
2161 | 187 | // TODO: Should all test macros return bool? See BOOST_TEST_MEM_EQ usage in fp_exaustive_test,cpp | ||
2162 | 188 | ////////////////////////////////////////////////////////////////////////////////////////// | ||
2163 | 189 | |||
2164 | 190 | |||
2165 | 191 | #define BOOST_TEST(expr) \ | ||
2166 | 192 | ((expr)? (void)0: ::boost::endian::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION)) | ||
2167 | 193 | |||
2168 | 194 | #define BOOST_ERROR(msg) \ | ||
2169 | 195 | ( ::boost::endian::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) ) | ||
2170 | 196 | |||
2171 | 197 | #define BOOST_TEST_EQ(expr1,expr2) \ | ||
2172 | 198 | ( ::boost::endian::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) | ||
2173 | 199 | #define BOOST_TEST_NE(expr1,expr2) \ | ||
2174 | 200 | ( ::boost::endian::detail::test_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) | ||
2175 | 201 | |||
2176 | 202 | #define BOOST_TEST_MEM_EQ(expr1,expr2) \ | ||
2177 | 203 | (::boost::endian::detail::test_memcmp_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2)) | ||
2178 | 204 | |||
2179 | 205 | #ifndef BOOST_NO_EXCEPTIONS | ||
2180 | 206 | #define BOOST_TEST_THROWS( EXPR, EXCEP ) \ | ||
2181 | 207 | try { \ | ||
2182 | 208 | EXPR; \ | ||
2183 | 209 | ::boost::detail::throw_failed_impl \ | ||
2184 | 210 | (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ | ||
2185 | 211 | } \ | ||
2186 | 212 | catch(EXCEP const&) { \ | ||
2187 | 213 | } \ | ||
2188 | 214 | catch(...) { \ | ||
2189 | 215 | ::boost::detail::throw_failed_impl \ | ||
2190 | 216 | (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ | ||
2191 | 217 | } \ | ||
2192 | 218 | // | ||
2193 | 219 | #else | ||
2194 | 220 | #define BOOST_TEST_THROWS( EXPR, EXCEP ) | ||
2195 | 221 | #endif | ||
2196 | 222 | |||
2197 | 223 | #endif // #ifndef BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP | ||
2198 | 0 | 224 | ||
2199 | === added file '3rd-party/boost/endian/endian.hpp' | |||
2200 | --- 3rd-party/boost/endian/endian.hpp 1970-01-01 00:00:00 +0000 | |||
2201 | +++ 3rd-party/boost/endian/endian.hpp 2016-03-10 19:55:08 +0000 | |||
2202 | @@ -0,0 +1,19 @@ | |||
2203 | 1 | // boost/endian/endian.hpp -----------------------------------------------------------// | ||
2204 | 2 | |||
2205 | 3 | // Copyright Beman Dawes 2015 | ||
2206 | 4 | |||
2207 | 5 | // Distributed under the Boost Software License, Version 1.0. | ||
2208 | 6 | // See http://www.boost.org/LICENSE_1_0.txt | ||
2209 | 7 | |||
2210 | 8 | // See library home page at http://www.boost.org/libs/endian | ||
2211 | 9 | |||
2212 | 10 | #ifndef BOOST_ENDIAN_ENDIAN_HPP | ||
2213 | 11 | #define BOOST_ENDIAN_ENDIAN_HPP | ||
2214 | 12 | |||
2215 | 13 | #ifndef BOOST_ENDIAN_DEPRECATED_NAMES | ||
2216 | 14 | # error "<boost/endian/endian.hpp> is deprecated. Define BOOST_ENDIAN_DEPRECATED_NAMES to use." | ||
2217 | 15 | #endif | ||
2218 | 16 | |||
2219 | 17 | #include <boost/endian/arithmetic.hpp> | ||
2220 | 18 | |||
2221 | 19 | #endif //BOOST_ENDIAN_ENDIAN_HPP | ||
2222 | 0 | 20 | ||
2223 | === added file '3rd-party/boost/endian/std_pair.hpp' | |||
2224 | --- 3rd-party/boost/endian/std_pair.hpp 1970-01-01 00:00:00 +0000 | |||
2225 | +++ 3rd-party/boost/endian/std_pair.hpp 2016-03-10 19:55:08 +0000 | |||
2226 | @@ -0,0 +1,38 @@ | |||
2227 | 1 | // boost/endian/std_pair.hpp ---------------------------------------------------------// | ||
2228 | 2 | |||
2229 | 3 | // Copyright Beman Dawes 2013 | ||
2230 | 4 | |||
2231 | 5 | // Distributed under the Boost Software License, Version 1.0. | ||
2232 | 6 | // http://www.boost.org/LICENSE_1_0.txt | ||
2233 | 7 | |||
2234 | 8 | //--------------------------------------------------------------------------------------// | ||
2235 | 9 | |||
2236 | 10 | #ifndef BOOST_ENDIAN_STD_PAIR_HPP | ||
2237 | 11 | #define BOOST_ENDIAN_STD_PAIR_HPP | ||
2238 | 12 | |||
2239 | 13 | #include <boost/endian/conversion.hpp> | ||
2240 | 14 | #include <utility> | ||
2241 | 15 | |||
2242 | 16 | namespace boost | ||
2243 | 17 | { | ||
2244 | 18 | namespace endian | ||
2245 | 19 | { | ||
2246 | 20 | template <class ReversibleValueT, class ReversibleValueU> | ||
2247 | 21 | std::pair<ReversibleValueT, ReversibleValueU> | ||
2248 | 22 | reverse_value(std::pair<ReversibleValueT, ReversibleValueU> x) | ||
2249 | 23 | { | ||
2250 | 24 | return std::pair<ReversibleValueT, ReversibleValueU>(reverse_value(x.first), | ||
2251 | 25 | reverse_value(x.second)); | ||
2252 | 26 | } | ||
2253 | 27 | |||
2254 | 28 | template <class ReversibleT, class ReversibleU> | ||
2255 | 29 | void reverse(std::pair<ReversibleT, ReversibleU>& x) | ||
2256 | 30 | { | ||
2257 | 31 | reverse(x.first); | ||
2258 | 32 | reverse(x.second); | ||
2259 | 33 | } | ||
2260 | 34 | |||
2261 | 35 | } | ||
2262 | 36 | } | ||
2263 | 37 | |||
2264 | 38 | #endif // BOOST_ENDIAN_STD_PAIR_HPP | ||
2265 | 0 | 39 | ||
2266 | === modified file 'CMakeLists.txt' | |||
2267 | --- CMakeLists.txt 2015-02-03 08:38:21 +0000 | |||
2268 | +++ CMakeLists.txt 2016-03-10 19:55:08 +0000 | |||
2269 | @@ -34,6 +34,7 @@ | |||
2270 | 34 | pkg_check_modules(PROCESS_CPP process-cpp REQUIRED) | 34 | pkg_check_modules(PROCESS_CPP process-cpp REQUIRED) |
2271 | 35 | pkg_check_modules(PROPERTIES_CPP properties-cpp REQUIRED) | 35 | pkg_check_modules(PROPERTIES_CPP properties-cpp REQUIRED) |
2272 | 36 | pkg_check_modules(TRUST_STORE trust-store REQUIRED) | 36 | pkg_check_modules(TRUST_STORE trust-store REQUIRED) |
2273 | 37 | pkg_check_modules(UBUNTU_PLATFORM_HARDWARE_API ubuntu-platform-hardware-api) | ||
2274 | 37 | ##################################################################### | 38 | ##################################################################### |
2275 | 38 | # Enable code coverage calculation with gcov/gcovr/lcov | 39 | # Enable code coverage calculation with gcov/gcovr/lcov |
2276 | 39 | # Usage: | 40 | # Usage: |
2277 | @@ -69,6 +70,8 @@ | |||
2278 | 69 | endif() | 70 | endif() |
2279 | 70 | 71 | ||
2280 | 71 | include_directories( | 72 | include_directories( |
2281 | 73 | 3rd-party/ | ||
2282 | 74 | |||
2283 | 72 | ${Boost_INCLUDE_DIRS} | 75 | ${Boost_INCLUDE_DIRS} |
2284 | 73 | ${DBUS_INCLUDE_DIRS} | 76 | ${DBUS_INCLUDE_DIRS} |
2285 | 74 | ${DBUS_CPP_INCLUDE_DIRS} | 77 | ${DBUS_CPP_INCLUDE_DIRS} |
2286 | 75 | 78 | ||
2287 | === modified file 'include/location_service/com/ubuntu/location/connectivity/manager.h' | |||
2288 | --- include/location_service/com/ubuntu/location/connectivity/manager.h 2014-07-10 16:44:26 +0000 | |||
2289 | +++ include/location_service/com/ubuntu/location/connectivity/manager.h 2016-03-10 19:55:08 +0000 | |||
2290 | @@ -219,6 +219,27 @@ | |||
2291 | 219 | Manager() = default; | 219 | Manager() = default; |
2292 | 220 | }; | 220 | }; |
2293 | 221 | 221 | ||
2294 | 222 | /** @brief ExtendedManager extends the Manager interface in an ABI-stable way. */ | ||
2295 | 223 | class ExtendedManager : public Manager | ||
2296 | 224 | { | ||
2297 | 225 | public: | ||
2298 | 226 | /** | ||
2299 | 227 | * @brief ismis requests enumeration of the imsis of all SIMs installed in the device. | ||
2300 | 228 | */ | ||
2301 | 229 | virtual void enumerate_imsis(const std::function<void(const std::string&)>&) const = 0; | ||
2302 | 230 | |||
2303 | 231 | /** | ||
2304 | 232 | * @brief msisdns requests enumeration of all mobile station international subscriber directory numbers | ||
2305 | 233 | * of all SIMs installed in the device. | ||
2306 | 234 | */ | ||
2307 | 235 | virtual void enumerate_msisdns(const std::function<void(const std::string&)>&) const = 0; | ||
2308 | 236 | |||
2309 | 237 | protected: | ||
2310 | 238 | /** @cond */ | ||
2311 | 239 | ExtendedManager() = default; | ||
2312 | 240 | /** @endcond */ | ||
2313 | 241 | }; | ||
2314 | 242 | |||
2315 | 222 | /** | 243 | /** |
2316 | 223 | * @brief Provides access to a platform-specific implementation/instance of a connectivity manager. | 244 | * @brief Provides access to a platform-specific implementation/instance of a connectivity manager. |
2317 | 224 | * @throw Manager::Errors::ConnectivityManagementNotSupported. | 245 | * @throw Manager::Errors::ConnectivityManagementNotSupported. |
2318 | 225 | 246 | ||
2319 | === modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt' | |||
2320 | --- src/location_service/com/ubuntu/location/CMakeLists.txt 2015-11-26 08:28:38 +0000 | |||
2321 | +++ src/location_service/com/ubuntu/location/CMakeLists.txt 2016-03-10 19:55:08 +0000 | |||
2322 | @@ -1,3 +1,7 @@ | |||
2323 | 1 | if (UBUNTU_PLATFORM_HARDWARE_API_FOUND) | ||
2324 | 2 | add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API) | ||
2325 | 3 | endif() | ||
2326 | 4 | |||
2327 | 1 | if (NET_CPP_FOUND) | 5 | if (NET_CPP_FOUND) |
2328 | 2 | add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP=1) | 6 | add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP=1) |
2329 | 3 | 7 | ||
2330 | @@ -10,6 +14,8 @@ | |||
2331 | 10 | service/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/service/config.h @ONLY | 14 | service/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/service/config.h @ONLY |
2332 | 11 | ) | 15 | ) |
2333 | 12 | 16 | ||
2334 | 17 | include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS}) | ||
2335 | 18 | |||
2336 | 13 | add_library( | 19 | add_library( |
2337 | 14 | ubuntu-location-service SHARED | 20 | ubuntu-location-service SHARED |
2338 | 15 | 21 | ||
2339 | @@ -29,6 +35,7 @@ | |||
2340 | 29 | settings.cpp | 35 | settings.cpp |
2341 | 30 | time_based_update_policy.cpp | 36 | time_based_update_policy.cpp |
2342 | 31 | set_name_for_thread.cpp | 37 | set_name_for_thread.cpp |
2343 | 38 | time_since_boot.cpp | ||
2344 | 32 | wifi_and_cell_reporting_state.cpp | 39 | wifi_and_cell_reporting_state.cpp |
2345 | 33 | 40 | ||
2346 | 34 | boost_ptree_settings.cpp | 41 | boost_ptree_settings.cpp |
2347 | @@ -126,6 +133,7 @@ | |||
2348 | 126 | ${LIBAPPARMOR_LDFLAGS} | 133 | ${LIBAPPARMOR_LDFLAGS} |
2349 | 127 | ${NET_CPP_LDFLAGS} | 134 | ${NET_CPP_LDFLAGS} |
2350 | 128 | ${TRUST_STORE_LDFLAGS} | 135 | ${TRUST_STORE_LDFLAGS} |
2351 | 136 | ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS} | ||
2352 | 129 | ${GLog_LIBRARY} | 137 | ${GLog_LIBRARY} |
2353 | 130 | ${GFlags_LIBRARY} | 138 | ${GFlags_LIBRARY} |
2354 | 131 | ) | 139 | ) |
2355 | 132 | 140 | ||
2356 | === modified file 'src/location_service/com/ubuntu/location/connectivity/ofono.h' | |||
2357 | --- src/location_service/com/ubuntu/location/connectivity/ofono.h 2015-01-06 12:35:02 +0000 | |||
2358 | +++ src/location_service/com/ubuntu/location/connectivity/ofono.h 2016-03-10 19:55:08 +0000 | |||
2359 | @@ -640,6 +640,118 @@ | |||
2360 | 640 | } signals; | 640 | } signals; |
2361 | 641 | }; | 641 | }; |
2362 | 642 | 642 | ||
2363 | 643 | struct SimManager | ||
2364 | 644 | { | ||
2365 | 645 | static const std::string& name() | ||
2366 | 646 | { | ||
2367 | 647 | static const std::string s{"org.ofono.SimManager"}; | ||
2368 | 648 | return s; | ||
2369 | 649 | } | ||
2370 | 650 | |||
2371 | 651 | struct GetProperties | ||
2372 | 652 | { | ||
2373 | 653 | static const std::string& name() | ||
2374 | 654 | { | ||
2375 | 655 | static const std::string s{"GetProperties"}; | ||
2376 | 656 | return s; | ||
2377 | 657 | } | ||
2378 | 658 | |||
2379 | 659 | typedef SimManager Interface; | ||
2380 | 660 | typedef std::map<std::string, core::dbus::types::Variant> ValueType; | ||
2381 | 661 | |||
2382 | 662 | static std::chrono::milliseconds default_timeout() | ||
2383 | 663 | { | ||
2384 | 664 | return std::chrono::seconds{1}; | ||
2385 | 665 | } | ||
2386 | 666 | }; | ||
2387 | 667 | |||
2388 | 668 | struct PropertyChanged | ||
2389 | 669 | { | ||
2390 | 670 | inline static std::string name() | ||
2391 | 671 | { | ||
2392 | 672 | return "PropertyChanged"; | ||
2393 | 673 | } | ||
2394 | 674 | |||
2395 | 675 | typedef SimManager Interface; | ||
2396 | 676 | |||
2397 | 677 | typedef std::tuple<std::string, core::dbus::types::Variant> ArgumentType; | ||
2398 | 678 | }; | ||
2399 | 679 | |||
2400 | 680 | struct Present | ||
2401 | 681 | { | ||
2402 | 682 | static const std::string& name() | ||
2403 | 683 | { | ||
2404 | 684 | static const std::string s{"Present"}; | ||
2405 | 685 | return s; | ||
2406 | 686 | } | ||
2407 | 687 | |||
2408 | 688 | typedef SimManager Interface; | ||
2409 | 689 | typedef bool ValueType; | ||
2410 | 690 | static const bool readable = true; | ||
2411 | 691 | static const bool writable = false; | ||
2412 | 692 | }; | ||
2413 | 693 | |||
2414 | 694 | struct SubscriberIdentity | ||
2415 | 695 | { | ||
2416 | 696 | static const std::string& name() | ||
2417 | 697 | { | ||
2418 | 698 | static const std::string s{"SubscriberIdentity"}; | ||
2419 | 699 | return s; | ||
2420 | 700 | } | ||
2421 | 701 | |||
2422 | 702 | typedef SimManager Interface; | ||
2423 | 703 | typedef std::string ValueType; | ||
2424 | 704 | static const bool readable = true; | ||
2425 | 705 | static const bool writable = false; | ||
2426 | 706 | }; | ||
2427 | 707 | |||
2428 | 708 | struct SubscriberNumbers | ||
2429 | 709 | { | ||
2430 | 710 | static const std::string& name() | ||
2431 | 711 | { | ||
2432 | 712 | static const std::string s{"SubscriberNumbers"}; | ||
2433 | 713 | return s; | ||
2434 | 714 | } | ||
2435 | 715 | |||
2436 | 716 | typedef SimManager Interface; | ||
2437 | 717 | typedef std::vector<std::string> ValueType; | ||
2438 | 718 | static const bool readable = true; | ||
2439 | 719 | static const bool writable = false; | ||
2440 | 720 | }; | ||
2441 | 721 | |||
2442 | 722 | SimManager(const std::shared_ptr<core::dbus::Object>& object) | ||
2443 | 723 | : object(object) | ||
2444 | 724 | { | ||
2445 | 725 | } | ||
2446 | 726 | |||
2447 | 727 | template<typename Property> | ||
2448 | 728 | void async_get(const std::function<void(const typename Property::ValueType& result)>& cb) const | ||
2449 | 729 | { | ||
2450 | 730 | object->invoke_method_asynchronously_with_callback<GetProperties, GetProperties::ValueType>( | ||
2451 | 731 | [cb](const core::dbus::Result<GetProperties::ValueType>& result) | ||
2452 | 732 | { | ||
2453 | 733 | if (result.is_error()) | ||
2454 | 734 | { | ||
2455 | 735 | LOG(WARNING) << "Failed to query properties: " << result.error().print(); | ||
2456 | 736 | return; | ||
2457 | 737 | } | ||
2458 | 738 | |||
2459 | 739 | auto properties = result.value(); | ||
2460 | 740 | auto it = properties.find(Property::name()); | ||
2461 | 741 | |||
2462 | 742 | if (it == properties.end()) | ||
2463 | 743 | { | ||
2464 | 744 | VLOG(1) << "Could not find property for name " << Property::name(); | ||
2465 | 745 | return; | ||
2466 | 746 | } | ||
2467 | 747 | |||
2468 | 748 | cb(it->second.template as<typename Property::ValueType>()); | ||
2469 | 749 | }); | ||
2470 | 750 | } | ||
2471 | 751 | |||
2472 | 752 | std::shared_ptr<core::dbus::Object> object; | ||
2473 | 753 | }; | ||
2474 | 754 | |||
2475 | 643 | Modem(const std::shared_ptr<core::dbus::Service>& service, | 755 | Modem(const std::shared_ptr<core::dbus::Service>& service, |
2476 | 644 | const std::shared_ptr<core::dbus::Object>& object) | 756 | const std::shared_ptr<core::dbus::Object>& object) |
2477 | 645 | : service(service), | 757 | : service(service), |
2478 | @@ -648,7 +760,8 @@ | |||
2479 | 648 | { | 760 | { |
2480 | 649 | object->get_signal<PropertyChanged>() | 761 | object->get_signal<PropertyChanged>() |
2481 | 650 | }, | 762 | }, |
2483 | 651 | network_registration{object} | 763 | network_registration{object}, |
2484 | 764 | sim_manager{object} | ||
2485 | 652 | { | 765 | { |
2486 | 653 | } | 766 | } |
2487 | 654 | 767 | ||
2488 | @@ -661,6 +774,7 @@ | |||
2489 | 661 | } signals; | 774 | } signals; |
2490 | 662 | 775 | ||
2491 | 663 | NetworkRegistration network_registration; | 776 | NetworkRegistration network_registration; |
2492 | 777 | SimManager sim_manager; | ||
2493 | 664 | }; | 778 | }; |
2494 | 665 | 779 | ||
2495 | 666 | Manager(const core::dbus::Bus::Ptr& bus) | 780 | Manager(const core::dbus::Bus::Ptr& bus) |
2496 | 667 | 781 | ||
2497 | === modified file 'src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp' | |||
2498 | --- src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2015-12-02 12:00:25 +0000 | |||
2499 | +++ src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2016-03-10 19:55:08 +0000 | |||
2500 | @@ -126,6 +126,33 @@ | |||
2501 | 126 | return d.active_connection_characteristics; | 126 | return d.active_connection_characteristics; |
2502 | 127 | } | 127 | } |
2503 | 128 | 128 | ||
2504 | 129 | void connectivity::OfonoNmConnectivityManager::enumerate_imsis(const std::function<void(const std::string&)>& cb) const | ||
2505 | 130 | { | ||
2506 | 131 | std::lock_guard<std::mutex> lg(d.cached.guard); | ||
2507 | 132 | |||
2508 | 133 | for (const auto& modem : d.cached.modems) | ||
2509 | 134 | { | ||
2510 | 135 | modem.second.sim_manager.async_get<org::Ofono::Manager::Modem::SimManager::SubscriberIdentity>([cb](const std::string& imsi) | ||
2511 | 136 | { | ||
2512 | 137 | cb(imsi); | ||
2513 | 138 | }); | ||
2514 | 139 | } | ||
2515 | 140 | } | ||
2516 | 141 | |||
2517 | 142 | void connectivity::OfonoNmConnectivityManager::enumerate_msisdns(const std::function<void(const std::string&)>& cb) const | ||
2518 | 143 | { | ||
2519 | 144 | std::lock_guard<std::mutex> lg(d.cached.guard); | ||
2520 | 145 | |||
2521 | 146 | for (const auto& modem : d.cached.modems) | ||
2522 | 147 | { | ||
2523 | 148 | modem.second.sim_manager.async_get<org::Ofono::Manager::Modem::SimManager::SubscriberNumbers>([cb](const std::vector<std::string>& msisdns) | ||
2524 | 149 | { | ||
2525 | 150 | for (const auto& nr : msisdns) | ||
2526 | 151 | cb(nr); | ||
2527 | 152 | }); | ||
2528 | 153 | } | ||
2529 | 154 | } | ||
2530 | 155 | |||
2531 | 129 | connectivity::OfonoNmConnectivityManager::Private::Private(const core::dbus::Bus::Ptr& bus) | 156 | connectivity::OfonoNmConnectivityManager::Private::Private(const core::dbus::Bus::Ptr& bus) |
2532 | 130 | : bus{bus}, | 157 | : bus{bus}, |
2533 | 131 | bus_daemon{std::make_shared<core::dbus::DBus>(bus)} | 158 | bus_daemon{std::make_shared<core::dbus::DBus>(bus)} |
2534 | @@ -340,11 +367,16 @@ | |||
2535 | 340 | auto itt = cached.cells.find(path); | 367 | auto itt = cached.cells.find(path); |
2536 | 341 | const bool has_cell_for_modem = itt != cached.cells.end(); | 368 | const bool has_cell_for_modem = itt != cached.cells.end(); |
2537 | 342 | 369 | ||
2539 | 343 | auto it = std::find( | 370 | auto itnr = std::find( |
2540 | 344 | interfaces.begin(), | 371 | interfaces.begin(), |
2541 | 345 | interfaces.end(), | 372 | interfaces.end(), |
2542 | 346 | std::string{org::Ofono::Manager::Modem::Properties::Interfaces::network_registration}); | 373 | std::string{org::Ofono::Manager::Modem::Properties::Interfaces::network_registration}); |
2544 | 347 | const bool modem_has_network_registration = it != interfaces.end(); | 374 | auto itsm = std::find( |
2545 | 375 | interfaces.begin(), | ||
2546 | 376 | interfaces.end(), | ||
2547 | 377 | std::string{org::Ofono::Manager::Modem::Properties::Interfaces::sim_manager}); | ||
2548 | 378 | const bool modem_has_network_registration = itnr != interfaces.end(); | ||
2549 | 379 | const bool modem_has_sim_manager = itnr != interfaces.end(); | ||
2550 | 348 | 380 | ||
2551 | 349 | if (has_cell_for_modem and not modem_has_network_registration) | 381 | if (has_cell_for_modem and not modem_has_network_registration) |
2552 | 350 | { | 382 | { |
2553 | 351 | 383 | ||
2554 | === modified file 'src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h' | |||
2555 | --- src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h 2015-04-27 15:44:40 +0000 | |||
2556 | +++ src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h 2016-03-10 19:55:08 +0000 | |||
2557 | @@ -52,7 +52,7 @@ | |||
2558 | 52 | namespace dbus = core::dbus; | 52 | namespace dbus = core::dbus; |
2559 | 53 | 53 | ||
2560 | 54 | namespace com { namespace ubuntu { namespace location { namespace connectivity { | 54 | namespace com { namespace ubuntu { namespace location { namespace connectivity { |
2562 | 55 | struct OfonoNmConnectivityManager : public com::ubuntu::location::connectivity::Manager | 55 | struct OfonoNmConnectivityManager : public com::ubuntu::location::connectivity::ExtendedManager |
2563 | 56 | { | 56 | { |
2564 | 57 | // Creates an instance of the manager, resolving services on the given bus. | 57 | // Creates an instance of the manager, resolving services on the given bus. |
2565 | 58 | OfonoNmConnectivityManager(const core::dbus::Bus::Ptr& bus); | 58 | OfonoNmConnectivityManager(const core::dbus::Bus::Ptr& bus); |
2566 | @@ -82,6 +82,10 @@ | |||
2567 | 82 | 82 | ||
2568 | 83 | const core::Property<com::ubuntu::location::connectivity::Characteristics>& active_connection_characteristics() const; | 83 | const core::Property<com::ubuntu::location::connectivity::Characteristics>& active_connection_characteristics() const; |
2569 | 84 | 84 | ||
2570 | 85 | void enumerate_imsis(const std::function<void(const std::string&)>&) const override; | ||
2571 | 86 | |||
2572 | 87 | void enumerate_msisdns(const std::function<void(const std::string&)>&) const override; | ||
2573 | 88 | |||
2574 | 85 | struct Private | 89 | struct Private |
2575 | 86 | { | 90 | { |
2576 | 87 | Private(const core::dbus::Bus::Ptr& bus); | 91 | Private(const core::dbus::Bus::Ptr& bus); |
2577 | 88 | 92 | ||
2578 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt' | |||
2579 | --- src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2014-07-28 19:14:58 +0000 | |||
2580 | +++ src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2016-03-10 19:55:08 +0000 | |||
2581 | @@ -4,30 +4,34 @@ | |||
2582 | 4 | ON | 4 | ON |
2583 | 5 | ) | 5 | ) |
2584 | 6 | 6 | ||
2592 | 7 | if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER) | 7 | if ((LOCATION_SERVICE_ENABLE_GPS_PROVIDER) AND (UBUNTU_PLATFORM_HARDWARE_API_FOUND)) |
2586 | 8 | find_file( | ||
2587 | 9 | UBUNTU_HARDWARE_GPS_H gps.h | ||
2588 | 10 | NAMES ubuntu/hardware/gps.h | ||
2589 | 11 | ) | ||
2590 | 12 | |||
2591 | 13 | if (UBUNTU_HARDWARE_GPS_H) | ||
2593 | 14 | message(STATUS "Enabling GPS location provider") | 8 | message(STATUS "Enabling GPS location provider") |
2594 | 15 | 9 | ||
2595 | 10 | include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS}) | ||
2596 | 11 | |||
2597 | 16 | add_library( | 12 | add_library( |
2598 | 17 | gps | 13 | gps |
2599 | 18 | 14 | ||
2600 | 19 | gps.conf | 15 | gps.conf |
2601 | 20 | 16 | ||
2602 | 17 | hardware_abstraction_layer.cpp | ||
2603 | 18 | |||
2604 | 21 | android_hardware_abstraction_layer.h | 19 | android_hardware_abstraction_layer.h |
2605 | 22 | android_hardware_abstraction_layer.cpp | 20 | android_hardware_abstraction_layer.cpp |
2606 | 23 | 21 | ||
2607 | 22 | sntp_reference_time_source.h | ||
2608 | 23 | sntp_reference_time_source.cpp | ||
2609 | 24 | |||
2610 | 25 | sntp_client.h | ||
2611 | 26 | sntp_client.cpp | ||
2612 | 27 | |||
2613 | 24 | hardware_abstraction_layer.h | 28 | hardware_abstraction_layer.h |
2614 | 25 | # hardware_abstraction_layer.cpp | 29 | # hardware_abstraction_layer.cpp |
2615 | 26 | 30 | ||
2616 | 27 | provider.h | 31 | provider.h |
2617 | 28 | provider.cpp) | 32 | provider.cpp) |
2618 | 29 | 33 | ||
2620 | 30 | target_link_libraries(gps ubuntu_platform_hardware_api.so) | 34 | target_link_libraries(gps ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS}) |
2621 | 31 | 35 | ||
2622 | 32 | set( | 36 | set( |
2623 | 33 | ENABLED_PROVIDER_TARGETS | 37 | ENABLED_PROVIDER_TARGETS |
2624 | @@ -41,5 +45,4 @@ | |||
2625 | 41 | ) | 45 | ) |
2626 | 42 | 46 | ||
2627 | 43 | install(FILES gps.conf DESTINATION /etc/) | 47 | install(FILES gps.conf DESTINATION /etc/) |
2630 | 44 | endif (UBUNTU_HARDWARE_GPS_H) | 48 | endif () |
2629 | 45 | endif (LOCATION_SERVICE_ENABLE_GPS_PROVIDER) | ||
2631 | 46 | 49 | ||
2632 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp' | |||
2633 | --- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2015-11-13 10:19:29 +0000 | |||
2634 | +++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2016-03-10 19:55:08 +0000 | |||
2635 | @@ -17,6 +17,7 @@ | |||
2636 | 17 | */ | 17 | */ |
2637 | 18 | 18 | ||
2638 | 19 | #include "android_hardware_abstraction_layer.h" | 19 | #include "android_hardware_abstraction_layer.h" |
2639 | 20 | #include "sntp_reference_time_source.h" | ||
2640 | 20 | 21 | ||
2641 | 21 | #if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP) | 22 | #if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP) |
2642 | 22 | #include "net_cpp_gps_xtra_downloader.h" | 23 | #include "net_cpp_gps_xtra_downloader.h" |
2643 | @@ -93,6 +94,44 @@ | |||
2644 | 93 | return impl.server_ip; | 94 | return impl.server_ip; |
2645 | 94 | } | 95 | } |
2646 | 95 | 96 | ||
2647 | 97 | void android::HardwareAbstractionLayer::SuplAssistant::set_set_id(SetIdType type, const std::string& id) const | ||
2648 | 98 | { | ||
2649 | 99 | u_hardware_gps_agps_set_set_id( | ||
2650 | 100 | impl.hal.impl.gps_handle, | ||
2651 | 101 | static_cast<UHardwareGpsAgpsSetIdType>(type), | ||
2652 | 102 | id.c_str()); | ||
2653 | 103 | } | ||
2654 | 104 | |||
2655 | 105 | |||
2656 | 106 | void android::HardwareAbstractionLayer::SuplAssistant::inject_radio_cell_information(const location::connectivity::RadioCell& cell) const | ||
2657 | 107 | { | ||
2658 | 108 | UHardwareGpsAGpsRefLocation ref_loc; | ||
2659 | 109 | switch (cell.type()) | ||
2660 | 110 | { | ||
2661 | 111 | case location::connectivity::RadioCell::Type::gsm: | ||
2662 | 112 | ref_loc.type = U_HARDWARE_GPS_AGPS_REF_LOCATION_TYPE_GSM_CELLID; | ||
2663 | 113 | ref_loc.u.cellID.mcc = cell.gsm().mobile_country_code; | ||
2664 | 114 | ref_loc.u.cellID.mnc = cell.gsm().mobile_network_code; | ||
2665 | 115 | ref_loc.u.cellID.lac = cell.gsm().location_area_code; | ||
2666 | 116 | ref_loc.u.cellID.cid = cell.gsm().id; | ||
2667 | 117 | break; | ||
2668 | 118 | case location::connectivity::RadioCell::Type::umts: | ||
2669 | 119 | ref_loc.type = U_HARDWARE_GPS_AGPS_REF_LOCATION_TYPE_UMTS_CELLID; | ||
2670 | 120 | ref_loc.u.cellID.mcc = cell.umts().mobile_country_code; | ||
2671 | 121 | ref_loc.u.cellID.mnc = cell.umts().mobile_network_code; | ||
2672 | 122 | ref_loc.u.cellID.lac = cell.umts().location_area_code; | ||
2673 | 123 | ref_loc.u.cellID.cid = cell.umts().id; | ||
2674 | 124 | break; | ||
2675 | 125 | default: | ||
2676 | 126 | return; | ||
2677 | 127 | } | ||
2678 | 128 | |||
2679 | 129 | u_hardware_gps_agps_set_reference_location( | ||
2680 | 130 | impl.hal.impl.gps_handle, | ||
2681 | 131 | &ref_loc, | ||
2682 | 132 | sizeof(ref_loc)); | ||
2683 | 133 | } | ||
2684 | 134 | |||
2685 | 96 | void android::HardwareAbstractionLayer::SuplAssistant::set_server(const std::string& host_name, std::uint16_t port) | 135 | void android::HardwareAbstractionLayer::SuplAssistant::set_server(const std::string& host_name, std::uint16_t port) |
2686 | 97 | { | 136 | { |
2687 | 98 | // TODO(tvoss): Reenable this once the platform api HAL changes land. | 137 | // TODO(tvoss): Reenable this once the platform api HAL changes land. |
2688 | @@ -169,16 +208,47 @@ | |||
2689 | 169 | 208 | ||
2690 | 170 | void android::HardwareAbstractionLayer::on_ril_request_set_id(uint32_t flags, void* context) | 209 | void android::HardwareAbstractionLayer::on_ril_request_set_id(uint32_t flags, void* context) |
2691 | 171 | { | 210 | { |
2695 | 172 | VLOG(1) << __PRETTY_FUNCTION__ << ": " | 211 | VLOG(1) << __PRETTY_FUNCTION__ << ": " << "flags=" << flags << " " << "context=" << context; |
2696 | 173 | << "flags=" << flags << " " | 212 | |
2697 | 174 | << "context=" << context; | 213 | if (auto thiz = static_cast<android::HardwareAbstractionLayer*>(context)) |
2698 | 214 | { | ||
2699 | 215 | switch (flags) | ||
2700 | 216 | { | ||
2701 | 217 | case U_HARDWARE_GPS_AGPS_REQUEST_SETID_IMSI: | ||
2702 | 218 | thiz->impl.connectivity_manager->enumerate_imsis([thiz](const std::string& imsi) | ||
2703 | 219 | { | ||
2704 | 220 | thiz->impl.supl_assistant.set_set_id(SuplAssistant::SetIdType::imsi, imsi); | ||
2705 | 221 | }); | ||
2706 | 222 | break; | ||
2707 | 223 | case U_HARDWARE_GPS_AGPS_REQUEST_SETID_MSISDN: | ||
2708 | 224 | thiz->impl.connectivity_manager->enumerate_msisdns([thiz](const std::string& msisdn) | ||
2709 | 225 | { | ||
2710 | 226 | thiz->impl.supl_assistant.set_set_id(SuplAssistant::SetIdType::msisdn, msisdn); | ||
2711 | 227 | }); | ||
2712 | 228 | break; | ||
2713 | 229 | } | ||
2714 | 230 | } | ||
2715 | 175 | } | 231 | } |
2716 | 176 | 232 | ||
2717 | 177 | void android::HardwareAbstractionLayer::on_ril_request_reference_location(uint32_t flags, void* context) | 233 | void android::HardwareAbstractionLayer::on_ril_request_reference_location(uint32_t flags, void* context) |
2718 | 178 | { | 234 | { |
2722 | 179 | VLOG(1) << __PRETTY_FUNCTION__ << ": " | 235 | VLOG(1) << __PRETTY_FUNCTION__ << ": " << "flags=" << flags << " " << "context=" << context; |
2723 | 180 | << "flags=" << flags << " " | 236 | |
2724 | 181 | << "context=" << context; | 237 | if (auto thiz = static_cast<android::HardwareAbstractionLayer*>(context)) |
2725 | 238 | { | ||
2726 | 239 | switch (flags) | ||
2727 | 240 | { | ||
2728 | 241 | case U_HARDWARE_GPS_AGPS_REQUEST_REFLOC_CELLID: | ||
2729 | 242 | thiz->impl.connectivity_manager->enumerate_connected_radio_cells([thiz](const connectivity::RadioCell::Ptr& cell) | ||
2730 | 243 | { | ||
2731 | 244 | thiz->impl.supl_assistant.inject_radio_cell_information(*cell); | ||
2732 | 245 | }); | ||
2733 | 246 | break; | ||
2734 | 247 | case U_HARDWARE_GPS_AGPS_REQUEST_REFLOC_MAC: | ||
2735 | 248 | default: | ||
2736 | 249 | break; | ||
2737 | 250 | } | ||
2738 | 251 | } | ||
2739 | 182 | } | 252 | } |
2740 | 183 | 253 | ||
2741 | 184 | void android::HardwareAbstractionLayer::on_location_update(UHardwareGpsLocation* location, void* context) | 254 | void android::HardwareAbstractionLayer::on_location_update(UHardwareGpsLocation* location, void* context) |
2742 | @@ -323,23 +393,18 @@ | |||
2743 | 323 | { | 393 | { |
2744 | 324 | VLOG(1) << __PRETTY_FUNCTION__; | 394 | VLOG(1) << __PRETTY_FUNCTION__; |
2745 | 325 | 395 | ||
2763 | 326 | auto thiz = static_cast<android::HardwareAbstractionLayer*>(context); | 396 | try |
2764 | 327 | 397 | { | |
2765 | 328 | if (thiz->impl.utc_time_request_handler) | 398 | if (auto thiz = static_cast<android::HardwareAbstractionLayer*>(context)) |
2766 | 329 | { | 399 | thiz->inject_reference_time(thiz->impl.reference_time_source->sample()); |
2767 | 330 | thiz->impl.utc_time_request_handler(); | 400 | } |
2768 | 331 | } else | 401 | catch (const std::runtime_error& e) |
2769 | 332 | { | 402 | { |
2770 | 333 | auto now = location::Clock::now().time_since_epoch(); | 403 | LOG(WARNING) << "Failed to inject reference time to chipset: " << e.what(); |
2771 | 334 | auto ms_since_epoch = std::chrono::duration_cast<std::chrono::milliseconds>(now); | 404 | } |
2772 | 335 | 405 | catch (...) | |
2773 | 336 | static const int zero_uncertainty = 0; | 406 | { |
2774 | 337 | 407 | LOG(WARNING) << "Failed to inject reference time to chipset."; | |
2758 | 338 | u_hardware_gps_inject_time( | ||
2759 | 339 | thiz->impl.gps_handle, | ||
2760 | 340 | ms_since_epoch.count(), | ||
2761 | 341 | ms_since_epoch.count(), | ||
2762 | 342 | zero_uncertainty); | ||
2775 | 343 | } | 408 | } |
2776 | 344 | } | 409 | } |
2777 | 345 | 410 | ||
2778 | @@ -534,19 +599,22 @@ | |||
2779 | 534 | return true; | 599 | return true; |
2780 | 535 | } | 600 | } |
2781 | 536 | 601 | ||
2785 | 537 | bool android::HardwareAbstractionLayer::inject_reference_time( | 602 | bool android::HardwareAbstractionLayer::inject_reference_time(const ReferenceTimeSample& sample) |
2783 | 538 | const std::chrono::microseconds& reference_time, | ||
2784 | 539 | const std::chrono::microseconds& sample_time) | ||
2786 | 540 | { | 603 | { |
2787 | 541 | if (!is_capable_of(gps::Capability::on_demand_time_injection)) | 604 | if (!is_capable_of(gps::Capability::on_demand_time_injection)) |
2788 | 542 | return false; | 605 | return false; |
2789 | 543 | 606 | ||
2790 | 544 | // TODO(tvoss): We should expose the int return type of the underyling | 607 | // TODO(tvoss): We should expose the int return type of the underyling |
2791 | 545 | // Android HAL to capture errors here. | 608 | // Android HAL to capture errors here. |
2792 | 609 | // | ||
2793 | 610 | // Please see: | ||
2794 | 611 | // http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/net/SntpClient.java#72 | ||
2795 | 612 | // for the bloody details of relating the system wall clock time to the elapsed realtime since boot | ||
2796 | 613 | // including deep sleep. | ||
2797 | 546 | u_hardware_gps_inject_time(impl.gps_handle, | 614 | u_hardware_gps_inject_time(impl.gps_handle, |
2801 | 547 | reference_time.count(), | 615 | sample.since_epoch.count(), |
2802 | 548 | sample_time.count(), | 616 | sample.since_boot.count(), |
2803 | 549 | 10); | 617 | sample.uncertainty.count()); |
2804 | 550 | return true; | 618 | return true; |
2805 | 551 | } | 619 | } |
2806 | 552 | 620 | ||
2807 | @@ -557,6 +625,8 @@ | |||
2808 | 557 | assistance_mode(gps::AssistanceMode::mobile_station_based), | 625 | assistance_mode(gps::AssistanceMode::mobile_station_based), |
2809 | 558 | position_mode(gps::PositionMode::periodic), | 626 | position_mode(gps::PositionMode::periodic), |
2810 | 559 | supl_assistant(*parent), | 627 | supl_assistant(*parent), |
2811 | 628 | connectivity_manager(configuration.connectivity_manager), | ||
2812 | 629 | reference_time_source(configuration.reference_time_source), | ||
2813 | 560 | gps_xtra_configuration(configuration.gps_xtra.configuration), | 630 | gps_xtra_configuration(configuration.gps_xtra.configuration), |
2814 | 561 | gps_xtra_downloader(configuration.gps_xtra.downloader) | 631 | gps_xtra_downloader(configuration.gps_xtra.downloader) |
2815 | 562 | { | 632 | { |
2816 | @@ -615,6 +685,22 @@ | |||
2817 | 615 | 685 | ||
2818 | 616 | namespace | 686 | namespace |
2819 | 617 | { | 687 | { |
2820 | 688 | gps::SntpReferenceTimeSource::Configuration sntp_reference_time_source_configuration(std::istream& in) | ||
2821 | 689 | { | ||
2822 | 690 | gps::SntpReferenceTimeSource::Configuration config; | ||
2823 | 691 | |||
2824 | 692 | try | ||
2825 | 693 | { | ||
2826 | 694 | config = gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(in); | ||
2827 | 695 | } | ||
2828 | 696 | catch (...) | ||
2829 | 697 | { | ||
2830 | 698 | // Consciously dropping all exceptions here. | ||
2831 | 699 | } | ||
2832 | 700 | |||
2833 | 701 | return config; | ||
2834 | 702 | } | ||
2835 | 703 | |||
2836 | 618 | android::GpsXtraDownloader::Configuration gps_xtra_downloader_configuration(std::istream& in) | 704 | android::GpsXtraDownloader::Configuration gps_xtra_downloader_configuration(std::istream& in) |
2837 | 619 | { | 705 | { |
2838 | 620 | android::GpsXtraDownloader::Configuration config; | 706 | android::GpsXtraDownloader::Configuration config; |
2839 | @@ -641,6 +727,8 @@ | |||
2840 | 641 | 727 | ||
2841 | 642 | return config; | 728 | return config; |
2842 | 643 | } | 729 | } |
2843 | 730 | |||
2844 | 731 | |||
2845 | 644 | } | 732 | } |
2846 | 645 | 733 | ||
2847 | 646 | std::shared_ptr<gps::HardwareAbstractionLayer> gps::HardwareAbstractionLayer::create_default_instance() | 734 | std::shared_ptr<gps::HardwareAbstractionLayer> gps::HardwareAbstractionLayer::create_default_instance() |
2848 | @@ -664,7 +752,9 @@ | |||
2849 | 664 | { | 752 | { |
2850 | 665 | create_xtra_downloader(), | 753 | create_xtra_downloader(), |
2851 | 666 | gps_xtra_downloader_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf)) | 754 | gps_xtra_downloader_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf)) |
2853 | 667 | } | 755 | }, |
2854 | 756 | std::dynamic_pointer_cast<connectivity::ExtendedManager>(connectivity::platform_default_manager()), | ||
2855 | 757 | std::make_shared<gps::SntpReferenceTimeSource>(sntp_reference_time_source_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf))) | ||
2856 | 668 | }; | 758 | }; |
2857 | 669 | 759 | ||
2858 | 670 | static std::shared_ptr<gps::HardwareAbstractionLayer> instance | 760 | static std::shared_ptr<gps::HardwareAbstractionLayer> instance |
2859 | 671 | 761 | ||
2860 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h' | |||
2861 | --- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2015-11-13 10:19:29 +0000 | |||
2862 | +++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2016-03-10 19:55:08 +0000 | |||
2863 | @@ -19,6 +19,9 @@ | |||
2864 | 19 | #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_ANDROID_HARDWARE_ABSTRACTION_LAYER_H_ | 19 | #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_ANDROID_HARDWARE_ABSTRACTION_LAYER_H_ |
2865 | 20 | 20 | ||
2866 | 21 | #include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h> | 21 | #include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h> |
2867 | 22 | #include <com/ubuntu/location/providers/gps/sntp_client.h> | ||
2868 | 23 | |||
2869 | 24 | #include <com/ubuntu/location/connectivity/manager.h> | ||
2870 | 22 | 25 | ||
2871 | 23 | #include <ubuntu/hardware/gps.h> | 26 | #include <ubuntu/hardware/gps.h> |
2872 | 24 | 27 | ||
2873 | @@ -66,7 +69,24 @@ | |||
2874 | 66 | }; | 69 | }; |
2875 | 67 | 70 | ||
2876 | 68 | struct HardwareAbstractionLayer : public gps::HardwareAbstractionLayer | 71 | struct HardwareAbstractionLayer : public gps::HardwareAbstractionLayer |
2878 | 69 | { | 72 | { |
2879 | 73 | /** @brief A ReferenceTimeSource provides samples of an arbitrary reference time source. */ | ||
2880 | 74 | class ReferenceTimeSource | ||
2881 | 75 | { | ||
2882 | 76 | public: | ||
2883 | 77 | /** @cond */ | ||
2884 | 78 | typedef std::shared_ptr<ReferenceTimeSource> Ptr; | ||
2885 | 79 | |||
2886 | 80 | virtual ~ReferenceTimeSource() = default; | ||
2887 | 81 | /** @endcond */ | ||
2888 | 82 | |||
2889 | 83 | /** @brief sample returns a sample of the current ReferenceTimeSource. */ | ||
2890 | 84 | virtual ReferenceTimeSample sample() = 0; | ||
2891 | 85 | |||
2892 | 86 | protected: | ||
2893 | 87 | ReferenceTimeSource() = default; | ||
2894 | 88 | }; | ||
2895 | 89 | |||
2896 | 70 | /** @brief Implements gps::HardwareAbstractionLayer::SuplAssistant interface for the android gps HAL. */ | 90 | /** @brief Implements gps::HardwareAbstractionLayer::SuplAssistant interface for the android gps HAL. */ |
2897 | 71 | struct SuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant | 91 | struct SuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant |
2898 | 72 | { | 92 | { |
2899 | @@ -74,6 +94,10 @@ | |||
2900 | 74 | SuplAssistant(android::HardwareAbstractionLayer& hal); | 94 | SuplAssistant(android::HardwareAbstractionLayer& hal); |
2901 | 75 | /** @brief Getable/observable access to the status of the assistant instance. */ | 95 | /** @brief Getable/observable access to the status of the assistant instance. */ |
2902 | 76 | const core::Property<Status>& status() const override; | 96 | const core::Property<Status>& status() const override; |
2903 | 97 | /** @brief Sets mobile subscriber identity. */ | ||
2904 | 98 | void set_set_id(SetIdType type, const std::string& id) const override; | ||
2905 | 99 | /** @brief Injects reference location information. */ | ||
2906 | 100 | void inject_radio_cell_information(const connectivity::RadioCell& radio_cell) const override; | ||
2907 | 77 | /** @brief Getable/setable/observable access to the status of the assistant instance. */ | 101 | /** @brief Getable/setable/observable access to the status of the assistant instance. */ |
2908 | 78 | core::Property<Status>& status(); | 102 | core::Property<Status>& status(); |
2909 | 79 | /** @brief Getable/observable access to the ip the assistance instance uses. */ | 103 | /** @brief Getable/observable access to the ip the assistance instance uses. */ |
2910 | @@ -186,6 +210,9 @@ | |||
2911 | 186 | std::shared_ptr<GpsXtraDownloader> downloader; | 210 | std::shared_ptr<GpsXtraDownloader> downloader; |
2912 | 187 | GpsXtraDownloader::Configuration configuration; | 211 | GpsXtraDownloader::Configuration configuration; |
2913 | 188 | } gps_xtra; | 212 | } gps_xtra; |
2914 | 213 | |||
2915 | 214 | std::shared_ptr<connectivity::ExtendedManager> connectivity_manager; | ||
2916 | 215 | ReferenceTimeSource::Ptr reference_time_source; | ||
2917 | 189 | }; | 216 | }; |
2918 | 190 | 217 | ||
2919 | 191 | HardwareAbstractionLayer(const Configuration& configuration); | 218 | HardwareAbstractionLayer(const Configuration& configuration); |
2920 | @@ -227,8 +254,8 @@ | |||
2921 | 227 | bool set_position_mode(gps::PositionMode mode) override; | 254 | bool set_position_mode(gps::PositionMode mode) override; |
2922 | 228 | 255 | ||
2923 | 229 | bool inject_reference_position(const location::Position& position) override; | 256 | bool inject_reference_position(const location::Position& position) override; |
2926 | 230 | bool inject_reference_time(const std::chrono::microseconds& reference_time, | 257 | bool inject_reference_time(const ReferenceTimeSample& sample) override; |
2927 | 231 | const std::chrono::microseconds& sample_time) override; | 258 | |
2928 | 232 | struct Impl | 259 | struct Impl |
2929 | 233 | { | 260 | { |
2930 | 234 | // Bootstraps access to the GPS chipset, wiring up all callbacks. | 261 | // Bootstraps access to the GPS chipset, wiring up all callbacks. |
2931 | @@ -252,8 +279,10 @@ | |||
2932 | 252 | // An implementation of the gps::HardwareAbstractionLayer::SuplAssistant interface. | 279 | // An implementation of the gps::HardwareAbstractionLayer::SuplAssistant interface. |
2933 | 253 | SuplAssistant supl_assistant; | 280 | SuplAssistant supl_assistant; |
2934 | 254 | 281 | ||
2937 | 255 | // Callback for handling utc time requests. | 282 | // An implementation of connectivity::Manager. |
2938 | 256 | gps::HardwareAbstractionLayer::UtcTimeRequestHandler utc_time_request_handler; | 283 | std::shared_ptr<connectivity::ExtendedManager> connectivity_manager; |
2939 | 284 | // An implementation of ReferenceTimeSource. | ||
2940 | 285 | ReferenceTimeSource::Ptr reference_time_source; | ||
2941 | 257 | 286 | ||
2942 | 258 | // Emitted whenever the set of visible space vehicles changes. | 287 | // Emitted whenever the set of visible space vehicles changes. |
2943 | 259 | core::Signal<std::set<location::SpaceVehicle>> space_vehicle_updates; | 288 | core::Signal<std::set<location::SpaceVehicle>> space_vehicle_updates; |
2944 | 260 | 289 | ||
2945 | === added file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp' | |||
2946 | --- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 1970-01-01 00:00:00 +0000 | |||
2947 | +++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 2016-03-10 19:55:08 +0000 | |||
2948 | @@ -0,0 +1,30 @@ | |||
2949 | 1 | /* | ||
2950 | 2 | * Copyright © 2012-2013 Canonical Ltd. | ||
2951 | 3 | * | ||
2952 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2953 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
2954 | 6 | * as published by the Free Software Foundation. | ||
2955 | 7 | * | ||
2956 | 8 | * This program is distributed in the hope that it will be useful, | ||
2957 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2958 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2959 | 11 | * GNU Lesser General Public License for more details. | ||
2960 | 12 | * | ||
2961 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
2962 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2963 | 15 | * | ||
2964 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
2965 | 17 | */ | ||
2966 | 18 | |||
2967 | 19 | #include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h> | ||
2968 | 20 | |||
2969 | 21 | #include <iostream> | ||
2970 | 22 | |||
2971 | 23 | namespace gps = com::ubuntu::location::providers::gps; | ||
2972 | 24 | |||
2973 | 25 | std::ostream& gps::operator<<(std::ostream& out, const gps::HardwareAbstractionLayer::ReferenceTimeSample& sample) | ||
2974 | 26 | { | ||
2975 | 27 | return out << "[since epoch: " << sample.since_epoch.count() << " [ms], since boot: " | ||
2976 | 28 | << sample.since_boot.count() << " [ms], uncertainty: " | ||
2977 | 29 | << sample.uncertainty.count() << " [ms]"; | ||
2978 | 30 | } | ||
2979 | 0 | 31 | ||
2980 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h' | |||
2981 | --- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2014-06-06 17:52:59 +0000 | |||
2982 | +++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2016-03-10 19:55:08 +0000 | |||
2983 | @@ -18,11 +18,14 @@ | |||
2984 | 18 | #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_ | 18 | #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_ |
2985 | 19 | #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_ | 19 | #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_ |
2986 | 20 | 20 | ||
2987 | 21 | #include <com/ubuntu/location/clock.h> | ||
2988 | 21 | #include <com/ubuntu/location/heading.h> | 22 | #include <com/ubuntu/location/heading.h> |
2989 | 22 | #include <com/ubuntu/location/position.h> | 23 | #include <com/ubuntu/location/position.h> |
2990 | 23 | #include <com/ubuntu/location/space_vehicle.h> | 24 | #include <com/ubuntu/location/space_vehicle.h> |
2991 | 24 | #include <com/ubuntu/location/velocity.h> | 25 | #include <com/ubuntu/location/velocity.h> |
2992 | 25 | 26 | ||
2993 | 27 | #include <com/ubuntu/location/connectivity/radio_cell.h> | ||
2994 | 28 | |||
2995 | 26 | #include <core/property.h> | 29 | #include <core/property.h> |
2996 | 27 | 30 | ||
2997 | 28 | #include <chrono> | 31 | #include <chrono> |
2998 | @@ -104,6 +107,13 @@ | |||
2999 | 104 | class HardwareAbstractionLayer | 107 | class HardwareAbstractionLayer |
3000 | 105 | { | 108 | { |
3001 | 106 | public: | 109 | public: |
3002 | 110 | /** @brief ReferenceTimeSample bundles together the local reference. */ | ||
3003 | 111 | struct ReferenceTimeSample | ||
3004 | 112 | { | ||
3005 | 113 | std::chrono::milliseconds since_epoch; /**< Reference wall-clock time since the epoch (UTC). */ | ||
3006 | 114 | std::chrono::milliseconds since_boot; /**< Reference time since boot. */ | ||
3007 | 115 | std::chrono::milliseconds uncertainty; /**< Uncertainty estimate of the sample. */ | ||
3008 | 116 | }; | ||
3009 | 107 | 117 | ||
3010 | 108 | class SuplAssistant | 118 | class SuplAssistant |
3011 | 109 | { | 119 | { |
3012 | @@ -148,6 +158,16 @@ | |||
3013 | 148 | data_connection_failed = 5 | 158 | data_connection_failed = 5 |
3014 | 149 | }; | 159 | }; |
3015 | 150 | 160 | ||
3016 | 161 | /** | ||
3017 | 162 | * @brief The SetIdType enum enumerates all valid types of SetIds. | ||
3018 | 163 | */ | ||
3019 | 164 | enum class SetIdType | ||
3020 | 165 | { | ||
3021 | 166 | none, | ||
3022 | 167 | imsi, | ||
3023 | 168 | msisdn | ||
3024 | 169 | }; | ||
3025 | 170 | |||
3026 | 151 | virtual ~SuplAssistant() = default; | 171 | virtual ~SuplAssistant() = default; |
3027 | 152 | SuplAssistant(const SuplAssistant&) = delete; | 172 | SuplAssistant(const SuplAssistant&) = delete; |
3028 | 153 | 173 | ||
3029 | @@ -165,6 +185,16 @@ | |||
3030 | 165 | virtual const core::Property<IpV4Address>& server_ip() const = 0; | 185 | virtual const core::Property<IpV4Address>& server_ip() const = 0; |
3031 | 166 | 186 | ||
3032 | 167 | /** | 187 | /** |
3033 | 188 | * @brief Sets mobile subscriber identity. | ||
3034 | 189 | */ | ||
3035 | 190 | virtual void set_set_id(SetIdType type, const std::string& id) const = 0; | ||
3036 | 191 | |||
3037 | 192 | /** | ||
3038 | 193 | * @brief Injects reference location information. | ||
3039 | 194 | */ | ||
3040 | 195 | virtual void inject_radio_cell_information(const connectivity::RadioCell& radio_cell) const = 0; | ||
3041 | 196 | |||
3042 | 197 | /** | ||
3043 | 168 | * @brief set_server informs the assistant instance about the SUPL server it should talk to. | 198 | * @brief set_server informs the assistant instance about the SUPL server it should talk to. |
3044 | 169 | * @param host_name The host name of the SUPL server. | 199 | * @param host_name The host name of the SUPL server. |
3045 | 170 | * @param port The port of the SUPL server. | 200 | * @param port The port of the SUPL server. |
3046 | @@ -304,16 +334,17 @@ | |||
3047 | 304 | 334 | ||
3048 | 305 | /** | 335 | /** |
3049 | 306 | * @brief Injects a new reference time to the underlying gps driver/chipset. | 336 | * @brief Injects a new reference time to the underlying gps driver/chipset. |
3052 | 307 | * @param reference_time The new reference time. | 337 | * @param sample The reference time sample |
3051 | 308 | * @param sample_time When the reference time was sampled. | ||
3053 | 309 | * @return true iff the injection was successful, false otherwise. | 338 | * @return true iff the injection was successful, false otherwise. |
3054 | 310 | */ | 339 | */ |
3057 | 311 | virtual bool inject_reference_time(const std::chrono::microseconds& reference_time, | 340 | virtual bool inject_reference_time(const ReferenceTimeSample& sample) = 0; |
3056 | 312 | const std::chrono::microseconds& sample_time) = 0; | ||
3058 | 313 | 341 | ||
3059 | 314 | protected: | 342 | protected: |
3060 | 315 | HardwareAbstractionLayer() = default; | 343 | HardwareAbstractionLayer() = default; |
3061 | 316 | }; | 344 | }; |
3062 | 345 | |||
3063 | 346 | /** @brief operator<< inserts sample into out. */ | ||
3064 | 347 | std::ostream& operator<<(std::ostream& out, const HardwareAbstractionLayer::ReferenceTimeSample& sample); | ||
3065 | 317 | } | 348 | } |
3066 | 318 | } | 349 | } |
3067 | 319 | } | 350 | } |
3068 | 320 | 351 | ||
3069 | === added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp' | |||
3070 | --- src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 1970-01-01 00:00:00 +0000 | |||
3071 | +++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 2016-03-10 19:55:08 +0000 | |||
3072 | @@ -0,0 +1,210 @@ | |||
3073 | 1 | /* | ||
3074 | 2 | * Copyright © 2012-2013 Canonical Ltd. | ||
3075 | 3 | * | ||
3076 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
3077 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
3078 | 6 | * as published by the Free Software Foundation. | ||
3079 | 7 | * | ||
3080 | 8 | * This program is distributed in the hope that it will be useful, | ||
3081 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3082 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3083 | 11 | * GNU Lesser General Public License for more details. | ||
3084 | 12 | * | ||
3085 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
3086 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3087 | 15 | * | ||
3088 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
3089 | 17 | */ | ||
3090 | 18 | |||
3091 | 19 | #include <com/ubuntu/location/providers/gps/sntp_client.h> | ||
3092 | 20 | |||
3093 | 21 | #include <com/ubuntu/location/time_since_boot.h> | ||
3094 | 22 | |||
3095 | 23 | #include <boost/asio/ip/udp.hpp> | ||
3096 | 24 | #include <boost/endian/buffers.hpp> | ||
3097 | 25 | |||
3098 | 26 | #include <bitset> | ||
3099 | 27 | #include <fstream> | ||
3100 | 28 | #include <future> | ||
3101 | 29 | #include <iostream> | ||
3102 | 30 | #include <thread> | ||
3103 | 31 | |||
3104 | 32 | namespace location = com::ubuntu::location; | ||
3105 | 33 | namespace gps = location::providers::gps; | ||
3106 | 34 | namespace ip = boost::asio::ip; | ||
3107 | 35 | |||
3108 | 36 | namespace | ||
3109 | 37 | { | ||
3110 | 38 | |||
3111 | 39 | template<typename T> | ||
3112 | 40 | T sync_or_throw(std::future<T>& f) | ||
3113 | 41 | { | ||
3114 | 42 | return f.get(); | ||
3115 | 43 | } | ||
3116 | 44 | |||
3117 | 45 | template<> | ||
3118 | 46 | void sync_or_throw<>(std::future<void>& f) | ||
3119 | 47 | { | ||
3120 | 48 | f.get(); | ||
3121 | 49 | } | ||
3122 | 50 | |||
3123 | 51 | struct Now | ||
3124 | 52 | { | ||
3125 | 53 | std::chrono::nanoseconds time = std::chrono::duration_cast<std::chrono::milliseconds>( | ||
3126 | 54 | std::chrono::system_clock::now().time_since_epoch()); | ||
3127 | 55 | std::chrono::nanoseconds ticks = location::time_since_boot(); | ||
3128 | 56 | }; | ||
3129 | 57 | } | ||
3130 | 58 | |||
3131 | 59 | const std::chrono::seconds& gps::sntp::offset_1900_to_1970() | ||
3132 | 60 | { | ||
3133 | 61 | static const std::uint64_t secs = ((365ull * 70ull) + 17ull) * 24ull * 60ull * 60ull; | ||
3134 | 62 | static const std::chrono::seconds seconds{secs}; | ||
3135 | 63 | return seconds; | ||
3136 | 64 | } | ||
3137 | 65 | |||
3138 | 66 | gps::sntp::LeapIndicator gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator() const | ||
3139 | 67 | { | ||
3140 | 68 | return static_cast<LeapIndicator>((livm.value() >> 6) & 0x3); | ||
3141 | 69 | } | ||
3142 | 70 | |||
3143 | 71 | gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator(LeapIndicator li) | ||
3144 | 72 | { | ||
3145 | 73 | livm = livm.value() | (static_cast<uint8_t>(li) << 6); | ||
3146 | 74 | return *this; | ||
3147 | 75 | } | ||
3148 | 76 | |||
3149 | 77 | std::uint8_t gps::sntp::Packet::LeapIndicatorVersionMode::version() const | ||
3150 | 78 | { | ||
3151 | 79 | return (livm.value() >> 3) & 0x7; | ||
3152 | 80 | } | ||
3153 | 81 | |||
3154 | 82 | gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::version(std::uint8_t version) | ||
3155 | 83 | { | ||
3156 | 84 | livm = livm.value() | (version << 3); | ||
3157 | 85 | return *this; | ||
3158 | 86 | } | ||
3159 | 87 | |||
3160 | 88 | gps::sntp::Mode gps::sntp::Packet::LeapIndicatorVersionMode::mode() const | ||
3161 | 89 | { | ||
3162 | 90 | return static_cast<Mode>(livm.value() & 0x7); | ||
3163 | 91 | } | ||
3164 | 92 | |||
3165 | 93 | gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::mode(Mode m) | ||
3166 | 94 | { | ||
3167 | 95 | livm = static_cast<uint8_t>(m) | livm.value(); | ||
3168 | 96 | return *this; | ||
3169 | 97 | } | ||
3170 | 98 | |||
3171 | 99 | gps::sntp::Client::Response gps::sntp::Client::request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios) | ||
3172 | 100 | { | ||
3173 | 101 | ip::udp::resolver resolver{ios}; | ||
3174 | 102 | ip::udp::socket socket{ios}; | ||
3175 | 103 | bool timed_out{false}; | ||
3176 | 104 | |||
3177 | 105 | std::promise<ip::udp::resolver::iterator> promise_resolve; | ||
3178 | 106 | auto future_resolve= promise_resolve.get_future(); | ||
3179 | 107 | |||
3180 | 108 | boost::asio::deadline_timer timer{ios}; | ||
3181 | 109 | timer.expires_from_now(boost::posix_time::milliseconds{timeout.count()}); | ||
3182 | 110 | timer.async_wait([&timed_out, &resolver, &socket](const boost::system::error_code& ec) | ||
3183 | 111 | { | ||
3184 | 112 | if (ec) | ||
3185 | 113 | return; | ||
3186 | 114 | |||
3187 | 115 | timed_out = true; | ||
3188 | 116 | |||
3189 | 117 | resolver.cancel(); | ||
3190 | 118 | socket.shutdown(ip::udp::socket::shutdown_both); | ||
3191 | 119 | socket.close(); | ||
3192 | 120 | }); | ||
3193 | 121 | |||
3194 | 122 | ip::udp::resolver::query query{ip::udp::v4(), host, "ntp"}; | ||
3195 | 123 | |||
3196 | 124 | resolver.async_resolve(query, [&promise_resolve](const boost::system::error_code& ec, ip::udp::resolver::iterator it) | ||
3197 | 125 | { | ||
3198 | 126 | if (ec) | ||
3199 | 127 | promise_resolve.set_exception(std::make_exception_ptr(boost::system::system_error(ec))); | ||
3200 | 128 | else | ||
3201 | 129 | promise_resolve.set_value(it); | ||
3202 | 130 | }); | ||
3203 | 131 | |||
3204 | 132 | auto it = sync_or_throw(future_resolve); | ||
3205 | 133 | |||
3206 | 134 | std::promise<void> promise_connect; | ||
3207 | 135 | auto future_connect = promise_connect.get_future(); | ||
3208 | 136 | |||
3209 | 137 | socket.async_connect(*it, [&promise_connect](const boost::system::error_code& ec) | ||
3210 | 138 | { | ||
3211 | 139 | if (ec) | ||
3212 | 140 | promise_connect.set_exception(std::make_exception_ptr(boost::system::system_error(ec))); | ||
3213 | 141 | else | ||
3214 | 142 | promise_connect.set_value(); | ||
3215 | 143 | }); | ||
3216 | 144 | |||
3217 | 145 | sync_or_throw(future_connect); | ||
3218 | 146 | |||
3219 | 147 | sntp::Packet packet; | ||
3220 | 148 | |||
3221 | 149 | Now before; | ||
3222 | 150 | { | ||
3223 | 151 | packet = request(socket); | ||
3224 | 152 | timer.cancel(); | ||
3225 | 153 | |||
3226 | 154 | if (timed_out) | ||
3227 | 155 | throw std::runtime_error("Operation timed out."); | ||
3228 | 156 | } | ||
3229 | 157 | Now after; | ||
3230 | 158 | |||
3231 | 159 | auto originate = packet.originate.to_milliseconds_since_epoch(); | ||
3232 | 160 | auto receive = packet.receive.to_milliseconds_since_epoch(); | ||
3233 | 161 | auto transmit = packet.transmit.to_milliseconds_since_epoch(); | ||
3234 | 162 | |||
3235 | 163 | auto rtt = after.ticks - before.ticks - (transmit - receive); | ||
3236 | 164 | auto offset = ((receive - originate) + (transmit - after.time))/2; | ||
3237 | 165 | |||
3238 | 166 | return | ||
3239 | 167 | { | ||
3240 | 168 | packet, | ||
3241 | 169 | std::chrono::duration_cast<std::chrono::milliseconds>(after.time + offset), | ||
3242 | 170 | std::chrono::duration_cast<std::chrono::milliseconds>(after.ticks), | ||
3243 | 171 | std::chrono::duration_cast<std::chrono::milliseconds>(rtt) | ||
3244 | 172 | }; | ||
3245 | 173 | } | ||
3246 | 174 | |||
3247 | 175 | gps::sntp::Packet gps::sntp::Client::request(boost::asio::ip::udp::socket& socket) | ||
3248 | 176 | { | ||
3249 | 177 | sntp::Packet packet; | ||
3250 | 178 | packet.transmit.from_milliseconds_since_epoch( | ||
3251 | 179 | std::chrono::duration_cast<std::chrono::milliseconds>( | ||
3252 | 180 | std::chrono::system_clock::now().time_since_epoch())); | ||
3253 | 181 | packet.livm.mode(sntp::Mode::client).version(sntp::version); | ||
3254 | 182 | |||
3255 | 183 | std::promise<std::size_t> promise_send; | ||
3256 | 184 | auto future_send = promise_send.get_future(); | ||
3257 | 185 | |||
3258 | 186 | socket.async_send(boost::asio::buffer(&packet, sizeof(packet)), [&promise_send](const boost::system::error_code& ec, std::size_t transferred) | ||
3259 | 187 | { | ||
3260 | 188 | if (ec) | ||
3261 | 189 | promise_send.set_exception(std::make_exception_ptr(boost::system::system_error(ec))); | ||
3262 | 190 | else | ||
3263 | 191 | promise_send.set_value(transferred); | ||
3264 | 192 | }); | ||
3265 | 193 | |||
3266 | 194 | sync_or_throw(future_send); | ||
3267 | 195 | |||
3268 | 196 | std::promise<std::size_t> promise_receive; | ||
3269 | 197 | auto future_receive = promise_receive.get_future(); | ||
3270 | 198 | |||
3271 | 199 | socket.async_receive(boost::asio::buffer(&packet, sizeof(packet)), [&promise_receive](const boost::system::error_code& ec, std::size_t transferred) | ||
3272 | 200 | { | ||
3273 | 201 | if (ec) | ||
3274 | 202 | promise_receive.set_exception(std::make_exception_ptr(boost::system::system_error(ec))); | ||
3275 | 203 | else | ||
3276 | 204 | promise_receive.set_value(transferred); | ||
3277 | 205 | }); | ||
3278 | 206 | |||
3279 | 207 | sync_or_throw(future_receive); | ||
3280 | 208 | |||
3281 | 209 | return packet; | ||
3282 | 210 | } | ||
3283 | 0 | 211 | ||
3284 | === added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.h' | |||
3285 | --- src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 1970-01-01 00:00:00 +0000 | |||
3286 | +++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 2016-03-10 19:55:08 +0000 | |||
3287 | @@ -0,0 +1,210 @@ | |||
3288 | 1 | /* | ||
3289 | 2 | * Copyright © 2012-2013 Canonical Ltd. | ||
3290 | 3 | * | ||
3291 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
3292 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
3293 | 6 | * as published by the Free Software Foundation. | ||
3294 | 7 | * | ||
3295 | 8 | * This program is distributed in the hope that it will be useful, | ||
3296 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3297 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3298 | 11 | * GNU Lesser General Public License for more details. | ||
3299 | 12 | * | ||
3300 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
3301 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3302 | 15 | * | ||
3303 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
3304 | 17 | */ | ||
3305 | 18 | #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_ | ||
3306 | 19 | #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_ | ||
3307 | 20 | |||
3308 | 21 | #include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h> | ||
3309 | 22 | |||
3310 | 23 | #include <boost/asio.hpp> | ||
3311 | 24 | #include <boost/endian/buffers.hpp> | ||
3312 | 25 | |||
3313 | 26 | #include <chrono> | ||
3314 | 27 | #include <string> | ||
3315 | 28 | |||
3316 | 29 | namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps { namespace sntp { | ||
3317 | 30 | // Please see https://tools.ietf.org/html/rfc4330 for a discussion of sntp | ||
3318 | 31 | // and for a detailed explanation of the different types and algorithms. | ||
3319 | 32 | |||
3320 | 33 | namespace detail | ||
3321 | 34 | { | ||
3322 | 35 | // enum_constant returns a compile-time constant assembled from 4 or at least | ||
3323 | 36 | // 3 individual characters. | ||
3324 | 37 | template<std::uint8_t a, std::uint8_t b, std::uint8_t c, std::uint8_t d = 0> | ||
3325 | 38 | constexpr uint32_t enum_constant() | ||
3326 | 39 | { | ||
3327 | 40 | return (a << 24) | (b << 16) | (c << 8) | d; | ||
3328 | 41 | } | ||
3329 | 42 | } | ||
3330 | 43 | |||
3331 | 44 | // offset_1900_to_1970 returns the number of seconds that elapsed between 1900 and 1970. | ||
3332 | 45 | const std::chrono::seconds& offset_1900_to_1970(); | ||
3333 | 46 | |||
3334 | 47 | // LeapIndicator enumerates warnings of an impending | ||
3335 | 48 | // leap second to be inserted/deleted in the last minute of the current | ||
3336 | 49 | // day. | ||
3337 | 50 | enum class LeapIndicator : std::uint8_t | ||
3338 | 51 | { | ||
3339 | 52 | no_warning = 0, | ||
3340 | 53 | last_minute_has_61_seconds = 1, | ||
3341 | 54 | last_minute_has_59_seconds = 2, | ||
3342 | 55 | alarm = 3 | ||
3343 | 56 | }; | ||
3344 | 57 | |||
3345 | 58 | // Mode enumerates the different protocol modes. | ||
3346 | 59 | enum class Mode : std::uint8_t | ||
3347 | 60 | { | ||
3348 | 61 | reserved = 0, | ||
3349 | 62 | symmetric_active = 1, | ||
3350 | 63 | symmetric_passive = 2, | ||
3351 | 64 | client = 3, | ||
3352 | 65 | server = 4, | ||
3353 | 66 | broadcast = 5, | ||
3354 | 67 | reserved_for_control = 6, | ||
3355 | 68 | reserved_for_private_use = 7 | ||
3356 | 69 | }; | ||
3357 | 70 | |||
3358 | 71 | // ReferenceIdentifier enumerates known references for NTP-servers | ||
3359 | 72 | // on stratum 0 or 1. | ||
3360 | 73 | enum class ReferenceIdentifier : std::uint32_t | ||
3361 | 74 | { | ||
3362 | 75 | locl = detail::enum_constant<'L','O','C','L'>(), // uncalibrated local clock | ||
3363 | 76 | cesm = detail::enum_constant<'C','E','S','M'>(), // calibrated Cesium clock | ||
3364 | 77 | rbdm = detail::enum_constant<'R','B','D','M'>(), // calibrated Rubidium clock | ||
3365 | 78 | pps = detail::enum_constant<'P','P','S'>(), // calibrated quartz clock or other pulse-per-second source | ||
3366 | 79 | irig = detail::enum_constant<'I','R','I','G'>(), // Inter-Range Instrumentation Group | ||
3367 | 80 | acts = detail::enum_constant<'A','C','T','S'>(), // NIST telephone modem service | ||
3368 | 81 | usno = detail::enum_constant<'U','S','N','O'>(), // USNO telephone modem service | ||
3369 | 82 | ptb = detail::enum_constant<'P','T','B'>(), // PTB (Germany) telephone modem service | ||
3370 | 83 | tdf = detail::enum_constant<'T','D','F'>(), // Allouis (France) Radio 164 kHz | ||
3371 | 84 | dcf = detail::enum_constant<'D','C','F'>(), // Mainflingen (Germany) Radio 77.5 kHz | ||
3372 | 85 | msf = detail::enum_constant<'M','S', 'F'>(), // Rugby (UK) Radio 60 kHz | ||
3373 | 86 | wwv = detail::enum_constant<'W','W','V'>(), // Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz | ||
3374 | 87 | wwvb = detail::enum_constant<'W','W','V','B'>(), // Boulder (US) Radio 60 kHz | ||
3375 | 88 | wwvh = detail::enum_constant<'W','W','V','H'>(), // Kauai Hawaii (US) Radio 2.5, 5, 10, 15 MHz | ||
3376 | 89 | chu = detail::enum_constant<'C','H','U'>(), // Ottawa (Canada) Radio 3330, 7335, 14670 kHz | ||
3377 | 90 | lorc = detail::enum_constant<'L','O','R','C'>(), // LORAN-C radionavigation system | ||
3378 | 91 | omeg = detail::enum_constant<'O','M','E','G'>(), // OMEGA radionavigation system | ||
3379 | 92 | gps = detail::enum_constant<'G','P','S'>() // Global Positioning Service | ||
3380 | 93 | }; | ||
3381 | 94 | |||
3382 | 95 | // Timestamp models a fixed-point NTP timestamp relative to 01.01.1900 | ||
3383 | 96 | template<typename Seconds, typename FractionalSeconds = Seconds> | ||
3384 | 97 | struct Timestamp | ||
3385 | 98 | { | ||
3386 | 99 | // To stay on the safe side, we only allow for the types specified below. | ||
3387 | 100 | // With that, we make sure that we only ever use endian-save types. | ||
3388 | 101 | static_assert(std::is_same<Seconds, boost::endian::big_int16_buf_t>::value || | ||
3389 | 102 | std::is_same<Seconds, boost::endian::big_uint16_buf_t>::value || | ||
3390 | 103 | std::is_same<Seconds, boost::endian::big_int32_buf_t>::value || | ||
3391 | 104 | std::is_same<Seconds, boost::endian::big_uint32_buf_t>::value, | ||
3392 | 105 | "Timestamp<> only supports boost::endian::big_{{u}int{16,32}}_buf_t"); | ||
3393 | 106 | |||
3394 | 107 | // from_milliseconds_since_epoch fills in seconds/fractional_seconds from | ||
3395 | 108 | // ms, converting to NTP's reference time. | ||
3396 | 109 | void from_milliseconds_since_epoch(const std::chrono::milliseconds& ts) | ||
3397 | 110 | { | ||
3398 | 111 | using s = std::chrono::seconds; | ||
3399 | 112 | using ms = std::chrono::milliseconds; | ||
3400 | 113 | |||
3401 | 114 | auto secs = std::chrono::duration_cast<s>(ts); | ||
3402 | 115 | auto msecs = std::chrono::duration_cast<ms>(ts - secs); | ||
3403 | 116 | |||
3404 | 117 | secs += offset_1900_to_1970(); | ||
3405 | 118 | |||
3406 | 119 | seconds = secs.count(); | ||
3407 | 120 | fractional_seconds = msecs.count() * std::numeric_limits<typename FractionalSeconds::value_type>::max() + 1 / 1000; | ||
3408 | 121 | } | ||
3409 | 122 | |||
3410 | 123 | // to_milliseconds_since_epoch returns a unix timestamp calculated from | ||
3411 | 124 | // an NTP-timestamp. | ||
3412 | 125 | std::chrono::milliseconds to_milliseconds_since_epoch() const | ||
3413 | 126 | { | ||
3414 | 127 | return std::chrono::seconds{seconds.value()} - offset_1900_to_1970() + | ||
3415 | 128 | std::chrono::milliseconds{(fractional_seconds.value() * 1000) / std::numeric_limits<typename FractionalSeconds::value_type>::max()}; | ||
3416 | 129 | } | ||
3417 | 130 | |||
3418 | 131 | Seconds seconds; | ||
3419 | 132 | FractionalSeconds fractional_seconds; | ||
3420 | 133 | }; | ||
3421 | 134 | |||
3422 | 135 | // Duration is just an alias to an sntp::Timestamp. | ||
3423 | 136 | template<typename T, typename U> | ||
3424 | 137 | using Duration = Timestamp<T, U>; | ||
3425 | 138 | |||
3426 | 139 | // Packet models the SNTP wire format. | ||
3427 | 140 | struct Packet | ||
3428 | 141 | { | ||
3429 | 142 | // LeapIndicatorVersionMode helps in handling the bitfield setup | ||
3430 | 143 | // for the first byte of an sntp::Packet in a portable and endianess-safe way. | ||
3431 | 144 | struct LeapIndicatorVersionMode | ||
3432 | 145 | { | ||
3433 | 146 | // leap_indicator extracts the LeapIndicator from the underlying data. | ||
3434 | 147 | LeapIndicator leap_indicator() const; | ||
3435 | 148 | // leap_indicator sets the value of the leap_indicatorin in the underyling | ||
3436 | 149 | // data to li. | ||
3437 | 150 | LeapIndicatorVersionMode& leap_indicator(LeapIndicator li); | ||
3438 | 151 | |||
3439 | 152 | // version extracts the version from the underlying data. | ||
3440 | 153 | std::uint8_t version() const; | ||
3441 | 154 | // version adjusts the version to version in the underlying data. | ||
3442 | 155 | LeapIndicatorVersionMode& version(std::uint8_t version); | ||
3443 | 156 | |||
3444 | 157 | // mode extracts the mode from the underlying data. | ||
3445 | 158 | Mode mode() const; | ||
3446 | 159 | // mode adjusts the mode to m in the underlying data. | ||
3447 | 160 | LeapIndicatorVersionMode& mode(Mode m); | ||
3448 | 161 | |||
3449 | 162 | boost::endian::big_uint8_buf_t livm; | ||
3450 | 163 | }; | ||
3451 | 164 | |||
3452 | 165 | LeapIndicatorVersionMode livm; | ||
3453 | 166 | boost::endian::big_uint8_buf_t stratum; | ||
3454 | 167 | boost::endian::big_uint8_buf_t poll_interval; | ||
3455 | 168 | boost::endian::big_int8_buf_t precision; | ||
3456 | 169 | Duration<boost::endian::big_int16_buf_t, boost::endian::big_uint16_buf_t> root_delay; | ||
3457 | 170 | Duration<boost::endian::big_uint16_buf_t, boost::endian::big_uint16_buf_t> root_dispersion; | ||
3458 | 171 | boost::endian::big_uint32_buf_t reference_identifier; | ||
3459 | 172 | Timestamp<boost::endian::big_uint32_buf_t> reference; | ||
3460 | 173 | Timestamp<boost::endian::big_uint32_buf_t> originate; | ||
3461 | 174 | Timestamp<boost::endian::big_uint32_buf_t> receive; | ||
3462 | 175 | Timestamp<boost::endian::big_uint32_buf_t> transmit; | ||
3463 | 176 | }; | ||
3464 | 177 | // The SNTP version we are working with. | ||
3465 | 178 | static constexpr const std::uint8_t version = 3; | ||
3466 | 179 | |||
3467 | 180 | // SntpClient provides access to querying time from an NTP server in | ||
3468 | 181 | // a unicast scenario. | ||
3469 | 182 | class Client | ||
3470 | 183 | { | ||
3471 | 184 | public: | ||
3472 | 185 | // Response is returned in a request for time information. | ||
3473 | 186 | struct Response | ||
3474 | 187 | { | ||
3475 | 188 | // The raw packet that was returned from the request. | ||
3476 | 189 | sntp::Packet packet; | ||
3477 | 190 | // Time computed from the NTP transaction. | ||
3478 | 191 | std::chrono::milliseconds ntp_time; | ||
3479 | 192 | // Reference clock value corresponding to the NTP time. | ||
3480 | 193 | std::chrono::milliseconds ntp_time_reference; | ||
3481 | 194 | // Round-trip time of the last NTP transaction. | ||
3482 | 195 | std::chrono::milliseconds round_trip_time; | ||
3483 | 196 | }; | ||
3484 | 197 | |||
3485 | 198 | // request_time_with_timeout reaches out to the SNTP server known under host, | ||
3486 | 199 | // and tries to determine the current UTC reference time. The operation aborts after | ||
3487 | 200 | // timeout milliseconds. | ||
3488 | 201 | // | ||
3489 | 202 | // std::runtime_error is thrown in case of issues. | ||
3490 | 203 | Response request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios); | ||
3491 | 204 | sntp::Packet request(boost::asio::ip::udp::socket& socket); | ||
3492 | 205 | }; | ||
3493 | 206 | } | ||
3494 | 207 | } | ||
3495 | 208 | |||
3496 | 209 | }}}} | ||
3497 | 210 | #endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_ | ||
3498 | 0 | 211 | ||
3499 | === added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp' | |||
3500 | --- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 1970-01-01 00:00:00 +0000 | |||
3501 | +++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 2016-03-10 19:55:08 +0000 | |||
3502 | @@ -0,0 +1,57 @@ | |||
3503 | 1 | /* | ||
3504 | 2 | * Copyright © 2012-2013 Canonical Ltd. | ||
3505 | 3 | * | ||
3506 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
3507 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
3508 | 6 | * as published by the Free Software Foundation. | ||
3509 | 7 | * | ||
3510 | 8 | * This program is distributed in the hope that it will be useful, | ||
3511 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3512 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3513 | 11 | * GNU Lesser General Public License for more details. | ||
3514 | 12 | * | ||
3515 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
3516 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3517 | 15 | * | ||
3518 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
3519 | 17 | */ | ||
3520 | 18 | |||
3521 | 19 | #include <com/ubuntu/location/providers/gps/sntp_reference_time_source.h> | ||
3522 | 20 | |||
3523 | 21 | #include <com/ubuntu/location/configuration.h> | ||
3524 | 22 | #include <com/ubuntu/location/service/runtime.h> | ||
3525 | 23 | |||
3526 | 24 | #include <boost/property_tree/ini_parser.hpp> | ||
3527 | 25 | |||
3528 | 26 | #include <future> | ||
3529 | 27 | |||
3530 | 28 | namespace location = com::ubuntu::location; | ||
3531 | 29 | namespace gps = com::ubuntu::location::providers::gps; | ||
3532 | 30 | |||
3533 | 31 | gps::SntpReferenceTimeSource::Configuration gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(std::istream& in) | ||
3534 | 32 | { | ||
3535 | 33 | gps::SntpReferenceTimeSource::Configuration result; | ||
3536 | 34 | |||
3537 | 35 | location::Configuration config; | ||
3538 | 36 | boost::property_tree::read_ini(in, config); | ||
3539 | 37 | |||
3540 | 38 | if (config.count("NTP_SERVER") > 0) | ||
3541 | 39 | result.host = config.get<std::string>("NTP_SERVER"); | ||
3542 | 40 | |||
3543 | 41 | return result; | ||
3544 | 42 | } | ||
3545 | 43 | gps::SntpReferenceTimeSource::SntpReferenceTimeSource(const Configuration& config) | ||
3546 | 44 | : config(config) | ||
3547 | 45 | { | ||
3548 | 46 | } | ||
3549 | 47 | |||
3550 | 48 | gps::HardwareAbstractionLayer::ReferenceTimeSample gps::SntpReferenceTimeSource::sample() | ||
3551 | 49 | { | ||
3552 | 50 | auto rt = location::service::Runtime::create(); | ||
3553 | 51 | rt->start(); | ||
3554 | 52 | |||
3555 | 53 | location::providers::gps::sntp::Client sntp_client; | ||
3556 | 54 | auto result = sntp_client.request_time(config.host, config.timeout, rt->service()); | ||
3557 | 55 | |||
3558 | 56 | return {result.ntp_time, result.ntp_time_reference, result.round_trip_time}; | ||
3559 | 57 | } | ||
3560 | 0 | 58 | ||
3561 | === added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h' | |||
3562 | --- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 1970-01-01 00:00:00 +0000 | |||
3563 | +++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 2016-03-10 19:55:08 +0000 | |||
3564 | @@ -0,0 +1,51 @@ | |||
3565 | 1 | /* | ||
3566 | 2 | * Copyright © 2016 Canonical Ltd. | ||
3567 | 3 | * | ||
3568 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
3569 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
3570 | 6 | * as published by the Free Software Foundation. | ||
3571 | 7 | * | ||
3572 | 8 | * This program is distributed in the hope that it will be useful, | ||
3573 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3574 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3575 | 11 | * GNU Lesser General Public License for more details. | ||
3576 | 12 | * | ||
3577 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
3578 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3579 | 15 | * | ||
3580 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
3581 | 17 | */ | ||
3582 | 18 | #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_ | ||
3583 | 19 | #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_ | ||
3584 | 20 | |||
3585 | 21 | #include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h> | ||
3586 | 22 | |||
3587 | 23 | #include <com/ubuntu/location/providers/gps/sntp_client.h> | ||
3588 | 24 | |||
3589 | 25 | namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps { | ||
3590 | 26 | |||
3591 | 27 | class SntpReferenceTimeSource : public android::HardwareAbstractionLayer::ReferenceTimeSource | ||
3592 | 28 | { | ||
3593 | 29 | public: | ||
3594 | 30 | |||
3595 | 31 | /** @brief Configuration summarizes default parameter available to implementations. */ | ||
3596 | 32 | struct Configuration | ||
3597 | 33 | { | ||
3598 | 34 | /** @brief Reads a configuration from a gps.conf file in INI format. */ | ||
3599 | 35 | static Configuration from_gps_conf_ini_file(std::istream& in); | ||
3600 | 36 | |||
3601 | 37 | std::string host{"pool.ntp.org"}; /**< NTP host. */ | ||
3602 | 38 | std::chrono::milliseconds timeout{5000}; /**< Timeout when querying the NTP server. */ | ||
3603 | 39 | }; | ||
3604 | 40 | |||
3605 | 41 | SntpReferenceTimeSource(const Configuration& configuration); | ||
3606 | 42 | |||
3607 | 43 | gps::HardwareAbstractionLayer::ReferenceTimeSample sample() override; | ||
3608 | 44 | |||
3609 | 45 | private: | ||
3610 | 46 | const Configuration config; | ||
3611 | 47 | }; | ||
3612 | 48 | |||
3613 | 49 | }}}}} | ||
3614 | 50 | |||
3615 | 51 | #endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_ | ||
3616 | 0 | 52 | ||
3617 | === modified file 'src/location_service/com/ubuntu/location/service/runtime.h' | |||
3618 | --- src/location_service/com/ubuntu/location/service/runtime.h 2015-11-25 09:20:12 +0000 | |||
3619 | +++ src/location_service/com/ubuntu/location/service/runtime.h 2016-03-10 19:55:08 +0000 | |||
3620 | @@ -42,7 +42,7 @@ | |||
3621 | 42 | { | 42 | { |
3622 | 43 | public: | 43 | public: |
3623 | 44 | // Our default concurrency setup. | 44 | // Our default concurrency setup. |
3625 | 45 | static constexpr const std::uint32_t worker_threads = 2; | 45 | static constexpr const std::uint32_t worker_threads = 4; |
3626 | 46 | 46 | ||
3627 | 47 | // create returns a Runtime instance with pool_size worker threads | 47 | // create returns a Runtime instance with pool_size worker threads |
3628 | 48 | // executing the underlying service. | 48 | // executing the underlying service. |
3629 | 49 | 49 | ||
3630 | === modified file 'src/location_service/com/ubuntu/location/service/runtime_tests.cpp' | |||
3631 | --- src/location_service/com/ubuntu/location/service/runtime_tests.cpp 2015-01-26 20:15:05 +0000 | |||
3632 | +++ src/location_service/com/ubuntu/location/service/runtime_tests.cpp 2016-03-10 19:55:08 +0000 | |||
3633 | @@ -16,6 +16,7 @@ | |||
3634 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> |
3635 | 17 | */ | 17 | */ |
3636 | 18 | 18 | ||
3637 | 19 | #include <com/ubuntu/location/service/runtime.h> | ||
3638 | 19 | #include <com/ubuntu/location/service/runtime_tests.h> | 20 | #include <com/ubuntu/location/service/runtime_tests.h> |
3639 | 20 | 21 | ||
3640 | 21 | #include <com/ubuntu/location/clock.h> | 22 | #include <com/ubuntu/location/clock.h> |
3641 | 22 | 23 | ||
3642 | === added file 'src/location_service/com/ubuntu/location/time_since_boot.cpp' | |||
3643 | --- src/location_service/com/ubuntu/location/time_since_boot.cpp 1970-01-01 00:00:00 +0000 | |||
3644 | +++ src/location_service/com/ubuntu/location/time_since_boot.cpp 2016-03-10 19:55:08 +0000 | |||
3645 | @@ -0,0 +1,140 @@ | |||
3646 | 1 | /* | ||
3647 | 2 | * Copyright © 2016 Canonical Ltd. | ||
3648 | 3 | * | ||
3649 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
3650 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
3651 | 6 | * as published by the Free Software Foundation. | ||
3652 | 7 | * | ||
3653 | 8 | * This program is distributed in the hope that it will be useful, | ||
3654 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3655 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3656 | 11 | * GNU Lesser General Public License for more details. | ||
3657 | 12 | * | ||
3658 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
3659 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3660 | 15 | * | ||
3661 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
3662 | 17 | */ | ||
3663 | 18 | |||
3664 | 19 | #include <com/ubuntu/location/time_since_boot.h> | ||
3665 | 20 | #include <com/ubuntu/location/logging.h> | ||
3666 | 21 | |||
3667 | 22 | #if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API) | ||
3668 | 23 | #include <ubuntu/hardware/alarm.h> | ||
3669 | 24 | #endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API | ||
3670 | 25 | |||
3671 | 26 | #include <fstream> | ||
3672 | 27 | #include <sstream> | ||
3673 | 28 | #include <stdexcept> | ||
3674 | 29 | #include <system_error> | ||
3675 | 30 | |||
3676 | 31 | namespace location = com::ubuntu::location; | ||
3677 | 32 | |||
3678 | 33 | namespace | ||
3679 | 34 | { | ||
3680 | 35 | bool have_ubuntu_hardware_alarm() | ||
3681 | 36 | { | ||
3682 | 37 | #if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API) | ||
3683 | 38 | return true; | ||
3684 | 39 | #else | ||
3685 | 40 | return false; | ||
3686 | 41 | #endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API | ||
3687 | 42 | } | ||
3688 | 43 | |||
3689 | 44 | std::chrono::nanoseconds from_ubuntu_hardware_alarm() | ||
3690 | 45 | { | ||
3691 | 46 | #if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API) | ||
3692 | 47 | struct Scope | ||
3693 | 48 | { | ||
3694 | 49 | Scope() : alarm{u_hardware_alarm_create()} | ||
3695 | 50 | { | ||
3696 | 51 | } | ||
3697 | 52 | |||
3698 | 53 | ~Scope() | ||
3699 | 54 | { | ||
3700 | 55 | u_hardware_alarm_unref(alarm); | ||
3701 | 56 | } | ||
3702 | 57 | |||
3703 | 58 | UHardwareAlarm alarm{nullptr}; | ||
3704 | 59 | }; | ||
3705 | 60 | |||
3706 | 61 | static Scope scope; | ||
3707 | 62 | |||
3708 | 63 | ::timespec ts; | ||
3709 | 64 | if (not scope.alarm) | ||
3710 | 65 | throw std::runtime_error{"Failed to access UHardwareAlarm subsystem."}; | ||
3711 | 66 | |||
3712 | 67 | if (U_STATUS_SUCCESS != u_hardware_alarm_get_elapsed_real_time(scope.alarm, &ts)) | ||
3713 | 68 | throw std::runtime_error{"Failed to query time since boot from UHardwareAlarm."}; | ||
3714 | 69 | |||
3715 | 70 | return std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}; | ||
3716 | 71 | #else | ||
3717 | 72 | throw std::logic_error{"not implemented"}; | ||
3718 | 73 | #endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API | ||
3719 | 74 | } | ||
3720 | 75 | |||
3721 | 76 | |||
3722 | 77 | std::chrono::nanoseconds from_clock_boottime() | ||
3723 | 78 | { | ||
3724 | 79 | ::timespec ts; | ||
3725 | 80 | if (-1 == clock_gettime(CLOCK_BOOTTIME, &ts)) | ||
3726 | 81 | throw std::system_error(errno, std::system_category()); | ||
3727 | 82 | |||
3728 | 83 | return std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}; | ||
3729 | 84 | } | ||
3730 | 85 | |||
3731 | 86 | std::chrono::nanoseconds boot_time() | ||
3732 | 87 | { | ||
3733 | 88 | std::ifstream in{"/proc/stat"}; | ||
3734 | 89 | std::string line; | ||
3735 | 90 | |||
3736 | 91 | while (std::getline(in, line)) | ||
3737 | 92 | { | ||
3738 | 93 | if (line.empty()) | ||
3739 | 94 | continue; | ||
3740 | 95 | |||
3741 | 96 | std::stringstream ss{line}; | ||
3742 | 97 | std::string name; ss >> name; | ||
3743 | 98 | |||
3744 | 99 | if (name != "btime") | ||
3745 | 100 | continue; | ||
3746 | 101 | |||
3747 | 102 | std::uint64_t ts; ss >> ts; | ||
3748 | 103 | return std::chrono::nanoseconds{std::chrono::seconds{ts}}; | ||
3749 | 104 | } | ||
3750 | 105 | |||
3751 | 106 | throw std::runtime_error{"Failed to determine system boot time."}; | ||
3752 | 107 | } | ||
3753 | 108 | |||
3754 | 109 | std::chrono::nanoseconds from_proc_stat() | ||
3755 | 110 | { | ||
3756 | 111 | static const std::chrono::nanoseconds bt{boot_time()}; | ||
3757 | 112 | return std::chrono::system_clock::now().time_since_epoch() - bt; | ||
3758 | 113 | } | ||
3759 | 114 | } | ||
3760 | 115 | |||
3761 | 116 | std::chrono::nanoseconds location::time_since_boot() | ||
3762 | 117 | { | ||
3763 | 118 | if (have_ubuntu_hardware_alarm()) | ||
3764 | 119 | { | ||
3765 | 120 | try | ||
3766 | 121 | { | ||
3767 | 122 | return from_ubuntu_hardware_alarm(); | ||
3768 | 123 | } | ||
3769 | 124 | catch (const std::exception& e) | ||
3770 | 125 | { | ||
3771 | 126 | VLOG(1) << e.what(); | ||
3772 | 127 | } | ||
3773 | 128 | } | ||
3774 | 129 | |||
3775 | 130 | try | ||
3776 | 131 | { | ||
3777 | 132 | return from_clock_boottime(); | ||
3778 | 133 | } | ||
3779 | 134 | catch (const std::exception& e) | ||
3780 | 135 | { | ||
3781 | 136 | VLOG(1) << e.what(); | ||
3782 | 137 | } | ||
3783 | 138 | |||
3784 | 139 | return from_proc_stat(); | ||
3785 | 140 | } | ||
3786 | 0 | 141 | ||
3787 | === added file 'src/location_service/com/ubuntu/location/time_since_boot.h' | |||
3788 | --- src/location_service/com/ubuntu/location/time_since_boot.h 1970-01-01 00:00:00 +0000 | |||
3789 | +++ src/location_service/com/ubuntu/location/time_since_boot.h 2016-03-10 19:55:08 +0000 | |||
3790 | @@ -0,0 +1,35 @@ | |||
3791 | 1 | /* | ||
3792 | 2 | * Copyright © 2016 Canonical Ltd. | ||
3793 | 3 | * | ||
3794 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
3795 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
3796 | 6 | * as published by the Free Software Foundation. | ||
3797 | 7 | * | ||
3798 | 8 | * This program is distributed in the hope that it will be useful, | ||
3799 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3800 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3801 | 11 | * GNU Lesser General Public License for more details. | ||
3802 | 12 | * | ||
3803 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
3804 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3805 | 15 | * | ||
3806 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
3807 | 17 | */ | ||
3808 | 18 | #ifndef LOCATION_SERVICE_UBUNTU_LOCATION_SERVICE_TIME_SINCE_BOOT_H_ | ||
3809 | 19 | #define LOCATION_SERVICE_UBUNTU_LOCATION_SERVICE_TIME_SINCE_BOOT_H_ | ||
3810 | 20 | |||
3811 | 21 | #include <chrono> | ||
3812 | 22 | |||
3813 | 23 | namespace com | ||
3814 | 24 | { | ||
3815 | 25 | namespace ubuntu | ||
3816 | 26 | { | ||
3817 | 27 | namespace location | ||
3818 | 28 | { | ||
3819 | 29 | /** @brief time_since_boot returns the nanoseconds that elapsed since boot. */ | ||
3820 | 30 | std::chrono::nanoseconds time_since_boot(); | ||
3821 | 31 | } | ||
3822 | 32 | } | ||
3823 | 33 | } | ||
3824 | 34 | |||
3825 | 35 | #endif // LOCATION_SERVICE_UBUNTU_LOCATION_SERVICE_TIME_SINCE_BOOT_H_ | ||
3826 | 0 | 36 | ||
3827 | === modified file 'tests/CMakeLists.txt' | |||
3828 | --- tests/CMakeLists.txt 2015-12-01 14:36:55 +0000 | |||
3829 | +++ tests/CMakeLists.txt 2016-03-10 19:55:08 +0000 | |||
3830 | @@ -98,6 +98,7 @@ | |||
3831 | 98 | if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER) | 98 | if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER) |
3832 | 99 | include_directories(${CMAKE_SOURCE_DIR}/src/location_service) | 99 | include_directories(${CMAKE_SOURCE_DIR}/src/location_service) |
3833 | 100 | LOCATION_SERVICE_ADD_TEST(gps_provider_test gps_provider_test.cpp) | 100 | LOCATION_SERVICE_ADD_TEST(gps_provider_test gps_provider_test.cpp) |
3834 | 101 | LOCATION_SERVICE_ADD_TEST(sntp_client_test sntp_client_test.cpp) | ||
3835 | 101 | endif(LOCATION_SERVICE_ENABLE_GPS_PROVIDER) | 102 | endif(LOCATION_SERVICE_ENABLE_GPS_PROVIDER) |
3836 | 102 | 103 | ||
3837 | 103 | if (LOCATION_SERVICE_ENABLE_GEOCLUE_PROVIDERS) | 104 | if (LOCATION_SERVICE_ENABLE_GEOCLUE_PROVIDERS) |
3838 | 104 | 105 | ||
3839 | === modified file 'tests/gps_provider_test.cpp' | |||
3840 | --- tests/gps_provider_test.cpp 2015-10-19 13:04:06 +0000 | |||
3841 | +++ tests/gps_provider_test.cpp 2016-03-10 19:55:08 +0000 | |||
3842 | @@ -81,6 +81,11 @@ | |||
3843 | 81 | MOCK_METHOD1(on_space_vehicles_updated, void(const std::set<location::SpaceVehicle>&)); | 81 | MOCK_METHOD1(on_space_vehicles_updated, void(const std::set<location::SpaceVehicle>&)); |
3844 | 82 | }; | 82 | }; |
3845 | 83 | 83 | ||
3846 | 84 | struct MockReferenceTimeSource : public gps::android::HardwareAbstractionLayer::ReferenceTimeSource | ||
3847 | 85 | { | ||
3848 | 86 | MOCK_METHOD0(sample, gps::HardwareAbstractionLayer::ReferenceTimeSample()); | ||
3849 | 87 | }; | ||
3850 | 88 | |||
3851 | 84 | struct MockSuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant | 89 | struct MockSuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant |
3852 | 85 | { | 90 | { |
3853 | 86 | MockSuplAssistant() | 91 | MockSuplAssistant() |
3854 | @@ -93,6 +98,8 @@ | |||
3855 | 93 | 98 | ||
3856 | 94 | MOCK_CONST_METHOD0(status, const core::Property<Status>&()); | 99 | MOCK_CONST_METHOD0(status, const core::Property<Status>&()); |
3857 | 95 | MOCK_CONST_METHOD0(server_ip, const core::Property<IpV4Address>&()); | 100 | MOCK_CONST_METHOD0(server_ip, const core::Property<IpV4Address>&()); |
3858 | 101 | MOCK_CONST_METHOD2(set_set_id, void(SetIdType, const std::string&)); | ||
3859 | 102 | MOCK_CONST_METHOD1(inject_radio_cell_information, void(const location::connectivity::RadioCell& radio_cell)); | ||
3860 | 96 | MOCK_METHOD2(set_server, void(const std::string&, std::uint16_t)); | 103 | MOCK_METHOD2(set_server, void(const std::string&, std::uint16_t)); |
3861 | 97 | MOCK_METHOD1(notify_data_connection_open_via_apn, void(const std::string&)); | 104 | MOCK_METHOD1(notify_data_connection_open_via_apn, void(const std::string&)); |
3862 | 98 | MOCK_METHOD0(notify_data_connection_closed, void()); | 105 | MOCK_METHOD0(notify_data_connection_closed, void()); |
3863 | @@ -133,9 +140,7 @@ | |||
3864 | 133 | MOCK_METHOD1(set_assistance_mode, bool(gps::AssistanceMode)); | 140 | MOCK_METHOD1(set_assistance_mode, bool(gps::AssistanceMode)); |
3865 | 134 | MOCK_METHOD1(set_position_mode, bool(gps::PositionMode)); | 141 | MOCK_METHOD1(set_position_mode, bool(gps::PositionMode)); |
3866 | 135 | MOCK_METHOD1(inject_reference_position, bool(const location::Position&)); | 142 | MOCK_METHOD1(inject_reference_position, bool(const location::Position&)); |
3870 | 136 | MOCK_METHOD2(inject_reference_time, | 143 | MOCK_METHOD1(inject_reference_time, bool(const location::providers::gps::HardwareAbstractionLayer::ReferenceTimeSample&)); |
3868 | 137 | bool(const std::chrono::microseconds&, | ||
3869 | 138 | const std::chrono::microseconds&)); | ||
3871 | 139 | 144 | ||
3872 | 140 | MockSuplAssistant supl_assistant_; | 145 | MockSuplAssistant supl_assistant_; |
3873 | 141 | core::Signal<location::Position> position_updates_; | 146 | core::Signal<location::Position> position_updates_; |
3874 | @@ -322,24 +327,54 @@ | |||
3875 | 322 | provider.on_reference_location_updated(pos); | 327 | provider.on_reference_location_updated(pos); |
3876 | 323 | } | 328 | } |
3877 | 324 | 329 | ||
3878 | 330 | TEST(GpsProvider, time_requests_query_reference_time_source) | ||
3879 | 331 | { | ||
3880 | 332 | using namespace ::testing; | ||
3881 | 333 | |||
3882 | 334 | NiceMock<MockHardwareGps> hardwareGps; | ||
3883 | 335 | |||
3884 | 336 | auto mock_reference_time_source = std::make_shared<MockReferenceTimeSource>(); | ||
3885 | 337 | EXPECT_CALL(*mock_reference_time_source, sample()) | ||
3886 | 338 | .Times(1) | ||
3887 | 339 | .WillRepeatedly(Return(gps::HardwareAbstractionLayer::ReferenceTimeSample{})); | ||
3888 | 340 | |||
3889 | 341 | gps::android::HardwareAbstractionLayer::Configuration configuration; | ||
3890 | 342 | configuration.reference_time_source = mock_reference_time_source; | ||
3891 | 343 | gps::android::HardwareAbstractionLayer hal(configuration); | ||
3892 | 344 | |||
3893 | 345 | gps::android::HardwareAbstractionLayer::on_request_utc_time(&hal); | ||
3894 | 346 | } | ||
3895 | 347 | |||
3896 | 325 | TEST(GpsProvider, time_requests_inject_current_time_into_the_hal) | 348 | TEST(GpsProvider, time_requests_inject_current_time_into_the_hal) |
3897 | 326 | { | 349 | { |
3898 | 327 | using namespace ::testing; | 350 | using namespace ::testing; |
3899 | 328 | 351 | ||
3900 | 352 | auto sample_reference_time = []() | ||
3901 | 353 | { | ||
3902 | 354 | auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch()); | ||
3903 | 355 | std::cout << duration.count() << std::endl; | ||
3904 | 356 | return gps::HardwareAbstractionLayer::ReferenceTimeSample{duration, duration, std::chrono::milliseconds{0}}; | ||
3905 | 357 | }; | ||
3906 | 358 | |||
3907 | 329 | NiceMock<MockHardwareGps> hardwareGps; | 359 | NiceMock<MockHardwareGps> hardwareGps; |
3908 | 330 | 360 | ||
3909 | 361 | auto mock_reference_time_source = std::make_shared<MockReferenceTimeSource>(); | ||
3910 | 362 | EXPECT_CALL(*mock_reference_time_source, sample()) | ||
3911 | 363 | .Times(1) | ||
3912 | 364 | .WillRepeatedly(Invoke(sample_reference_time)); | ||
3913 | 365 | |||
3914 | 331 | gps::android::HardwareAbstractionLayer::Configuration configuration; | 366 | gps::android::HardwareAbstractionLayer::Configuration configuration; |
3915 | 367 | configuration.reference_time_source = mock_reference_time_source; | ||
3916 | 332 | gps::android::HardwareAbstractionLayer hal(configuration); | 368 | gps::android::HardwareAbstractionLayer hal(configuration); |
3918 | 333 | std::shared_ptr<gps::HardwareAbstractionLayer> hal_ptr(&hal, [](gps::HardwareAbstractionLayer*){}); | 369 | hal.capabilities() = U_HARDWARE_GPS_CAPABILITY_ON_DEMAND_TIME; |
3919 | 334 | 370 | ||
3920 | 335 | gps::Provider provider(hal_ptr); | ||
3921 | 336 | int64_t time = 0; | 371 | int64_t time = 0; |
3922 | 337 | EXPECT_CALL(hardwareGps, inject_time(_, _, 0)).Times(1).WillOnce(SaveArg<0>(&time)); | 372 | EXPECT_CALL(hardwareGps, inject_time(_, _, 0)).Times(1).WillOnce(SaveArg<0>(&time)); |
3923 | 338 | 373 | ||
3924 | 339 | auto t0 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch()); | 374 | auto t0 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch()); |
3926 | 340 | 375 | //std::this_thread::sleep_for(std::chrono::milliseconds{10}); | |
3927 | 341 | gps::android::HardwareAbstractionLayer::on_request_utc_time(&hal); | 376 | gps::android::HardwareAbstractionLayer::on_request_utc_time(&hal); |
3929 | 342 | 377 | //std::this_thread::sleep_for(std::chrono::milliseconds{10}); | |
3930 | 343 | auto t1 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch()); | 378 | auto t1 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch()); |
3931 | 344 | EXPECT_THAT(time, AllOf(Ge(t0.count()), Le(t1.count()))); | 379 | EXPECT_THAT(time, AllOf(Ge(t0.count()), Le(t1.count()))); |
3932 | 345 | } | 380 | } |
3933 | @@ -929,4 +964,3 @@ | |||
3934 | 929 | static_cast<std::uint64_t>(variance(stats)))).count() | 964 | static_cast<std::uint64_t>(variance(stats)))).count() |
3935 | 930 | << std::endl; | 965 | << std::endl; |
3936 | 931 | } | 966 | } |
3937 | 932 | |||
3938 | 933 | 967 | ||
3939 | === added file 'tests/sntp_client_test.cpp' | |||
3940 | --- tests/sntp_client_test.cpp 1970-01-01 00:00:00 +0000 | |||
3941 | +++ tests/sntp_client_test.cpp 2016-03-10 19:55:08 +0000 | |||
3942 | @@ -0,0 +1,104 @@ | |||
3943 | 1 | /* | ||
3944 | 2 | * Copyright © 2016 Canonical Ltd. | ||
3945 | 3 | * | ||
3946 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
3947 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
3948 | 6 | * as published by the Free Software Foundation. | ||
3949 | 7 | * | ||
3950 | 8 | * This program is distributed in the hope that it will be useful, | ||
3951 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3952 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3953 | 11 | * GNU Lesser General Public License for more details. | ||
3954 | 12 | * | ||
3955 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
3956 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
3957 | 15 | * | ||
3958 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
3959 | 17 | */ | ||
3960 | 18 | |||
3961 | 19 | #include <com/ubuntu/location/providers/gps/sntp_client.h> | ||
3962 | 20 | #include <com/ubuntu/location/service/runtime.h> | ||
3963 | 21 | |||
3964 | 22 | #include <future> | ||
3965 | 23 | |||
3966 | 24 | #include <core/posix/this_process.h> | ||
3967 | 25 | |||
3968 | 26 | #include <gtest/gtest.h> | ||
3969 | 27 | |||
3970 | 28 | namespace env = core::posix::this_process::env; | ||
3971 | 29 | namespace location = com::ubuntu::location; | ||
3972 | 30 | namespace sntp = location::providers::gps::sntp; | ||
3973 | 31 | |||
3974 | 32 | namespace | ||
3975 | 33 | { | ||
3976 | 34 | struct SntpClient : public ::testing::Test | ||
3977 | 35 | { | ||
3978 | 36 | void SetUp() | ||
3979 | 37 | { | ||
3980 | 38 | rt->start(); | ||
3981 | 39 | } | ||
3982 | 40 | |||
3983 | 41 | void TearDown() | ||
3984 | 42 | { | ||
3985 | 43 | rt->stop(); | ||
3986 | 44 | } | ||
3987 | 45 | |||
3988 | 46 | std::shared_ptr<location::service::Runtime> rt = location::service::Runtime::create(); | ||
3989 | 47 | std::string host = env::get("UBUNTU_LOCATION_SERVICE_NTP_HOST_FOR_TESTING", "ntp.ubuntu.com"); | ||
3990 | 48 | }; | ||
3991 | 49 | } | ||
3992 | 50 | |||
3993 | 51 | TEST_F(SntpClient, packet_has_correct_size) | ||
3994 | 52 | { | ||
3995 | 53 | static_assert(sizeof(sntp::Packet) == 48, ""); | ||
3996 | 54 | } | ||
3997 | 55 | |||
3998 | 56 | #pragma GCC diagnostic push | ||
3999 | 57 | #pragma GCC diagnostic ignored "-Wmultichar" | ||
4000 | 58 | TEST(EnumConstant, yields_same_value_as_multibyte_constant) | ||
4001 | 59 | { | ||
4002 | 60 | static_assert(sntp::detail::enum_constant<'L','O','C','L'>() == 'LOCL', ""); | ||
4003 | 61 | } | ||
4004 | 62 | #pragma GCC diagnostic pop | ||
4005 | 63 | |||
4006 | 64 | TEST_F(SntpClient, succeeds_in_querying_time_from_server) | ||
4007 | 65 | { | ||
4008 | 66 | location::providers::gps::sntp::Client sntp_client; | ||
4009 | 67 | try | ||
4010 | 68 | { | ||
4011 | 69 | sntp_client.request_time(host, std::chrono::milliseconds{5000}, rt->service()); | ||
4012 | 70 | } | ||
4013 | 71 | catch(...) | ||
4014 | 72 | { | ||
4015 | 73 | } | ||
4016 | 74 | } | ||
4017 | 75 | |||
4018 | 76 | TEST_F(SntpClient, throws_for_timed_out_operation) | ||
4019 | 77 | { | ||
4020 | 78 | location::providers::gps::sntp::Client sntp_client; | ||
4021 | 79 | EXPECT_ANY_THROW(sntp_client.request_time(host, std::chrono::milliseconds{1}, rt->service())); | ||
4022 | 80 | } | ||
4023 | 81 | |||
4024 | 82 | TEST_F(SntpClient, returns_correct_data_in_packet) | ||
4025 | 83 | { | ||
4026 | 84 | for (unsigned int i = 0; i < 10; i++) | ||
4027 | 85 | { | ||
4028 | 86 | location::providers::gps::sntp::Client sntp_client; | ||
4029 | 87 | try | ||
4030 | 88 | { | ||
4031 | 89 | auto response = sntp_client.request_time(host, std::chrono::milliseconds{1000}, rt->service()); | ||
4032 | 90 | |||
4033 | 91 | EXPECT_LE(0, response.packet.stratum.value()); | ||
4034 | 92 | if (response.packet.stratum.value() <= 1) | ||
4035 | 93 | { | ||
4036 | 94 | std::stringstream ss; ss << response.packet.reference_identifier; | ||
4037 | 95 | EXPECT_TRUE(ss.str().size() > 0); | ||
4038 | 96 | } | ||
4039 | 97 | } | ||
4040 | 98 | catch(...) | ||
4041 | 99 | { | ||
4042 | 100 | // We ignore any exception being thrown as we are working against a real-world server | ||
4043 | 101 | // in a load-test scenario. | ||
4044 | 102 | } | ||
4045 | 103 | } | ||
4046 | 104 | } |