Merge lp:~thomas-voss/location-service/cherry-pick-fwd into lp:location-service/trunk
- cherry-pick-fwd
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Alberto Mardegan |
Approved revision: | 217 |
Merged at revision: | 225 |
Proposed branch: | lp:~thomas-voss/location-service/cherry-pick-fwd |
Merge into: | lp:location-service/trunk |
Diff against target: |
6542 lines (+5190/-291) 73 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 (+17/-0) _clang-format (+56/-0) astyle-config (+43/-0) debian/changelog (+111/-0) debian/source/format (+1/-1) doc/Doxyfile.in (+2/-2) doc/daemon_and_cli.md (+55/-0) doc/debugging.md (+91/-0) doc/hacking.md (+146/-0) doc/intro.md (+67/-0) doc/manual_testing.md (+174/-0) doc/tips_n_tricks.md (+21/-0) examples/service/service.cpp (+14/-15) include/location_service/com/ubuntu/location/provider_factory.h (+3/-0) po/ubuntu-location-service.pot (+7/-11) src/location_service/com/ubuntu/location/CMakeLists.txt (+9/-0) src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp (+12/-6) src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h (+12/-0) src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp (+1/-1) src/location_service/com/ubuntu/location/engine.cpp (+25/-28) src/location_service/com/ubuntu/location/engine.h (+3/-3) src/location_service/com/ubuntu/location/provider_factory.cpp (+14/-0) src/location_service/com/ubuntu/location/providers/config.cpp (+7/-0) src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt (+3/-1) src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp (+42/-0) src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h (+62/-0) 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 (+43/-26) src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h (+26/-6) 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 (+13/-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/providers/remote/provider.cpp (+23/-0) src/location_service/com/ubuntu/location/service/daemon.cpp (+42/-82) src/location_service/com/ubuntu/location/service/daemon_main.cpp (+0/-31) src/location_service/com/ubuntu/location/service/implementation.cpp (+25/-4) src/location_service/com/ubuntu/location/service/provider_daemon.cpp (+17/-16) src/location_service/com/ubuntu/location/service/runtime.cpp (+109/-0) src/location_service/com/ubuntu/location/service/runtime.h (+90/-0) src/location_service/com/ubuntu/location/service/runtime_tests.cpp (+1/-0) src/location_service/com/ubuntu/location/service/session/skeleton.cpp (+21/-3) src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp (+1/-1) src/location_service/com/ubuntu/location/time_based_update_policy.cpp (+4/-3) 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 (+5/-0) tests/acceptance_tests.cpp (+114/-12) tests/bug_1447110.cpp (+66/-0) tests/delayed_service_test.cpp (+193/-0) tests/engine_test.cpp (+4/-13) tests/gps_provider_test.cpp (+119/-4) tests/mock_event_receiver.h (+35/-0) tests/position_test.cpp (+1/-1) tests/remote_providerd_test.cpp (+1/-7) tests/runtime_test.cpp (+118/-0) tests/sntp_client_test.cpp (+104/-0) tools/CMakeLists.txt (+1/-0) tools/symbol_diff.in (+70/-0) |
To merge this branch: | bzr merge lp:~thomas-voss/location-service/cherry-pick-fwd |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alberto Mardegan (community) | Approve | ||
Review via email: mp+277219@code.launchpad.net |
Commit message
[ Alberto Mardegan ]
* Make sure that injected time is given in milliseconds
[ Thomas Voß ]
* Cherry-pick rev. 196 and 199 from lp:location-service. The changes
got accidentally removed by merging the outstanding documentation
branch.
* Handle responses of clients to updates asynchronously. Rely on
dummy:
#1462664, #1387643)
[ Thomas Voß ]
* Add documentation for debugging, hacking and debugging the location
service. Pull manual testing instructions over from the wiki. Add
tools for formatting the source.
[ thomas-voss ]
* Add documentation for debugging, hacking and debugging the location
service. Pull manual testing instructions over from the wiki. Add
tools for formatting the source.
Description of the change
[ Alberto Mardegan ]
* Make sure that injected time is given in milliseconds
[ Thomas Voß ]
* Cherry-pick rev. 196 and 199 from lp:location-service. The changes
got accidentally removed by merging the outstanding documentation
branch.
* Handle responses of clients to updates asynchronously. Rely on
dummy:
#1462664, #1387643)
[ Thomas Voß ]
* Add documentation for debugging, hacking and debugging the location
service. Pull manual testing instructions over from the wiki. Add
tools for formatting the source.
[ thomas-voss ]
* Add documentation for debugging, hacking and debugging the location
service. Pull manual testing instructions over from the wiki. Add
tools for formatting the source.
- 218. By Thomas Voß
-
Adjust default timeout for downloading GPS XTRA data.
- 219. By Thomas Voß
-
[ Alberto Mardegan ]
* Set debian source format to "3.0 (native)"
[ Scott Sweeny ]
* Allow providers to register themselves asynchronously (LP: #1415029)
* Account for changes in trust-store w.r.t. assembling the description
of a trust prompt.
* Fix settings not being applied correctly.
* Ensure that event connections are cleaned up on destruction. (LP:
#1480877)
[ Alberto Mardegan ]
* Send last known position on session start
[ CI Train Bot ]
* New rebuild forced.
[ Thomas Voß ]
* Factor out service::Runtime from daemon.cpp into its own .h/.cpp
pair of files. Add test cases around correct operation of
service::Runtime. added:
src/location_service/ com/ubuntu/ location/ service/ runtime. cpp
src/location_service/ com/ubuntu/ location/ service/ runtime. h
tests/runtime_ test.cpp
[ thomas-voss ]
* Factor out service::Runtime from daemon.cpp into its own .h/.cpp
pair of files. Add test cases around correct operation of
service::Runtime. added:
src/location_service/ com/ubuntu/ location/ service/ runtime. cpp
src/location_service/ com/ubuntu/ location/ service/ runtime. h
tests/runtime_ test.cpp - 220. By Thomas Voß
-
* Add SntpClient for querying reference time information.
* Remove explicit option to disable satellite-based positioning
services. - 221. By Thomas Voß
-
Resync to trunk.
- 222. By Thomas Voß
-
Log to stderr by default, relying on upstart to rotate logs
appropriately. (LP: #1447110)
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-04-01 06:55:25 +0000 |
7 | @@ -0,0 +1,192 @@ |
8 | +// scoped_enum.hpp ---------------------------------------------------------// |
9 | + |
10 | +// Copyright Beman Dawes, 2009 |
11 | +// Copyright (C) 2011-2012 Vicente J. Botet Escriba |
12 | +// Copyright (C) 2012 Anthony Williams |
13 | + |
14 | +// Distributed under the Boost Software License, Version 1.0. |
15 | +// See http://www.boost.org/LICENSE_1_0.txt |
16 | + |
17 | +#ifndef BOOST_CORE_SCOPED_ENUM_HPP |
18 | +#define BOOST_CORE_SCOPED_ENUM_HPP |
19 | + |
20 | +#include <boost/config.hpp> |
21 | + |
22 | +#ifdef BOOST_HAS_PRAGMA_ONCE |
23 | +#pragma once |
24 | +#endif |
25 | + |
26 | +namespace boost |
27 | +{ |
28 | + |
29 | +#ifdef BOOST_NO_CXX11_SCOPED_ENUMS |
30 | + |
31 | + /** |
32 | + * Meta-function to get the native enum type associated to an enum class or its emulation. |
33 | + */ |
34 | + template <typename EnumType> |
35 | + struct native_type |
36 | + { |
37 | + /** |
38 | + * The member typedef type names the native enum type associated to the scoped enum, |
39 | + * which is it self if the compiler supports scoped enums or EnumType::enum_type if it is an emulated scoped enum. |
40 | + */ |
41 | + typedef typename EnumType::enum_type type; |
42 | + }; |
43 | + |
44 | + /** |
45 | + * Casts a scoped enum to its underlying type. |
46 | + * |
47 | + * This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type. |
48 | + * @param v A scoped enum. |
49 | + * @returns The underlying type. |
50 | + * @throws No-throws. |
51 | + */ |
52 | + template <typename UnderlyingType, typename EnumType> |
53 | + UnderlyingType underlying_cast(EnumType v) |
54 | + { |
55 | + return v.get_underlying_value_(); |
56 | + } |
57 | + |
58 | + /** |
59 | + * Casts a scoped enum to its native enum type. |
60 | + * |
61 | + * This function is useful to make programs portable when the scoped enum emulation can not be use where native enums can. |
62 | + * |
63 | + * EnumType the scoped enum type |
64 | + * |
65 | + * @param v A scoped enum. |
66 | + * @returns The native enum value. |
67 | + * @throws No-throws. |
68 | + */ |
69 | + template <typename EnumType> |
70 | + inline |
71 | + typename EnumType::enum_type native_value(EnumType e) |
72 | + { |
73 | + return e.get_native_value_(); |
74 | + } |
75 | + |
76 | +#else // BOOST_NO_CXX11_SCOPED_ENUMS |
77 | + |
78 | + template <typename EnumType> |
79 | + struct native_type |
80 | + { |
81 | + typedef EnumType type; |
82 | + }; |
83 | + |
84 | + template <typename UnderlyingType, typename EnumType> |
85 | + UnderlyingType underlying_cast(EnumType v) |
86 | + { |
87 | + return static_cast<UnderlyingType>(v); |
88 | + } |
89 | + |
90 | + template <typename EnumType> |
91 | + inline |
92 | + EnumType native_value(EnumType e) |
93 | + { |
94 | + return e; |
95 | + } |
96 | + |
97 | +#endif // BOOST_NO_CXX11_SCOPED_ENUMS |
98 | +} |
99 | + |
100 | + |
101 | +#ifdef BOOST_NO_CXX11_SCOPED_ENUMS |
102 | + |
103 | +#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS |
104 | + |
105 | +#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ |
106 | + explicit operator underlying_type() const BOOST_NOEXCEPT { return get_underlying_value_(); } |
107 | + |
108 | +#else |
109 | + |
110 | +#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR |
111 | + |
112 | +#endif |
113 | + |
114 | +/** |
115 | + * Start a declaration of a scoped enum. |
116 | + * |
117 | + * @param EnumType The new scoped enum. |
118 | + * @param UnderlyingType The underlying type. |
119 | + */ |
120 | +#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType, UnderlyingType) \ |
121 | + struct EnumType { \ |
122 | + typedef void is_boost_scoped_enum_tag; \ |
123 | + typedef UnderlyingType underlying_type; \ |
124 | + EnumType() BOOST_NOEXCEPT {} \ |
125 | + explicit EnumType(underlying_type v) BOOST_NOEXCEPT : v_(v) {} \ |
126 | + underlying_type get_underlying_value_() const BOOST_NOEXCEPT { return v_; } \ |
127 | + BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ |
128 | + private: \ |
129 | + underlying_type v_; \ |
130 | + typedef EnumType self_type; \ |
131 | + public: \ |
132 | + enum enum_type |
133 | + |
134 | +#define BOOST_SCOPED_ENUM_DECLARE_END2() \ |
135 | + enum_type get_native_value_() const BOOST_NOEXCEPT { return enum_type(v_); } \ |
136 | + friend bool operator ==(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \ |
137 | + friend bool operator ==(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \ |
138 | + friend bool operator ==(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \ |
139 | + friend bool operator !=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=enum_type(rhs.v_); } \ |
140 | + friend bool operator !=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=rhs; } \ |
141 | + friend bool operator !=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs!=enum_type(rhs.v_); } \ |
142 | + friend bool operator <(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<enum_type(rhs.v_); } \ |
143 | + friend bool operator <(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<rhs; } \ |
144 | + friend bool operator <(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<enum_type(rhs.v_); } \ |
145 | + friend bool operator <=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=enum_type(rhs.v_); } \ |
146 | + friend bool operator <=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=rhs; } \ |
147 | + friend bool operator <=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<=enum_type(rhs.v_); } \ |
148 | + friend bool operator >(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>enum_type(rhs.v_); } \ |
149 | + friend bool operator >(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>rhs; } \ |
150 | + friend bool operator >(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>enum_type(rhs.v_); } \ |
151 | + friend bool operator >=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=enum_type(rhs.v_); } \ |
152 | + friend bool operator >=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=rhs; } \ |
153 | + friend bool operator >=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>=enum_type(rhs.v_); } \ |
154 | + }; |
155 | + |
156 | +#define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) \ |
157 | + ; \ |
158 | + EnumType(enum_type v) BOOST_NOEXCEPT : v_(v) {} \ |
159 | + BOOST_SCOPED_ENUM_DECLARE_END2() |
160 | + |
161 | +/** |
162 | + * Starts a declaration of a scoped enum with the default int underlying type. |
163 | + * |
164 | + * @param EnumType The new scoped enum. |
165 | + */ |
166 | +#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) \ |
167 | + BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,int) |
168 | + |
169 | +/** |
170 | + * Name of the native enum type. |
171 | + * |
172 | + * @param EnumType The new scoped enum. |
173 | + */ |
174 | +#define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType::enum_type |
175 | +/** |
176 | + * Forward declares an scoped enum. |
177 | + * |
178 | + * @param EnumType The scoped enum. |
179 | + */ |
180 | +#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) struct EnumType |
181 | + |
182 | +#else // BOOST_NO_CXX11_SCOPED_ENUMS |
183 | + |
184 | +#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,UnderlyingType) enum class EnumType : UnderlyingType |
185 | +#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) enum class EnumType |
186 | +#define BOOST_SCOPED_ENUM_DECLARE_END2() |
187 | +#define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) ; |
188 | + |
189 | +#define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType |
190 | +#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) enum class EnumType |
191 | + |
192 | +#endif // BOOST_NO_CXX11_SCOPED_ENUMS |
193 | + |
194 | +// Deprecated macros |
195 | +#define BOOST_SCOPED_ENUM_START(name) BOOST_SCOPED_ENUM_DECLARE_BEGIN(name) |
196 | +#define BOOST_SCOPED_ENUM_END BOOST_SCOPED_ENUM_DECLARE_END2() |
197 | +#define BOOST_SCOPED_ENUM(name) BOOST_SCOPED_ENUM_NATIVE(name) |
198 | + |
199 | +#endif // BOOST_CORE_SCOPED_ENUM_HPP |
200 | |
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-04-01 06:55:25 +0000 |
205 | @@ -0,0 +1,413 @@ |
206 | +// boost/endian/arithmetic.hpp -------------------------------------------------------// |
207 | + |
208 | +// (C) Copyright Darin Adler 2000 |
209 | +// (C) Copyright Beman Dawes 2006, 2009, 2014 |
210 | + |
211 | +// Distributed under the Boost Software License, Version 1.0. |
212 | +// See http://www.boost.org/LICENSE_1_0.txt |
213 | + |
214 | +// See library home page at http://www.boost.org/libs/endian |
215 | + |
216 | +//--------------------------------------------------------------------------------------// |
217 | + |
218 | +// Original design developed by Darin Adler based on classes developed by Mark |
219 | +// Borgerding. Four original class templates were combined into a single endian |
220 | +// class template by Beman Dawes, who also added the unrolled_byte_loops sign |
221 | +// partial specialization to correctly extend the sign when cover integer size |
222 | +// differs from endian representation size. |
223 | + |
224 | +// TODO: When a compiler supporting constexpr becomes available, try possible uses. |
225 | + |
226 | +#ifndef BOOST_ENDIAN_ARITHMETIC_HPP |
227 | +#define BOOST_ENDIAN_ARITHMETIC_HPP |
228 | + |
229 | +#if defined(_MSC_VER) |
230 | +# pragma warning(push) |
231 | +# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch |
232 | +#endif |
233 | + |
234 | +#ifdef BOOST_ENDIAN_LOG |
235 | +# include <iostream> |
236 | +#endif |
237 | + |
238 | +#if defined(__BORLANDC__) || defined( __CODEGEARC__) |
239 | +# pragma pack(push, 1) |
240 | +#endif |
241 | + |
242 | +#include <boost/config.hpp> |
243 | +#include <boost/predef/detail/endian_compat.h> |
244 | +#include <boost/endian/conversion.hpp> |
245 | +#include <boost/endian/buffers.hpp> |
246 | +#define BOOST_ENDIAN_MINIMAL_COVER_OPERATORS |
247 | +#include <boost/endian/detail/cover_operators.hpp> |
248 | +#undef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS |
249 | +#include <boost/type_traits/is_signed.hpp> |
250 | +#include <boost/cstdint.hpp> |
251 | +#include <boost/static_assert.hpp> |
252 | +#include <boost/core/scoped_enum.hpp> |
253 | +#include <iosfwd> |
254 | +#include <climits> |
255 | + |
256 | +# if CHAR_BIT != 8 |
257 | +# error Platforms with CHAR_BIT != 8 are not supported |
258 | +# endif |
259 | + |
260 | +# ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS |
261 | +# define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03 |
262 | +# else |
263 | +# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x |
264 | +# endif |
265 | + |
266 | +# if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS) |
267 | +# define BOOST_ENDIAN_NO_CTORS |
268 | +# endif |
269 | + |
270 | +# ifndef BOOST_ENDIAN_EXPLICIT_CTORS |
271 | +# define BOOST_ENDIAN_EXPLICIT_OPT |
272 | +# else |
273 | +# define BOOST_ENDIAN_EXPLICIT_OPT explicit |
274 | +# endif |
275 | + |
276 | +//---------------------------------- synopsis ----------------------------------------// |
277 | + |
278 | +namespace boost |
279 | +{ |
280 | +namespace endian |
281 | +{ |
282 | + |
283 | + template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits, |
284 | + BOOST_SCOPED_ENUM(align) A = align::no> |
285 | + class endian_arithmetic; |
286 | + |
287 | + // big endian signed integer aligned types |
288 | + typedef endian_arithmetic<order::big, int8_t, 8, align::yes> big_int8_at; |
289 | + typedef endian_arithmetic<order::big, int16_t, 16, align::yes> big_int16_at; |
290 | + typedef endian_arithmetic<order::big, int32_t, 32, align::yes> big_int32_at; |
291 | + typedef endian_arithmetic<order::big, int64_t, 64, align::yes> big_int64_at; |
292 | + |
293 | + // big endian unsigned integer aligned types |
294 | + typedef endian_arithmetic<order::big, uint8_t, 8, align::yes> big_uint8_at; |
295 | + typedef endian_arithmetic<order::big, uint16_t, 16, align::yes> big_uint16_at; |
296 | + typedef endian_arithmetic<order::big, uint32_t, 32, align::yes> big_uint32_at; |
297 | + typedef endian_arithmetic<order::big, uint64_t, 64, align::yes> big_uint64_at; |
298 | + |
299 | + // little endian signed integer aligned types |
300 | + typedef endian_arithmetic<order::little, int8_t, 8, align::yes> little_int8_at; |
301 | + typedef endian_arithmetic<order::little, int16_t, 16, align::yes> little_int16_at; |
302 | + typedef endian_arithmetic<order::little, int32_t, 32, align::yes> little_int32_at; |
303 | + typedef endian_arithmetic<order::little, int64_t, 64, align::yes> little_int64_at; |
304 | + |
305 | + // little endian unsigned integer aligned types |
306 | + typedef endian_arithmetic<order::little, uint8_t, 8, align::yes> little_uint8_at; |
307 | + typedef endian_arithmetic<order::little, uint16_t, 16, align::yes> little_uint16_at; |
308 | + typedef endian_arithmetic<order::little, uint32_t, 32, align::yes> little_uint32_at; |
309 | + typedef endian_arithmetic<order::little, uint64_t, 64, align::yes> little_uint64_at; |
310 | + |
311 | + // aligned native endian typedefs are not provided because |
312 | + // <cstdint> types are superior for this use case |
313 | + |
314 | + // big endian signed integer unaligned types |
315 | + typedef endian_arithmetic<order::big, int_least8_t, 8> big_int8_t; |
316 | + typedef endian_arithmetic<order::big, int_least16_t, 16> big_int16_t; |
317 | + typedef endian_arithmetic<order::big, int_least32_t, 24> big_int24_t; |
318 | + typedef endian_arithmetic<order::big, int_least32_t, 32> big_int32_t; |
319 | + typedef endian_arithmetic<order::big, int_least64_t, 40> big_int40_t; |
320 | + typedef endian_arithmetic<order::big, int_least64_t, 48> big_int48_t; |
321 | + typedef endian_arithmetic<order::big, int_least64_t, 56> big_int56_t; |
322 | + typedef endian_arithmetic<order::big, int_least64_t, 64> big_int64_t; |
323 | + |
324 | + // big endian unsigned integer unaligned types |
325 | + typedef endian_arithmetic<order::big, uint_least8_t, 8> big_uint8_t; |
326 | + typedef endian_arithmetic<order::big, uint_least16_t, 16> big_uint16_t; |
327 | + typedef endian_arithmetic<order::big, uint_least32_t, 24> big_uint24_t; |
328 | + typedef endian_arithmetic<order::big, uint_least32_t, 32> big_uint32_t; |
329 | + typedef endian_arithmetic<order::big, uint_least64_t, 40> big_uint40_t; |
330 | + typedef endian_arithmetic<order::big, uint_least64_t, 48> big_uint48_t; |
331 | + typedef endian_arithmetic<order::big, uint_least64_t, 56> big_uint56_t; |
332 | + typedef endian_arithmetic<order::big, uint_least64_t, 64> big_uint64_t; |
333 | + |
334 | + // little endian signed integer unaligned types |
335 | + typedef endian_arithmetic<order::little, int_least8_t, 8> little_int8_t; |
336 | + typedef endian_arithmetic<order::little, int_least16_t, 16> little_int16_t; |
337 | + typedef endian_arithmetic<order::little, int_least32_t, 24> little_int24_t; |
338 | + typedef endian_arithmetic<order::little, int_least32_t, 32> little_int32_t; |
339 | + typedef endian_arithmetic<order::little, int_least64_t, 40> little_int40_t; |
340 | + typedef endian_arithmetic<order::little, int_least64_t, 48> little_int48_t; |
341 | + typedef endian_arithmetic<order::little, int_least64_t, 56> little_int56_t; |
342 | + typedef endian_arithmetic<order::little, int_least64_t, 64> little_int64_t; |
343 | + |
344 | + // little endian unsigned integer unaligned types |
345 | + typedef endian_arithmetic<order::little, uint_least8_t, 8> little_uint8_t; |
346 | + typedef endian_arithmetic<order::little, uint_least16_t, 16> little_uint16_t; |
347 | + typedef endian_arithmetic<order::little, uint_least32_t, 24> little_uint24_t; |
348 | + typedef endian_arithmetic<order::little, uint_least32_t, 32> little_uint32_t; |
349 | + typedef endian_arithmetic<order::little, uint_least64_t, 40> little_uint40_t; |
350 | + typedef endian_arithmetic<order::little, uint_least64_t, 48> little_uint48_t; |
351 | + typedef endian_arithmetic<order::little, uint_least64_t, 56> little_uint56_t; |
352 | + typedef endian_arithmetic<order::little, uint_least64_t, 64> little_uint64_t; |
353 | + |
354 | +# ifdef BOOST_BIG_ENDIAN |
355 | + // native endian signed integer unaligned types |
356 | + typedef big_int8_t native_int8_t; |
357 | + typedef big_int16_t native_int16_t; |
358 | + typedef big_int24_t native_int24_t; |
359 | + typedef big_int32_t native_int32_t; |
360 | + typedef big_int40_t native_int40_t; |
361 | + typedef big_int48_t native_int48_t; |
362 | + typedef big_int56_t native_int56_t; |
363 | + typedef big_int64_t native_int64_t; |
364 | + |
365 | + // native endian unsigned integer unaligned types |
366 | + typedef big_uint8_t native_uint8_t; |
367 | + typedef big_uint16_t native_uint16_t; |
368 | + typedef big_uint24_t native_uint24_t; |
369 | + typedef big_uint32_t native_uint32_t; |
370 | + typedef big_uint40_t native_uint40_t; |
371 | + typedef big_uint48_t native_uint48_t; |
372 | + typedef big_uint56_t native_uint56_t; |
373 | + typedef big_uint64_t native_uint64_t; |
374 | +# else |
375 | + // native endian signed integer unaligned types |
376 | + typedef little_int8_t native_int8_t; |
377 | + typedef little_int16_t native_int16_t; |
378 | + typedef little_int24_t native_int24_t; |
379 | + typedef little_int32_t native_int32_t; |
380 | + typedef little_int40_t native_int40_t; |
381 | + typedef little_int48_t native_int48_t; |
382 | + typedef little_int56_t native_int56_t; |
383 | + typedef little_int64_t native_int64_t; |
384 | + |
385 | + // native endian unsigned integer unaligned types |
386 | + typedef little_uint8_t native_uint8_t; |
387 | + typedef little_uint16_t native_uint16_t; |
388 | + typedef little_uint24_t native_uint24_t; |
389 | + typedef little_uint32_t native_uint32_t; |
390 | + typedef little_uint40_t native_uint40_t; |
391 | + typedef little_uint48_t native_uint48_t; |
392 | + typedef little_uint56_t native_uint56_t; |
393 | + typedef little_uint64_t native_uint64_t; |
394 | +# endif |
395 | + |
396 | +# ifdef BOOST_ENDIAN_DEPRECATED_NAMES |
397 | + |
398 | + typedef order endianness; |
399 | + typedef align alignment; |
400 | + |
401 | +# ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES |
402 | + template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits, |
403 | + BOOST_SCOPED_ENUM(align) Align = align::no> |
404 | + using endian = endian_arithmetic<Order, T, n_bits, Align>; |
405 | +# endif |
406 | + |
407 | + // unaligned big endian signed integer types |
408 | + typedef endian_arithmetic< order::big, int_least8_t, 8 > big8_t; |
409 | + typedef endian_arithmetic< order::big, int_least16_t, 16 > big16_t; |
410 | + typedef endian_arithmetic< order::big, int_least32_t, 24 > big24_t; |
411 | + typedef endian_arithmetic< order::big, int_least32_t, 32 > big32_t; |
412 | + typedef endian_arithmetic< order::big, int_least64_t, 40 > big40_t; |
413 | + typedef endian_arithmetic< order::big, int_least64_t, 48 > big48_t; |
414 | + typedef endian_arithmetic< order::big, int_least64_t, 56 > big56_t; |
415 | + typedef endian_arithmetic< order::big, int_least64_t, 64 > big64_t; |
416 | + |
417 | + // unaligned big endian_arithmetic unsigned integer types |
418 | + typedef endian_arithmetic< order::big, uint_least8_t, 8 > ubig8_t; |
419 | + typedef endian_arithmetic< order::big, uint_least16_t, 16 > ubig16_t; |
420 | + typedef endian_arithmetic< order::big, uint_least32_t, 24 > ubig24_t; |
421 | + typedef endian_arithmetic< order::big, uint_least32_t, 32 > ubig32_t; |
422 | + typedef endian_arithmetic< order::big, uint_least64_t, 40 > ubig40_t; |
423 | + typedef endian_arithmetic< order::big, uint_least64_t, 48 > ubig48_t; |
424 | + typedef endian_arithmetic< order::big, uint_least64_t, 56 > ubig56_t; |
425 | + typedef endian_arithmetic< order::big, uint_least64_t, 64 > ubig64_t; |
426 | + |
427 | + // unaligned little endian_arithmetic signed integer types |
428 | + typedef endian_arithmetic< order::little, int_least8_t, 8 > little8_t; |
429 | + typedef endian_arithmetic< order::little, int_least16_t, 16 > little16_t; |
430 | + typedef endian_arithmetic< order::little, int_least32_t, 24 > little24_t; |
431 | + typedef endian_arithmetic< order::little, int_least32_t, 32 > little32_t; |
432 | + typedef endian_arithmetic< order::little, int_least64_t, 40 > little40_t; |
433 | + typedef endian_arithmetic< order::little, int_least64_t, 48 > little48_t; |
434 | + typedef endian_arithmetic< order::little, int_least64_t, 56 > little56_t; |
435 | + typedef endian_arithmetic< order::little, int_least64_t, 64 > little64_t; |
436 | + |
437 | + // unaligned little endian_arithmetic unsigned integer types |
438 | + typedef endian_arithmetic< order::little, uint_least8_t, 8 > ulittle8_t; |
439 | + typedef endian_arithmetic< order::little, uint_least16_t, 16 > ulittle16_t; |
440 | + typedef endian_arithmetic< order::little, uint_least32_t, 24 > ulittle24_t; |
441 | + typedef endian_arithmetic< order::little, uint_least32_t, 32 > ulittle32_t; |
442 | + typedef endian_arithmetic< order::little, uint_least64_t, 40 > ulittle40_t; |
443 | + typedef endian_arithmetic< order::little, uint_least64_t, 48 > ulittle48_t; |
444 | + typedef endian_arithmetic< order::little, uint_least64_t, 56 > ulittle56_t; |
445 | + typedef endian_arithmetic< order::little, uint_least64_t, 64 > ulittle64_t; |
446 | + |
447 | + // unaligned native endian_arithmetic signed integer types |
448 | + typedef endian_arithmetic< order::native, int_least8_t, 8 > native8_t; |
449 | + typedef endian_arithmetic< order::native, int_least16_t, 16 > native16_t; |
450 | + typedef endian_arithmetic< order::native, int_least32_t, 24 > native24_t; |
451 | + typedef endian_arithmetic< order::native, int_least32_t, 32 > native32_t; |
452 | + typedef endian_arithmetic< order::native, int_least64_t, 40 > native40_t; |
453 | + typedef endian_arithmetic< order::native, int_least64_t, 48 > native48_t; |
454 | + typedef endian_arithmetic< order::native, int_least64_t, 56 > native56_t; |
455 | + typedef endian_arithmetic< order::native, int_least64_t, 64 > native64_t; |
456 | + |
457 | + // unaligned native endian_arithmetic unsigned integer types |
458 | + typedef endian_arithmetic< order::native, uint_least8_t, 8 > unative8_t; |
459 | + typedef endian_arithmetic< order::native, uint_least16_t, 16 > unative16_t; |
460 | + typedef endian_arithmetic< order::native, uint_least32_t, 24 > unative24_t; |
461 | + typedef endian_arithmetic< order::native, uint_least32_t, 32 > unative32_t; |
462 | + typedef endian_arithmetic< order::native, uint_least64_t, 40 > unative40_t; |
463 | + typedef endian_arithmetic< order::native, uint_least64_t, 48 > unative48_t; |
464 | + typedef endian_arithmetic< order::native, uint_least64_t, 56 > unative56_t; |
465 | + typedef endian_arithmetic< order::native, uint_least64_t, 64 > unative64_t; |
466 | + |
467 | + // aligned native endian_arithmetic typedefs are not provided because |
468 | + // <cstdint> types are superior for this use case |
469 | + |
470 | + typedef endian_arithmetic< order::big, int16_t, 16, align::yes > aligned_big16_t; |
471 | + typedef endian_arithmetic< order::big, uint16_t, 16, align::yes > aligned_ubig16_t; |
472 | + typedef endian_arithmetic< order::little, int16_t, 16, align::yes > aligned_little16_t; |
473 | + typedef endian_arithmetic< order::little, uint16_t, 16, align::yes > aligned_ulittle16_t; |
474 | + |
475 | + typedef endian_arithmetic< order::big, int32_t, 32, align::yes > aligned_big32_t; |
476 | + typedef endian_arithmetic< order::big, uint32_t, 32, align::yes > aligned_ubig32_t; |
477 | + typedef endian_arithmetic< order::little, int32_t, 32, align::yes > aligned_little32_t; |
478 | + typedef endian_arithmetic< order::little, uint32_t, 32, align::yes > aligned_ulittle32_t; |
479 | + |
480 | + typedef endian_arithmetic< order::big, int64_t, 64, align::yes > aligned_big64_t; |
481 | + typedef endian_arithmetic< order::big, uint64_t, 64, align::yes > aligned_ubig64_t; |
482 | + typedef endian_arithmetic< order::little, int64_t, 64, align::yes > aligned_little64_t; |
483 | + typedef endian_arithmetic< order::little, uint64_t, 64, align::yes > aligned_ulittle64_t; |
484 | + |
485 | +# endif |
486 | + |
487 | +//---------------------------------- end synopsis ------------------------------------// |
488 | + |
489 | +// endian class template specializations ---------------------------------------------// |
490 | + |
491 | + // Specializations that represent unaligned bytes. |
492 | + // Taking an integer type as a parameter provides a nice way to pass both |
493 | + // the size and signness of the desired integer and get the appropriate |
494 | + // corresponding integer type for the interface. |
495 | + |
496 | + // unaligned integer big endian specialization |
497 | + template <typename T, std::size_t n_bits> |
498 | + class endian_arithmetic< order::big, T, n_bits, align::no > |
499 | + : public endian_buffer< order::big, T, n_bits, align::no >, |
500 | + cover_operators<endian_arithmetic<order::big, T, n_bits>, T> |
501 | + { |
502 | + BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); |
503 | + public: |
504 | + typedef T value_type; |
505 | +# ifndef BOOST_ENDIAN_NO_CTORS |
506 | + endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT |
507 | + BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT |
508 | + { |
509 | +# ifdef BOOST_ENDIAN_LOG |
510 | + if ( endian_log ) |
511 | + std::cout << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n"; |
512 | +# endif |
513 | + detail::store_big_endian<T, n_bits/8>(this->m_value, val); |
514 | + } |
515 | +# endif |
516 | + endian_arithmetic& operator=(T val) BOOST_NOEXCEPT |
517 | + { detail::store_big_endian<T, n_bits/8>(this->m_value, val); return *this; } |
518 | + operator value_type() const BOOST_NOEXCEPT { return this->value(); } |
519 | + }; |
520 | + |
521 | + // unaligned little endian specialization |
522 | + template <typename T, std::size_t n_bits> |
523 | + class endian_arithmetic< order::little, T, n_bits, align::no > |
524 | + : public endian_buffer< order::little, T, n_bits, align::no >, |
525 | + cover_operators< endian_arithmetic< order::little, T, n_bits >, T > |
526 | + { |
527 | + BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); |
528 | + public: |
529 | + typedef T value_type; |
530 | +# ifndef BOOST_ENDIAN_NO_CTORS |
531 | + endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT |
532 | + BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT |
533 | + { |
534 | +# ifdef BOOST_ENDIAN_LOG |
535 | + if ( endian_log ) |
536 | + std::cout << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n"; |
537 | +# endif |
538 | + detail::store_little_endian<T, n_bits/8>(this->m_value, val); |
539 | + } |
540 | +# endif |
541 | + endian_arithmetic& operator=(T val) BOOST_NOEXCEPT |
542 | + { detail::store_little_endian<T, n_bits/8>(this->m_value, val); return *this; } |
543 | + operator value_type() const BOOST_NOEXCEPT { return this->value(); } |
544 | + }; |
545 | + |
546 | + // align::yes specializations; only n_bits == 16/32/64 supported |
547 | + |
548 | + // aligned big endian specialization |
549 | + template <typename T, std::size_t n_bits> |
550 | + class endian_arithmetic<order::big, T, n_bits, align::yes> |
551 | + : public endian_buffer< order::big, T, n_bits, align::yes >, |
552 | + cover_operators<endian_arithmetic<order::big, T, n_bits, align::yes>, T> |
553 | + { |
554 | + BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); |
555 | + BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); |
556 | + public: |
557 | + typedef T value_type; |
558 | +# ifndef BOOST_ENDIAN_NO_CTORS |
559 | + endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT |
560 | + BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT |
561 | + { |
562 | +# ifdef BOOST_ENDIAN_LOG |
563 | + if ( endian_log ) |
564 | + std::cout << "big, aligned, " << n_bits << "-bits, construct(" << val << ")\n"; |
565 | +# endif |
566 | + this->m_value = ::boost::endian::native_to_big(val); |
567 | + } |
568 | + |
569 | +# endif |
570 | + endian_arithmetic& operator=(T val) BOOST_NOEXCEPT |
571 | + { |
572 | + this->m_value = ::boost::endian::native_to_big(val); |
573 | + return *this; |
574 | + } |
575 | + operator value_type() const BOOST_NOEXCEPT { return this->value(); } |
576 | + }; |
577 | + |
578 | + // aligned little endian specialization |
579 | + template <typename T, std::size_t n_bits> |
580 | + class endian_arithmetic<order::little, T, n_bits, align::yes> |
581 | + : public endian_buffer< order::little, T, n_bits, align::yes >, |
582 | + cover_operators<endian_arithmetic<order::little, T, n_bits, align::yes>, T> |
583 | + { |
584 | + BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); |
585 | + BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); |
586 | + public: |
587 | + typedef T value_type; |
588 | +# ifndef BOOST_ENDIAN_NO_CTORS |
589 | + endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT |
590 | + BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT |
591 | + { |
592 | +# ifdef BOOST_ENDIAN_LOG |
593 | + if ( endian_log ) |
594 | + std::cout << "little, aligned, " << n_bits << "-bits, construct(" << val << ")\n"; |
595 | +# endif |
596 | + this->m_value = ::boost::endian::native_to_little(val); |
597 | + } |
598 | +# endif |
599 | + endian_arithmetic& operator=(T val) BOOST_NOEXCEPT |
600 | + { |
601 | + this->m_value = ::boost::endian::native_to_little(val); |
602 | + return *this; |
603 | + } |
604 | + operator value_type() const BOOST_NOEXCEPT { return this->value(); } |
605 | + }; |
606 | + |
607 | +} // namespace endian |
608 | +} // namespace boost |
609 | + |
610 | +#if defined(__BORLANDC__) || defined( __CODEGEARC__) |
611 | +# pragma pack(pop) |
612 | +#endif |
613 | + |
614 | +#if defined(_MSC_VER) |
615 | +# pragma warning(pop) |
616 | +#endif |
617 | + |
618 | +#endif // BOOST_ENDIAN_ARITHMETIC_HPP |
619 | |
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-04-01 06:55:25 +0000 |
623 | @@ -0,0 +1,515 @@ |
624 | +// boost/endian/buffers.hpp ----------------------------------------------------------// |
625 | + |
626 | +// (C) Copyright Darin Adler 2000 |
627 | +// (C) Copyright Beman Dawes 2006, 2009, 2014 |
628 | + |
629 | +// Distributed under the Boost Software License, Version 1.0. |
630 | +// See http://www.boost.org/LICENSE_1_0.txt |
631 | + |
632 | +// See library home page at http://www.boost.org/libs/endian |
633 | + |
634 | +//--------------------------------------------------------------------------------------// |
635 | + |
636 | +// Original design developed by Darin Adler based on classes developed by Mark |
637 | +// Borgerding. Four original class templates were combined into a single endian |
638 | +// class template by Beman Dawes, who also added the unrolled_byte_loops sign |
639 | +// partial specialization to correctly extend the sign when cover integer size |
640 | +// differs from endian representation size. |
641 | + |
642 | +// TODO: When a compiler supporting constexpr becomes available, try possible uses. |
643 | + |
644 | +#ifndef BOOST_ENDIAN_BUFFERS_HPP |
645 | +#define BOOST_ENDIAN_BUFFERS_HPP |
646 | + |
647 | +#if defined(_MSC_VER) |
648 | +# pragma warning(push) |
649 | +# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch |
650 | +#endif |
651 | + |
652 | +#ifdef BOOST_ENDIAN_LOG |
653 | +# include <iostream> |
654 | +#endif |
655 | + |
656 | +#if defined(__BORLANDC__) || defined( __CODEGEARC__) |
657 | +# pragma pack(push, 1) |
658 | +#endif |
659 | + |
660 | +#include <boost/config.hpp> |
661 | +#include <boost/predef/detail/endian_compat.h> |
662 | +#include <boost/endian/conversion.hpp> |
663 | +#include <boost/type_traits/is_signed.hpp> |
664 | +#include <boost/cstdint.hpp> |
665 | +#include <boost/static_assert.hpp> |
666 | +#include <boost/core/scoped_enum.hpp> |
667 | +#include <iosfwd> |
668 | +#include <climits> |
669 | + |
670 | +# if CHAR_BIT != 8 |
671 | +# error Platforms with CHAR_BIT != 8 are not supported |
672 | +# endif |
673 | + |
674 | +# ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS |
675 | +# define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03 |
676 | +# else |
677 | +# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x |
678 | +# endif |
679 | + |
680 | +# if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS) |
681 | +# define BOOST_ENDIAN_NO_CTORS |
682 | +# endif |
683 | + |
684 | +//---------------------------------- synopsis ----------------------------------------// |
685 | + |
686 | +namespace boost |
687 | +{ |
688 | +namespace endian |
689 | +{ |
690 | + |
691 | + BOOST_SCOPED_ENUM_START(align) |
692 | + {no, yes |
693 | +# ifdef BOOST_ENDIAN_DEPRECATED_NAMES |
694 | + , unaligned = no, aligned = yes |
695 | +# endif |
696 | + }; BOOST_SCOPED_ENUM_END |
697 | + |
698 | + template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits, |
699 | + BOOST_SCOPED_ENUM(align) A = align::no> |
700 | + class endian_buffer; |
701 | + |
702 | + // aligned big endian signed integer buffers |
703 | + typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at; |
704 | + typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at; |
705 | + typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at; |
706 | + typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at; |
707 | + |
708 | + // aligned big endian unsigned integer buffers |
709 | + typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at; |
710 | + typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at; |
711 | + typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at; |
712 | + typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at; |
713 | + |
714 | + // aligned little endian signed integer buffers |
715 | + typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at; |
716 | + typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_at; |
717 | + typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_at; |
718 | + typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_at; |
719 | + |
720 | + // aligned little endian unsigned integer buffers |
721 | + typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_at; |
722 | + typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at; |
723 | + typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at; |
724 | + typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at; |
725 | + |
726 | + // aligned native endian typedefs are not provided because |
727 | + // <cstdint> types are superior for this use case |
728 | + |
729 | + // unaligned big endian signed integer buffers |
730 | + typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t; |
731 | + typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t; |
732 | + typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t; |
733 | + typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t; |
734 | + typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t; |
735 | + typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t; |
736 | + typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t; |
737 | + typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t; |
738 | + |
739 | + // unaligned big endian unsigned integer buffers |
740 | + typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t; |
741 | + typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t; |
742 | + typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t; |
743 | + typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t; |
744 | + typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t; |
745 | + typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t; |
746 | + typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t; |
747 | + typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t; |
748 | + |
749 | + // unaligned little endian signed integer buffers |
750 | + typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t; |
751 | + typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t; |
752 | + typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t; |
753 | + typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t; |
754 | + typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t; |
755 | + typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t; |
756 | + typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t; |
757 | + typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t; |
758 | + |
759 | + // unaligned little endian unsigned integer buffers |
760 | + typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t; |
761 | + typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t; |
762 | + typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t; |
763 | + typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t; |
764 | + typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t; |
765 | + typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t; |
766 | + typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t; |
767 | + typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t; |
768 | + |
769 | +# ifdef BOOST_BIG_ENDIAN |
770 | + // unaligned native endian signed integer buffers |
771 | + typedef big_int8_buf_t native_int8_buf_t; |
772 | + typedef big_int16_buf_t native_int16_buf_t; |
773 | + typedef big_int24_buf_t native_int24_buf_t; |
774 | + typedef big_int32_buf_t native_int32_buf_t; |
775 | + typedef big_int40_buf_t native_int40_buf_t; |
776 | + typedef big_int48_buf_t native_int48_buf_t; |
777 | + typedef big_int56_buf_t native_int56_buf_t; |
778 | + typedef big_int64_buf_t native_int64_buf_t; |
779 | + |
780 | + // unaligned native endian unsigned integer buffers |
781 | + typedef big_uint8_buf_t native_uint8_buf_t; |
782 | + typedef big_uint16_buf_t native_uint16_buf_t; |
783 | + typedef big_uint24_buf_t native_uint24_buf_t; |
784 | + typedef big_uint32_buf_t native_uint32_buf_t; |
785 | + typedef big_uint40_buf_t native_uint40_buf_t; |
786 | + typedef big_uint48_buf_t native_uint48_buf_t; |
787 | + typedef big_uint56_buf_t native_uint56_buf_t; |
788 | + typedef big_uint64_buf_t native_uint64_buf_t; |
789 | +# else |
790 | + // unaligned native endian signed integer buffers |
791 | + typedef little_int8_buf_t native_int8_buf_t; |
792 | + typedef little_int16_buf_t native_int16_buf_t; |
793 | + typedef little_int24_buf_t native_int24_buf_t; |
794 | + typedef little_int32_buf_t native_int32_buf_t; |
795 | + typedef little_int40_buf_t native_int40_buf_t; |
796 | + typedef little_int48_buf_t native_int48_buf_t; |
797 | + typedef little_int56_buf_t native_int56_buf_t; |
798 | + typedef little_int64_buf_t native_int64_buf_t; |
799 | + |
800 | + // unaligned native endian unsigned integer buffers |
801 | + typedef little_uint8_buf_t native_uint8_buf_t; |
802 | + typedef little_uint16_buf_t native_uint16_buf_t; |
803 | + typedef little_uint24_buf_t native_uint24_buf_t; |
804 | + typedef little_uint32_buf_t native_uint32_buf_t; |
805 | + typedef little_uint40_buf_t native_uint40_buf_t; |
806 | + typedef little_uint48_buf_t native_uint48_buf_t; |
807 | + typedef little_uint56_buf_t native_uint56_buf_t; |
808 | + typedef little_uint64_buf_t native_uint64_buf_t; |
809 | +# endif |
810 | + |
811 | + // Stream inserter |
812 | + template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T, |
813 | + std::size_t n_bits, BOOST_SCOPED_ENUM(align) A> |
814 | + std::basic_ostream<charT, traits>& |
815 | + operator<<(std::basic_ostream<charT, traits>& os, |
816 | + const endian_buffer<Order, T, n_bits, A>& x) |
817 | + { |
818 | + return os << x.value(); |
819 | + } |
820 | + |
821 | + // Stream extractor |
822 | + template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T, |
823 | + std::size_t n_bits, BOOST_SCOPED_ENUM(align) A> |
824 | + std::basic_istream<charT, traits>& |
825 | + operator>>(std::basic_istream<charT, traits>& is, |
826 | + endian_buffer<Order, T, n_bits, A>& x) |
827 | + { |
828 | + T i; |
829 | + if (is >> i) |
830 | + x = i; |
831 | + return is; |
832 | + } |
833 | + |
834 | +//---------------------------------- end synopsis ------------------------------------// |
835 | + |
836 | + namespace detail |
837 | + { |
838 | + |
839 | + // Unrolled loops for loading and storing streams of bytes. |
840 | + |
841 | + template <typename T, std::size_t n_bytes, |
842 | + bool sign=boost::is_signed<T>::value > |
843 | + struct unrolled_byte_loops |
844 | + { |
845 | + typedef unrolled_byte_loops<T, n_bytes - 1, sign> next; |
846 | + |
847 | + static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT |
848 | + { return static_cast<T>(*(bytes - 1) | (next::load_big(bytes - 1) << 8)); } |
849 | + static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT |
850 | + { return static_cast<T>(*bytes | (next::load_little(bytes + 1) << 8)); } |
851 | + |
852 | + static void store_big(char* bytes, T value) BOOST_NOEXCEPT |
853 | + { |
854 | + *(bytes - 1) = static_cast<char>(value); |
855 | + next::store_big(bytes - 1, static_cast<T>(value >> 8)); |
856 | + } |
857 | + static void store_little(char* bytes, T value) BOOST_NOEXCEPT |
858 | + { |
859 | + *bytes = static_cast<char>(value); |
860 | + next::store_little(bytes + 1, static_cast<T>(value >> 8)); |
861 | + } |
862 | + }; |
863 | + |
864 | + template <typename T> |
865 | + struct unrolled_byte_loops<T, 1, false> |
866 | + { |
867 | + static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT |
868 | + { return *(bytes - 1); } |
869 | + static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT |
870 | + { return *bytes; } |
871 | + static void store_big(char* bytes, T value) BOOST_NOEXCEPT |
872 | + { *(bytes - 1) = static_cast<char>(value); } |
873 | + static void store_little(char* bytes, T value) BOOST_NOEXCEPT |
874 | + { *bytes = static_cast<char>(value); } |
875 | + |
876 | + }; |
877 | + |
878 | + template <typename T> |
879 | + struct unrolled_byte_loops<T, 1, true> |
880 | + { |
881 | + static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT |
882 | + { return *reinterpret_cast<const signed char*>(bytes - 1); } |
883 | + static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT |
884 | + { return *reinterpret_cast<const signed char*>(bytes); } |
885 | + static void store_big(char* bytes, T value) BOOST_NOEXCEPT |
886 | + { *(bytes - 1) = static_cast<char>(value); } |
887 | + static void store_little(char* bytes, T value) BOOST_NOEXCEPT |
888 | + { *bytes = static_cast<char>(value); } |
889 | + }; |
890 | + |
891 | + template <typename T, std::size_t n_bytes> |
892 | + inline |
893 | + T load_big_endian(const void* bytes) BOOST_NOEXCEPT |
894 | + { |
895 | + return unrolled_byte_loops<T, n_bytes>::load_big |
896 | + (static_cast<const unsigned char*>(bytes) + n_bytes); |
897 | + } |
898 | + |
899 | + template <typename T, std::size_t n_bytes> |
900 | + inline |
901 | + T load_little_endian(const void* bytes) BOOST_NOEXCEPT |
902 | + { |
903 | +# if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) |
904 | + // On x86 (which is little endian), unaligned loads are permitted |
905 | + if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this |
906 | + // test and generate code only for the applicable return |
907 | + // case since sizeof(T) and n_bytes are known at compile |
908 | + // time. |
909 | + { |
910 | + return *reinterpret_cast<T const *>(bytes); |
911 | + } |
912 | +# endif |
913 | + return unrolled_byte_loops<T, n_bytes>::load_little |
914 | + (static_cast<const unsigned char*>(bytes)); |
915 | + } |
916 | + |
917 | + template <typename T, std::size_t n_bytes> |
918 | + inline |
919 | + void store_big_endian(void* bytes, T value) BOOST_NOEXCEPT |
920 | + { |
921 | + unrolled_byte_loops<T, n_bytes>::store_big |
922 | + (static_cast<char*>(bytes) + n_bytes, value); |
923 | + } |
924 | + |
925 | + template <typename T, std::size_t n_bytes> |
926 | + inline |
927 | + void store_little_endian(void* bytes, T value) BOOST_NOEXCEPT |
928 | + { |
929 | +# if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) |
930 | + // On x86 (which is little endian), unaligned stores are permitted |
931 | + if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this |
932 | + // test and generate code only for the applicable return |
933 | + // case since sizeof(T) and n_bytes are known at compile |
934 | + // time. |
935 | + { |
936 | + *reinterpret_cast<T *>(bytes) = value; |
937 | + return; |
938 | + } |
939 | +# endif |
940 | + unrolled_byte_loops<T, n_bytes>::store_little |
941 | + (static_cast<char*>(bytes), value); |
942 | + } |
943 | + |
944 | + } // namespace detail |
945 | + |
946 | +# ifdef BOOST_ENDIAN_LOG |
947 | + bool endian_log(true); |
948 | +# endif |
949 | + |
950 | +// endian_buffer class template specializations --------------------------------------// |
951 | + |
952 | + // Specializations that represent unaligned bytes. |
953 | + // Taking an integer type as a parameter provides a nice way to pass both |
954 | + // the size and signedness of the desired integer and get the appropriate |
955 | + // corresponding integer type for the interface. |
956 | + |
957 | + // Q: Should endian_buffer supply "value_type operator value_type() const noexcept"? |
958 | + // A: No. The rationale for endian_buffers is to prevent high-cost hidden |
959 | + // conversions. If an implicit conversion operator is supplied, hidden conversions |
960 | + // can occur. |
961 | + |
962 | + // unaligned big endian_buffer specialization |
963 | + template <typename T, std::size_t n_bits> |
964 | + class endian_buffer< order::big, T, n_bits, align::no > |
965 | + { |
966 | + BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); |
967 | + public: |
968 | + typedef T value_type; |
969 | +# ifndef BOOST_ENDIAN_NO_CTORS |
970 | + endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT |
971 | + explicit endian_buffer(T val) BOOST_NOEXCEPT |
972 | + { |
973 | +# ifdef BOOST_ENDIAN_LOG |
974 | + if ( endian_log ) |
975 | + std::cout << "big, unaligned, " |
976 | + << n_bits << "-bits, construct(" << val << ")\n"; |
977 | +# endif |
978 | + detail::store_big_endian<T, n_bits/8>(m_value, val); |
979 | + } |
980 | +# endif |
981 | + endian_buffer & operator=(T val) BOOST_NOEXCEPT |
982 | + { |
983 | +# ifdef BOOST_ENDIAN_LOG |
984 | + if (endian_log) |
985 | + std::cout << "big, unaligned, " << n_bits << "-bits, assign(" << val << ")\n"; |
986 | +# endif |
987 | + detail::store_big_endian<T, n_bits/8>(m_value, val); |
988 | + return *this; |
989 | + } |
990 | + value_type value() const BOOST_NOEXCEPT |
991 | + { |
992 | +# ifdef BOOST_ENDIAN_LOG |
993 | + if ( endian_log ) |
994 | + std::cout << "big, unaligned, " << n_bits << "-bits, convert(" |
995 | + << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n"; |
996 | +# endif |
997 | + return detail::load_big_endian<T, n_bits/8>(m_value); |
998 | + } |
999 | + const char* data() const BOOST_NOEXCEPT { return m_value; } |
1000 | + protected: |
1001 | + char m_value[n_bits/8]; |
1002 | + }; |
1003 | + |
1004 | + // unaligned little endian_buffer specialization |
1005 | + template <typename T, std::size_t n_bits> |
1006 | + class endian_buffer< order::little, T, n_bits, align::no > |
1007 | + { |
1008 | + BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); |
1009 | + public: |
1010 | + typedef T value_type; |
1011 | +# ifndef BOOST_ENDIAN_NO_CTORS |
1012 | + endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT |
1013 | + explicit endian_buffer(T val) BOOST_NOEXCEPT |
1014 | + { |
1015 | +# ifdef BOOST_ENDIAN_LOG |
1016 | + if ( endian_log ) |
1017 | + std::cout << "little, unaligned, " << n_bits << "-bits, construct(" |
1018 | + << val << ")\n"; |
1019 | +# endif |
1020 | + detail::store_little_endian<T, n_bits/8>(m_value, val); |
1021 | + } |
1022 | +# endif |
1023 | + endian_buffer & operator=(T val) BOOST_NOEXCEPT |
1024 | + { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; } |
1025 | + value_type value() const BOOST_NOEXCEPT |
1026 | + { |
1027 | +# ifdef BOOST_ENDIAN_LOG |
1028 | + if ( endian_log ) |
1029 | + std::cout << "little, unaligned, " << n_bits << "-bits, convert(" |
1030 | + << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n"; |
1031 | +# endif |
1032 | + return detail::load_little_endian<T, n_bits/8>(m_value); |
1033 | + } |
1034 | + const char* data() const BOOST_NOEXCEPT { return m_value; } |
1035 | + protected: |
1036 | + char m_value[n_bits/8]; |
1037 | + }; |
1038 | + |
1039 | + // align::yes specializations; only n_bits == 16/32/64 supported |
1040 | + |
1041 | + // aligned big endian_buffer specialization |
1042 | + template <typename T, std::size_t n_bits> |
1043 | + class endian_buffer<order::big, T, n_bits, align::yes> |
1044 | + { |
1045 | + BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); |
1046 | + BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); |
1047 | + public: |
1048 | + typedef T value_type; |
1049 | +# ifndef BOOST_ENDIAN_NO_CTORS |
1050 | + endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT |
1051 | + explicit endian_buffer(T val) BOOST_NOEXCEPT |
1052 | + { |
1053 | +# ifdef BOOST_ENDIAN_LOG |
1054 | + if ( endian_log ) |
1055 | + std::cout << "big, aligned, " << n_bits |
1056 | + << "-bits, construct(" << val << ")\n"; |
1057 | +# endif |
1058 | + m_value = ::boost::endian::native_to_big(val); |
1059 | + } |
1060 | + |
1061 | +# endif |
1062 | + endian_buffer& operator=(T val) BOOST_NOEXCEPT |
1063 | + { |
1064 | + m_value = ::boost::endian::native_to_big(val); |
1065 | + return *this; |
1066 | + } |
1067 | + //operator value_type() const BOOST_NOEXCEPT |
1068 | + //{ |
1069 | + // return ::boost::endian::big_to_native(m_value); |
1070 | + //} |
1071 | + value_type value() const BOOST_NOEXCEPT |
1072 | + { |
1073 | +# ifdef BOOST_ENDIAN_LOG |
1074 | + if ( endian_log ) |
1075 | + std::cout << "big, aligned, " << n_bits << "-bits, convert(" |
1076 | + << ::boost::endian::big_to_native(m_value) << ")\n"; |
1077 | +# endif |
1078 | + return ::boost::endian::big_to_native(m_value); |
1079 | + } |
1080 | + const char* data() const BOOST_NOEXCEPT |
1081 | + {return reinterpret_cast<const char*>(&m_value);} |
1082 | + protected: |
1083 | + T m_value; |
1084 | + }; |
1085 | + |
1086 | + // aligned little endian_buffer specialization |
1087 | + template <typename T, std::size_t n_bits> |
1088 | + class endian_buffer<order::little, T, n_bits, align::yes> |
1089 | + { |
1090 | + BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); |
1091 | + BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); |
1092 | + public: |
1093 | + typedef T value_type; |
1094 | +# ifndef BOOST_ENDIAN_NO_CTORS |
1095 | + endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT |
1096 | + explicit endian_buffer(T val) BOOST_NOEXCEPT |
1097 | + { |
1098 | +# ifdef BOOST_ENDIAN_LOG |
1099 | + if ( endian_log ) |
1100 | + std::cout << "little, aligned, " << n_bits |
1101 | + << "-bits, construct(" << val << ")\n"; |
1102 | +# endif |
1103 | + m_value = ::boost::endian::native_to_little(val); |
1104 | + } |
1105 | + |
1106 | +# endif |
1107 | + endian_buffer& operator=(T val) BOOST_NOEXCEPT |
1108 | + { |
1109 | + m_value = ::boost::endian::native_to_little(val); |
1110 | + return *this; |
1111 | + } |
1112 | + value_type value() const BOOST_NOEXCEPT |
1113 | + { |
1114 | +# ifdef BOOST_ENDIAN_LOG |
1115 | + if ( endian_log ) |
1116 | + std::cout << "little, aligned, " << n_bits << "-bits, convert(" |
1117 | + << ::boost::endian::little_to_native(m_value) << ")\n"; |
1118 | +# endif |
1119 | + return ::boost::endian::little_to_native(m_value); |
1120 | + } |
1121 | + const char* data() const BOOST_NOEXCEPT |
1122 | + {return reinterpret_cast<const char*>(&m_value);} |
1123 | + protected: |
1124 | + T m_value; |
1125 | + }; |
1126 | + |
1127 | +} // namespace endian |
1128 | +} // namespace boost |
1129 | + |
1130 | +#if defined(__BORLANDC__) || defined( __CODEGEARC__) |
1131 | +# pragma pack(pop) |
1132 | +#endif |
1133 | + |
1134 | +#if defined(_MSC_VER) |
1135 | +# pragma warning(pop) |
1136 | +#endif |
1137 | + |
1138 | +#endif // BOOST_ENDIAN_BUFFERS_HPP |
1139 | |
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-04-01 06:55:25 +0000 |
1143 | @@ -0,0 +1,487 @@ |
1144 | +// boost/endian/conversion.hpp -------------------------------------------------------// |
1145 | + |
1146 | +// Copyright Beman Dawes 2010, 2011, 2014 |
1147 | + |
1148 | +// Distributed under the Boost Software License, Version 1.0. |
1149 | +// http://www.boost.org/LICENSE_1_0.txt |
1150 | + |
1151 | +#ifndef BOOST_ENDIAN_CONVERSION_HPP |
1152 | +#define BOOST_ENDIAN_CONVERSION_HPP |
1153 | + |
1154 | +#include <boost/config.hpp> |
1155 | +#include <boost/predef/detail/endian_compat.h> |
1156 | +#include <boost/cstdint.hpp> |
1157 | +#include <boost/endian/detail/intrinsic.hpp> |
1158 | +#include <boost/core/scoped_enum.hpp> |
1159 | +#include <boost/static_assert.hpp> |
1160 | +#include <algorithm> |
1161 | +#include <cstring> // for memcpy |
1162 | + |
1163 | +//------------------------------------- synopsis ---------------------------------------// |
1164 | + |
1165 | +namespace boost |
1166 | +{ |
1167 | +namespace endian |
1168 | +{ |
1169 | +#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED |
1170 | + BOOST_SCOPED_ENUM_START(order) |
1171 | + { |
1172 | + big, little, |
1173 | +# ifdef BOOST_BIG_ENDIAN |
1174 | + native = big |
1175 | +# else |
1176 | + native = little |
1177 | +# endif |
1178 | + }; BOOST_SCOPED_ENUM_END |
1179 | +# define BOOST_ENDIAN_ORDER_ENUM_DEFINED |
1180 | +#endif |
1181 | + |
1182 | +//--------------------------------------------------------------------------------------// |
1183 | +// // |
1184 | +// return-by-value interfaces // |
1185 | +// suggested by Phil Endecott // |
1186 | +// // |
1187 | +// user-defined types (UDTs) // |
1188 | +// // |
1189 | +// All return-by-value conversion function templates are required to be implemented in // |
1190 | +// terms of an unqualified call to "endian_reverse(x)", a function returning the // |
1191 | +// value of x with endianness reversed. This provides a customization point for any // |
1192 | +// UDT that provides a "endian_reverse" free-function meeting the requirements. // |
1193 | +// It must be defined in the same namespace as the UDT itself so that it will be found // |
1194 | +// by argument dependent lookup (ADL). // |
1195 | +// // |
1196 | +//--------------------------------------------------------------------------------------// |
1197 | + |
1198 | + // customization for exact-length arithmetic types. See doc/conversion.html/#FAQ |
1199 | + inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT; |
1200 | + inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT; |
1201 | + inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT; |
1202 | + inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT; |
1203 | + inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT; |
1204 | + inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT; |
1205 | + inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT; |
1206 | + inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT; |
1207 | + |
1208 | + // reverse byte order unless native endianness is big |
1209 | + template <class EndianReversible > |
1210 | + inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT; |
1211 | + // Returns: x if native endian order is big, otherwise endian_reverse(x) |
1212 | + template <class EndianReversible > |
1213 | + inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT; |
1214 | + // Returns: x if native endian order is big, otherwise endian_reverse(x) |
1215 | + |
1216 | + // reverse byte order unless native endianness is little |
1217 | + template <class EndianReversible > |
1218 | + inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT; |
1219 | + // Returns: x if native endian order is little, otherwise endian_reverse(x) |
1220 | + template <class EndianReversible > |
1221 | + inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT; |
1222 | + // Returns: x if native endian order is little, otherwise endian_reverse(x) |
1223 | + |
1224 | + // generic conditional reverse byte order |
1225 | + template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, |
1226 | + class EndianReversible> |
1227 | + inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT; |
1228 | + // Returns: If From == To have different values, from. |
1229 | + // Otherwise endian_reverse(from). |
1230 | + // Remarks: The From == To test, and as a consequence which form the return takes, is |
1231 | + // is determined at compile time. |
1232 | + |
1233 | + // runtime conditional reverse byte order |
1234 | + template <class EndianReversible > |
1235 | + inline EndianReversible conditional_reverse(EndianReversible from, |
1236 | + BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) |
1237 | + BOOST_NOEXCEPT; |
1238 | + // Returns: from_order == to_order ? from : endian_reverse(from). |
1239 | + |
1240 | + //------------------------------------------------------------------------------------// |
1241 | + |
1242 | + |
1243 | + // Q: What happended to bswap, htobe, and the other synonym functions based on names |
1244 | + // popularized by BSD, OS X, and Linux? |
1245 | + // A: Turned out these may be implemented as macros on some systems. Ditto POSIX names |
1246 | + // for such functionality. Since macros would cause endless problems with functions |
1247 | + // of the same names, and these functions are just synonyms anyhow, they have been |
1248 | + // removed. |
1249 | + |
1250 | + |
1251 | + //------------------------------------------------------------------------------------// |
1252 | + // // |
1253 | + // reverse in place interfaces // |
1254 | + // // |
1255 | + // user-defined types (UDTs) // |
1256 | + // // |
1257 | + // All reverse in place function templates are required to be implemented in terms // |
1258 | + // of an unqualified call to "endian_reverse_inplace(x)", a function reversing // |
1259 | + // the endianness of x, which is a non-const reference. This provides a // |
1260 | + // customization point for any UDT that provides a "reverse_inplace" free-function // |
1261 | + // meeting the requirements. The free-function must be declared in the same // |
1262 | + // namespace as the UDT itself so that it will be found by argument-dependent // |
1263 | + // lookup (ADL). // |
1264 | + // // |
1265 | + //------------------------------------------------------------------------------------// |
1266 | + |
1267 | + // reverse in place |
1268 | + template <class EndianReversible> |
1269 | + inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT; |
1270 | + // Effects: x = endian_reverse(x) |
1271 | + |
1272 | + // reverse in place unless native endianness is big |
1273 | + template <class EndianReversibleInplace> |
1274 | + inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; |
1275 | + // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x) |
1276 | + template <class EndianReversibleInplace> |
1277 | + inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; |
1278 | + // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x) |
1279 | + |
1280 | + // reverse in place unless native endianness is little |
1281 | + template <class EndianReversibleInplace> |
1282 | + inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; |
1283 | + // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x); |
1284 | + template <class EndianReversibleInplace> |
1285 | + inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; |
1286 | + // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x); |
1287 | + |
1288 | + // generic conditional reverse in place |
1289 | + template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, |
1290 | + class EndianReversibleInplace> |
1291 | + inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT; |
1292 | + |
1293 | + // runtime reverse in place |
1294 | + template <class EndianReversibleInplace> |
1295 | + inline void conditional_reverse_inplace(EndianReversibleInplace& x, |
1296 | + BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) |
1297 | + BOOST_NOEXCEPT; |
1298 | + |
1299 | +//----------------------------------- end synopsis -------------------------------------// |
1300 | + |
1301 | + namespace detail |
1302 | + { |
1303 | + // generic reverse function template implementation approach using std::reverse |
1304 | + // suggested by Mathias Gaunard. Primary motivation for inclusion is to have an |
1305 | + // independent implementation to test against. |
1306 | + |
1307 | + template <class T> |
1308 | + inline T std_endian_reverse(T x) BOOST_NOEXCEPT |
1309 | + { |
1310 | + T tmp(x); |
1311 | + std::reverse( |
1312 | + reinterpret_cast<unsigned char*>(&tmp), |
1313 | + reinterpret_cast<unsigned char*>(&tmp) + sizeof(T)); |
1314 | + return tmp; |
1315 | + } |
1316 | + |
1317 | + // conditional unaligned reverse copy, patterned after std::reverse_copy |
1318 | + template <class T> |
1319 | + inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT; |
1320 | + template <class T> |
1321 | + inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT; |
1322 | + template <class T> |
1323 | + inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT; |
1324 | + template <class T> |
1325 | + inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT; |
1326 | + } // namespace detail |
1327 | + |
1328 | +//--------------------------------------------------------------------------------------// |
1329 | +// // |
1330 | +// return-by-value implementation // |
1331 | +// // |
1332 | +// -- portable approach suggested by tymofey, with avoidance of undefined behavior // |
1333 | +// as suggested by Giovanni Piero Deretta, with a further refinement suggested // |
1334 | +// by Pyry Jahkola. // |
1335 | +// -- intrinsic approach suggested by reviewers, and by David Stone, who provided // |
1336 | +// his Boost licensed macro implementation (detail/intrinsic.hpp) // |
1337 | +// // |
1338 | +//--------------------------------------------------------------------------------------// |
1339 | + |
1340 | + inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT |
1341 | + { |
1342 | + return x; |
1343 | + } |
1344 | + |
1345 | + inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT |
1346 | + { |
1347 | +# ifdef BOOST_ENDIAN_NO_INTRINSICS |
1348 | + return (static_cast<uint16_t>(x) << 8) |
1349 | + | (static_cast<uint16_t>(x) >> 8); |
1350 | +# else |
1351 | + return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(static_cast<uint16_t>(x)); |
1352 | +# endif |
1353 | + } |
1354 | + |
1355 | + inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT |
1356 | + { |
1357 | +# ifdef BOOST_ENDIAN_NO_INTRINSICS |
1358 | + uint32_t step16; |
1359 | + step16 = static_cast<uint32_t>(x) << 16 | static_cast<uint32_t>(x) >> 16; |
1360 | + return |
1361 | + ((static_cast<uint32_t>(step16) << 8) & 0xff00ff00) |
1362 | + | ((static_cast<uint32_t>(step16) >> 8) & 0x00ff00ff); |
1363 | +# else |
1364 | + return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(static_cast<uint32_t>(x)); |
1365 | +# endif |
1366 | + } |
1367 | + |
1368 | + inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT |
1369 | + { |
1370 | +# ifdef BOOST_ENDIAN_NO_INTRINSICS |
1371 | + uint64_t step32, step16; |
1372 | + step32 = static_cast<uint64_t>(x) << 32 | static_cast<uint64_t>(x) >> 32; |
1373 | + step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 |
1374 | + | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; |
1375 | + return static_cast<int64_t>((step16 & 0x00FF00FF00FF00FFULL) << 8 |
1376 | + | (step16 & 0xFF00FF00FF00FF00ULL) >> 8); |
1377 | +# else |
1378 | + return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(static_cast<uint64_t>(x)); |
1379 | +# endif |
1380 | + } |
1381 | + |
1382 | + inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT |
1383 | + { |
1384 | + return x; |
1385 | + } |
1386 | + |
1387 | + inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT |
1388 | + { |
1389 | +# ifdef BOOST_ENDIAN_NO_INTRINSICS |
1390 | + return (x << 8) |
1391 | + | (x >> 8); |
1392 | +# else |
1393 | + return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x); |
1394 | +# endif |
1395 | + } |
1396 | + |
1397 | + inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT |
1398 | + { |
1399 | +# ifdef BOOST_ENDIAN_NO_INTRINSICS |
1400 | + uint32_t step16; |
1401 | + step16 = x << 16 | x >> 16; |
1402 | + return |
1403 | + ((step16 << 8) & 0xff00ff00) |
1404 | + | ((step16 >> 8) & 0x00ff00ff); |
1405 | +# else |
1406 | + return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x); |
1407 | +# endif |
1408 | + } |
1409 | + |
1410 | + inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT |
1411 | + { |
1412 | +# ifdef BOOST_ENDIAN_NO_INTRINSICS |
1413 | + uint64_t step32, step16; |
1414 | + step32 = x << 32 | x >> 32; |
1415 | + step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 |
1416 | + | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; |
1417 | + return (step16 & 0x00FF00FF00FF00FFULL) << 8 |
1418 | + | (step16 & 0xFF00FF00FF00FF00ULL) >> 8; |
1419 | +# else |
1420 | + return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x); |
1421 | +# endif |
1422 | + } |
1423 | + |
1424 | + template <class EndianReversible > |
1425 | + inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT |
1426 | + { |
1427 | +# ifdef BOOST_BIG_ENDIAN |
1428 | + return x; |
1429 | +# else |
1430 | + return endian_reverse(x); |
1431 | +# endif |
1432 | + } |
1433 | + |
1434 | + template <class EndianReversible > |
1435 | + inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT |
1436 | + { |
1437 | +# ifdef BOOST_BIG_ENDIAN |
1438 | + return x; |
1439 | +# else |
1440 | + return endian_reverse(x); |
1441 | +# endif |
1442 | + } |
1443 | + |
1444 | + template <class EndianReversible > |
1445 | + inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT |
1446 | + { |
1447 | +# ifdef BOOST_LITTLE_ENDIAN |
1448 | + return x; |
1449 | +# else |
1450 | + return endian_reverse(x); |
1451 | +# endif |
1452 | + } |
1453 | + |
1454 | + template <class EndianReversible > |
1455 | + inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT |
1456 | + { |
1457 | +# ifdef BOOST_LITTLE_ENDIAN |
1458 | + return x; |
1459 | +# else |
1460 | + return endian_reverse(x); |
1461 | +# endif |
1462 | + } |
1463 | + |
1464 | + namespace detail |
1465 | + { |
1466 | + // Primary template and specializations to support endian_reverse(). |
1467 | + // See rationale in endian_reverse() below. |
1468 | + template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, |
1469 | + class EndianReversible> |
1470 | + class value_converter ; // primary template |
1471 | + template <class T> class value_converter <order::big, order::big, T> |
1472 | + {public: T operator()(T x) BOOST_NOEXCEPT {return x;}}; |
1473 | + template <class T> class value_converter <order::little, order::little, T> |
1474 | + {public: T operator()(T x) BOOST_NOEXCEPT {return x;}}; |
1475 | + template <class T> class value_converter <order::big, order::little, T> |
1476 | + {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}}; |
1477 | + template <class T> class value_converter <order::little, order::big, T> |
1478 | + {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}}; |
1479 | + } |
1480 | + |
1481 | + // generic conditional reverse |
1482 | + template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, |
1483 | + class EndianReversible> |
1484 | + inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT { |
1485 | + // work around lack of function template partial specialization by instantiating |
1486 | + // a function object of a class that is partially specialized on the two order |
1487 | + // template parameters, and then calling its operator(). |
1488 | + detail::value_converter <From, To, EndianReversible> tmp; |
1489 | + return tmp(from); |
1490 | + } |
1491 | + |
1492 | + // runtime conditional reverse |
1493 | + template <class EndianReversible > |
1494 | + inline EndianReversible conditional_reverse(EndianReversible from, |
1495 | + BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT |
1496 | + { |
1497 | + return from_order == to_order ? from : endian_reverse(from); |
1498 | + } |
1499 | + |
1500 | +//--------------------------------------------------------------------------------------// |
1501 | +// reverse-in-place implementation // |
1502 | +//--------------------------------------------------------------------------------------// |
1503 | + |
1504 | + // reverse in place |
1505 | + template <class EndianReversible> |
1506 | + inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT |
1507 | + { |
1508 | + x = endian_reverse(x); |
1509 | + } |
1510 | + |
1511 | + template <class EndianReversibleInplace> |
1512 | +# ifdef BOOST_BIG_ENDIAN |
1513 | + inline void big_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} |
1514 | +# else |
1515 | + inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT |
1516 | + { endian_reverse_inplace(x); } |
1517 | +# endif |
1518 | + template <class EndianReversibleInplace> |
1519 | +# ifdef BOOST_BIG_ENDIAN |
1520 | + inline void native_to_big_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} |
1521 | +# else |
1522 | + inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT |
1523 | + { |
1524 | + endian_reverse_inplace(x); |
1525 | + } |
1526 | +# endif |
1527 | + |
1528 | + template <class EndianReversibleInplace> |
1529 | +# ifdef BOOST_LITTLE_ENDIAN |
1530 | + inline void little_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} |
1531 | +# else |
1532 | + inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT |
1533 | + { endian_reverse_inplace(x); } |
1534 | +# endif |
1535 | + template <class EndianReversibleInplace> |
1536 | +# ifdef BOOST_LITTLE_ENDIAN |
1537 | + inline void native_to_little_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {} |
1538 | +# else |
1539 | + inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT |
1540 | + { |
1541 | + endian_reverse_inplace(x); |
1542 | + } |
1543 | +# endif |
1544 | + |
1545 | + namespace detail |
1546 | + { |
1547 | + // Primary template and specializations support generic |
1548 | + // endian_reverse_inplace(). |
1549 | + // See rationale in endian_reverse_inplace() below. |
1550 | + template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, |
1551 | + class EndianReversibleInplace> |
1552 | + class converter; // primary template |
1553 | + template <class T> class converter<order::big, order::big, T> |
1554 | + {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}}; |
1555 | + template <class T> class converter<order::little, order::little, T> |
1556 | + {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}}; |
1557 | + template <class T> class converter<order::big, order::little, T> |
1558 | + {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }}; |
1559 | + template <class T> class converter<order::little, order::big, T> |
1560 | + {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }}; |
1561 | + } // namespace detail |
1562 | + |
1563 | + // generic conditional reverse in place |
1564 | + template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, |
1565 | + class EndianReversibleInplace> |
1566 | + inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT |
1567 | + { |
1568 | + // work around lack of function template partial specialization by instantiating |
1569 | + // a function object of a class that is partially specialized on the two order |
1570 | + // template parameters, and then calling its operator(). |
1571 | + detail::converter<From, To, EndianReversibleInplace> tmp; |
1572 | + tmp(x); // call operator () |
1573 | + } |
1574 | + |
1575 | + // runtime reverse in place |
1576 | + template <class EndianReversibleInplace> |
1577 | + inline void conditional_reverse_inplace(EndianReversibleInplace& x, |
1578 | + BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) |
1579 | + BOOST_NOEXCEPT |
1580 | + { |
1581 | + if (from_order != to_order) |
1582 | + endian_reverse_inplace(x); |
1583 | + } |
1584 | + |
1585 | + |
1586 | + namespace detail |
1587 | + { |
1588 | + template <class T> |
1589 | + inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT |
1590 | + { |
1591 | +# ifdef BOOST_BIG_ENDIAN |
1592 | + std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T)); |
1593 | +# else |
1594 | + std::reverse_copy(reinterpret_cast<const char*>(&from), |
1595 | + reinterpret_cast<const char*>(&from) + sizeof(T), to); |
1596 | +# endif |
1597 | + } |
1598 | + template <class T> |
1599 | + inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT |
1600 | + { |
1601 | +# ifdef BOOST_BIG_ENDIAN |
1602 | + std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T)); |
1603 | +# else |
1604 | + std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to)); |
1605 | +# endif |
1606 | + } |
1607 | + template <class T> |
1608 | + inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT |
1609 | + { |
1610 | +# ifdef BOOST_LITTLE_ENDIAN |
1611 | + std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T)); |
1612 | +# else |
1613 | + std::reverse_copy(reinterpret_cast<const char*>(&from), |
1614 | + reinterpret_cast<const char*>(&from) + sizeof(T), to); |
1615 | +# endif |
1616 | + } |
1617 | + template <class T> |
1618 | + inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT |
1619 | + { |
1620 | +# ifdef BOOST_LITTLE_ENDIAN |
1621 | + std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T)); |
1622 | +# else |
1623 | + std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to)); |
1624 | +# endif |
1625 | + } |
1626 | + } // namespace detail |
1627 | +} // namespace endian |
1628 | +} // namespace boost |
1629 | + |
1630 | +#endif // BOOST_ENDIAN_CONVERSION_HPP |
1631 | |
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-04-01 06:55:25 +0000 |
1636 | @@ -0,0 +1,62 @@ |
1637 | +// boost/endian/detail/config.hpp ----------------------------------------------------// |
1638 | + |
1639 | +// Copyright Beman Dawes 2003, 2010 |
1640 | + |
1641 | +// Distributed under the Boost Software License, Version 1.0. |
1642 | +// See http://www.boost.org/LICENSE_1_0.txt |
1643 | + |
1644 | +//--------------------------------------------------------------------------------------// |
1645 | + |
1646 | +#ifndef BOOST_ENDIAN_CONFIG_HPP |
1647 | +#define BOOST_ENDIAN_CONFIG_HPP |
1648 | + |
1649 | +// This header implements separate compilation features as described in |
1650 | +// http://www.boost.org/more/separate_compilation.html |
1651 | + |
1652 | +#include <boost/config.hpp> |
1653 | +#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API |
1654 | + |
1655 | +// throw an exception ----------------------------------------------------------------// |
1656 | +// |
1657 | +// Exceptions were originally thrown via boost::throw_exception(). |
1658 | +// As throw_exception() became more complex, it caused user error reporting |
1659 | +// to be harder to interpret, since the exception reported became much more complex. |
1660 | +// The immediate fix was to throw directly, wrapped in a macro to make any later change |
1661 | +// easier. |
1662 | + |
1663 | +#define BOOST_ENDIAN_THROW(EX) throw EX |
1664 | + |
1665 | +// enable dynamic linking -------------------------------------------------------------// |
1666 | + |
1667 | +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK) |
1668 | +# if defined(BOOST_ENDIAN_SOURCE) |
1669 | +# define BOOST_ENDIAN_DECL BOOST_SYMBOL_EXPORT |
1670 | +# else |
1671 | +# define BOOST_ENDIAN_DECL BOOST_SYMBOL_IMPORT |
1672 | +# endif |
1673 | +#else |
1674 | +# define BOOST_ENDIAN_DECL |
1675 | +#endif |
1676 | + |
1677 | +// enable automatic library variant selection ----------------------------------------// |
1678 | + |
1679 | +#if !defined(BOOST_ENDIAN_SOURCE) && !defined(BOOST_ALL_NO_LIB) \ |
1680 | + && !defined(BOOST_ENDIAN_NO_LIB) |
1681 | +// |
1682 | +// Set the name of our library, this will get undef'ed by auto_link.hpp |
1683 | +// once it's done with it: |
1684 | +// |
1685 | +#define BOOST_LIB_NAME boost_endian |
1686 | +// |
1687 | +// If we're importing code from a dll, then tell auto_link.hpp about it: |
1688 | +// |
1689 | +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK) |
1690 | +# define BOOST_DYN_LINK |
1691 | +#endif |
1692 | +// |
1693 | +// And include the header that does the work: |
1694 | +// |
1695 | +#include <boost/config/auto_link.hpp> |
1696 | +#endif // auto-linking disabled |
1697 | + |
1698 | +#endif // BOOST_ENDIAN_CONFIG_HPP |
1699 | |
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-04-01 06:55:25 +0000 |
1703 | @@ -0,0 +1,142 @@ |
1704 | +// boost/endian/detail/cover_operators.hpp ----------------------------------// |
1705 | + |
1706 | +// Copyright Darin Adler 2000 |
1707 | +// Copyright Beman Dawes 2008 |
1708 | + |
1709 | +// Distributed under the Boost Software License, Version 1.0. (See accompanying |
1710 | +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
1711 | + |
1712 | +#ifndef BOOST_ENDIAN_COVER_OPERATORS_HPP |
1713 | +#define BOOST_ENDIAN_COVER_OPERATORS_HPP |
1714 | + |
1715 | +#if defined(_MSC_VER) |
1716 | +# pragma warning(push) |
1717 | +# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch |
1718 | +#endif |
1719 | + |
1720 | +# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS |
1721 | +# include <boost/operators.hpp> |
1722 | +# endif |
1723 | + |
1724 | +#include <boost/config.hpp> |
1725 | +#include <iosfwd> |
1726 | + |
1727 | +namespace boost |
1728 | +{ |
1729 | + namespace endian |
1730 | + { |
1731 | + |
1732 | +//--------------------------------------------------------------------------------------// |
1733 | + |
1734 | +// A class that adds arithmetic operators to an arithmetic cover class |
1735 | +// |
1736 | +// Uses the curiously recurring template pattern (CRTP). |
1737 | +// |
1738 | +// If the class being covered has a non-explicit conversion to an integer type |
1739 | +// then a smaller number of cover operations are needed. Define the macro |
1740 | +// BOOST_ENDIAN_MINIMAL_COVER_OPERATORS to indicate this. |
1741 | +// |
1742 | +// Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired. |
1743 | + |
1744 | +//--------------------------------------------------------------------------------------// |
1745 | + |
1746 | + template <class D, // D is the CRTP derived type, i.e. the cover class |
1747 | + class ArithmeticT> |
1748 | + class cover_operators |
1749 | +# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS |
1750 | + : boost::operators<D> |
1751 | +# endif |
1752 | + { |
1753 | + // The other operations take advantage of the type conversion that's |
1754 | + // built into unary +. |
1755 | + |
1756 | + // Unary operations. |
1757 | + friend ArithmeticT operator+(const D& x) BOOST_NOEXCEPT { return x; } |
1758 | +# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS |
1759 | + friend ArithmeticT operator-(const D& x) BOOST_NOEXCEPT { return -+x; } |
1760 | + friend ArithmeticT operator~(const D& x) BOOST_NOEXCEPT { return ~+x; } |
1761 | + friend ArithmeticT operator!(const D& x) BOOST_NOEXCEPT { return !+x; } |
1762 | + |
1763 | + // The basic ordering operations. |
1764 | + friend bool operator==(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x == y; } |
1765 | + friend bool operator<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x < y; } |
1766 | +# endif |
1767 | + |
1768 | + // The basic arithmetic operations. |
1769 | + friend D& operator+=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1770 | + { return x = static_cast<ArithmeticT>(+x + y); } |
1771 | + friend D& operator-=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1772 | + { return x = static_cast<ArithmeticT>(+x - y); } |
1773 | + friend D& operator*=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1774 | + { return x = static_cast<ArithmeticT>(+x * y); } |
1775 | + friend D& operator/=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1776 | + { return x = static_cast<ArithmeticT>(+x / y); } |
1777 | + friend D& operator%=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1778 | + { return x = static_cast<ArithmeticT>(+x % y); } |
1779 | + friend D& operator&=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1780 | + { return x = static_cast<ArithmeticT>(+x & y); } |
1781 | + friend D& operator|=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1782 | + { return x = static_cast<ArithmeticT>(+x | y); } |
1783 | + friend D& operator^=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1784 | + { return x = static_cast<ArithmeticT>(+x ^ y); } |
1785 | + friend D& operator<<=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1786 | + { return x = static_cast<ArithmeticT>(+x << y); } |
1787 | + friend D& operator>>=(D& x, ArithmeticT y) BOOST_NOEXCEPT |
1788 | + { return x = static_cast<ArithmeticT>(+x >> y); } |
1789 | + |
1790 | + // A few binary arithmetic operations not covered by operators base class. |
1791 | + friend ArithmeticT operator<<(const D& x, ArithmeticT y) BOOST_NOEXCEPT |
1792 | + { return static_cast<ArithmeticT>(+x << y); } |
1793 | + friend ArithmeticT operator>>(const D& x, ArithmeticT y) BOOST_NOEXCEPT |
1794 | + { return static_cast<ArithmeticT>(+x >> y); } |
1795 | + |
1796 | + // Auto-increment and auto-decrement can be defined in terms of the |
1797 | + // arithmetic operations. |
1798 | + friend D& operator++(D& x) BOOST_NOEXCEPT { return x += 1; } |
1799 | + friend D& operator--(D& x) BOOST_NOEXCEPT { return x -= 1; } |
1800 | + |
1801 | +# ifdef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS |
1802 | + friend D operator++(D& x, int) BOOST_NOEXCEPT |
1803 | + { |
1804 | + D tmp(x); |
1805 | + x += 1; |
1806 | + return tmp; |
1807 | + } |
1808 | + friend D operator--(D& x, int) BOOST_NOEXCEPT |
1809 | + { |
1810 | + D tmp(x); |
1811 | + x -= 1; |
1812 | + return tmp; |
1813 | + } |
1814 | +# endif |
1815 | + |
1816 | +# ifndef BOOST_NO_IO_COVER_OPERATORS |
1817 | + |
1818 | + // Stream inserter |
1819 | + template <class charT, class traits> |
1820 | + friend std::basic_ostream<charT, traits>& |
1821 | + operator<<(std::basic_ostream<charT, traits>& os, const D& x) |
1822 | + { |
1823 | + return os << +x; |
1824 | + } |
1825 | + |
1826 | + // Stream extractor |
1827 | + template <class charT, class traits> |
1828 | + friend std::basic_istream<charT, traits>& |
1829 | + operator>>(std::basic_istream<charT, traits>& is, D& x) |
1830 | + { |
1831 | + ArithmeticT i; |
1832 | + if (is >> i) |
1833 | + x = i; |
1834 | + return is; |
1835 | + } |
1836 | +# endif |
1837 | + }; |
1838 | + } // namespace endian |
1839 | +} // namespace boost |
1840 | + |
1841 | +#if defined(_MSC_VER) |
1842 | +# pragma warning(pop) |
1843 | +#endif |
1844 | + |
1845 | +#endif // BOOST_ENDIAN_COVER_OPERATORS_HPP |
1846 | |
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-04-01 06:55:25 +0000 |
1850 | @@ -0,0 +1,33 @@ |
1851 | +// disable_warnings.hpp --------------------------------------------------------------// |
1852 | + |
1853 | +// Copyright Beman Dawes 2011 |
1854 | + |
1855 | +// Distributed under the Boost Software License, Version 1.0. |
1856 | +// See http://www.boost.org/LICENSE_1_0.txt |
1857 | + |
1858 | +//--------------------------------------------------------------------------------------// |
1859 | + |
1860 | +#ifdef _MSC_VER |
1861 | + |
1862 | +#ifndef _SCL_SECURE_NO_WARNINGS |
1863 | +# define _SCL_SECURE_NO_WARNINGS |
1864 | +#endif |
1865 | + |
1866 | +#ifndef _CRT_SECURE_NO_WARNINGS |
1867 | +# define _CRT_SECURE_NO_WARNINGS |
1868 | +#endif |
1869 | + |
1870 | +# pragma warning(push) |
1871 | + |
1872 | +// triggered by boost/detail/lightweight_test.hpp |
1873 | +# pragma warning( disable : 4640 ) // ... construction of local static object is not thread-safe |
1874 | + |
1875 | +// triggered by Microsoft's own headers, so disable |
1876 | +# pragma warning( disable : 4820 ) // padding added after data member |
1877 | +# pragma warning( disable : 4548 ) // expression before comma has no effect |
1878 | +# pragma warning( disable : 4668 ) // ... is not defined as a preprocessor macro |
1879 | +# pragma warning( disable : 4514 ) // ... unreferenced inline function has been removed |
1880 | +# pragma warning( disable : 4710 ) // ... function not inlined |
1881 | +# pragma warning( disable : 4986 ) // ... exception specification does not match previous declaration |
1882 | +# pragma warning( disable : 4711 ) // ... selected for automatic inline expansion |
1883 | +#endif |
1884 | |
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-04-01 06:55:25 +0000 |
1888 | @@ -0,0 +1,12 @@ |
1889 | +// disable_warnings_pop.hpp ----------------------------------------------------------// |
1890 | + |
1891 | +// Copyright Beman Dawes 2011 |
1892 | + |
1893 | +// Distributed under the Boost Software License, Version 1.0. |
1894 | +// See http://www.boost.org/LICENSE_1_0.txt |
1895 | + |
1896 | +//--------------------------------------------------------------------------------------// |
1897 | + |
1898 | +#ifdef _MSC_VER |
1899 | +# pragma warning(push) |
1900 | +#endif |
1901 | |
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-04-01 06:55:25 +0000 |
1905 | @@ -0,0 +1,64 @@ |
1906 | +// endian/detail/intrinsic.hpp -------------------------------------------------------// |
1907 | + |
1908 | +// Copyright (C) 2012 David Stone |
1909 | +// Copyright Beman Dawes 2013 |
1910 | + |
1911 | +// Distributed under the Boost Software License, Version 1.0. |
1912 | +// http://www.boost.org/LICENSE_1_0.txt |
1913 | + |
1914 | +#ifndef BOOST_ENDIAN_INTRINSIC_HPP |
1915 | +#define BOOST_ENDIAN_INTRINSIC_HPP |
1916 | + |
1917 | +// Allow user to force BOOST_ENDIAN_NO_INTRINSICS in case they aren't available for a |
1918 | +// particular platform/compiler combination. Please report such platform/compiler |
1919 | +// combinations to the Boost mailing list. |
1920 | +#ifndef BOOST_ENDIAN_NO_INTRINSICS |
1921 | + |
1922 | +#ifndef __has_builtin // Optional of course |
1923 | + #define __has_builtin(x) 0 // Compatibility with non-clang compilers |
1924 | +#endif |
1925 | + |
1926 | +// GCC and Clang recent versions provide intrinsic byte swaps via builtins |
1927 | +#if (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) \ |
1928 | + || (defined(__GNUC__ ) && \ |
1929 | + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) |
1930 | +# define BOOST_ENDIAN_INTRINSIC_MSG "__builtin_bswap16, etc." |
1931 | +// prior to 4.8, gcc did not provide __builtin_bswap16 on some platforms so we emulate it |
1932 | +// see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624 |
1933 | +// Clang has a similar problem, but their feature test macros make it easier to detect |
1934 | +# if (defined(__clang__) && __has_builtin(__builtin_bswap16)) \ |
1935 | + || (defined(__GNUC__) &&(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) |
1936 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) __builtin_bswap16(x) |
1937 | +# else |
1938 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) __builtin_bswap32((x) << 16) |
1939 | +# endif |
1940 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) __builtin_bswap32(x) |
1941 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) __builtin_bswap64(x) |
1942 | + |
1943 | +// Linux systems provide the byteswap.h header, with |
1944 | +#elif defined(__linux__) |
1945 | +// don't check for obsolete forms defined(linux) and defined(__linux) on the theory that |
1946 | +// compilers that predefine only these are so old that byteswap.h probably isn't present. |
1947 | +# define BOOST_ENDIAN_INTRINSIC_MSG "byteswap.h bswap_16, etc." |
1948 | +# include <byteswap.h> |
1949 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) bswap_16(x) |
1950 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) bswap_32(x) |
1951 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) bswap_64(x) |
1952 | + |
1953 | +#elif defined(_MSC_VER) |
1954 | +// Microsoft documents these as being compatible since Windows 95 and specificly |
1955 | +// lists runtime library support since Visual Studio 2003 (aka 7.1). |
1956 | +# define BOOST_ENDIAN_INTRINSIC_MSG "cstdlib _byteswap_ushort, etc." |
1957 | +# include <cstdlib> |
1958 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) _byteswap_ushort(x) |
1959 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) _byteswap_ulong(x) |
1960 | +# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) _byteswap_uint64(x) |
1961 | +#else |
1962 | +# define BOOST_ENDIAN_NO_INTRINSICS |
1963 | +# define BOOST_ENDIAN_INTRINSIC_MSG "no byte swap intrinsics" |
1964 | +#endif |
1965 | + |
1966 | +#elif !defined(BOOST_ENDIAN_INTRINSIC_MSG) |
1967 | +# define BOOST_ENDIAN_INTRINSIC_MSG "no byte swap intrinsics" |
1968 | +#endif // BOOST_ENDIAN_NO_INTRINSICS |
1969 | +#endif // BOOST_ENDIAN_INTRINSIC_HPP |
1970 | |
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-04-01 06:55:25 +0000 |
1974 | @@ -0,0 +1,223 @@ |
1975 | +// boost/endian/detail/lightweight_test.hpp --------------------------------------------// |
1976 | + |
1977 | +#ifndef BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP |
1978 | +#define BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP |
1979 | + |
1980 | +// MS compatible compilers support #pragma once |
1981 | + |
1982 | +#if defined(_MSC_VER) |
1983 | +# pragma once |
1984 | +#endif |
1985 | + |
1986 | +// |
1987 | +// Copyright (c) 2002, 2009, 2014 Peter Dimov |
1988 | +// Copyright (2) Beman Dawes 2010, 2011, 2015 |
1989 | +// Copyright (3) Ion Gaztanaga 2013 |
1990 | +// |
1991 | +// Distributed under the Boost Software License, Version 1.0. |
1992 | +// See http://www.boost.org/LICENSE_1_0.txt |
1993 | +// |
1994 | + |
1995 | +#include <boost/assert.hpp> |
1996 | +#include <boost/current_function.hpp> |
1997 | +#include <boost/core/no_exceptions_support.hpp> |
1998 | +#include <cstring> // for memcmp |
1999 | +#include <iostream> |
2000 | + |
2001 | +// IDE's like Visual Studio perform better if output goes to std::cout or |
2002 | +// some other stream, so allow user to configure output stream: |
2003 | +#ifndef BOOST_LIGHTWEIGHT_TEST_OSTREAM |
2004 | +# define BOOST_LIGHTWEIGHT_TEST_OSTREAM std::cerr |
2005 | +#endif |
2006 | + |
2007 | +namespace boost |
2008 | +{ |
2009 | +namespace endian |
2010 | +{ |
2011 | +namespace detail |
2012 | +{ |
2013 | + |
2014 | +struct report_errors_reminder |
2015 | +{ |
2016 | + bool called_report_errors_function; |
2017 | + |
2018 | + report_errors_reminder() : called_report_errors_function(false) {} |
2019 | + |
2020 | + ~report_errors_reminder() |
2021 | + { |
2022 | + BOOST_ASSERT(called_report_errors_function); // verify report_errors() was called |
2023 | + } |
2024 | +}; |
2025 | + |
2026 | +inline report_errors_reminder& report_errors_remind() |
2027 | +{ |
2028 | + static report_errors_reminder r; |
2029 | + return r; |
2030 | +} |
2031 | + |
2032 | +inline int & test_errors() |
2033 | +{ |
2034 | + static int x = 0; |
2035 | + report_errors_remind(); |
2036 | + return x; |
2037 | +} |
2038 | + |
2039 | +inline void test_failed_impl(char const * expr, char const * file, int line, char const * function) |
2040 | +{ |
2041 | + BOOST_LIGHTWEIGHT_TEST_OSTREAM |
2042 | + << file << "(" << line << "): test '" << expr << "' failed in function '" |
2043 | + << function << "'" << std::endl; |
2044 | + ++test_errors(); |
2045 | +} |
2046 | + |
2047 | +inline void error_impl(char const * msg, char const * file, int line, char const * function) |
2048 | +{ |
2049 | + BOOST_LIGHTWEIGHT_TEST_OSTREAM |
2050 | + << file << "(" << line << "): " << msg << " in function '" |
2051 | + << function << "'" << std::endl; |
2052 | + ++test_errors(); |
2053 | +} |
2054 | + |
2055 | +inline void throw_failed_impl(char const * excep, char const * file, int line, char const * function) |
2056 | +{ |
2057 | + BOOST_LIGHTWEIGHT_TEST_OSTREAM |
2058 | + << file << "(" << line << "): Exception '" << excep << "' not thrown in function '" |
2059 | + << function << "'" << std::endl; |
2060 | + ++test_errors(); |
2061 | +} |
2062 | + |
2063 | +template<class T, class U> inline void test_eq_impl( char const * expr1, char const * expr2, |
2064 | + char const * file, int line, char const * function, T const & t, U const & u ) |
2065 | +{ |
2066 | + if( t == u ) |
2067 | + { |
2068 | + report_errors_remind(); |
2069 | + } |
2070 | + else |
2071 | + { |
2072 | + BOOST_LIGHTWEIGHT_TEST_OSTREAM |
2073 | + << file << "(" << line << "): test '" << expr1 << " == " << expr2 |
2074 | + << "' failed in function '" << function << "': " |
2075 | + << "'" << t << "' != '" << u << "'" << std::endl; |
2076 | + ++test_errors(); |
2077 | + } |
2078 | +} |
2079 | + |
2080 | +template<class T, class U> inline void test_ne_impl( char const * expr1, char const * expr2, |
2081 | + char const * file, int line, char const * function, T const & t, U const & u ) |
2082 | +{ |
2083 | + if( t != u ) |
2084 | + { |
2085 | + report_errors_remind(); |
2086 | + } |
2087 | + else |
2088 | + { |
2089 | + BOOST_LIGHTWEIGHT_TEST_OSTREAM |
2090 | + << file << "(" << line << "): test '" << expr1 << " != " << expr2 |
2091 | + << "' failed in function '" << function << "': " |
2092 | + << "'" << t << "' == '" << u << "'" << std::endl; |
2093 | + ++test_errors(); |
2094 | + } |
2095 | +} |
2096 | + |
2097 | +template <class T> |
2098 | +std::string to_hex(const T& x) |
2099 | +{ |
2100 | + const char hex[] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; |
2101 | + std::string tmp; |
2102 | + const unsigned char* p = reinterpret_cast<const unsigned char*>(&x); |
2103 | + const unsigned char* e = p + sizeof(T); |
2104 | + |
2105 | + for (; p < e; ++p) |
2106 | + { |
2107 | + tmp += hex[*p >> 4]; // high-order nibble |
2108 | + tmp += hex[*p & 0x0f]; // low-order nibble |
2109 | + } |
2110 | + return tmp; |
2111 | +} |
2112 | + |
2113 | +template<class T, class U> inline bool test_memcmp_eq_impl(char const * expr1, |
2114 | + char const * expr2, char const * file, int line, char const * function, T const & t, |
2115 | + U const & u) |
2116 | +{ |
2117 | + BOOST_ASSERT(sizeof(T) == sizeof(U)); |
2118 | + if (sizeof(T) == sizeof(U) |
2119 | + && std::memcmp(&t, &u, sizeof(T)) == 0) |
2120 | + { |
2121 | + report_errors_remind(); |
2122 | + return true; |
2123 | + } |
2124 | + else |
2125 | + { |
2126 | + BOOST_LIGHTWEIGHT_TEST_OSTREAM |
2127 | + << file << "(" << line << "): test 'std::memcmp(" << expr1 << ", " << expr2 |
2128 | + << ") == 0' fails in function '" << function << "': " |
2129 | + << " with values '" << to_hex(t) << "' and '" << to_hex(u) << "'" << std::endl; |
2130 | + ++test_errors(); |
2131 | + return false; |
2132 | + } |
2133 | +} |
2134 | + |
2135 | +} // namespace detail |
2136 | + |
2137 | +inline int report_errors() |
2138 | +{ |
2139 | + boost::endian::detail::report_errors_remind().called_report_errors_function = true; |
2140 | + |
2141 | + int errors = boost::endian::detail::test_errors(); |
2142 | + |
2143 | + if( errors == 0 ) |
2144 | + { |
2145 | + BOOST_LIGHTWEIGHT_TEST_OSTREAM |
2146 | + << "No errors detected." << std::endl; |
2147 | + return 0; |
2148 | + } |
2149 | + else |
2150 | + { |
2151 | + BOOST_LIGHTWEIGHT_TEST_OSTREAM |
2152 | + << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl; |
2153 | + return 1; |
2154 | + } |
2155 | +} |
2156 | + |
2157 | +} // namespace endian |
2158 | +} // namespace boost |
2159 | + |
2160 | +////////////////////////////////////////////////////////////////////////////////////////// |
2161 | +// TODO: Should all test macros return bool? See BOOST_TEST_MEM_EQ usage in fp_exaustive_test,cpp |
2162 | +////////////////////////////////////////////////////////////////////////////////////////// |
2163 | + |
2164 | + |
2165 | +#define BOOST_TEST(expr) \ |
2166 | + ((expr)? (void)0: ::boost::endian::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION)) |
2167 | + |
2168 | +#define BOOST_ERROR(msg) \ |
2169 | + ( ::boost::endian::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) ) |
2170 | + |
2171 | +#define BOOST_TEST_EQ(expr1,expr2) \ |
2172 | + ( ::boost::endian::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
2173 | +#define BOOST_TEST_NE(expr1,expr2) \ |
2174 | + ( ::boost::endian::detail::test_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
2175 | + |
2176 | +#define BOOST_TEST_MEM_EQ(expr1,expr2) \ |
2177 | + (::boost::endian::detail::test_memcmp_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2)) |
2178 | + |
2179 | +#ifndef BOOST_NO_EXCEPTIONS |
2180 | + #define BOOST_TEST_THROWS( EXPR, EXCEP ) \ |
2181 | + try { \ |
2182 | + EXPR; \ |
2183 | + ::boost::detail::throw_failed_impl \ |
2184 | + (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ |
2185 | + } \ |
2186 | + catch(EXCEP const&) { \ |
2187 | + } \ |
2188 | + catch(...) { \ |
2189 | + ::boost::detail::throw_failed_impl \ |
2190 | + (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ |
2191 | + } \ |
2192 | + // |
2193 | +#else |
2194 | + #define BOOST_TEST_THROWS( EXPR, EXCEP ) |
2195 | +#endif |
2196 | + |
2197 | +#endif // #ifndef BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP |
2198 | |
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-04-01 06:55:25 +0000 |
2202 | @@ -0,0 +1,19 @@ |
2203 | +// boost/endian/endian.hpp -----------------------------------------------------------// |
2204 | + |
2205 | +// Copyright Beman Dawes 2015 |
2206 | + |
2207 | +// Distributed under the Boost Software License, Version 1.0. |
2208 | +// See http://www.boost.org/LICENSE_1_0.txt |
2209 | + |
2210 | +// See library home page at http://www.boost.org/libs/endian |
2211 | + |
2212 | +#ifndef BOOST_ENDIAN_ENDIAN_HPP |
2213 | +#define BOOST_ENDIAN_ENDIAN_HPP |
2214 | + |
2215 | +#ifndef BOOST_ENDIAN_DEPRECATED_NAMES |
2216 | +# error "<boost/endian/endian.hpp> is deprecated. Define BOOST_ENDIAN_DEPRECATED_NAMES to use." |
2217 | +#endif |
2218 | + |
2219 | +#include <boost/endian/arithmetic.hpp> |
2220 | + |
2221 | +#endif //BOOST_ENDIAN_ENDIAN_HPP |
2222 | |
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-04-01 06:55:25 +0000 |
2226 | @@ -0,0 +1,38 @@ |
2227 | +// boost/endian/std_pair.hpp ---------------------------------------------------------// |
2228 | + |
2229 | +// Copyright Beman Dawes 2013 |
2230 | + |
2231 | +// Distributed under the Boost Software License, Version 1.0. |
2232 | +// http://www.boost.org/LICENSE_1_0.txt |
2233 | + |
2234 | +//--------------------------------------------------------------------------------------// |
2235 | + |
2236 | +#ifndef BOOST_ENDIAN_STD_PAIR_HPP |
2237 | +#define BOOST_ENDIAN_STD_PAIR_HPP |
2238 | + |
2239 | +#include <boost/endian/conversion.hpp> |
2240 | +#include <utility> |
2241 | + |
2242 | +namespace boost |
2243 | +{ |
2244 | +namespace endian |
2245 | +{ |
2246 | + template <class ReversibleValueT, class ReversibleValueU> |
2247 | + std::pair<ReversibleValueT, ReversibleValueU> |
2248 | + reverse_value(std::pair<ReversibleValueT, ReversibleValueU> x) |
2249 | + { |
2250 | + return std::pair<ReversibleValueT, ReversibleValueU>(reverse_value(x.first), |
2251 | + reverse_value(x.second)); |
2252 | + } |
2253 | + |
2254 | + template <class ReversibleT, class ReversibleU> |
2255 | + void reverse(std::pair<ReversibleT, ReversibleU>& x) |
2256 | + { |
2257 | + reverse(x.first); |
2258 | + reverse(x.second); |
2259 | + } |
2260 | + |
2261 | +} |
2262 | +} |
2263 | + |
2264 | +#endif // BOOST_ENDIAN_STD_PAIR_HPP |
2265 | |
2266 | === modified file 'CMakeLists.txt' |
2267 | --- CMakeLists.txt 2014-09-18 23:06:08 +0000 |
2268 | +++ CMakeLists.txt 2016-04-01 06:55:25 +0000 |
2269 | @@ -34,6 +34,7 @@ |
2270 | pkg_check_modules(PROCESS_CPP process-cpp REQUIRED) |
2271 | pkg_check_modules(PROPERTIES_CPP properties-cpp REQUIRED) |
2272 | pkg_check_modules(TRUST_STORE trust-store REQUIRED) |
2273 | +pkg_check_modules(UBUNTU_PLATFORM_HARDWARE_API ubuntu-platform-hardware-api) |
2274 | ##################################################################### |
2275 | # Enable code coverage calculation with gcov/gcovr/lcov |
2276 | # Usage: |
2277 | @@ -54,7 +55,23 @@ |
2278 | SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-local-typedefs") |
2279 | endif (DISABLE_ERROR_ON_LOCAL_TYPEDEFS_WARNINGS) |
2280 | |
2281 | +# |
2282 | +# Code style fixer. We rely on clang-format to adjust the formatting of source code. |
2283 | +# |
2284 | +find_program(CLANG_FORMAT_COMMAND NAMES clang-format-3.6 clang-format-3.5) |
2285 | +if (NOT CLANG_FORMAT_COMMAND) |
2286 | + message(WARNING "Cannot find clang-format >= clang-format-3.5: formatcode target will not be available") |
2287 | +endif() |
2288 | + |
2289 | +if (CLANG_FORMAT_COMMAND) |
2290 | + file(GLOB_RECURSE UBUNTU_LOCATION_SERVICE_INTERFACE_HEADER_FILES ${CMAKE_SOURCE_DIR}/include/*.h) |
2291 | + file(GLOB_RECURSE UBUNTU_LOCATION_SERVICE_IMPLEMENTATION_FILES ${CMAKE_SOURCE_DIR}/src/*.h ${CMAKE_SOURCE_DIR}/src/*.cpp) |
2292 | + add_custom_target(formatcode ${CLANG_FORMAT_COMMAND} -i ${UBUNTU_LOCATION_SERVICE_INTERFACE_HEADER_FILES} ${UBUNTU_LOCATION_SERVICE_IMPLEMENTATION_FILES} SOURCES _clang-format) |
2293 | +endif() |
2294 | + |
2295 | include_directories( |
2296 | + 3rd-party/ |
2297 | + |
2298 | ${Boost_INCLUDE_DIRS} |
2299 | ${DBUS_INCLUDE_DIRS} |
2300 | ${DBUS_CPP_INCLUDE_DIRS} |
2301 | |
2302 | === added file '_clang-format' |
2303 | --- _clang-format 1970-01-01 00:00:00 +0000 |
2304 | +++ _clang-format 2016-04-01 06:55:25 +0000 |
2305 | @@ -0,0 +1,56 @@ |
2306 | +--- |
2307 | +Language: Cpp |
2308 | +AccessModifierOffset: -4 |
2309 | +ConstructorInitializerIndentWidth: 4 |
2310 | +AlignEscapedNewlinesLeft: false |
2311 | +AlignTrailingComments: true |
2312 | +AllowAllParametersOfDeclarationOnNextLine: true |
2313 | +AllowShortBlocksOnASingleLine: false |
2314 | +AllowShortIfStatementsOnASingleLine: false |
2315 | +AllowShortLoopsOnASingleLine: false |
2316 | +AllowShortFunctionsOnASingleLine: All |
2317 | +AlwaysBreakTemplateDeclarations: false |
2318 | +AlwaysBreakBeforeMultilineStrings: false |
2319 | +BreakBeforeBinaryOperators: false |
2320 | +BreakBeforeTernaryOperators: true |
2321 | +BreakConstructorInitializersBeforeComma: false |
2322 | +BinPackParameters: true |
2323 | +ColumnLimit: 0 |
2324 | +ConstructorInitializerAllOnOneLineOrOnePerLine: false |
2325 | +DerivePointerAlignment: false |
2326 | +ExperimentalAutoDetectBinPacking: false |
2327 | +IndentCaseLabels: false |
2328 | +IndentWrappedFunctionNames: false |
2329 | +IndentFunctionDeclarationAfterType: false |
2330 | +MaxEmptyLinesToKeep: 1 |
2331 | +KeepEmptyLinesAtTheStartOfBlocks: true |
2332 | +NamespaceIndentation: None |
2333 | +ObjCSpaceAfterProperty: false |
2334 | +ObjCSpaceBeforeProtocolList: true |
2335 | +PenaltyBreakBeforeFirstCallParameter: 19 |
2336 | +PenaltyBreakComment: 300 |
2337 | +PenaltyBreakString: 1000 |
2338 | +PenaltyBreakFirstLessLess: 120 |
2339 | +PenaltyExcessCharacter: 1000000 |
2340 | +PenaltyReturnTypeOnItsOwnLine: 60 |
2341 | +PointerAlignment: Left |
2342 | +SpacesBeforeTrailingComments: 1 |
2343 | +Cpp11BracedListStyle: true |
2344 | +Standard: Cpp11 |
2345 | +IndentWidth: 4 |
2346 | +TabWidth: 8 |
2347 | +UseTab: Never |
2348 | +BreakBeforeBraces: Allman |
2349 | +SpacesInParentheses: false |
2350 | +SpacesInAngles: false |
2351 | +SpaceInEmptyParentheses: false |
2352 | +SpacesInCStyleCastParentheses: false |
2353 | +SpacesInContainerLiterals: true |
2354 | +SpaceBeforeAssignmentOperators: true |
2355 | +ContinuationIndentWidth: 4 |
2356 | +CommentPragmas: '^ IWYU pragma:' |
2357 | +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] |
2358 | +SpaceBeforeParens: ControlStatements |
2359 | +DisableFormat: false |
2360 | +... |
2361 | + |
2362 | |
2363 | === added file 'astyle-config' |
2364 | --- astyle-config 1970-01-01 00:00:00 +0000 |
2365 | +++ astyle-config 2016-04-01 06:55:25 +0000 |
2366 | @@ -0,0 +1,43 @@ |
2367 | +# Options for formatting code with astyle. |
2368 | +# |
2369 | +# This helps to make code match the style guide. |
2370 | +# |
2371 | +# Use like this: |
2372 | +# |
2373 | +# astyle --options=astyle-config mfile.h myfile.cpp |
2374 | +# |
2375 | +# Occasionally, astyle does something silly (particularly with lambdas), so it's |
2376 | +# still necessary to scan the changes for things that are wrong. |
2377 | +# But, for most files, it does a good job. |
2378 | +# |
2379 | +# Please consider using this before checking code in for review. Code reviews shouldn't |
2380 | +# have to deal with layout issues, they are just a distraction. It's better to be able |
2381 | +# to focus on semantics in a code review, with style issues out of the way. |
2382 | + |
2383 | +--formatted |
2384 | +--style=allman |
2385 | +--min-conditional-indent=2 |
2386 | +--indent-switches |
2387 | +--max-instatement-indent=120 |
2388 | +--pad-header |
2389 | +--align-pointer=type |
2390 | +--align-reference=type |
2391 | +--convert-tabs |
2392 | +--close-templates |
2393 | +--max-code-length=120 |
2394 | + |
2395 | +# --pad-oper |
2396 | +# |
2397 | +# Commented out for now. It changes |
2398 | +# |
2399 | +# for (int i=0; i<10; ++i) |
2400 | +# to |
2401 | +# for (int i = 0; i < 10; ++i) |
2402 | +# |
2403 | +# Unfortunately, it also messes with rvalue references: |
2404 | +# |
2405 | +# ResourcePtr& operator=(ResourcePtr&& r); |
2406 | +# |
2407 | +# becomes: |
2408 | +# |
2409 | +# ResourcePtr& operator=(ResourcePtr && r); |
2410 | |
2411 | === modified file 'debian/changelog' |
2412 | --- debian/changelog 2015-07-27 18:07:37 +0000 |
2413 | +++ debian/changelog 2016-04-01 06:55:25 +0000 |
2414 | @@ -36,6 +36,117 @@ |
2415 | |
2416 | -- CI Train Bot <ci-train-bot@canonical.com> Thu, 28 May 2015 11:40:58 +0000 |
2417 | |
2418 | +location-service (2.1+15.04.20160331.2-0ubuntu1) vivid; urgency=medium |
2419 | + |
2420 | + * Log to stderr by default, relying on upstart to rotate logs |
2421 | + appropriately. (LP: #1447110) |
2422 | + |
2423 | + -- Thomas Voß <ci-train-bot@canonical.com> Thu, 31 Mar 2016 11:03:46 +0000 |
2424 | + |
2425 | +location-service (2.1+15.04.20160308.1-0ubuntu1) vivid; urgency=medium |
2426 | + |
2427 | + * Add SntpClient for querying reference time information. |
2428 | + |
2429 | + -- Thomas Voß <ci-train-bot@canonical.com> Tue, 08 Mar 2016 08:54:07 +0000 |
2430 | + |
2431 | +location-service (2.1+15.04.20160302.1-0ubuntu1) vivid; urgency=medium |
2432 | + |
2433 | + * Remove explicit option to disable satellite-based positioning |
2434 | + services. |
2435 | + |
2436 | + -- Thomas Voß <ci-train-bot@canonical.com> Wed, 02 Mar 2016 15:28:02 +0000 |
2437 | + |
2438 | +location-service (2.1+15.04.20160106-0ubuntu1) vivid; urgency=medium |
2439 | + |
2440 | + [ Alberto Mardegan ] |
2441 | + * Set debian source format to "3.0 (native)" |
2442 | + |
2443 | + [ Scott Sweeny ] |
2444 | + * Allow providers to register themselves asynchronously (LP: #1415029) |
2445 | + |
2446 | + -- Thomas Voß <ci-train-bot@canonical.com> Wed, 06 Jan 2016 16:15:29 +0000 |
2447 | + |
2448 | +location-service (2.1+15.04.20151211-0ubuntu1) vivid; urgency=medium |
2449 | + |
2450 | + * Account for changes in trust-store w.r.t. assembling the description |
2451 | + of a trust prompt. |
2452 | + |
2453 | + -- Thomas Voß <ci-train-bot@canonical.com> Fri, 11 Dec 2015 08:57:44 +0000 |
2454 | + |
2455 | +location-service (2.1+15.04.20151209-0ubuntu1) vivid; urgency=medium |
2456 | + |
2457 | + * Fix settings not being applied correctly. |
2458 | + |
2459 | + -- Thomas Voß <ci-train-bot@canonical.com> Wed, 09 Dec 2015 15:22:22 +0000 |
2460 | + |
2461 | +location-service (2.1+15.04.20151202.1-0ubuntu1) vivid; urgency=medium |
2462 | + |
2463 | + * Ensure that event connections are cleaned up on destruction. (LP: |
2464 | + #1480877) |
2465 | + |
2466 | + -- Thomas Voß <ci-train-bot@canonical.com> Wed, 02 Dec 2015 12:12:21 +0000 |
2467 | + |
2468 | +location-service (2.1+15.04.20151127-0ubuntu1) vivid; urgency=medium |
2469 | + |
2470 | + [ Alberto Mardegan ] |
2471 | + * Send last known position on session start |
2472 | + |
2473 | + [ CI Train Bot ] |
2474 | + * New rebuild forced. |
2475 | + |
2476 | + [ Thomas Voß ] |
2477 | + * Factor out service::Runtime from daemon.cpp into its own .h/.cpp |
2478 | + pair of files. Add test cases around correct operation of |
2479 | + service::Runtime. added: |
2480 | + src/location_service/com/ubuntu/location/service/runtime.cpp |
2481 | + src/location_service/com/ubuntu/location/service/runtime.h |
2482 | + tests/runtime_test.cpp |
2483 | + |
2484 | + [ thomas-voss ] |
2485 | + * Factor out service::Runtime from daemon.cpp into its own .h/.cpp |
2486 | + pair of files. Add test cases around correct operation of |
2487 | + service::Runtime. added: |
2488 | + src/location_service/com/ubuntu/location/service/runtime.cpp |
2489 | + src/location_service/com/ubuntu/location/service/runtime.h |
2490 | + tests/runtime_test.cpp |
2491 | + |
2492 | + -- Thomas Voß <ci-train-bot@canonical.com> Fri, 27 Nov 2015 13:00:33 +0000 |
2493 | + |
2494 | +location-service (2.1+15.04.20151113-0ubuntu1) vivid; urgency=medium |
2495 | + |
2496 | + * Adjust default timeout for downloading GPS XTRA data. |
2497 | + |
2498 | + -- Thomas Voß <ci-train-bot@canonical.com> Fri, 13 Nov 2015 10:33:56 +0000 |
2499 | + |
2500 | +location-service (2.1+15.04.20151109.2-0ubuntu1) vivid; urgency=medium |
2501 | + |
2502 | + [ Alberto Mardegan ] |
2503 | + * Make sure that injected time is given in milliseconds |
2504 | + |
2505 | + [ Thomas Voß ] |
2506 | + * Cherry-pick rev. 196 and 199 from lp:location-service. The changes |
2507 | + got accidentally removed by merging the outstanding documentation |
2508 | + branch. |
2509 | + * Handle responses of clients to updates asynchronously. Rely on |
2510 | + dummy::ConnectivityManager as harvesting is disabled anyway. (LP: |
2511 | + #1462664, #1387643) |
2512 | + |
2513 | + -- David Barth <david.barth@canonical.com> Mon, 09 Nov 2015 20:48:48 +0000 |
2514 | + |
2515 | +location-service (2.1+15.04.20151022-0ubuntu1) vivid; urgency=medium |
2516 | + |
2517 | + [ Thomas Voß ] |
2518 | + * Add documentation for debugging, hacking and debugging the location |
2519 | + service. Pull manual testing instructions over from the wiki. Add |
2520 | + tools for formatting the source. |
2521 | + |
2522 | + [ thomas-voss ] |
2523 | + * Add documentation for debugging, hacking and debugging the location |
2524 | + service. Pull manual testing instructions over from the wiki. Add |
2525 | + tools for formatting the source. |
2526 | + |
2527 | + -- Thomas Voß <ci-train-bot@canonical.com> Thu, 22 Oct 2015 07:16:50 +0000 |
2528 | + |
2529 | location-service (2.1+15.04.20150427.1-0ubuntu1) vivid; urgency=medium |
2530 | |
2531 | [ CI Train Bot ] |
2532 | |
2533 | === modified file 'debian/source/format' |
2534 | --- debian/source/format 2014-07-30 14:15:06 +0000 |
2535 | +++ debian/source/format 2016-04-01 06:55:25 +0000 |
2536 | @@ -1,1 +1,1 @@ |
2537 | -3.0 (quilt) |
2538 | +3.0 (native) |
2539 | |
2540 | === modified file 'doc/Doxyfile.in' |
2541 | --- doc/Doxyfile.in 2014-05-19 09:55:25 +0000 |
2542 | +++ doc/Doxyfile.in 2016-04-01 06:55:25 +0000 |
2543 | @@ -748,7 +748,7 @@ |
2544 | # directories that contain image that are included in the documentation (see |
2545 | # the \image command). |
2546 | |
2547 | -IMAGE_PATH = |
2548 | +IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/images |
2549 | |
2550 | # The INPUT_FILTER tag can be used to specify a program that doxygen should |
2551 | # invoke to filter for each input file. Doxygen will invoke the filter program |
2552 | @@ -1463,7 +1463,7 @@ |
2553 | # generate an XML file that captures the structure of |
2554 | # the code including all documentation. |
2555 | |
2556 | -GENERATE_XML = NO |
2557 | +GENERATE_XML = YES |
2558 | |
2559 | # The XML_OUTPUT tag is used to specify where the XML pages will be put. |
2560 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be |
2561 | |
2562 | === added file 'doc/daemon_and_cli.md' |
2563 | --- doc/daemon_and_cli.md 1970-01-01 00:00:00 +0000 |
2564 | +++ doc/daemon_and_cli.md 2016-04-01 06:55:25 +0000 |
2565 | @@ -0,0 +1,55 @@ |
2566 | +# Service Daemon and CLI |
2567 | + |
2568 | +The location service offers a daemon executable and a corresponding |
2569 | +command-line interface for interacting with it. The daemon does not |
2570 | +necessarily require root privileges, but might so depending on your |
2571 | +configuration. |
2572 | + |
2573 | +Run the following command to receive an overview of the arguments to |
2574 | +the daemon: |
2575 | + |
2576 | + ubuntu-location-serviced --help |
2577 | + |
2578 | +An example invocation of the daemon, configuring a GPS provider that |
2579 | +relies on the Android HAL to talk to the chipset, exposing the service |
2580 | +on the system DBus instance: |
2581 | + |
2582 | + ubuntu-location-serviced --bus system --provider gps::Provider |
2583 | + |
2584 | +The cli allows for querying properties of a running service instance, e.g.: |
2585 | + |
2586 | + ubuntu-location-serviced-cli --bus system --get --property is_online |
2587 | + |
2588 | +## Configuring an Out-Of-Process Provider |
2589 | + |
2590 | +If you want to run a provider out of process, the daemon executable |
2591 | +allows you to do so by instantiating a so-called remote provider. The |
2592 | +following invocation of the service tries to connect to the provider |
2593 | +instance described by the given unique DBus name and path. |
2594 | + |
2595 | + ubuntu-location-serviced \ |
2596 | + --bus system \ |
2597 | + --provider remote::Provider \ |
2598 | + --remote::Provider::bus=system \ |
2599 | + --remote::Provider::name=com.ubuntu.location.provider.Gps \ |
2600 | + --remote::Provider::path=/ |
2601 | + |
2602 | +Please note that the service allows for decorating provider names to |
2603 | +uniquely identify per provider configuration options and to allow for |
2604 | +loading more than one provider of a certain kind. The following |
2605 | +configuration configures two remote providers, one relying on GPS |
2606 | +(decorated with @gps) and another one relying on network-based |
2607 | +positioning (decorated with @network): |
2608 | + |
2609 | + ubuntu-location-serviced \ |
2610 | + --bus system \ |
2611 | + --provider remote::Provider@gps \ |
2612 | + --remote::Provider@gps::bus=system \ |
2613 | + --remote::Provider@gps::name=com.ubuntu.location.provider.Gps \ |
2614 | + --remote::Provider@gps::path=/ \ |
2615 | + --provider remote::Provider@network \ |
2616 | + --remote::Provider@network::bus=system \ |
2617 | + --remote::Provider@network::name=com.ubuntu.location.provider.Network \ |
2618 | + --remote::Provider@network::path=/ |
2619 | + |
2620 | + |
2621 | |
2622 | === added file 'doc/debugging.md' |
2623 | --- doc/debugging.md 1970-01-01 00:00:00 +0000 |
2624 | +++ doc/debugging.md 2016-04-01 06:55:25 +0000 |
2625 | @@ -0,0 +1,91 @@ |
2626 | +# Debugging |
2627 | + |
2628 | +Location not working? Here's how to debug. |
2629 | + |
2630 | +## Layers |
2631 | + |
2632 | +Test in OSMTouch (QML app using Qt API) before testing in webapps or |
2633 | +webbrowser app. Different results? File a bug where it doesn't |
2634 | +work. Same result of no location? Next step. |
2635 | + |
2636 | +## Check that stack works with dummy provider |
2637 | + |
2638 | +Edit /etc/init/ubuntu-location-provider.override to start |
2639 | +location-serviced with just the dummy provider; this should |
2640 | +work. Doesn't work? File a bug against location-service. Works? Reset |
2641 | +config to defaults and try the next thing. |
2642 | + |
2643 | +## Hardware GPS breaking all of location-service |
2644 | + |
2645 | +GPS provider is built-in into location-service and might break all of |
2646 | +it if it goes south (working on splitting it out); try enabling only |
2647 | +the HERE provider on the location-serviced command-line and see if |
2648 | +that works. Works? File a bug against location-service. Doesn't work? |
2649 | +Move on. |
2650 | + |
2651 | +## HERE test |
2652 | + |
2653 | +To test whether the low-level HERE stack gets a location, put |
2654 | +http://people.canonical.com/~lool/espoo-cli on your phone (will be |
2655 | +included along HERE bits in the future) and run with: |
2656 | + |
2657 | + chmod a+x espoo-cli |
2658 | + GLOG_logtostderr=1 GLOG_v=100 LD_LIBRARY_PATH=/custom/vendor/here/location-provider/lib/arm-linux-gnueabihf ./espoo-cli 5 |
2659 | + |
2660 | +NB: 5 is the number of location updates after which the tool exits; |
2661 | +updates should come in at approx 15s interval. Output looks like: |
2662 | + |
2663 | + I1101 21:30:01.285964 4403 cli.cpp:117] Requested number of updates is 2 |
2664 | + I1101 21:30:01.299002 4403 cli.cpp:133] Starting location updates |
2665 | + I1101 21:30:01.301888 4403 cli.cpp:141] Starting GLib main loop |
2666 | + I1101 21:30:11.304612 4403 cli.cpp:158] Location: tstamp=1414891811 lat=xyz long=foo hor. acc.=2569 alt=nan vert. acc.=nan tech=cell |
2667 | + I1101 21:30:11.306061 4403 cli.cpp:170] Remaining updates: 1 |
2668 | + I1101 21:30:26.736821 4403 cli.cpp:158] Location: tstamp=1414891826 lat=xyz long=foo hor. acc.=2824 alt=nan vert. acc.=nan tech=cell |
2669 | + I1101 21:30:26.738348 4403 cli.cpp:148] Stopping location updates |
2670 | + |
2671 | +Low-level HERE stack works but location-serviced with just HERE |
2672 | +provider doesn't work? File a bug against espoo projet (HERE) and/or |
2673 | +location-service. Low-level HERE stack doesn't work? Move on |
2674 | + |
2675 | +## location-service and espoo-service debug |
2676 | + |
2677 | +Collect some debug data by editing /etc/init/ubuntu-espoo-service.conf |
2678 | +and /etc/init/ubuntu-location-service.override and changing the start |
2679 | +sequence to add some env vars: |
2680 | + |
2681 | + export GLOG_v=200 |
2682 | + |
2683 | +before the exec. Reboot, and start some app. You should have some log |
2684 | +files under /var/log/upstart/ubuntu-espoo-service.log and |
2685 | +/var/log/upstart/ubuntu-location-service.log to attach to a bug |
2686 | +report; e.g. a working espoo log looks like this: |
2687 | + |
2688 | + WARNING: Logging before InitGoogleLogging() is written to STDERR |
2689 | + I1105 16:30:10.221474 1620 provider.cpp:568] StartPositionUpdates |
2690 | + I1105 16:30:10.224901 1620 provider.cpp:122] Successfully started position updates. |
2691 | + I1105 16:30:10.228739 1620 provider.cpp:596] StartVelocityUpdates |
2692 | + I1105 16:30:13.046851 1621 provider.cpp:83] Received location: Position(lat: Coordinate(12.34 deg), lon: Coordinate(12.34 deg), alt: Coordinate(nan m), hor.acc.: 1430 m, ver.acc.: nan m) |
2693 | + |
2694 | +No position there? check connectivity API works by running: |
2695 | + |
2696 | + cd /tmp |
2697 | + wget http://people.ubuntu.com/~lool/connectivity |
2698 | + GLOG_v=200 GLOG_logtostderr=1 ./connectivity |
2699 | + |
2700 | +you should see something like: |
2701 | + |
2702 | + I1105 16:47:26.431466 11140 cached_radio_cell.cpp:160] (mcc: 123, mnc: 2, lac: 1234, id: 123456, asu: 1) |
2703 | + I1105 16:47:26.533818 11140 connectivity.cpp:47] Is wifi enabled: true |
2704 | + I1105 16:47:26.533963 11140 connectivity.cpp:48] Is wifi hw enabled: true |
2705 | + I1105 16:47:26.534010 11140 connectivity.cpp:49] Is wwan enabled: true |
2706 | + I1105 16:47:26.534050 11140 connectivity.cpp:50] Is wwan hw enabled: true |
2707 | + I1105 16:47:26.534442 11140 connectivity.cpp:122] umts(mcc: 123, mnc: 2, lac: 1234, id: 123456, asu: 1) |
2708 | + I1105 16:47:26.534633 11140 connectivity.cpp:155] (bssid: 12:12:12:12:12:12, ssid: xyz, last seen: 1415224046, mode: Mode::infrastructure, frequency: 2442, strength: 63) |
2709 | + I1105 16:47:26.534828 11140 connectivity.cpp:155] (bssid: 12:12:12:12:12:12, ssid: boing, last seen: 1415224046, mode: Mode::infrastructure, frequency: 2467, strength: 57) |
2710 | + |
2711 | +Also, please attach output of /usr/share/ofono/scripts/list-modems > list-modems-output.txt |
2712 | +Please note that the command might take ~1 minute to complete. |
2713 | + |
2714 | +TODO: document dbus-monitor / d-feet capturing of client / system traffic with snooping config. |
2715 | + |
2716 | + |
2717 | |
2718 | === added file 'doc/hacking.md' |
2719 | --- doc/hacking.md 1970-01-01 00:00:00 +0000 |
2720 | +++ doc/hacking.md 2016-04-01 06:55:25 +0000 |
2721 | @@ -0,0 +1,146 @@ |
2722 | +# Hacking |
2723 | + |
2724 | + |
2725 | +## Building the code |
2726 | + |
2727 | +By default, the code is built in release mode. To build a debug version, use |
2728 | + |
2729 | + $ mkdir builddebug |
2730 | + $ cd builddebug |
2731 | + $ cmake -DCMAKE_BUILD_TYPE=debug .. |
2732 | + $ make |
2733 | + |
2734 | +For a release version, use -DCMAKE_BUILD_TYPE=release |
2735 | + |
2736 | +## Running the tests |
2737 | + |
2738 | + $ make |
2739 | + $ make test |
2740 | + |
2741 | +Note that "make test" alone is dangerous because it does not rebuild |
2742 | +any tests if either the library or the test files themselves need |
2743 | +rebuilding. It's not possible to fix this with cmake because cmake cannot |
2744 | +add build dependencies to built-in targets. To make sure that everything |
2745 | +is up-to-date, run "make" before running "make test"! |
2746 | + |
2747 | +## Coverage |
2748 | + |
2749 | +To build with the flags for coverage testing enabled and get coverage: |
2750 | + |
2751 | + $ mkdir buildcoverage |
2752 | + $ cd buildcoverage |
2753 | + $ cmake -DCMAKE_BUILD_TYPE=coverage |
2754 | + $ make |
2755 | + $ make test |
2756 | + $ make coverage |
2757 | + |
2758 | +Unfortunately, it is not possible to get 100% coverage for some files, |
2759 | +mainly due to gcc's generation of two destructors for dynamic and non- |
2760 | +dynamic instances. For abstract base classes and for classes that |
2761 | +prevent stack and static allocation, this causes one of the destructors |
2762 | +to be reported as uncovered. |
2763 | + |
2764 | +There are also issues with some functions in header files that are |
2765 | +incorrectly reported as uncovered due to inlining, as well as |
2766 | +the impossibility of covering defensive assert(false) statements, |
2767 | +such as an assert in the default branch of a switch, where the |
2768 | +switch is meant to handle all possible cases explicitly. |
2769 | + |
2770 | +If you run a binary and get lots of warnings about a "merge mismatch for summaries", |
2771 | +this is caused by having made changes to the source that add or remove code |
2772 | +that was previously run, so the new coverage output cannot sensibly be merged |
2773 | +into the old coverage output. You can get rid of this problem by running |
2774 | + |
2775 | + $ make clean-coverage |
2776 | + |
2777 | +This deletes all the .gcda files, allowing the merge to (sometimes) succeed again. |
2778 | +If this doesn't work either, the only remedy is to do a clean build. |
2779 | + |
2780 | +If lcov complains about unrecognized lines involving '=====', |
2781 | +you can patch geninfo and gcovr as explained here: |
2782 | + |
2783 | +https://bugs.launchpad.net/gcovr/+bug/1086695/comments/2 |
2784 | + |
2785 | +## Code style |
2786 | + |
2787 | +We use a format tool that fixes a whole lot of issues |
2788 | +regarding code style. The formatting changes made by |
2789 | +the tool are generally sensible (even though they may not be your |
2790 | +personal preference in all cases). If there is a case where the formatting |
2791 | +really messes things up, consider re-arranging the code to avoid the problem. |
2792 | +The convenience of running the entire code base through the pretty-printer |
2793 | +far outweighs any minor glitches with pretty printing, and it means that |
2794 | +we get consistent code style for free, rather than endlessly having to |
2795 | +watch out for formatting issues during code reviews. |
2796 | + |
2797 | +As of clang-format-3.7, you can use |
2798 | + |
2799 | + // clang-format off |
2800 | + void unformatted_code ; |
2801 | + // clang-format on |
2802 | + |
2803 | +to suppress formatting for a section of code. |
2804 | + |
2805 | +To format specific files: |
2806 | + |
2807 | + ${CMAKE_BINARY_DIR}/tools/formatcode x.cpp x.h |
2808 | + |
2809 | +If no arguments are provided, formatcode reads stdin and writes |
2810 | +stdout, so you can easily pipe code into the tool from within an |
2811 | +editor. For example, to reformat the entire file in vi (assuming |
2812 | +${CMAKE_BINARY_DIR}/tools is in your PATH): |
2813 | + |
2814 | + 1G!Gformatcode |
2815 | + |
2816 | +To re-format all source and header files in the tree: |
2817 | + |
2818 | + $ make formatcode |
2819 | + |
2820 | +## Thread and address sanitizer |
2821 | + |
2822 | +Set SANITIZER to "thread" or "address" to build with the |
2823 | +corresponding sanitizer enabled. |
2824 | + |
2825 | +## Updating symbols file |
2826 | + |
2827 | +To easily spot new/removed/changed symbols in the library, the debian |
2828 | +package maintains a .symbols file that lists all exported symbols |
2829 | +present in the library .so. If you add new public symbols to the library, |
2830 | +it's necessary to refresh the symbols file, otherwise the package will |
2831 | +fail to build. The easiest way to do that is using bzr-builddeb: |
2832 | + |
2833 | + $ bzr bd -- -us -uc -j8 # Don't sign source package or changes file, 8 compiles in parallel |
2834 | + $ # this will exit with an error if symbols file isn't up-to-date |
2835 | + $ cd ../build-area/location-service-[version] |
2836 | + $ ./obj-[arch]/tools/symbol_diff |
2837 | + |
2838 | +This creates a diff of the symbols in /tmp/symbols.diff. |
2839 | +(The demangled symbols from the debian build are in ./new_symbols.) |
2840 | + |
2841 | +Review any changes in /tmp/symbols.diff. If they are OK: |
2842 | + |
2843 | + $ cd - |
2844 | + $ patch -p0 < /tmp/symbols.diff |
2845 | + |
2846 | +## ABI compliance test |
2847 | + |
2848 | +To use this, install abi-compliance-checker package from the archives. |
2849 | + |
2850 | +You can use abi-compliance-checker to test whether a particular build |
2851 | +is ABI compatible with another build. The tool does some source-level |
2852 | +analysis in addition to checking library symbols, so it catches things |
2853 | +that are potentially dangerous, but won't be picked up by just looking |
2854 | +at the symbol table. |
2855 | + |
2856 | +Assume you have built devel in src/devel, and you have a later build |
2857 | +in src/mybranch and want to check that mybranch is still compatible. |
2858 | +To run the compliance test: |
2859 | + |
2860 | + $ cd src |
2861 | + $ abi-compliance-checker -lib libunity-scopes.so -old devel/build/test/abi-compliance/abi.xml -new mybranch/build/test/abi-compliance/abi.xml |
2862 | + |
2863 | +The script will take about two minutes to run. Now point your browser at |
2864 | + |
2865 | + src/compat_reports/libunity-scopes.so/[version]_to_[version]/compat_report.html |
2866 | + |
2867 | +The report provides a nicely layed-out page with all the details. |
2868 | |
2869 | === added directory 'doc/images' |
2870 | === added file 'doc/images/LocationServiceHighLevel.png' |
2871 | Binary files doc/images/LocationServiceHighLevel.png 1970-01-01 00:00:00 +0000 and doc/images/LocationServiceHighLevel.png 2016-04-01 06:55:25 +0000 differ |
2872 | === added file 'doc/intro.md' |
2873 | --- doc/intro.md 1970-01-01 00:00:00 +0000 |
2874 | +++ doc/intro.md 2016-04-01 06:55:25 +0000 |
2875 | @@ -0,0 +1,67 @@ |
2876 | +# Introduction {#mainpage} |
2877 | + |
2878 | +Ubuntu's location service is a central hub for multiplexing access to |
2879 | +positioning subsystems available via hard- and software. It provides a |
2880 | +client API offering positioning capabilities to applications and other |
2881 | +system components, abstracting away the details of individual |
2882 | +positioning solutions. |
2883 | + |
2884 | +## Vocabulary |
2885 | + |
2886 | +To make the remainder of this documentation as easily understandable |
2887 | +as possible, we start over with introducing some vocabulary: |
2888 | + |
2889 | +- Engine: |
2890 | + Responsible for handling input from multiple positioning |
2891 | + subsystems and maintaining the state of the overall system. Think |
2892 | + about it like the heart of the system. |
2893 | + |
2894 | +- Provider: |
2895 | + A positioning subsystem that feeds into the positioning |
2896 | + engine. Common examples are a GPS provider or a network-based |
2897 | + positioning provider. |
2898 | + |
2899 | +- Service: |
2900 | + The point of entry for applications and services that would |
2901 | + like to receive position data. |
2902 | + |
2903 | +- Session: |
2904 | + In order to receive position information, every application |
2905 | + or service has to create a session with the location Service. |
2906 | + |
2907 | +- Update: An update is a timestamped entity to a certain type of data. |
2908 | + |
2909 | +- [WGS84, http://en.wikipedia.org/wiki/World_Geodetic_System]: The coordinate system that is used throughout the entire location subsystem. |
2910 | + |
2911 | +## Architectural Overview |
2912 | + |
2913 | +The high-level architecture of the service is shown in the following diagram: |
2914 | + |
2915 | +![High-level architectural overview](images/LocationServiceHighLevel.png) |
2916 | + |
2917 | +In this diagram, the configuration of the engine refers to: |
2918 | + |
2919 | + * The current state of any satellite-based positioning subsystems. Can either be off or on. |
2920 | + * The current state of reporting facilities responsible for harvesting wifi and cell id measurements together with location information and sending them off to remote services. Can either be off or on. |
2921 | + * The overall state of the engine. Can either be off, on or active. |
2922 | + |
2923 | +The Service takes this configuration and exposes it to client |
2924 | +applications. In addition, mainly for debugging purposes, the set of |
2925 | +currently visible satellites (if any) is maintained and exposed to |
2926 | +privileged client applications. |
2927 | + |
2928 | +## Privacy & Access Control |
2929 | + |
2930 | +Location information is highly privacy relevant. For this reason, the |
2931 | +location service is deeply integrated with AppArmor and Ubuntu's |
2932 | +overall trust infrastructure. Every incoming session request is |
2933 | +validated and if in doubt, the user is asked to explicitly grant trust |
2934 | +to the application requesting access to positioning |
2935 | +information. Please see [@ref com::ubuntu::location::service::PermissionManager] |
2936 | +for further details. |
2937 | + |
2938 | +In addition, the location service allows for selectively adjusting the |
2939 | +accuracy and reporting setup of the location Engine to provide further |
2940 | +fine-grained control over the exposed data to user. Within this setup, |
2941 | +a user is able to entirely disable all positioning. |
2942 | + |
2943 | |
2944 | === added file 'doc/manual_testing.md' |
2945 | --- doc/manual_testing.md 1970-01-01 00:00:00 +0000 |
2946 | +++ doc/manual_testing.md 2016-04-01 06:55:25 +0000 |
2947 | @@ -0,0 +1,174 @@ |
2948 | +# Manual Testplan |
2949 | + |
2950 | +[TOC] |
2951 | + |
2952 | +While the automatic test suite of the location service is |
2953 | +comprehensive and covers large parts of the functionality of the |
2954 | +service itself, we still provide an additional level of acceptance |
2955 | +testing covering the entire location stack/experience as a part of |
2956 | +this document. |
2957 | + |
2958 | +## Dependents/Clients |
2959 | + |
2960 | + - qtubuntu-sensors |
2961 | + - Qt/QML applications: |
2962 | + - Browser |
2963 | + - osmTouch |
2964 | + |
2965 | +## Test Plan |
2966 | + |
2967 | +This test plan is not supposed to be complete; use it to guide your |
2968 | +manual testing so you don't miss big functional areas that are part of |
2969 | +the component; also this should be used as guideline to inspire the |
2970 | +exploratory testing which should be adapted smartly based on the real |
2971 | +content of a MP. |
2972 | + |
2973 | +Please note that if you're testing the GPS provider, the location |
2974 | +service relies on GPS hardware to obtain a location fix. For that, it |
2975 | +might be required that you execute the manual steps listed before |
2976 | +close to a window or ideally outside, with good satellite visibility |
2977 | +conditions. |
2978 | + |
2979 | +__Note: It can take up to 15 minutes for the GPS device to get a lock, due to lack of assisted GPS__ |
2980 | + |
2981 | + - Install latest image on phone |
2982 | + - Install freshly built MPs that are needed for landing |
2983 | + |
2984 | +Depending on the default configuration of location-service on the |
2985 | +image, you may skip parts of this test plan. E.g. if GPS hardware is |
2986 | +disabled, skip this part. You can see which providers are enabled by |
2987 | +looking at the list of providers on the location-serviced command-line |
2988 | +(`ps fauxw | grep location-service`, then look at the `--provider` |
2989 | +flags). |
2990 | + |
2991 | +### Dummy provider |
2992 | + |
2993 | +This tests forces location-service to use only the dummy provider; |
2994 | +this providers a baseline test for the app to trust-store to |
2995 | +location-service path. |
2996 | + |
2997 | + - phablet-shell into the phone: |
2998 | + - `sudo service ubuntu-location-service stop && sudo /usr/bin/ubuntu-location-serviced --bus system --provider dummy::Provider --dummy::Provider::ReferenceLocationLat=48.857503 --dummy::Provider::ReferenceLocationLon=2.295072` |
2999 | + - As phablet, start the trust store again (it stops when location-service is stopped) with: `start ubuntu-location-service-trust-stored` |
3000 | + - Ensure that all AP tests for the webbrowser pass as expected |
3001 | + - Point the browser to maps.google.com (alternatively: here.com, maps.bing.fr). |
3002 | + - Request centering the map on current position and observe if it works correctly (should show the Eiffel tower) |
3003 | + - Install osmTouch from the app store |
3004 | + - Launch osmTouch and check if it centers on the Eiffel tower. |
3005 | + - Install a maps webapp such as HERE or Google Maps webapp from the app store |
3006 | + - Launch maps webapp and check if it centers on the Eiffel tower. |
3007 | + |
3008 | +### GPS Test Plan |
3009 | + |
3010 | +This applies only if GPS provider is enabled. |
3011 | + |
3012 | + - (If applicable: Remember to add the silo you are testing) |
3013 | + - `sudo apt-get install ubuntu-location-service-tests` |
3014 | + - If you want to send off crowdsourced information, i.e., information about visible wifis and visible radio cells for the obtained location fixes to Mozilla's location service and our own instance: |
3015 | + - `sudo GLOG_v=40 GLOG_logtostderr=1 GPS_TEST_ENABLE_HARVESTING_DURING_TESTS=1 /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_without_supl_benchmark_requires_hardware` |
3016 | + - If you '''don't''' want to send off crowdsourced information: |
3017 | + - `sudo GLOG_v=40 GLOG_logtostderr=1 /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_without_supl_benchmark_requires_hardware` |
3018 | + |
3019 | + - The test will output a lot of diagnostic information to the |
3020 | + terminal and will take ~30 minutes. If satellite visibility is |
3021 | + limited, it can take even longer. The test will automatically |
3022 | + report success or failure. |
3023 | + |
3024 | +### Preliminary AGPS Test Plan |
3025 | + |
3026 | +**Does not apply to Krillin** |
3027 | + |
3028 | +Please note that the Krillin GPS chipset driver and its integration |
3029 | +within Ubuntu does not support vanilla AGPS (i.e., SUPL) right |
3030 | +now. For that, this test case is irrelevant for Krillin and is likely |
3031 | +to fail. |
3032 | + |
3033 | +This applied only if GPS provider and some other provider (giving |
3034 | +_A_ssistance) are enabled. |
3035 | + |
3036 | + - Add the silo. |
3037 | + - `sudo apt-get install ubuntu-location-service-tests` |
3038 | + - Obtain a (rough) location estimate for your current location on Google maps. |
3039 | + - Make sure to replace INSERT_ESTIMATE_HERE with the respective |
3040 | + values obtained from Google maps. |
3041 | + - If you want to send off crowdsourced information, i.e., information |
3042 | + about visible wifis and visible radio cells for the obtained |
3043 | + location fixes to Mozilla's location service and our own instance: |
3044 | + - `sudo GLOG_v=40 GLOG_logtostderr=1 GPS_TEST_ENABLE_HARVESTING_DURING_TESTS=1 GPS_TEST_REF_LAT=INSERT_ESTIMATE_HERE GPS_TEST_REF_LON=INSERT_ESTIMATE_HERE /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_with_supl_benchmark_requires_hardware` |
3045 | + - If you '''don't''' want to send off crowdsourced information: |
3046 | + - `sudo GLOG_v=40 GLOG_logtostderr=1 GPS_TEST_REF_LAT=INSERT_ESTIMATE_HERE GPS_TEST_REF_LON=INSERT_ESTIMATE_HERE /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_with_supl_benchmark_requires_hardware` |
3047 | + |
3048 | + - The test will output a lot of diagnostic information to the |
3049 | + terminal and will take ~10 minutes or less. The test will |
3050 | + automatically report success or failure. |
3051 | + |
3052 | +### Espoo / HERE provider |
3053 | + |
3054 | +This applies only if the Espoo / HERE remote provider is enabled. This |
3055 | +provider should be enabled by default and may either work standalone |
3056 | +as the only provider or as an assistance for the GPS hardware to lock. |
3057 | + |
3058 | + - Add the silo; special exception for lxc-android-config: see https://wiki.ubuntu.com/Touch/Testing/lxc-android-config |
3059 | + - If noted, deploy an updated custom tarball: |
3060 | + - Download the tarball under /tmp ('''NOT''' under /) |
3061 | + - Unpack there: `cd /tmp; sudo tar xvf custom-vendor-here-*.tar.xz` |
3062 | + - Remove older bits: `sudo rm -rf /custom/vendor/here/` |
3063 | + - Update custom bits: `sudo mv /tmp/system/custom/vendor/here /custom/vendor` |
3064 | + - Reboot |
3065 | + - After boot, check you have these three processes running on top of location-service: |
3066 | + - slpgwd |
3067 | + - posclientd |
3068 | + - ubuntu-espoo-service |
3069 | + - Make sure SIM is unlocked and attached to the network (has some reliable signal) and that WiFi is turned on. |
3070 | + - Install OSMTouch app |
3071 | + - Run OSMTouch app, hit the position button every other second until you get a blue circle showing your current location; |
3072 | + |
3073 | +# Connectivity API |
3074 | + |
3075 | +For integration of network-based positioning providers, the location |
3076 | +service offers a connectivity API that provides access to wifi and |
3077 | +cell measurements as well as information on the current overall |
3078 | +connectivity status of the device. Please execute the following |
3079 | +commands on a newly flashed device with a writable image: |
3080 | + |
3081 | + - `sudo apt-get update && sudo apt-get build-dep location-service && sudo apt-get install libubuntu-location-service-dev ubuntu-location-service-examples` |
3082 | + - `mkdir /tmp/build && cd /tmp/build && cmake /usr/share/ubuntu-location-service/examples/standalone/connectivity/ && make` |
3083 | + - `GLOG_logtostderr=1 ./connectivity` |
3084 | + |
3085 | +Verify that the output looks similar to: |
3086 | + |
3087 | + phablet@ubuntu-phablet:/tmp/build$ ./connectivity |
3088 | + Is wifi enabled: true |
3089 | + Is wifi hw enabled: true |
3090 | + Is wwan enabled: false |
3091 | + Is wwan hw enabled: true |
3092 | + umts(mcc: 262, mnc: 2, lac: 5313, id: 131948771, asu: 7) |
3093 | + (bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2462, strength: 72) |
3094 | + (bssid: 00:22:3F:35:43:58, ssid: JustAnotherWLAN, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2412, strength: 24) |
3095 | + (bssid: 82:C7:A6:40:8C:4E, ssid: EasyBox-44D054, last seen: 1408955206, mode: Mode::infrastructure, frequency: 2417, strength: 17) |
3096 | + (bssid: 00:24:01:B8:32:8D, ssid: gra, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2412, strength: 12) |
3097 | + (bssid: C0:25:06:3C:28:22, ssid: FRITZ!Box 6360 Cable, last seen: 1408954966, mode: Mode::infrastructure, frequency: 2412, strength: 17) |
3098 | + (bssid: 00:1C:4A:A5:B7:59, ssid: FRITZ!Box Fon WLAN 7170, last seen: 1408954966, mode: Mode::infrastructure, frequency: 2437, strength: 10) |
3099 | + Last seen changed for wifi (bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2462, strength: 72) |
3100 | + Last seen changed for wifi (bssid: 00:22:3F:35:43:58, ssid: JustAnotherWLAN, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2412, strength: 24) |
3101 | + Signal strength changed for wifi: (bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2462, strength: 73) |
3102 | + |
3103 | +# Trust Store Integration |
3104 | + |
3105 | +Please note that we are assuming a freshly wiped system for testing |
3106 | +here. If you cannot fulfill that pre-condition, please run `rm -rf |
3107 | +/home/phablet/.local/share/UbuntuLocationService && sudo shutdown -r` prior to running the |
3108 | +tests: |
3109 | + |
3110 | +## Unconfined |
3111 | + |
3112 | + - Open the browser, go to maps.google.com |
3113 | + - Observe the in-browser dialog asking for granting access to location. |
3114 | + |
3115 | +## Confined Web-App |
3116 | + |
3117 | + - Open the Nokia Here web app, observe the trust dialog appearing. |
3118 | + |
3119 | +## Confined Application |
3120 | + |
3121 | + - Open osmtouch and observe the osmtouch surface sliding up, presenting you with a trust dialog. |
3122 | |
3123 | === added file 'doc/tips_n_tricks.md' |
3124 | --- doc/tips_n_tricks.md 1970-01-01 00:00:00 +0000 |
3125 | +++ doc/tips_n_tricks.md 2016-04-01 06:55:25 +0000 |
3126 | @@ -0,0 +1,21 @@ |
3127 | +# Tips'n'Tricks |
3128 | + |
3129 | +## Mark HERE license as accepted from cmdline |
3130 | + |
3131 | + sudo LC_ALL=C gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User32011 --method org.freedesktop.DBus.Properties.Set com.ubuntu.location.providers.here.AccountsService LicenseAccepted '<true>' |
3132 | + |
3133 | +## Force startup after ofono and NM are started |
3134 | + |
3135 | +This is a *workaround* to get connectivity API to collect; mount your |
3136 | +system read-write and edit |
3137 | +/etc/init/ubuntu-location-provider-here-slpgwd.conf: |
3138 | + |
3139 | + sudo mount -o remount,rw / |
3140 | + sudo vi /etc/init/ubuntu-location-provider-here-slpgwd.conf |
3141 | + |
3142 | +change: `start on started dbus and (started ofono or started network-manager)` |
3143 | +to: `start on started dbus and started ofono and started network-manager` |
3144 | + |
3145 | + sudo mount -o remount,ro / |
3146 | + sync |
3147 | + sudo reboot |
3148 | |
3149 | === modified file 'examples/service/service.cpp' |
3150 | --- examples/service/service.cpp 2014-11-14 11:26:45 +0000 |
3151 | +++ examples/service/service.cpp 2016-04-01 06:55:25 +0000 |
3152 | @@ -99,7 +99,10 @@ |
3153 | auto selected_providers = options.value_for_key<std::vector<std::string>>("provider"); |
3154 | |
3155 | std::map<std::string, cul::ProviderFactory::Configuration> config_lut; |
3156 | - std::set<cul::Provider::Ptr> instantiated_providers; |
3157 | + |
3158 | + culs::DefaultConfiguration config; |
3159 | + auto settings = std::make_shared<cul::BoostPtreeSettings>(options.value_for_key<std::string>("config-file")); |
3160 | + auto engine = config.the_engine(std::set<cul::Provider::Ptr>{}, config.the_provider_selection_policy(), settings); |
3161 | |
3162 | for (const std::string& provider : selected_providers) |
3163 | { |
3164 | @@ -129,15 +132,15 @@ |
3165 | |
3166 | try |
3167 | { |
3168 | - auto p = cul::ProviderFactory::instance().create_provider_for_name_with_config( |
3169 | - provider, |
3170 | - config_lut[provider]); |
3171 | - |
3172 | - if (p) |
3173 | - instantiated_providers.insert(p); |
3174 | - else |
3175 | - throw std::runtime_error("Problem instantiating provider"); |
3176 | - |
3177 | + auto result = std::async(std::launch::async, [provider, config_lut, engine] { |
3178 | + return cul::ProviderFactory::instance().create_provider_for_name_with_config( |
3179 | + provider, |
3180 | + config_lut.at(provider), |
3181 | + [engine](cul::Provider::Ptr provider) |
3182 | + { |
3183 | + engine->add_provider(provider); |
3184 | + }); |
3185 | + }); |
3186 | } catch(const std::runtime_error& e) |
3187 | { |
3188 | std::cerr << "Exception instantiating provider: " << e.what() << " ... Aborting now." << std::endl; |
3189 | @@ -163,15 +166,11 @@ |
3190 | }; |
3191 | outgoing->install_executor(dbus::asio::make_executor(outgoing)); |
3192 | |
3193 | - auto settings = std::make_shared<cul::BoostPtreeSettings>(options.value_for_key<std::string>("config-file")); |
3194 | - |
3195 | - culs::DefaultConfiguration config; |
3196 | - |
3197 | culs::Implementation::Configuration configuration |
3198 | { |
3199 | incoming, |
3200 | outgoing, |
3201 | - config.the_engine(instantiated_providers, config.the_provider_selection_policy(), settings), |
3202 | + engine, |
3203 | config.the_permission_manager(incoming), |
3204 | culs::Harvester::Configuration |
3205 | { |
3206 | |
3207 | === modified file 'include/location_service/com/ubuntu/location/provider_factory.h' |
3208 | --- include/location_service/com/ubuntu/location/provider_factory.h 2014-10-27 21:58:16 +0000 |
3209 | +++ include/location_service/com/ubuntu/location/provider_factory.h 2016-04-01 06:55:25 +0000 |
3210 | @@ -54,6 +54,9 @@ |
3211 | // --provider=remote::Provider@gps --remote::Provider@gps::name="com.ubuntu.android.gps.Provider" --remote::Provider@gps::path="/com/ubuntu/android/gps/Provider" |
3212 | Provider::Ptr create_provider_for_name_with_config(const std::string& name, const Configuration& config); |
3213 | |
3214 | + // Async version of above. |
3215 | + void create_provider_for_name_with_config(const std::string& name, const Configuration& config, const std::function<void(Provider::Ptr)>& cb); |
3216 | + |
3217 | void enumerate(const std::function<void(const std::string&, const Factory&)>& enumerator); |
3218 | |
3219 | private: |
3220 | |
3221 | === modified file 'po/ubuntu-location-service.pot' |
3222 | --- po/ubuntu-location-service.pot 2014-09-19 09:06:30 +0000 |
3223 | +++ po/ubuntu-location-service.pot 2016-04-01 06:55:25 +0000 |
3224 | @@ -1,13 +1,14 @@ |
3225 | -# Copyright (C) 2014 Canonical Ltd. |
3226 | -# This file is distributed under the same license as the ubuntu-location-service package. |
3227 | -# Thomas Voß <thomas.voss@canonical.com>, 2014. |
3228 | +# SOME DESCRIPTIVE TITLE. |
3229 | +# Copyright (C) YEAR Canonical Ltd. |
3230 | +# This file is distributed under the same license as the PACKAGE package. |
3231 | +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. |
3232 | # |
3233 | #, fuzzy |
3234 | msgid "" |
3235 | msgstr "" |
3236 | "Project-Id-Version: ubuntu-location-service\n" |
3237 | "Report-Msgid-Bugs-To: \n" |
3238 | -"POT-Creation-Date: 2014-09-19 01:04+0200\n" |
3239 | +"POT-Creation-Date: 2015-11-27 14:07+0100\n" |
3240 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
3241 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
3242 | "Language-Team: LANGUAGE <LL@li.org>\n" |
3243 | @@ -16,11 +17,6 @@ |
3244 | "Content-Type: text/plain; charset=CHARSET\n" |
3245 | "Content-Transfer-Encoding: 8bit\n" |
3246 | |
3247 | -#: /tmp/i18n/src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp:170 |
3248 | -msgid "An unconfined application wants to access your current location." |
3249 | -msgstr "" |
3250 | - |
3251 | -#: /tmp/i18n/src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp:173 |
3252 | -#, boost-format |
3253 | -msgid "%1% wants to access your current location." |
3254 | +#: /home/tvoss/ubuntu/scratch/fix-prompt-string/src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp:149 |
3255 | +msgid "wants to access your current location." |
3256 | msgstr "" |
3257 | |
3258 | === modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt' |
3259 | --- src/location_service/com/ubuntu/location/CMakeLists.txt 2015-04-23 14:48:44 +0000 |
3260 | +++ src/location_service/com/ubuntu/location/CMakeLists.txt 2016-04-01 06:55:25 +0000 |
3261 | @@ -1,3 +1,7 @@ |
3262 | +if (UBUNTU_PLATFORM_HARDWARE_API_FOUND) |
3263 | + add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API) |
3264 | +endif() |
3265 | + |
3266 | if (NET_CPP_FOUND) |
3267 | add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP=1) |
3268 | |
3269 | @@ -10,6 +14,8 @@ |
3270 | service/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/service/config.h @ONLY |
3271 | ) |
3272 | |
3273 | +include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS}) |
3274 | + |
3275 | add_library( |
3276 | ubuntu-location-service SHARED |
3277 | |
3278 | @@ -29,6 +35,7 @@ |
3279 | settings.cpp |
3280 | time_based_update_policy.cpp |
3281 | set_name_for_thread.cpp |
3282 | + time_since_boot.cpp |
3283 | wifi_and_cell_reporting_state.cpp |
3284 | |
3285 | boost_ptree_settings.cpp |
3286 | @@ -38,6 +45,7 @@ |
3287 | service/harvester.cpp |
3288 | service/demultiplexing_reporter.h |
3289 | service/demultiplexing_reporter.cpp |
3290 | + service/runtime.cpp |
3291 | service/runtime_tests.h |
3292 | service/runtime_tests.cpp |
3293 | service/trust_store_permission_manager.cpp |
3294 | @@ -125,6 +133,7 @@ |
3295 | ${LIBAPPARMOR_LDFLAGS} |
3296 | ${NET_CPP_LDFLAGS} |
3297 | ${TRUST_STORE_LDFLAGS} |
3298 | + ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS} |
3299 | ${GLog_LIBRARY} |
3300 | ${GFlags_LIBRARY} |
3301 | ) |
3302 | |
3303 | === modified file 'src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp' |
3304 | --- src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp 2015-05-28 10:57:24 +0000 |
3305 | +++ src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp 2016-04-01 06:55:25 +0000 |
3306 | @@ -123,7 +123,14 @@ |
3307 | const org::freedesktop::NetworkManager::Device& device, |
3308 | const org::freedesktop::NetworkManager::AccessPoint& ap) |
3309 | : device_(device), |
3310 | - access_point_(ap) |
3311 | + access_point_(ap), |
3312 | + connections |
3313 | + { |
3314 | + access_point_.properties_changed->connect([this](const std::map<std::string, core::dbus::types::Variant>& dict) |
3315 | + { |
3316 | + on_access_point_properties_changed(dict); |
3317 | + }) |
3318 | + } |
3319 | { |
3320 | last_seen_ = translate_time_stamp(access_point_.last_seen->get()); |
3321 | |
3322 | @@ -138,12 +145,11 @@ |
3323 | { |
3324 | static_cast<int>(access_point_.strength->get()) |
3325 | }; |
3326 | +} |
3327 | |
3328 | - // Wire up all the connections |
3329 | - access_point_.properties_changed->connect([this](const std::map<std::string, core::dbus::types::Variant>& dict) |
3330 | - { |
3331 | - on_access_point_properties_changed(dict); |
3332 | - }); |
3333 | +detail::CachedWirelessNetwork::~CachedWirelessNetwork() |
3334 | +{ |
3335 | + access_point_.properties_changed->disconnect(connections.ap_properties_changed); |
3336 | } |
3337 | |
3338 | void detail::CachedWirelessNetwork::on_access_point_properties_changed(const std::map<std::string, core::dbus::types::Variant>& dict) |
3339 | |
3340 | === modified file 'src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h' |
3341 | --- src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h 2014-08-14 20:25:22 +0000 |
3342 | +++ src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h 2016-04-01 06:55:25 +0000 |
3343 | @@ -41,6 +41,8 @@ |
3344 | const org::freedesktop::NetworkManager::Device& device, |
3345 | const org::freedesktop::NetworkManager::AccessPoint& ap); |
3346 | |
3347 | + ~CachedWirelessNetwork(); |
3348 | + |
3349 | // Timestamp when the network became visible. |
3350 | const core::Property<std::chrono::system_clock::time_point>& last_seen() const override; |
3351 | |
3352 | @@ -67,6 +69,16 @@ |
3353 | // The actual access point stub. |
3354 | org::freedesktop::NetworkManager::AccessPoint access_point_; |
3355 | |
3356 | + // Encapsulates all event connections that have to be cut on destruction. |
3357 | + struct |
3358 | + { |
3359 | + core::dbus::Signal |
3360 | + < |
3361 | + org::freedesktop::NetworkManager::AccessPoint::PropertiesChanged, |
3362 | + org::freedesktop::NetworkManager::AccessPoint::PropertiesChanged::ArgumentType |
3363 | + >::SubscriptionToken ap_properties_changed; |
3364 | + } connections; |
3365 | + |
3366 | core::Property<std::chrono::system_clock::time_point> last_seen_; |
3367 | core::Property<std::string> bssid_; |
3368 | core::Property<std::string> ssid_; |
3369 | |
3370 | === modified file 'src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp' |
3371 | --- src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2015-05-27 18:40:37 +0000 |
3372 | +++ src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2016-04-01 06:55:25 +0000 |
3373 | @@ -595,7 +595,7 @@ |
3374 | |
3375 | xdg::NetworkManager::AccessPoint ap |
3376 | { |
3377 | - network_manager->service->add_object_for_path(ap_path) |
3378 | + network_manager->service->object_for_path(ap_path) |
3379 | }; |
3380 | |
3381 | auto wifi = std::make_shared<detail::CachedWirelessNetwork>(itd->second, ap); |
3382 | |
3383 | === modified file 'src/location_service/com/ubuntu/location/engine.cpp' |
3384 | --- src/location_service/com/ubuntu/location/engine.cpp 2015-04-23 14:48:44 +0000 |
3385 | +++ src/location_service/com/ubuntu/location/engine.cpp 2016-04-01 06:55:25 +0000 |
3386 | @@ -97,10 +97,7 @@ |
3387 | Configuration::Keys::engine_state, |
3388 | Configuration::Defaults::engine_state); |
3389 | |
3390 | - configuration.satellite_based_positioning_state = |
3391 | - settings->get_enum_for_key<SatelliteBasedPositioningState>( |
3392 | - Configuration::Keys::satellite_based_positioning_state, |
3393 | - Configuration::Defaults::satellite_based_positioning_state); |
3394 | + configuration.satellite_based_positioning_state = Configuration::Defaults::satellite_based_positioning_state; |
3395 | |
3396 | configuration.wifi_and_cell_id_reporting_state = |
3397 | settings->get_enum_for_key<WifiAndCellIdReportingState>( |
3398 | @@ -110,12 +107,7 @@ |
3399 | configuration.engine_state.changed().connect([this](const Engine::Status& status) |
3400 | { |
3401 | Engine::settings->set_enum_for_key<Engine::Status>(Configuration::Keys::engine_state, status); |
3402 | - }); |
3403 | - |
3404 | - configuration.satellite_based_positioning_state.changed().connect([this](SatelliteBasedPositioningState state) |
3405 | - { |
3406 | - Engine::settings->set_enum_for_key<SatelliteBasedPositioningState>(Configuration::Keys::satellite_based_positioning_state, state); |
3407 | - }); |
3408 | + }); |
3409 | |
3410 | configuration.wifi_and_cell_id_reporting_state.changed().connect([this](WifiAndCellIdReportingState state) |
3411 | { |
3412 | @@ -129,10 +121,6 @@ |
3413 | Configuration::Keys::engine_state, |
3414 | configuration.engine_state); |
3415 | |
3416 | - settings->set_enum_for_key<SatelliteBasedPositioningState>( |
3417 | - Configuration::Keys::satellite_based_positioning_state, |
3418 | - configuration.satellite_based_positioning_state); |
3419 | - |
3420 | settings->set_enum_for_key<WifiAndCellIdReportingState>( |
3421 | Configuration::Keys::wifi_and_cell_id_reporting_state, |
3422 | configuration.wifi_and_cell_id_reporting_state); |
3423 | @@ -169,19 +157,28 @@ |
3424 | |
3425 | // We wire up changes in the engine's configuration to the respective slots |
3426 | // of the provider. |
3427 | - auto cp = updates.reference_location.changed().connect([provider](const cul::Update<cul::Position>& pos) |
3428 | - { |
3429 | - provider->on_reference_location_updated(pos); |
3430 | - }); |
3431 | - |
3432 | - auto cv = updates.reference_velocity.changed().connect([provider](const cul::Update<cul::Velocity>& velocity) |
3433 | - { |
3434 | - provider->on_reference_velocity_updated(velocity); |
3435 | - }); |
3436 | - |
3437 | - auto ch = updates.reference_heading.changed().connect([provider](const cul::Update<cul::Heading>& heading) |
3438 | - { |
3439 | - provider->on_reference_heading_updated(heading); |
3440 | + auto cp = updates.last_known_location.changed().connect([provider](const cul::Optional<cul::Update<cul::Position>>& pos) |
3441 | + { |
3442 | + if (pos) |
3443 | + { |
3444 | + provider->on_reference_location_updated(pos.get()); |
3445 | + } |
3446 | + }); |
3447 | + |
3448 | + auto cv = updates.last_known_velocity.changed().connect([provider](const cul::Optional<cul::Update<cul::Velocity>>& velocity) |
3449 | + { |
3450 | + if (velocity) |
3451 | + { |
3452 | + provider->on_reference_velocity_updated(velocity.get()); |
3453 | + } |
3454 | + }); |
3455 | + |
3456 | + auto ch = updates.last_known_heading.changed().connect([provider](const cul::Optional<cul::Update<cul::Heading>>& heading) |
3457 | + { |
3458 | + if (heading) |
3459 | + { |
3460 | + provider->on_reference_heading_updated(heading.get()); |
3461 | + } |
3462 | }); |
3463 | |
3464 | auto cr = configuration.wifi_and_cell_id_reporting_state.changed().connect([provider](cul::WifiAndCellIdReportingState state) |
3465 | @@ -207,7 +204,7 @@ |
3466 | // We should come up with a better heuristic here. |
3467 | auto cpr = provider->updates().position.connect([this](const cul::Update<cul::Position>& src) |
3468 | { |
3469 | - updates.reference_location = update_policy->verify_update(src); |
3470 | + updates.last_known_location = update_policy->verify_update(src); |
3471 | }); |
3472 | |
3473 | std::lock_guard<std::mutex> lg(guard); |
3474 | |
3475 | === modified file 'src/location_service/com/ubuntu/location/engine.h' |
3476 | --- src/location_service/com/ubuntu/location/engine.h 2015-04-23 14:48:44 +0000 |
3477 | +++ src/location_service/com/ubuntu/location/engine.h 2016-04-01 06:55:25 +0000 |
3478 | @@ -127,11 +127,11 @@ |
3479 | struct Updates |
3480 | { |
3481 | /** The current best known reference location */ |
3482 | - core::Property<Update<Position>> reference_location{}; |
3483 | + core::Property<Optional<Update<Position>>> last_known_location{}; |
3484 | /** The current best known velocity estimate. */ |
3485 | - core::Property<Update<Velocity>> reference_velocity{}; |
3486 | + core::Property<Optional<Update<Velocity>>> last_known_velocity{}; |
3487 | /** The current best known heading estimate. */ |
3488 | - core::Property<Update<Heading>> reference_heading{}; |
3489 | + core::Property<Optional<Update<Heading>>> last_known_heading{}; |
3490 | /** The current set of visible SpaceVehicles. */ |
3491 | core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>> visible_space_vehicles{}; |
3492 | }; |
3493 | |
3494 | === modified file 'src/location_service/com/ubuntu/location/provider_factory.cpp' |
3495 | --- src/location_service/com/ubuntu/location/provider_factory.cpp 2014-10-27 21:58:16 +0000 |
3496 | +++ src/location_service/com/ubuntu/location/provider_factory.cpp 2016-04-01 06:55:25 +0000 |
3497 | @@ -52,6 +52,20 @@ |
3498 | return cul::Provider::Ptr{factory_store.at(undecorated_name)(config)}; |
3499 | } |
3500 | |
3501 | +void cul::ProviderFactory::create_provider_for_name_with_config( |
3502 | + const std::string& name, |
3503 | + const cul::ProviderFactory::Configuration& config, |
3504 | + const std::function<void(Provider::Ptr)>& cb) |
3505 | +{ |
3506 | + auto undecorated_name = name.substr(0, name.find("@")); |
3507 | + |
3508 | + std::lock_guard<std::mutex> lg(guard); |
3509 | + if (factory_store.count(undecorated_name) == 0) |
3510 | + return; |
3511 | + |
3512 | + cb(cul::Provider::Ptr{factory_store.at(undecorated_name)(config)}); |
3513 | +} |
3514 | + |
3515 | void cul::ProviderFactory::enumerate( |
3516 | const std::function<void(const std::string&, const cul::ProviderFactory::Factory&)>& enumerator) |
3517 | { |
3518 | |
3519 | === modified file 'src/location_service/com/ubuntu/location/providers/config.cpp' |
3520 | --- src/location_service/com/ubuntu/location/providers/config.cpp 2014-09-15 08:58:50 +0000 |
3521 | +++ src/location_service/com/ubuntu/location/providers/config.cpp 2016-04-01 06:55:25 +0000 |
3522 | @@ -19,6 +19,7 @@ |
3523 | #include <com/ubuntu/location/provider_factory.h> |
3524 | |
3525 | #include "dummy/provider.h" |
3526 | +#include "dummy/delayed_provider.h" |
3527 | |
3528 | #include <map> |
3529 | |
3530 | @@ -41,6 +42,12 @@ |
3531 | com::ubuntu::location::providers::dummy::Provider::create_instance |
3532 | }; |
3533 | |
3534 | +static FactoryInjector dummy_delayed_injector |
3535 | +{ |
3536 | + "dummy::DelayedProvider", |
3537 | + com::ubuntu::location::providers::dummy::DelayedProvider::create_instance |
3538 | +}; |
3539 | + |
3540 | #include <com/ubuntu/location/providers/remote/provider.h> |
3541 | static FactoryInjector remote_injector |
3542 | { |
3543 | |
3544 | === modified file 'src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt' |
3545 | --- src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt 2014-02-07 17:16:49 +0000 |
3546 | +++ src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt 2016-04-01 06:55:25 +0000 |
3547 | @@ -2,7 +2,9 @@ |
3548 | dummy |
3549 | |
3550 | provider.h |
3551 | - provider.cpp) |
3552 | + provider.cpp |
3553 | + delayed_provider.h |
3554 | + delayed_provider.cpp) |
3555 | |
3556 | set( |
3557 | ENABLED_PROVIDER_TARGETS |
3558 | |
3559 | === added file 'src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp' |
3560 | --- src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp 1970-01-01 00:00:00 +0000 |
3561 | +++ src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp 2016-04-01 06:55:25 +0000 |
3562 | @@ -0,0 +1,42 @@ |
3563 | +/* |
3564 | + * Copyright © 2015 Canonical Ltd. |
3565 | + * |
3566 | + * This program is free software: you can redistribute it and/or modify it |
3567 | + * under the terms of the GNU Lesser General Public License version 3, |
3568 | + * as published by the Free Software Foundation. |
3569 | + * |
3570 | + * This program is distributed in the hope that it will be useful, |
3571 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3572 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3573 | + * GNU Lesser General Public License for more details. |
3574 | + * |
3575 | + * You should have received a copy of the GNU Lesser General Public License |
3576 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3577 | + * |
3578 | + * Authored by: Scott Sweeny <scott.sweeny@canonical.com> |
3579 | + */ |
3580 | + |
3581 | +#include <com/ubuntu/location/logging.h> |
3582 | + |
3583 | +#include <chrono> |
3584 | +#include <thread> |
3585 | + |
3586 | +#include "delayed_provider.h" |
3587 | + |
3588 | +namespace location = com::ubuntu::location; |
3589 | +namespace dummy = com::ubuntu::location::providers::dummy; |
3590 | + |
3591 | +std::string dummy::DelayedProvider::class_name() |
3592 | +{ |
3593 | + return "dummy::DelayedProvider"; |
3594 | +} |
3595 | + |
3596 | +location::Provider::Ptr dummy::DelayedProvider::create_instance(const ProviderFactory::Configuration& config) |
3597 | +{ |
3598 | + int delay = config.get(dummy::DelayConfiguration::Keys::delay, 0); |
3599 | + VLOG(1) << __PRETTY_FUNCTION__ << ": delay for " << delay << "ms"; |
3600 | + |
3601 | + std::this_thread::sleep_for(std::chrono::milliseconds{delay}); |
3602 | + |
3603 | + return dummy::Provider::create_instance(config); |
3604 | +} |
3605 | |
3606 | === added file 'src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h' |
3607 | --- src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h 1970-01-01 00:00:00 +0000 |
3608 | +++ src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h 2016-04-01 06:55:25 +0000 |
3609 | @@ -0,0 +1,62 @@ |
3610 | +/* |
3611 | + * Copyright © 2015 Canonical Ltd. |
3612 | + * |
3613 | + * This program is free software: you can redistribute it and/or modify it |
3614 | + * under the terms of the GNU Lesser General Public License version 3, |
3615 | + * as published by the Free Software Foundation. |
3616 | + * |
3617 | + * This program is distributed in the hope that it will be useful, |
3618 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3619 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3620 | + * GNU Lesser General Public License for more details. |
3621 | + * |
3622 | + * You should have received a copy of the GNU Lesser General Public License |
3623 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3624 | + * |
3625 | + * Authored by: Scott Sweeny <scott.sweeny@canonical.com> |
3626 | + */ |
3627 | + |
3628 | +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_DUMMY_DELAYED_PROVIDER_H_ |
3629 | +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_DUMMY_DELAYED_PROVIDER_H_ |
3630 | + |
3631 | +#include "provider.h" |
3632 | + |
3633 | +namespace com |
3634 | +{ |
3635 | +namespace ubuntu |
3636 | +{ |
3637 | +namespace location |
3638 | +{ |
3639 | +namespace providers |
3640 | +{ |
3641 | +namespace dummy |
3642 | +{ |
3643 | + struct DelayConfiguration |
3644 | + { |
3645 | + struct Keys |
3646 | + { |
3647 | + static constexpr const char* delay |
3648 | + { |
3649 | + "DelayInMs" |
3650 | + }; |
3651 | + }; |
3652 | + }; |
3653 | + |
3654 | +class DelayedProvider : public Provider |
3655 | +{ |
3656 | + public: |
3657 | + // For integration with the Provider factory |
3658 | + static std::string class_name(); |
3659 | + // Waits for "DelayInMs" from the provided property bundle then |
3660 | + // instantiates a new provider instance, populating the configuration object |
3661 | + // from the provided property bundle. |
3662 | + static DelayedProvider::Ptr create_instance(const ProviderFactory::Configuration&); |
3663 | + // Creates a new provider instance from the given configuration. |
3664 | + DelayedProvider(const Configuration config = Configuration{}); |
3665 | +}; |
3666 | +} |
3667 | +} |
3668 | +} |
3669 | +} |
3670 | +} |
3671 | +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_DUMMY_DELAYED_PROVIDER_H_ |
3672 | |
3673 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt' |
3674 | --- src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2014-07-28 19:14:58 +0000 |
3675 | +++ src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2016-04-01 06:55:25 +0000 |
3676 | @@ -4,30 +4,34 @@ |
3677 | ON |
3678 | ) |
3679 | |
3680 | -if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER) |
3681 | - find_file( |
3682 | - UBUNTU_HARDWARE_GPS_H gps.h |
3683 | - NAMES ubuntu/hardware/gps.h |
3684 | - ) |
3685 | - |
3686 | - if (UBUNTU_HARDWARE_GPS_H) |
3687 | +if ((LOCATION_SERVICE_ENABLE_GPS_PROVIDER) AND (UBUNTU_PLATFORM_HARDWARE_API_FOUND)) |
3688 | message(STATUS "Enabling GPS location provider") |
3689 | |
3690 | + include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS}) |
3691 | + |
3692 | add_library( |
3693 | gps |
3694 | |
3695 | gps.conf |
3696 | |
3697 | + hardware_abstraction_layer.cpp |
3698 | + |
3699 | android_hardware_abstraction_layer.h |
3700 | android_hardware_abstraction_layer.cpp |
3701 | |
3702 | + sntp_reference_time_source.h |
3703 | + sntp_reference_time_source.cpp |
3704 | + |
3705 | + sntp_client.h |
3706 | + sntp_client.cpp |
3707 | + |
3708 | hardware_abstraction_layer.h |
3709 | # hardware_abstraction_layer.cpp |
3710 | |
3711 | provider.h |
3712 | provider.cpp) |
3713 | |
3714 | - target_link_libraries(gps ubuntu_platform_hardware_api.so) |
3715 | + target_link_libraries(gps ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS}) |
3716 | |
3717 | set( |
3718 | ENABLED_PROVIDER_TARGETS |
3719 | @@ -41,5 +45,4 @@ |
3720 | ) |
3721 | |
3722 | install(FILES gps.conf DESTINATION /etc/) |
3723 | - endif (UBUNTU_HARDWARE_GPS_H) |
3724 | -endif (LOCATION_SERVICE_ENABLE_GPS_PROVIDER) |
3725 | +endif () |
3726 | |
3727 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp' |
3728 | --- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2014-10-27 21:58:16 +0000 |
3729 | +++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2016-04-01 06:55:25 +0000 |
3730 | @@ -17,6 +17,7 @@ |
3731 | */ |
3732 | |
3733 | #include "android_hardware_abstraction_layer.h" |
3734 | +#include "sntp_reference_time_source.h" |
3735 | |
3736 | #if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP) |
3737 | #include "net_cpp_gps_xtra_downloader.h" |
3738 | @@ -66,8 +67,6 @@ |
3739 | if (config.count("XTRA_SERVER_3") > 0) |
3740 | result.xtra_hosts.push_back(config.get<std::string>("XTRA_SERVER_3")); |
3741 | |
3742 | - result.timeout = std::chrono::milliseconds{1500}; |
3743 | - |
3744 | return result; |
3745 | } |
3746 | |
3747 | @@ -325,23 +324,18 @@ |
3748 | { |
3749 | VLOG(1) << __PRETTY_FUNCTION__; |
3750 | |
3751 | - auto thiz = static_cast<android::HardwareAbstractionLayer*>(context); |
3752 | - |
3753 | - if (thiz->impl.utc_time_request_handler) |
3754 | - { |
3755 | - thiz->impl.utc_time_request_handler(); |
3756 | - } else |
3757 | - { |
3758 | - auto now = location::Clock::now().time_since_epoch(); |
3759 | - auto thiz = static_cast<android::HardwareAbstractionLayer*>(context); |
3760 | - |
3761 | - static const int zero_uncertainty = 0; |
3762 | - |
3763 | - u_hardware_gps_inject_time( |
3764 | - thiz->impl.gps_handle, |
3765 | - now.count(), |
3766 | - now.count(), |
3767 | - zero_uncertainty); |
3768 | + try |
3769 | + { |
3770 | + if (auto thiz = static_cast<android::HardwareAbstractionLayer*>(context)) |
3771 | + thiz->inject_reference_time(thiz->impl.reference_time_source->sample()); |
3772 | + } |
3773 | + catch (const std::runtime_error& e) |
3774 | + { |
3775 | + LOG(WARNING) << "Failed to inject reference time to chipset: " << e.what(); |
3776 | + } |
3777 | + catch (...) |
3778 | + { |
3779 | + LOG(WARNING) << "Failed to inject reference time to chipset."; |
3780 | } |
3781 | } |
3782 | |
3783 | @@ -536,19 +530,22 @@ |
3784 | return true; |
3785 | } |
3786 | |
3787 | -bool android::HardwareAbstractionLayer::inject_reference_time( |
3788 | - const std::chrono::microseconds& reference_time, |
3789 | - const std::chrono::microseconds& sample_time) |
3790 | +bool android::HardwareAbstractionLayer::inject_reference_time(const ReferenceTimeSample& sample) |
3791 | { |
3792 | if (!is_capable_of(gps::Capability::on_demand_time_injection)) |
3793 | return false; |
3794 | |
3795 | // TODO(tvoss): We should expose the int return type of the underyling |
3796 | // Android HAL to capture errors here. |
3797 | + // |
3798 | + // Please see: |
3799 | + // http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/net/SntpClient.java#72 |
3800 | + // for the bloody details of relating the system wall clock time to the elapsed realtime since boot |
3801 | + // including deep sleep. |
3802 | u_hardware_gps_inject_time(impl.gps_handle, |
3803 | - reference_time.count(), |
3804 | - sample_time.count(), |
3805 | - 10); |
3806 | + sample.since_epoch.count(), |
3807 | + sample.since_boot.count(), |
3808 | + sample.uncertainty.count()); |
3809 | return true; |
3810 | } |
3811 | |
3812 | @@ -559,6 +556,7 @@ |
3813 | assistance_mode(gps::AssistanceMode::mobile_station_based), |
3814 | position_mode(gps::PositionMode::periodic), |
3815 | supl_assistant(*parent), |
3816 | + reference_time_source(configuration.reference_time_source), |
3817 | gps_xtra_configuration(configuration.gps_xtra.configuration), |
3818 | gps_xtra_downloader(configuration.gps_xtra.downloader) |
3819 | { |
3820 | @@ -617,6 +615,22 @@ |
3821 | |
3822 | namespace |
3823 | { |
3824 | +gps::SntpReferenceTimeSource::Configuration sntp_reference_time_source_configuration(std::istream& in) |
3825 | +{ |
3826 | + gps::SntpReferenceTimeSource::Configuration config; |
3827 | + |
3828 | + try |
3829 | + { |
3830 | + config = gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(in); |
3831 | + } |
3832 | + catch (...) |
3833 | + { |
3834 | + // Consciously dropping all exceptions here. |
3835 | + } |
3836 | + |
3837 | + return config; |
3838 | +} |
3839 | + |
3840 | android::GpsXtraDownloader::Configuration gps_xtra_downloader_configuration(std::istream& in) |
3841 | { |
3842 | android::GpsXtraDownloader::Configuration config; |
3843 | @@ -643,6 +657,8 @@ |
3844 | |
3845 | return config; |
3846 | } |
3847 | + |
3848 | + |
3849 | } |
3850 | |
3851 | std::shared_ptr<gps::HardwareAbstractionLayer> gps::HardwareAbstractionLayer::create_default_instance() |
3852 | @@ -666,7 +682,8 @@ |
3853 | { |
3854 | create_xtra_downloader(), |
3855 | gps_xtra_downloader_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf)) |
3856 | - } |
3857 | + }, |
3858 | + std::make_shared<gps::SntpReferenceTimeSource>(sntp_reference_time_source_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf))) |
3859 | }; |
3860 | |
3861 | static std::shared_ptr<gps::HardwareAbstractionLayer> instance |
3862 | |
3863 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h' |
3864 | --- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2015-04-22 13:30:04 +0000 |
3865 | +++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2016-04-01 06:55:25 +0000 |
3866 | @@ -19,6 +19,7 @@ |
3867 | #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_ANDROID_HARDWARE_ABSTRACTION_LAYER_H_ |
3868 | |
3869 | #include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h> |
3870 | +#include <com/ubuntu/location/providers/gps/sntp_client.h> |
3871 | |
3872 | #include <ubuntu/hardware/gps.h> |
3873 | |
3874 | @@ -49,7 +50,7 @@ |
3875 | /** @brief Timeout on gps xtra download operations. */ |
3876 | std::chrono::milliseconds timeout |
3877 | { |
3878 | - 5000 |
3879 | + 30000 |
3880 | }; |
3881 | |
3882 | /** Set of hosts serving GPS xtra data. */ |
3883 | @@ -66,7 +67,24 @@ |
3884 | }; |
3885 | |
3886 | struct HardwareAbstractionLayer : public gps::HardwareAbstractionLayer |
3887 | -{ |
3888 | +{ |
3889 | + /** @brief A ReferenceTimeSource provides samples of an arbitrary reference time source. */ |
3890 | + class ReferenceTimeSource |
3891 | + { |
3892 | + public: |
3893 | + /** @cond */ |
3894 | + typedef std::shared_ptr<ReferenceTimeSource> Ptr; |
3895 | + |
3896 | + virtual ~ReferenceTimeSource() = default; |
3897 | + /** @endcond */ |
3898 | + |
3899 | + /** @brief sample returns a sample of the current ReferenceTimeSource. */ |
3900 | + virtual ReferenceTimeSample sample() = 0; |
3901 | + |
3902 | + protected: |
3903 | + ReferenceTimeSource() = default; |
3904 | + }; |
3905 | + |
3906 | /** @brief Implements gps::HardwareAbstractionLayer::SuplAssistant interface for the android gps HAL. */ |
3907 | struct SuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant |
3908 | { |
3909 | @@ -186,6 +204,8 @@ |
3910 | std::shared_ptr<GpsXtraDownloader> downloader; |
3911 | GpsXtraDownloader::Configuration configuration; |
3912 | } gps_xtra; |
3913 | + |
3914 | + ReferenceTimeSource::Ptr reference_time_source; |
3915 | }; |
3916 | |
3917 | HardwareAbstractionLayer(const Configuration& configuration); |
3918 | @@ -227,8 +247,8 @@ |
3919 | bool set_position_mode(gps::PositionMode mode) override; |
3920 | |
3921 | bool inject_reference_position(const location::Position& position) override; |
3922 | - bool inject_reference_time(const std::chrono::microseconds& reference_time, |
3923 | - const std::chrono::microseconds& sample_time) override; |
3924 | + bool inject_reference_time(const ReferenceTimeSample& sample) override; |
3925 | + |
3926 | struct Impl |
3927 | { |
3928 | // Bootstraps access to the GPS chipset, wiring up all callbacks. |
3929 | @@ -252,8 +272,8 @@ |
3930 | // An implementation of the gps::HardwareAbstractionLayer::SuplAssistant interface. |
3931 | SuplAssistant supl_assistant; |
3932 | |
3933 | - // Callback for handling utc time requests. |
3934 | - gps::HardwareAbstractionLayer::UtcTimeRequestHandler utc_time_request_handler; |
3935 | + // An implementation of ReferenceTimeSource. |
3936 | + ReferenceTimeSource::Ptr reference_time_source; |
3937 | |
3938 | // Emitted whenever the set of visible space vehicles changes. |
3939 | core::Signal<std::set<location::SpaceVehicle>> space_vehicle_updates; |
3940 | |
3941 | === added file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp' |
3942 | --- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 1970-01-01 00:00:00 +0000 |
3943 | +++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 2016-04-01 06:55:25 +0000 |
3944 | @@ -0,0 +1,30 @@ |
3945 | +/* |
3946 | + * Copyright © 2012-2013 Canonical Ltd. |
3947 | + * |
3948 | + * This program is free software: you can redistribute it and/or modify it |
3949 | + * under the terms of the GNU Lesser General Public License version 3, |
3950 | + * as published by the Free Software Foundation. |
3951 | + * |
3952 | + * This program is distributed in the hope that it will be useful, |
3953 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3954 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3955 | + * GNU Lesser General Public License for more details. |
3956 | + * |
3957 | + * You should have received a copy of the GNU Lesser General Public License |
3958 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3959 | + * |
3960 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
3961 | + */ |
3962 | + |
3963 | +#include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h> |
3964 | + |
3965 | +#include <iostream> |
3966 | + |
3967 | +namespace gps = com::ubuntu::location::providers::gps; |
3968 | + |
3969 | +std::ostream& gps::operator<<(std::ostream& out, const gps::HardwareAbstractionLayer::ReferenceTimeSample& sample) |
3970 | +{ |
3971 | + return out << "[since epoch: " << sample.since_epoch.count() << " [ms], since boot: " |
3972 | + << sample.since_boot.count() << " [ms], uncertainty: " |
3973 | + << sample.uncertainty.count() << " [ms]"; |
3974 | +} |
3975 | |
3976 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h' |
3977 | --- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2014-06-06 17:52:59 +0000 |
3978 | +++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2016-04-01 06:55:25 +0000 |
3979 | @@ -18,6 +18,7 @@ |
3980 | #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_ |
3981 | #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_ |
3982 | |
3983 | +#include <com/ubuntu/location/clock.h> |
3984 | #include <com/ubuntu/location/heading.h> |
3985 | #include <com/ubuntu/location/position.h> |
3986 | #include <com/ubuntu/location/space_vehicle.h> |
3987 | @@ -104,6 +105,13 @@ |
3988 | class HardwareAbstractionLayer |
3989 | { |
3990 | public: |
3991 | + /** @brief ReferenceTimeSample bundles together the local reference. */ |
3992 | + struct ReferenceTimeSample |
3993 | + { |
3994 | + std::chrono::milliseconds since_epoch; /**< Reference wall-clock time since the epoch (UTC). */ |
3995 | + std::chrono::milliseconds since_boot; /**< Reference time since boot. */ |
3996 | + std::chrono::milliseconds uncertainty; /**< Uncertainty estimate of the sample. */ |
3997 | + }; |
3998 | |
3999 | class SuplAssistant |
4000 | { |
4001 | @@ -304,16 +312,17 @@ |
4002 | |
4003 | /** |
4004 | * @brief Injects a new reference time to the underlying gps driver/chipset. |
4005 | - * @param reference_time The new reference time. |
4006 | - * @param sample_time When the reference time was sampled. |
4007 | + * @param sample The reference time sample |
4008 | * @return true iff the injection was successful, false otherwise. |
4009 | */ |
4010 | - virtual bool inject_reference_time(const std::chrono::microseconds& reference_time, |
4011 | - const std::chrono::microseconds& sample_time) = 0; |
4012 | + virtual bool inject_reference_time(const ReferenceTimeSample& sample) = 0; |
4013 | |
4014 | protected: |
4015 | HardwareAbstractionLayer() = default; |
4016 | }; |
4017 | + |
4018 | +/** @brief operator<< inserts sample into out. */ |
4019 | +std::ostream& operator<<(std::ostream& out, const HardwareAbstractionLayer::ReferenceTimeSample& sample); |
4020 | } |
4021 | } |
4022 | } |
4023 | |
4024 | === added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp' |
4025 | --- src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 1970-01-01 00:00:00 +0000 |
4026 | +++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 2016-04-01 06:55:25 +0000 |
4027 | @@ -0,0 +1,210 @@ |
4028 | +/* |
4029 | + * Copyright © 2012-2013 Canonical Ltd. |
4030 | + * |
4031 | + * This program is free software: you can redistribute it and/or modify it |
4032 | + * under the terms of the GNU Lesser General Public License version 3, |
4033 | + * as published by the Free Software Foundation. |
4034 | + * |
4035 | + * This program is distributed in the hope that it will be useful, |
4036 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4037 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4038 | + * GNU Lesser General Public License for more details. |
4039 | + * |
4040 | + * You should have received a copy of the GNU Lesser General Public License |
4041 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4042 | + * |
4043 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4044 | + */ |
4045 | + |
4046 | +#include <com/ubuntu/location/providers/gps/sntp_client.h> |
4047 | + |
4048 | +#include <com/ubuntu/location/time_since_boot.h> |
4049 | + |
4050 | +#include <boost/asio/ip/udp.hpp> |
4051 | +#include <boost/endian/buffers.hpp> |
4052 | + |
4053 | +#include <bitset> |
4054 | +#include <fstream> |
4055 | +#include <future> |
4056 | +#include <iostream> |
4057 | +#include <thread> |
4058 | + |
4059 | +namespace location = com::ubuntu::location; |
4060 | +namespace gps = location::providers::gps; |
4061 | +namespace ip = boost::asio::ip; |
4062 | + |
4063 | +namespace |
4064 | +{ |
4065 | + |
4066 | +template<typename T> |
4067 | +T sync_or_throw(std::future<T>& f) |
4068 | +{ |
4069 | + return f.get(); |
4070 | +} |
4071 | + |
4072 | +template<> |
4073 | +void sync_or_throw<>(std::future<void>& f) |
4074 | +{ |
4075 | + f.get(); |
4076 | +} |
4077 | + |
4078 | +struct Now |
4079 | +{ |
4080 | + std::chrono::nanoseconds time = std::chrono::duration_cast<std::chrono::milliseconds>( |
4081 | + std::chrono::system_clock::now().time_since_epoch()); |
4082 | + std::chrono::nanoseconds ticks = location::time_since_boot(); |
4083 | +}; |
4084 | +} |
4085 | + |
4086 | +const std::chrono::seconds& gps::sntp::offset_1900_to_1970() |
4087 | +{ |
4088 | + static const std::uint64_t secs = ((365ull * 70ull) + 17ull) * 24ull * 60ull * 60ull; |
4089 | + static const std::chrono::seconds seconds{secs}; |
4090 | + return seconds; |
4091 | +} |
4092 | + |
4093 | +gps::sntp::LeapIndicator gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator() const |
4094 | +{ |
4095 | + return static_cast<LeapIndicator>((livm.value() >> 6) & 0x3); |
4096 | +} |
4097 | + |
4098 | +gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator(LeapIndicator li) |
4099 | +{ |
4100 | + livm = livm.value() | (static_cast<uint8_t>(li) << 6); |
4101 | + return *this; |
4102 | +} |
4103 | + |
4104 | +std::uint8_t gps::sntp::Packet::LeapIndicatorVersionMode::version() const |
4105 | +{ |
4106 | + return (livm.value() >> 3) & 0x7; |
4107 | +} |
4108 | + |
4109 | +gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::version(std::uint8_t version) |
4110 | +{ |
4111 | + livm = livm.value() | (version << 3); |
4112 | + return *this; |
4113 | +} |
4114 | + |
4115 | +gps::sntp::Mode gps::sntp::Packet::LeapIndicatorVersionMode::mode() const |
4116 | +{ |
4117 | + return static_cast<Mode>(livm.value() & 0x7); |
4118 | +} |
4119 | + |
4120 | +gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::mode(Mode m) |
4121 | +{ |
4122 | + livm = static_cast<uint8_t>(m) | livm.value(); |
4123 | + return *this; |
4124 | +} |
4125 | + |
4126 | +gps::sntp::Client::Response gps::sntp::Client::request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios) |
4127 | +{ |
4128 | + ip::udp::resolver resolver{ios}; |
4129 | + ip::udp::socket socket{ios}; |
4130 | + bool timed_out{false}; |
4131 | + |
4132 | + std::promise<ip::udp::resolver::iterator> promise_resolve; |
4133 | + auto future_resolve= promise_resolve.get_future(); |
4134 | + |
4135 | + boost::asio::deadline_timer timer{ios}; |
4136 | + timer.expires_from_now(boost::posix_time::milliseconds{timeout.count()}); |
4137 | + timer.async_wait([&timed_out, &resolver, &socket](const boost::system::error_code& ec) |
4138 | + { |
4139 | + if (ec) |
4140 | + return; |
4141 | + |
4142 | + timed_out = true; |
4143 | + |
4144 | + resolver.cancel(); |
4145 | + socket.shutdown(ip::udp::socket::shutdown_both); |
4146 | + socket.close(); |
4147 | + }); |
4148 | + |
4149 | + ip::udp::resolver::query query{ip::udp::v4(), host, "ntp"}; |
4150 | + |
4151 | + resolver.async_resolve(query, [&promise_resolve](const boost::system::error_code& ec, ip::udp::resolver::iterator it) |
4152 | + { |
4153 | + if (ec) |
4154 | + promise_resolve.set_exception(std::make_exception_ptr(boost::system::system_error(ec))); |
4155 | + else |
4156 | + promise_resolve.set_value(it); |
4157 | + }); |
4158 | + |
4159 | + auto it = sync_or_throw(future_resolve); |
4160 | + |
4161 | + std::promise<void> promise_connect; |
4162 | + auto future_connect = promise_connect.get_future(); |
4163 | + |
4164 | + socket.async_connect(*it, [&promise_connect](const boost::system::error_code& ec) |
4165 | + { |
4166 | + if (ec) |
4167 | + promise_connect.set_exception(std::make_exception_ptr(boost::system::system_error(ec))); |
4168 | + else |
4169 | + promise_connect.set_value(); |
4170 | + }); |
4171 | + |
4172 | + sync_or_throw(future_connect); |
4173 | + |
4174 | + sntp::Packet packet; |
4175 | + |
4176 | + Now before; |
4177 | + { |
4178 | + packet = request(socket); |
4179 | + timer.cancel(); |
4180 | + |
4181 | + if (timed_out) |
4182 | + throw std::runtime_error("Operation timed out."); |
4183 | + } |
4184 | + Now after; |
4185 | + |
4186 | + auto originate = packet.originate.to_milliseconds_since_epoch(); |
4187 | + auto receive = packet.receive.to_milliseconds_since_epoch(); |
4188 | + auto transmit = packet.transmit.to_milliseconds_since_epoch(); |
4189 | + |
4190 | + auto rtt = after.ticks - before.ticks - (transmit - receive); |
4191 | + auto offset = ((receive - originate) + (transmit - after.time))/2; |
4192 | + |
4193 | + return |
4194 | + { |
4195 | + packet, |
4196 | + std::chrono::duration_cast<std::chrono::milliseconds>(after.time + offset), |
4197 | + std::chrono::duration_cast<std::chrono::milliseconds>(after.ticks), |
4198 | + std::chrono::duration_cast<std::chrono::milliseconds>(rtt) |
4199 | + }; |
4200 | +} |
4201 | + |
4202 | +gps::sntp::Packet gps::sntp::Client::request(boost::asio::ip::udp::socket& socket) |
4203 | +{ |
4204 | + sntp::Packet packet; |
4205 | + packet.transmit.from_milliseconds_since_epoch( |
4206 | + std::chrono::duration_cast<std::chrono::milliseconds>( |
4207 | + std::chrono::system_clock::now().time_since_epoch())); |
4208 | + packet.livm.mode(sntp::Mode::client).version(sntp::version); |
4209 | + |
4210 | + std::promise<std::size_t> promise_send; |
4211 | + auto future_send = promise_send.get_future(); |
4212 | + |
4213 | + socket.async_send(boost::asio::buffer(&packet, sizeof(packet)), [&promise_send](const boost::system::error_code& ec, std::size_t transferred) |
4214 | + { |
4215 | + if (ec) |
4216 | + promise_send.set_exception(std::make_exception_ptr(boost::system::system_error(ec))); |
4217 | + else |
4218 | + promise_send.set_value(transferred); |
4219 | + }); |
4220 | + |
4221 | + sync_or_throw(future_send); |
4222 | + |
4223 | + std::promise<std::size_t> promise_receive; |
4224 | + auto future_receive = promise_receive.get_future(); |
4225 | + |
4226 | + socket.async_receive(boost::asio::buffer(&packet, sizeof(packet)), [&promise_receive](const boost::system::error_code& ec, std::size_t transferred) |
4227 | + { |
4228 | + if (ec) |
4229 | + promise_receive.set_exception(std::make_exception_ptr(boost::system::system_error(ec))); |
4230 | + else |
4231 | + promise_receive.set_value(transferred); |
4232 | + }); |
4233 | + |
4234 | + sync_or_throw(future_receive); |
4235 | + |
4236 | + return packet; |
4237 | +} |
4238 | |
4239 | === added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.h' |
4240 | --- src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 1970-01-01 00:00:00 +0000 |
4241 | +++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 2016-04-01 06:55:25 +0000 |
4242 | @@ -0,0 +1,210 @@ |
4243 | +/* |
4244 | + * Copyright © 2012-2013 Canonical Ltd. |
4245 | + * |
4246 | + * This program is free software: you can redistribute it and/or modify it |
4247 | + * under the terms of the GNU Lesser General Public License version 3, |
4248 | + * as published by the Free Software Foundation. |
4249 | + * |
4250 | + * This program is distributed in the hope that it will be useful, |
4251 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4252 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4253 | + * GNU Lesser General Public License for more details. |
4254 | + * |
4255 | + * You should have received a copy of the GNU Lesser General Public License |
4256 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4257 | + * |
4258 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4259 | + */ |
4260 | +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_ |
4261 | +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_ |
4262 | + |
4263 | +#include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h> |
4264 | + |
4265 | +#include <boost/asio.hpp> |
4266 | +#include <boost/endian/buffers.hpp> |
4267 | + |
4268 | +#include <chrono> |
4269 | +#include <string> |
4270 | + |
4271 | +namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps { namespace sntp { |
4272 | +// Please see https://tools.ietf.org/html/rfc4330 for a discussion of sntp |
4273 | +// and for a detailed explanation of the different types and algorithms. |
4274 | + |
4275 | +namespace detail |
4276 | +{ |
4277 | +// enum_constant returns a compile-time constant assembled from 4 or at least |
4278 | +// 3 individual characters. |
4279 | +template<std::uint8_t a, std::uint8_t b, std::uint8_t c, std::uint8_t d = 0> |
4280 | +constexpr uint32_t enum_constant() |
4281 | +{ |
4282 | + return (a << 24) | (b << 16) | (c << 8) | d; |
4283 | +} |
4284 | +} |
4285 | + |
4286 | +// offset_1900_to_1970 returns the number of seconds that elapsed between 1900 and 1970. |
4287 | +const std::chrono::seconds& offset_1900_to_1970(); |
4288 | + |
4289 | +// LeapIndicator enumerates warnings of an impending |
4290 | +// leap second to be inserted/deleted in the last minute of the current |
4291 | +// day. |
4292 | +enum class LeapIndicator : std::uint8_t |
4293 | +{ |
4294 | + no_warning = 0, |
4295 | + last_minute_has_61_seconds = 1, |
4296 | + last_minute_has_59_seconds = 2, |
4297 | + alarm = 3 |
4298 | +}; |
4299 | + |
4300 | +// Mode enumerates the different protocol modes. |
4301 | +enum class Mode : std::uint8_t |
4302 | +{ |
4303 | + reserved = 0, |
4304 | + symmetric_active = 1, |
4305 | + symmetric_passive = 2, |
4306 | + client = 3, |
4307 | + server = 4, |
4308 | + broadcast = 5, |
4309 | + reserved_for_control = 6, |
4310 | + reserved_for_private_use = 7 |
4311 | +}; |
4312 | + |
4313 | +// ReferenceIdentifier enumerates known references for NTP-servers |
4314 | +// on stratum 0 or 1. |
4315 | +enum class ReferenceIdentifier : std::uint32_t |
4316 | +{ |
4317 | + locl = detail::enum_constant<'L','O','C','L'>(), // uncalibrated local clock |
4318 | + cesm = detail::enum_constant<'C','E','S','M'>(), // calibrated Cesium clock |
4319 | + rbdm = detail::enum_constant<'R','B','D','M'>(), // calibrated Rubidium clock |
4320 | + pps = detail::enum_constant<'P','P','S'>(), // calibrated quartz clock or other pulse-per-second source |
4321 | + irig = detail::enum_constant<'I','R','I','G'>(), // Inter-Range Instrumentation Group |
4322 | + acts = detail::enum_constant<'A','C','T','S'>(), // NIST telephone modem service |
4323 | + usno = detail::enum_constant<'U','S','N','O'>(), // USNO telephone modem service |
4324 | + ptb = detail::enum_constant<'P','T','B'>(), // PTB (Germany) telephone modem service |
4325 | + tdf = detail::enum_constant<'T','D','F'>(), // Allouis (France) Radio 164 kHz |
4326 | + dcf = detail::enum_constant<'D','C','F'>(), // Mainflingen (Germany) Radio 77.5 kHz |
4327 | + msf = detail::enum_constant<'M','S', 'F'>(), // Rugby (UK) Radio 60 kHz |
4328 | + wwv = detail::enum_constant<'W','W','V'>(), // Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz |
4329 | + wwvb = detail::enum_constant<'W','W','V','B'>(), // Boulder (US) Radio 60 kHz |
4330 | + wwvh = detail::enum_constant<'W','W','V','H'>(), // Kauai Hawaii (US) Radio 2.5, 5, 10, 15 MHz |
4331 | + chu = detail::enum_constant<'C','H','U'>(), // Ottawa (Canada) Radio 3330, 7335, 14670 kHz |
4332 | + lorc = detail::enum_constant<'L','O','R','C'>(), // LORAN-C radionavigation system |
4333 | + omeg = detail::enum_constant<'O','M','E','G'>(), // OMEGA radionavigation system |
4334 | + gps = detail::enum_constant<'G','P','S'>() // Global Positioning Service |
4335 | +}; |
4336 | + |
4337 | +// Timestamp models a fixed-point NTP timestamp relative to 01.01.1900 |
4338 | +template<typename Seconds, typename FractionalSeconds = Seconds> |
4339 | +struct Timestamp |
4340 | +{ |
4341 | + // To stay on the safe side, we only allow for the types specified below. |
4342 | + // With that, we make sure that we only ever use endian-save types. |
4343 | + static_assert(std::is_same<Seconds, boost::endian::big_int16_buf_t>::value || |
4344 | + std::is_same<Seconds, boost::endian::big_uint16_buf_t>::value || |
4345 | + std::is_same<Seconds, boost::endian::big_int32_buf_t>::value || |
4346 | + std::is_same<Seconds, boost::endian::big_uint32_buf_t>::value, |
4347 | + "Timestamp<> only supports boost::endian::big_{{u}int{16,32}}_buf_t"); |
4348 | + |
4349 | + // from_milliseconds_since_epoch fills in seconds/fractional_seconds from |
4350 | + // ms, converting to NTP's reference time. |
4351 | + void from_milliseconds_since_epoch(const std::chrono::milliseconds& ts) |
4352 | + { |
4353 | + using s = std::chrono::seconds; |
4354 | + using ms = std::chrono::milliseconds; |
4355 | + |
4356 | + auto secs = std::chrono::duration_cast<s>(ts); |
4357 | + auto msecs = std::chrono::duration_cast<ms>(ts - secs); |
4358 | + |
4359 | + secs += offset_1900_to_1970(); |
4360 | + |
4361 | + seconds = secs.count(); |
4362 | + fractional_seconds = msecs.count() * std::numeric_limits<typename FractionalSeconds::value_type>::max() + 1 / 1000; |
4363 | + } |
4364 | + |
4365 | + // to_milliseconds_since_epoch returns a unix timestamp calculated from |
4366 | + // an NTP-timestamp. |
4367 | + std::chrono::milliseconds to_milliseconds_since_epoch() const |
4368 | + { |
4369 | + return std::chrono::seconds{seconds.value()} - offset_1900_to_1970() + |
4370 | + std::chrono::milliseconds{(fractional_seconds.value() * 1000) / std::numeric_limits<typename FractionalSeconds::value_type>::max()}; |
4371 | + } |
4372 | + |
4373 | + Seconds seconds; |
4374 | + FractionalSeconds fractional_seconds; |
4375 | +}; |
4376 | + |
4377 | +// Duration is just an alias to an sntp::Timestamp. |
4378 | +template<typename T, typename U> |
4379 | +using Duration = Timestamp<T, U>; |
4380 | + |
4381 | +// Packet models the SNTP wire format. |
4382 | +struct Packet |
4383 | +{ |
4384 | + // LeapIndicatorVersionMode helps in handling the bitfield setup |
4385 | + // for the first byte of an sntp::Packet in a portable and endianess-safe way. |
4386 | + struct LeapIndicatorVersionMode |
4387 | + { |
4388 | + // leap_indicator extracts the LeapIndicator from the underlying data. |
4389 | + LeapIndicator leap_indicator() const; |
4390 | + // leap_indicator sets the value of the leap_indicatorin in the underyling |
4391 | + // data to li. |
4392 | + LeapIndicatorVersionMode& leap_indicator(LeapIndicator li); |
4393 | + |
4394 | + // version extracts the version from the underlying data. |
4395 | + std::uint8_t version() const; |
4396 | + // version adjusts the version to version in the underlying data. |
4397 | + LeapIndicatorVersionMode& version(std::uint8_t version); |
4398 | + |
4399 | + // mode extracts the mode from the underlying data. |
4400 | + Mode mode() const; |
4401 | + // mode adjusts the mode to m in the underlying data. |
4402 | + LeapIndicatorVersionMode& mode(Mode m); |
4403 | + |
4404 | + boost::endian::big_uint8_buf_t livm; |
4405 | + }; |
4406 | + |
4407 | + LeapIndicatorVersionMode livm; |
4408 | + boost::endian::big_uint8_buf_t stratum; |
4409 | + boost::endian::big_uint8_buf_t poll_interval; |
4410 | + boost::endian::big_int8_buf_t precision; |
4411 | + Duration<boost::endian::big_int16_buf_t, boost::endian::big_uint16_buf_t> root_delay; |
4412 | + Duration<boost::endian::big_uint16_buf_t, boost::endian::big_uint16_buf_t> root_dispersion; |
4413 | + boost::endian::big_uint32_buf_t reference_identifier; |
4414 | + Timestamp<boost::endian::big_uint32_buf_t> reference; |
4415 | + Timestamp<boost::endian::big_uint32_buf_t> originate; |
4416 | + Timestamp<boost::endian::big_uint32_buf_t> receive; |
4417 | + Timestamp<boost::endian::big_uint32_buf_t> transmit; |
4418 | +}; |
4419 | +// The SNTP version we are working with. |
4420 | +static constexpr const std::uint8_t version = 3; |
4421 | + |
4422 | +// SntpClient provides access to querying time from an NTP server in |
4423 | +// a unicast scenario. |
4424 | +class Client |
4425 | +{ |
4426 | +public: |
4427 | + // Response is returned in a request for time information. |
4428 | + struct Response |
4429 | + { |
4430 | + // The raw packet that was returned from the request. |
4431 | + sntp::Packet packet; |
4432 | + // Time computed from the NTP transaction. |
4433 | + std::chrono::milliseconds ntp_time; |
4434 | + // Reference clock value corresponding to the NTP time. |
4435 | + std::chrono::milliseconds ntp_time_reference; |
4436 | + // Round-trip time of the last NTP transaction. |
4437 | + std::chrono::milliseconds round_trip_time; |
4438 | + }; |
4439 | + |
4440 | + // request_time_with_timeout reaches out to the SNTP server known under host, |
4441 | + // and tries to determine the current UTC reference time. The operation aborts after |
4442 | + // timeout milliseconds. |
4443 | + // |
4444 | + // std::runtime_error is thrown in case of issues. |
4445 | + Response request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios); |
4446 | + sntp::Packet request(boost::asio::ip::udp::socket& socket); |
4447 | +}; |
4448 | +} |
4449 | +} |
4450 | + |
4451 | +}}}} |
4452 | +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_ |
4453 | |
4454 | === added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp' |
4455 | --- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 1970-01-01 00:00:00 +0000 |
4456 | +++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 2016-04-01 06:55:25 +0000 |
4457 | @@ -0,0 +1,57 @@ |
4458 | +/* |
4459 | + * Copyright © 2012-2013 Canonical Ltd. |
4460 | + * |
4461 | + * This program is free software: you can redistribute it and/or modify it |
4462 | + * under the terms of the GNU Lesser General Public License version 3, |
4463 | + * as published by the Free Software Foundation. |
4464 | + * |
4465 | + * This program is distributed in the hope that it will be useful, |
4466 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4467 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4468 | + * GNU Lesser General Public License for more details. |
4469 | + * |
4470 | + * You should have received a copy of the GNU Lesser General Public License |
4471 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4472 | + * |
4473 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4474 | + */ |
4475 | + |
4476 | +#include <com/ubuntu/location/providers/gps/sntp_reference_time_source.h> |
4477 | + |
4478 | +#include <com/ubuntu/location/configuration.h> |
4479 | +#include <com/ubuntu/location/service/runtime.h> |
4480 | + |
4481 | +#include <boost/property_tree/ini_parser.hpp> |
4482 | + |
4483 | +#include <future> |
4484 | + |
4485 | +namespace location = com::ubuntu::location; |
4486 | +namespace gps = com::ubuntu::location::providers::gps; |
4487 | + |
4488 | +gps::SntpReferenceTimeSource::Configuration gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(std::istream& in) |
4489 | +{ |
4490 | + gps::SntpReferenceTimeSource::Configuration result; |
4491 | + |
4492 | + location::Configuration config; |
4493 | + boost::property_tree::read_ini(in, config); |
4494 | + |
4495 | + if (config.count("NTP_SERVER") > 0) |
4496 | + result.host = config.get<std::string>("NTP_SERVER"); |
4497 | + |
4498 | + return result; |
4499 | +} |
4500 | +gps::SntpReferenceTimeSource::SntpReferenceTimeSource(const Configuration& config) |
4501 | + : config(config) |
4502 | +{ |
4503 | +} |
4504 | + |
4505 | +gps::HardwareAbstractionLayer::ReferenceTimeSample gps::SntpReferenceTimeSource::sample() |
4506 | +{ |
4507 | + auto rt = location::service::Runtime::create(); |
4508 | + rt->start(); |
4509 | + |
4510 | + location::providers::gps::sntp::Client sntp_client; |
4511 | + auto result = sntp_client.request_time(config.host, config.timeout, rt->service()); |
4512 | + |
4513 | + return {result.ntp_time, result.ntp_time_reference, result.round_trip_time}; |
4514 | +} |
4515 | |
4516 | === added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h' |
4517 | --- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 1970-01-01 00:00:00 +0000 |
4518 | +++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 2016-04-01 06:55:25 +0000 |
4519 | @@ -0,0 +1,51 @@ |
4520 | +/* |
4521 | + * Copyright © 2016 Canonical Ltd. |
4522 | + * |
4523 | + * This program is free software: you can redistribute it and/or modify it |
4524 | + * under the terms of the GNU Lesser General Public License version 3, |
4525 | + * as published by the Free Software Foundation. |
4526 | + * |
4527 | + * This program is distributed in the hope that it will be useful, |
4528 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4529 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4530 | + * GNU Lesser General Public License for more details. |
4531 | + * |
4532 | + * You should have received a copy of the GNU Lesser General Public License |
4533 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4534 | + * |
4535 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4536 | + */ |
4537 | +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_ |
4538 | +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_ |
4539 | + |
4540 | +#include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h> |
4541 | + |
4542 | +#include <com/ubuntu/location/providers/gps/sntp_client.h> |
4543 | + |
4544 | +namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps { |
4545 | + |
4546 | +class SntpReferenceTimeSource : public android::HardwareAbstractionLayer::ReferenceTimeSource |
4547 | +{ |
4548 | +public: |
4549 | + |
4550 | + /** @brief Configuration summarizes default parameter available to implementations. */ |
4551 | + struct Configuration |
4552 | + { |
4553 | + /** @brief Reads a configuration from a gps.conf file in INI format. */ |
4554 | + static Configuration from_gps_conf_ini_file(std::istream& in); |
4555 | + |
4556 | + std::string host{"pool.ntp.org"}; /**< NTP host. */ |
4557 | + std::chrono::milliseconds timeout{5000}; /**< Timeout when querying the NTP server. */ |
4558 | + }; |
4559 | + |
4560 | + SntpReferenceTimeSource(const Configuration& configuration); |
4561 | + |
4562 | + gps::HardwareAbstractionLayer::ReferenceTimeSample sample() override; |
4563 | + |
4564 | +private: |
4565 | + const Configuration config; |
4566 | +}; |
4567 | + |
4568 | +}}}}} |
4569 | + |
4570 | +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_ |
4571 | |
4572 | === modified file 'src/location_service/com/ubuntu/location/providers/remote/provider.cpp' |
4573 | --- src/location_service/com/ubuntu/location/providers/remote/provider.cpp 2015-04-14 18:54:00 +0000 |
4574 | +++ src/location_service/com/ubuntu/location/providers/remote/provider.cpp 2016-04-01 06:55:25 +0000 |
4575 | @@ -23,6 +23,7 @@ |
4576 | #include <com/ubuntu/location/logging.h> |
4577 | |
4578 | #include <core/dbus/object.h> |
4579 | +#include <core/dbus/service_watcher.h> |
4580 | #include <core/dbus/signal.h> |
4581 | #include <core/dbus/asio/executor.h> |
4582 | |
4583 | @@ -191,6 +192,28 @@ |
4584 | auto service = dbus::Service::use_service(bus, name); |
4585 | auto object = service->object_for_path(path); |
4586 | |
4587 | + // Check if the service has come up |
4588 | + if (!bus->has_owner_for_name(name)) { |
4589 | + // If it hasn't wait for it to come up |
4590 | + bool valid = false; |
4591 | + std::mutex guard; |
4592 | + std::condition_variable cv; |
4593 | + dbus::DBus daemon(bus); |
4594 | + dbus::ServiceWatcher::Ptr service_watcher( |
4595 | + daemon.make_service_watcher(name, dbus::DBus::WatchMode::registration)); |
4596 | + |
4597 | + service_watcher->service_registered().connect([&valid, &guard, &cv]() |
4598 | + { |
4599 | + std::unique_lock<std::mutex> ul(guard); |
4600 | + valid = true; |
4601 | + cv.notify_all(); |
4602 | + }); |
4603 | + |
4604 | + std::unique_lock<std::mutex> ul(guard); |
4605 | + if (not cv.wait_for(ul, std::chrono::seconds{30}, [&valid]() { return valid; })) |
4606 | + throw std::runtime_error("Remote service failed to start"); |
4607 | + } |
4608 | + |
4609 | return create_instance_with_config(remote::stub::Configuration{object}); |
4610 | } |
4611 | |
4612 | |
4613 | === modified file 'src/location_service/com/ubuntu/location/service/daemon.cpp' |
4614 | --- src/location_service/com/ubuntu/location/service/daemon.cpp 2015-04-16 10:03:29 +0000 |
4615 | +++ src/location_service/com/ubuntu/location/service/daemon.cpp 2016-04-01 06:55:25 +0000 |
4616 | @@ -20,6 +20,9 @@ |
4617 | #include <com/ubuntu/location/boost_ptree_settings.h> |
4618 | #include <com/ubuntu/location/provider_factory.h> |
4619 | |
4620 | +#include <com/ubuntu/location/logging.h> |
4621 | +#include <com/ubuntu/location/connectivity/dummy_connectivity_manager.h> |
4622 | + |
4623 | #include <com/ubuntu/location/service/default_configuration.h> |
4624 | #include <com/ubuntu/location/service/demultiplexing_reporter.h> |
4625 | #include <com/ubuntu/location/service/ichnaea_reporter.h> |
4626 | @@ -30,6 +33,7 @@ |
4627 | |
4628 | #include "program_options.h" |
4629 | #include "daemon.h" |
4630 | +#include "runtime.h" |
4631 | |
4632 | #include <core/dbus/announcer.h> |
4633 | #include <core/dbus/resolver.h> |
4634 | @@ -37,6 +41,9 @@ |
4635 | |
4636 | #include <core/posix/signal.h> |
4637 | |
4638 | +#include <boost/asio.hpp> |
4639 | +#include <boost/filesystem.hpp> |
4640 | + |
4641 | #include <system_error> |
4642 | #include <thread> |
4643 | |
4644 | @@ -164,6 +171,20 @@ |
4645 | |
4646 | int location::service::Daemon::main(const location::service::Daemon::Configuration& config) |
4647 | { |
4648 | + // Ensure that log files dating back to before the fix |
4649 | + // for lp:1447110 are removed and do not waste space. |
4650 | + { |
4651 | + static const boost::filesystem::path old_log_dir{"/var/log/ubuntu-location-service"}; |
4652 | + boost::system::error_code ec; |
4653 | + boost::filesystem::remove_all(old_log_dir, ec); |
4654 | + } |
4655 | + // Setup logging for the daemon. |
4656 | + FLAGS_logtostderr = true; |
4657 | + FLAGS_stop_logging_if_full_disk = true; |
4658 | + FLAGS_max_log_size = 5; |
4659 | + |
4660 | + google::InitGoogleLogging("com.ubuntu.location"); |
4661 | + |
4662 | auto trap = core::posix::trap_signals_for_all_subsequent_threads( |
4663 | { |
4664 | core::posix::Signal::sig_term, |
4665 | @@ -175,116 +196,55 @@ |
4666 | trap->stop(); |
4667 | }); |
4668 | |
4669 | - const location::Configuration empty_provider_configuration; |
4670 | - |
4671 | - std::set<location::Provider::Ptr> instantiated_providers; |
4672 | - |
4673 | + auto runtime = location::service::Runtime::create(4); |
4674 | + |
4675 | + location::service::DefaultConfiguration dc; |
4676 | + auto engine = dc.the_engine(std::set<location::Provider::Ptr>{}, dc.the_provider_selection_policy(), config.settings); |
4677 | for (const std::string& provider : config.providers) |
4678 | { |
4679 | std::cout << "Instantiating and configuring: " << provider << std::endl; |
4680 | |
4681 | try |
4682 | { |
4683 | - auto p = location::ProviderFactory::instance().create_provider_for_name_with_config( |
4684 | - provider, |
4685 | - config.provider_options.count(provider) > 0 ? |
4686 | - config.provider_options.at(provider) : empty_provider_configuration); |
4687 | - |
4688 | - if (p) |
4689 | - instantiated_providers.insert(p); |
4690 | - else |
4691 | - throw std::runtime_error("Problem instantiating provider"); |
4692 | - |
4693 | + auto result = std::async(std::launch::async, [provider, config, engine] { |
4694 | + return location::ProviderFactory::instance().create_provider_for_name_with_config( |
4695 | + provider, |
4696 | + config.provider_options.count(provider) > 0 ? |
4697 | + config.provider_options.at(provider) : location::Configuration {}, |
4698 | + [engine](Provider::Ptr provider) |
4699 | + { |
4700 | + engine->add_provider(provider); |
4701 | + } |
4702 | + ); |
4703 | + }); |
4704 | } catch(const std::runtime_error& e) |
4705 | { |
4706 | std::cerr << "Issue instantiating provider: " << e.what() << std::endl; |
4707 | } |
4708 | } |
4709 | |
4710 | - config.incoming->install_executor(dbus::asio::make_executor(config.incoming)); |
4711 | - config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing)); |
4712 | + config.incoming->install_executor(dbus::asio::make_executor(config.incoming, runtime->service())); |
4713 | + config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing, runtime->service())); |
4714 | |
4715 | - location::service::DefaultConfiguration dc; |
4716 | + runtime->start(); |
4717 | |
4718 | location::service::Implementation::Configuration configuration |
4719 | { |
4720 | config.incoming, |
4721 | config.outgoing, |
4722 | - dc.the_engine(instantiated_providers, dc.the_provider_selection_policy(), config.settings), |
4723 | + engine, |
4724 | dc.the_permission_manager(config.outgoing), |
4725 | location::service::Harvester::Configuration |
4726 | { |
4727 | - location::connectivity::platform_default_manager(), |
4728 | - // We submit location/wifi/cell measurements to both |
4729 | - // Mozilla's location service and to Ubuntu's own instance. |
4730 | - std::make_shared<service::DemultiplexingReporter>( |
4731 | - std::initializer_list<service::Harvester::Reporter::Ptr> |
4732 | - { |
4733 | - std::make_shared<service::ichnaea::Reporter>( |
4734 | - service::ichnaea::Reporter::Configuration |
4735 | - { |
4736 | - "https://location.services.mozilla.com", |
4737 | - "UbuntuLocationService", |
4738 | - "UbuntuLocationService" |
4739 | - } |
4740 | - ), |
4741 | - std::make_shared<service::ichnaea::Reporter>( |
4742 | - service::ichnaea::Reporter::Configuration |
4743 | - { |
4744 | - "https://162.213.35.107", |
4745 | - "UbuntuLocationService", |
4746 | - "UbuntuLocationService" |
4747 | - } |
4748 | - ) |
4749 | - }) |
4750 | + std::make_shared<dummy::ConnectivityManager>(), |
4751 | + std::make_shared<NullReporter>() |
4752 | } |
4753 | }; |
4754 | |
4755 | auto location_service = std::make_shared<location::service::Implementation>(configuration); |
4756 | - // We need to ensure that any exception raised by the executor does not crash the app |
4757 | - // and also gets logged. |
4758 | - auto execute = [] (std::shared_ptr<core::dbus::Bus> bus) { |
4759 | - while(true) |
4760 | - { |
4761 | - try |
4762 | - { |
4763 | - VLOG(10) << "Starting a bus executor"; |
4764 | - bus->run(); |
4765 | - break; // run() exited normally |
4766 | - } |
4767 | - catch (const std::exception& e) |
4768 | - { |
4769 | - LOG(WARNING) << e.what(); |
4770 | - } |
4771 | - catch (...) |
4772 | - { |
4773 | - LOG(WARNING) << "Unexpected exception was raised by the bus executor"; |
4774 | - } |
4775 | - } |
4776 | - }; |
4777 | - |
4778 | - std::thread t1{execute, config.incoming}; |
4779 | - std::thread t2{execute, config.incoming}; |
4780 | - std::thread t3{execute, config.incoming}; |
4781 | - std::thread t4{execute, config.outgoing}; |
4782 | |
4783 | trap->run(); |
4784 | |
4785 | - config.incoming->stop(); |
4786 | - config.outgoing->stop(); |
4787 | - |
4788 | - if (t1.joinable()) |
4789 | - t1.join(); |
4790 | - |
4791 | - if (t2.joinable()) |
4792 | - t2.join(); |
4793 | - |
4794 | - if (t3.joinable()) |
4795 | - t3.join(); |
4796 | - |
4797 | - if (t4.joinable()) |
4798 | - t4.join(); |
4799 | - |
4800 | return EXIT_SUCCESS; |
4801 | } |
4802 | |
4803 | |
4804 | === modified file 'src/location_service/com/ubuntu/location/service/daemon_main.cpp' |
4805 | --- src/location_service/com/ubuntu/location/service/daemon_main.cpp 2015-01-13 16:35:20 +0000 |
4806 | +++ src/location_service/com/ubuntu/location/service/daemon_main.cpp 2016-04-01 06:55:25 +0000 |
4807 | @@ -18,41 +18,10 @@ |
4808 | |
4809 | #include "daemon.h" |
4810 | |
4811 | -#include <com/ubuntu/location/logging.h> |
4812 | - |
4813 | -#include <boost/filesystem.hpp> |
4814 | - |
4815 | namespace location = com::ubuntu::location; |
4816 | |
4817 | -namespace |
4818 | -{ |
4819 | -// The directory we put log files in. |
4820 | -constexpr const char* log_dir{"/var/log/ubuntu-location-service"}; |
4821 | -} |
4822 | - |
4823 | int main(int argc, const char** argv) |
4824 | { |
4825 | - // Setup logging for the daemon. |
4826 | - boost::system::error_code ec; |
4827 | - boost::filesystem::create_directories(boost::filesystem::path{log_dir}, ec); |
4828 | - |
4829 | - // According to http://www.boost.org/doc/libs/1_55_0/libs/filesystem/doc/reference.html#create_directories |
4830 | - // Creation failure because p resolves to an existing directory shall not be treated as an error. |
4831 | - // With that, we are free to check the error condition and adjust to stderr |
4832 | - // logging accordingly. |
4833 | - if (ec) |
4834 | - { |
4835 | - FLAGS_logtostderr = true; |
4836 | - VLOG(1) << "Problem creating directory for log files: " << ec << "." |
4837 | - << "Falling back to stderr logging."; |
4838 | - } |
4839 | - |
4840 | - FLAGS_log_dir = log_dir; |
4841 | - FLAGS_stop_logging_if_full_disk = true; |
4842 | - FLAGS_max_log_size = 5; |
4843 | - |
4844 | - google::InitGoogleLogging("com.ubuntu.location"); |
4845 | - |
4846 | location::service::Daemon::Configuration config; |
4847 | try |
4848 | { |
4849 | |
4850 | === modified file 'src/location_service/com/ubuntu/location/service/implementation.cpp' |
4851 | --- src/location_service/com/ubuntu/location/service/implementation.cpp 2014-08-13 13:08:22 +0000 |
4852 | +++ src/location_service/com/ubuntu/location/service/implementation.cpp 2016-04-01 06:55:25 +0000 |
4853 | @@ -113,10 +113,13 @@ |
4854 | { |
4855 | visible_space_vehicles() = svs; |
4856 | }), |
4857 | - configuration.engine->updates.reference_location.changed().connect( |
4858 | - [this](const cul::Update<cul::Position>& update) |
4859 | + configuration.engine->updates.last_known_location.changed().connect( |
4860 | + [this](const cul::Optional<cul::Update<cul::Position>>& update) |
4861 | { |
4862 | - harvester.report_position_update(update); |
4863 | + if (update) |
4864 | + { |
4865 | + harvester.report_position_update(update.get()); |
4866 | + } |
4867 | }) |
4868 | } |
4869 | { |
4870 | @@ -149,5 +152,23 @@ |
4871 | new ProxyProvider{provider_selection} |
4872 | }; |
4873 | |
4874 | - return session::Interface::Ptr{new culs::session::Implementation(proxy_provider)}; |
4875 | + session::Interface::Ptr session_iface{new session::Implementation(proxy_provider)}; |
4876 | + std::weak_ptr<session::Interface> session_weak{session_iface}; |
4877 | + session_iface->updates().position_status.changed().connect([this, session_weak](const session::Interface::Updates::Status& status) |
4878 | + { |
4879 | + cul::Optional<cul::Update<cul::Position>> last_known_position = configuration.engine->updates.last_known_location.get(); |
4880 | + bool has_last_known_position = last_known_position ? true : false; |
4881 | + bool is_session_enabled = status == culs::session::Interface::Updates::Status::enabled; |
4882 | + bool is_session_on_or_active = configuration.engine->configuration.engine_state != Engine::Status::off; |
4883 | + |
4884 | + if (has_last_known_position && is_session_enabled && is_session_on_or_active) |
4885 | + { |
4886 | + // Immediately send the last known position to the client |
4887 | + if (auto session_iface = session_weak.lock()) |
4888 | + { |
4889 | + session_iface->updates().position = last_known_position.get(); |
4890 | + } |
4891 | + } |
4892 | + }); |
4893 | + return session_iface; |
4894 | } |
4895 | |
4896 | === modified file 'src/location_service/com/ubuntu/location/service/provider_daemon.cpp' |
4897 | --- src/location_service/com/ubuntu/location/service/provider_daemon.cpp 2014-10-27 21:58:16 +0000 |
4898 | +++ src/location_service/com/ubuntu/location/service/provider_daemon.cpp 2016-04-01 06:55:25 +0000 |
4899 | @@ -25,6 +25,7 @@ |
4900 | |
4901 | #include <com/ubuntu/location/service/configuration.h> |
4902 | #include <com/ubuntu/location/service/program_options.h> |
4903 | +#include <com/ubuntu/location/service/runtime.h> |
4904 | |
4905 | #include <core/dbus/asio/executor.h> |
4906 | |
4907 | @@ -65,7 +66,6 @@ |
4908 | location::service::ProviderDaemon::Configuration result; |
4909 | |
4910 | result.connection = factory(mutable_daemon_options().bus()); |
4911 | - result.connection->install_executor(core::dbus::asio::make_executor(result.connection)); |
4912 | |
4913 | auto service = core::dbus::Service::add_service( |
4914 | result.connection, |
4915 | @@ -108,7 +108,15 @@ |
4916 | return result; |
4917 | } |
4918 | |
4919 | -int location::service::ProviderDaemon::main(const location::service::ProviderDaemon::Configuration& configuration) |
4920 | +namespace |
4921 | +{ |
4922 | +std::shared_ptr<location::service::Runtime> runtime() |
4923 | +{ |
4924 | + static const auto inst = location::service::Runtime::create(2); |
4925 | + return inst; |
4926 | +} |
4927 | +} |
4928 | +int location::service::ProviderDaemon::main(const location::service::ProviderDaemon::Configuration& config) |
4929 | { |
4930 | auto trap = core::posix::trap_signals_for_all_subsequent_threads( |
4931 | { |
4932 | @@ -121,27 +129,20 @@ |
4933 | trap->stop(); |
4934 | }); |
4935 | |
4936 | - std::thread worker |
4937 | - { |
4938 | - [configuration]() |
4939 | - { |
4940 | - configuration.connection->run(); |
4941 | - } |
4942 | - }; |
4943 | + config.connection->install_executor(core::dbus::asio::make_executor(config.connection, runtime()->service())); |
4944 | |
4945 | auto skeleton = location::providers::remote::skeleton::create_with_configuration(location::providers::remote::skeleton::Configuration |
4946 | { |
4947 | - configuration.object, |
4948 | - configuration.connection, |
4949 | - configuration.provider |
4950 | + config.object, |
4951 | + config.connection, |
4952 | + config.provider |
4953 | }); |
4954 | |
4955 | + runtime()->start(); |
4956 | + |
4957 | trap->run(); |
4958 | |
4959 | - configuration.connection->stop(); |
4960 | - |
4961 | - if (worker.joinable()) |
4962 | - worker.join(); |
4963 | + config.connection->stop(); |
4964 | |
4965 | return EXIT_SUCCESS; |
4966 | } |
4967 | |
4968 | === added file 'src/location_service/com/ubuntu/location/service/runtime.cpp' |
4969 | --- src/location_service/com/ubuntu/location/service/runtime.cpp 1970-01-01 00:00:00 +0000 |
4970 | +++ src/location_service/com/ubuntu/location/service/runtime.cpp 2016-04-01 06:55:25 +0000 |
4971 | @@ -0,0 +1,109 @@ |
4972 | +/* |
4973 | + * Copyright © 2015 Canonical Ltd. |
4974 | + * |
4975 | + * This program is free software: you can redistribute it and/or modify it |
4976 | + * under the terms of the GNU Lesser General Public License version 3, |
4977 | + * as published by the Free Software Foundation. |
4978 | + * |
4979 | + * This program is distributed in the hope that it will be useful, |
4980 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4981 | + * MERCHANTABILITY or FITNESS FOR A PARTIlocationAR PURPOSE. See the |
4982 | + * GNU Lesser General Public License for more details. |
4983 | + * |
4984 | + * You should have received a copy of the GNU Lesser General Public License |
4985 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4986 | + * |
4987 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4988 | + */ |
4989 | +#include <com/ubuntu/location/service/runtime.h> |
4990 | + |
4991 | +#include <com/ubuntu/location/logging.h> |
4992 | + |
4993 | +namespace culs = com::ubuntu::location::service; |
4994 | + |
4995 | +namespace |
4996 | +{ |
4997 | +// exception_safe_run runs service, catching all exceptions and |
4998 | +// restarting operation until an explicit shutdown has been requested. |
4999 | +// |
5000 | +// TODO(tvoss): Catching all exceptions is risky as they might signal unrecoverable |
LGTM