Merge lp:~thomas-voss/location-service/inject-reference-time-from-ntp-server into lp:location-service/15.04

Proposed by Thomas Voß
Status: Merged
Approved by: Thomas Voß
Approved revision: 228
Merged at revision: 218
Proposed branch: lp:~thomas-voss/location-service/inject-reference-time-from-ntp-server
Merge into: lp:location-service/15.04
Diff against target: 3625 lines (+3185/-52)
30 files modified
3rd-party/boost/core/scoped_enum.hpp (+192/-0)
3rd-party/boost/endian/arithmetic.hpp (+413/-0)
3rd-party/boost/endian/buffers.hpp (+515/-0)
3rd-party/boost/endian/conversion.hpp (+487/-0)
3rd-party/boost/endian/detail/config.hpp (+62/-0)
3rd-party/boost/endian/detail/cover_operators.hpp (+142/-0)
3rd-party/boost/endian/detail/disable_warnings.hpp (+33/-0)
3rd-party/boost/endian/detail/disable_warnings_pop.hpp (+12/-0)
3rd-party/boost/endian/detail/intrinsic.hpp (+64/-0)
3rd-party/boost/endian/detail/lightweight_test.hpp (+223/-0)
3rd-party/boost/endian/endian.hpp (+19/-0)
3rd-party/boost/endian/std_pair.hpp (+38/-0)
CMakeLists.txt (+3/-0)
src/location_service/com/ubuntu/location/CMakeLists.txt (+8/-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/-24)
src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h (+25/-5)
src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp (+30/-0)
src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h (+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/service/runtime.h (+1/-1)
src/location_service/com/ubuntu/location/service/runtime_tests.cpp (+1/-0)
src/location_service/com/ubuntu/location/time_since_boot.cpp (+140/-0)
src/location_service/com/ubuntu/location/time_since_boot.h (+35/-0)
tests/CMakeLists.txt (+1/-0)
tests/gps_provider_test.cpp (+40/-8)
tests/sntp_client_test.cpp (+104/-0)
To merge this branch: bzr merge lp:~thomas-voss/location-service/inject-reference-time-from-ntp-server
Reviewer Review Type Date Requested Status
Łukasz Zemczak 3rd-party Approve
Simon Fels Approve
Review via email: mp+284012@code.launchpad.net

Commit message

Add SntpClient for querying reference time information.

Description of the change

Add SntpClient for querying reference time information.

To post a comment you must log in.
Revision history for this message
Simon Fels (morphis) wrote :

LGTM

review: Approve
219. By Thomas Voß

Add local copy of boost::endian as vivid+o only has boost 1.55.
Add missing includes for std exceptions.

Revision history for this message
Łukasz Zemczak (sil2100) wrote :

Addition of the endian boost parts looks good. Of course in the long term I would opt for getting libboost1.58 available for the overlay (as proposed by Thomas), but this would require a lot more testing and preparation. For now this looks like a solution we could survive. As long as it compiles though!

review: Approve (3rd-party)
220. By Thomas Voß

Adjust test-case and make it more robust in-case of hitting non-stratum-1 ntp servers.

221. By Thomas Voß

EXPECT_GE really is EXPECT_LE.

222. By Thomas Voß

Relax SntpClient::succeeds_in_querying_time_from_server.

223. By Thomas Voß

Pump up number of threads in pool running location::service::Runtime.

224. By Thomas Voß

Rely on async and cancellable operations.

225. By Thomas Voß

Start up a location::service::Runtime instance during runtime tests.

226. By Thomas Voß

Ensure that the local service::Runtime instance is started.

227. By Thomas Voß

Do not call std::future<T>::get twice to get hold of an iterator over all resolved endpoints.

228. By Thomas Voß

Gracefully handle exceptions thrown from the reference time source.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory '3rd-party'
2=== added directory '3rd-party/boost'
3=== added directory '3rd-party/boost/core'
4=== added file '3rd-party/boost/core/scoped_enum.hpp'
5--- 3rd-party/boost/core/scoped_enum.hpp 1970-01-01 00:00:00 +0000
6+++ 3rd-party/boost/core/scoped_enum.hpp 2016-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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-03-08 08:03:57 +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 2015-02-03 08:38:21 +0000
2268+++ CMakeLists.txt 2016-03-08 08:03:57 +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@@ -69,6 +70,8 @@
2278 endif()
2279
2280 include_directories(
2281+ 3rd-party/
2282+
2283 ${Boost_INCLUDE_DIRS}
2284 ${DBUS_INCLUDE_DIRS}
2285 ${DBUS_CPP_INCLUDE_DIRS}
2286
2287=== modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt'
2288--- src/location_service/com/ubuntu/location/CMakeLists.txt 2015-11-26 08:28:38 +0000
2289+++ src/location_service/com/ubuntu/location/CMakeLists.txt 2016-03-08 08:03:57 +0000
2290@@ -1,3 +1,7 @@
2291+if (UBUNTU_PLATFORM_HARDWARE_API_FOUND)
2292+ add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API)
2293+endif()
2294+
2295 if (NET_CPP_FOUND)
2296 add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP=1)
2297
2298@@ -10,6 +14,8 @@
2299 service/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/service/config.h @ONLY
2300 )
2301
2302+include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS})
2303+
2304 add_library(
2305 ubuntu-location-service SHARED
2306
2307@@ -29,6 +35,7 @@
2308 settings.cpp
2309 time_based_update_policy.cpp
2310 set_name_for_thread.cpp
2311+ time_since_boot.cpp
2312 wifi_and_cell_reporting_state.cpp
2313
2314 boost_ptree_settings.cpp
2315@@ -126,6 +133,7 @@
2316 ${LIBAPPARMOR_LDFLAGS}
2317 ${NET_CPP_LDFLAGS}
2318 ${TRUST_STORE_LDFLAGS}
2319+ ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS}
2320 ${GLog_LIBRARY}
2321 ${GFlags_LIBRARY}
2322 )
2323
2324=== modified file 'src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt'
2325--- src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2014-07-28 19:14:58 +0000
2326+++ src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2016-03-08 08:03:57 +0000
2327@@ -4,30 +4,34 @@
2328 ON
2329 )
2330
2331-if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
2332- find_file(
2333- UBUNTU_HARDWARE_GPS_H gps.h
2334- NAMES ubuntu/hardware/gps.h
2335- )
2336-
2337- if (UBUNTU_HARDWARE_GPS_H)
2338+if ((LOCATION_SERVICE_ENABLE_GPS_PROVIDER) AND (UBUNTU_PLATFORM_HARDWARE_API_FOUND))
2339 message(STATUS "Enabling GPS location provider")
2340
2341+ include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS})
2342+
2343 add_library(
2344 gps
2345
2346 gps.conf
2347
2348+ hardware_abstraction_layer.cpp
2349+
2350 android_hardware_abstraction_layer.h
2351 android_hardware_abstraction_layer.cpp
2352
2353+ sntp_reference_time_source.h
2354+ sntp_reference_time_source.cpp
2355+
2356+ sntp_client.h
2357+ sntp_client.cpp
2358+
2359 hardware_abstraction_layer.h
2360 # hardware_abstraction_layer.cpp
2361
2362 provider.h
2363 provider.cpp)
2364
2365- target_link_libraries(gps ubuntu_platform_hardware_api.so)
2366+ target_link_libraries(gps ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS})
2367
2368 set(
2369 ENABLED_PROVIDER_TARGETS
2370@@ -41,5 +45,4 @@
2371 )
2372
2373 install(FILES gps.conf DESTINATION /etc/)
2374- endif (UBUNTU_HARDWARE_GPS_H)
2375-endif (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
2376+endif ()
2377
2378=== modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp'
2379--- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2015-11-13 10:19:29 +0000
2380+++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2016-03-08 08:03:57 +0000
2381@@ -17,6 +17,7 @@
2382 */
2383
2384 #include "android_hardware_abstraction_layer.h"
2385+#include "sntp_reference_time_source.h"
2386
2387 #if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP)
2388 #include "net_cpp_gps_xtra_downloader.h"
2389@@ -323,23 +324,18 @@
2390 {
2391 VLOG(1) << __PRETTY_FUNCTION__;
2392
2393- auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
2394-
2395- if (thiz->impl.utc_time_request_handler)
2396- {
2397- thiz->impl.utc_time_request_handler();
2398- } else
2399- {
2400- auto now = location::Clock::now().time_since_epoch();
2401- auto ms_since_epoch = std::chrono::duration_cast<std::chrono::milliseconds>(now);
2402-
2403- static const int zero_uncertainty = 0;
2404-
2405- u_hardware_gps_inject_time(
2406- thiz->impl.gps_handle,
2407- ms_since_epoch.count(),
2408- ms_since_epoch.count(),
2409- zero_uncertainty);
2410+ try
2411+ {
2412+ if (auto thiz = static_cast<android::HardwareAbstractionLayer*>(context))
2413+ thiz->inject_reference_time(thiz->impl.reference_time_source->sample());
2414+ }
2415+ catch (const std::runtime_error& e)
2416+ {
2417+ LOG(WARNING) << "Failed to inject reference time to chipset: " << e.what();
2418+ }
2419+ catch (...)
2420+ {
2421+ LOG(WARNING) << "Failed to inject reference time to chipset.";
2422 }
2423 }
2424
2425@@ -534,19 +530,22 @@
2426 return true;
2427 }
2428
2429-bool android::HardwareAbstractionLayer::inject_reference_time(
2430- const std::chrono::microseconds& reference_time,
2431- const std::chrono::microseconds& sample_time)
2432+bool android::HardwareAbstractionLayer::inject_reference_time(const ReferenceTimeSample& sample)
2433 {
2434 if (!is_capable_of(gps::Capability::on_demand_time_injection))
2435 return false;
2436
2437 // TODO(tvoss): We should expose the int return type of the underyling
2438 // Android HAL to capture errors here.
2439+ //
2440+ // Please see:
2441+ // http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/net/SntpClient.java#72
2442+ // for the bloody details of relating the system wall clock time to the elapsed realtime since boot
2443+ // including deep sleep.
2444 u_hardware_gps_inject_time(impl.gps_handle,
2445- reference_time.count(),
2446- sample_time.count(),
2447- 10);
2448+ sample.since_epoch.count(),
2449+ sample.since_boot.count(),
2450+ sample.uncertainty.count());
2451 return true;
2452 }
2453
2454@@ -557,6 +556,7 @@
2455 assistance_mode(gps::AssistanceMode::mobile_station_based),
2456 position_mode(gps::PositionMode::periodic),
2457 supl_assistant(*parent),
2458+ reference_time_source(configuration.reference_time_source),
2459 gps_xtra_configuration(configuration.gps_xtra.configuration),
2460 gps_xtra_downloader(configuration.gps_xtra.downloader)
2461 {
2462@@ -615,6 +615,22 @@
2463
2464 namespace
2465 {
2466+gps::SntpReferenceTimeSource::Configuration sntp_reference_time_source_configuration(std::istream& in)
2467+{
2468+ gps::SntpReferenceTimeSource::Configuration config;
2469+
2470+ try
2471+ {
2472+ config = gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(in);
2473+ }
2474+ catch (...)
2475+ {
2476+ // Consciously dropping all exceptions here.
2477+ }
2478+
2479+ return config;
2480+}
2481+
2482 android::GpsXtraDownloader::Configuration gps_xtra_downloader_configuration(std::istream& in)
2483 {
2484 android::GpsXtraDownloader::Configuration config;
2485@@ -641,6 +657,8 @@
2486
2487 return config;
2488 }
2489+
2490+
2491 }
2492
2493 std::shared_ptr<gps::HardwareAbstractionLayer> gps::HardwareAbstractionLayer::create_default_instance()
2494@@ -664,7 +682,8 @@
2495 {
2496 create_xtra_downloader(),
2497 gps_xtra_downloader_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf))
2498- }
2499+ },
2500+ std::make_shared<gps::SntpReferenceTimeSource>(sntp_reference_time_source_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf)))
2501 };
2502
2503 static std::shared_ptr<gps::HardwareAbstractionLayer> instance
2504
2505=== modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h'
2506--- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2015-11-13 10:19:29 +0000
2507+++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2016-03-08 08:03:57 +0000
2508@@ -19,6 +19,7 @@
2509 #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_ANDROID_HARDWARE_ABSTRACTION_LAYER_H_
2510
2511 #include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h>
2512+#include <com/ubuntu/location/providers/gps/sntp_client.h>
2513
2514 #include <ubuntu/hardware/gps.h>
2515
2516@@ -66,7 +67,24 @@
2517 };
2518
2519 struct HardwareAbstractionLayer : public gps::HardwareAbstractionLayer
2520-{
2521+{
2522+ /** @brief A ReferenceTimeSource provides samples of an arbitrary reference time source. */
2523+ class ReferenceTimeSource
2524+ {
2525+ public:
2526+ /** @cond */
2527+ typedef std::shared_ptr<ReferenceTimeSource> Ptr;
2528+
2529+ virtual ~ReferenceTimeSource() = default;
2530+ /** @endcond */
2531+
2532+ /** @brief sample returns a sample of the current ReferenceTimeSource. */
2533+ virtual ReferenceTimeSample sample() = 0;
2534+
2535+ protected:
2536+ ReferenceTimeSource() = default;
2537+ };
2538+
2539 /** @brief Implements gps::HardwareAbstractionLayer::SuplAssistant interface for the android gps HAL. */
2540 struct SuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant
2541 {
2542@@ -186,6 +204,8 @@
2543 std::shared_ptr<GpsXtraDownloader> downloader;
2544 GpsXtraDownloader::Configuration configuration;
2545 } gps_xtra;
2546+
2547+ ReferenceTimeSource::Ptr reference_time_source;
2548 };
2549
2550 HardwareAbstractionLayer(const Configuration& configuration);
2551@@ -227,8 +247,8 @@
2552 bool set_position_mode(gps::PositionMode mode) override;
2553
2554 bool inject_reference_position(const location::Position& position) override;
2555- bool inject_reference_time(const std::chrono::microseconds& reference_time,
2556- const std::chrono::microseconds& sample_time) override;
2557+ bool inject_reference_time(const ReferenceTimeSample& sample) override;
2558+
2559 struct Impl
2560 {
2561 // Bootstraps access to the GPS chipset, wiring up all callbacks.
2562@@ -252,8 +272,8 @@
2563 // An implementation of the gps::HardwareAbstractionLayer::SuplAssistant interface.
2564 SuplAssistant supl_assistant;
2565
2566- // Callback for handling utc time requests.
2567- gps::HardwareAbstractionLayer::UtcTimeRequestHandler utc_time_request_handler;
2568+ // An implementation of ReferenceTimeSource.
2569+ ReferenceTimeSource::Ptr reference_time_source;
2570
2571 // Emitted whenever the set of visible space vehicles changes.
2572 core::Signal<std::set<location::SpaceVehicle>> space_vehicle_updates;
2573
2574=== added file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp'
2575--- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 1970-01-01 00:00:00 +0000
2576+++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 2016-03-08 08:03:57 +0000
2577@@ -0,0 +1,30 @@
2578+/*
2579+ * Copyright © 2012-2013 Canonical Ltd.
2580+ *
2581+ * This program is free software: you can redistribute it and/or modify it
2582+ * under the terms of the GNU Lesser General Public License version 3,
2583+ * as published by the Free Software Foundation.
2584+ *
2585+ * This program is distributed in the hope that it will be useful,
2586+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2587+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2588+ * GNU Lesser General Public License for more details.
2589+ *
2590+ * You should have received a copy of the GNU Lesser General Public License
2591+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2592+ *
2593+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2594+ */
2595+
2596+#include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h>
2597+
2598+#include <iostream>
2599+
2600+namespace gps = com::ubuntu::location::providers::gps;
2601+
2602+std::ostream& gps::operator<<(std::ostream& out, const gps::HardwareAbstractionLayer::ReferenceTimeSample& sample)
2603+{
2604+ return out << "[since epoch: " << sample.since_epoch.count() << " [ms], since boot: "
2605+ << sample.since_boot.count() << " [ms], uncertainty: "
2606+ << sample.uncertainty.count() << " [ms]";
2607+}
2608
2609=== modified file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h'
2610--- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2014-06-06 17:52:59 +0000
2611+++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2016-03-08 08:03:57 +0000
2612@@ -18,6 +18,7 @@
2613 #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_
2614 #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_
2615
2616+#include <com/ubuntu/location/clock.h>
2617 #include <com/ubuntu/location/heading.h>
2618 #include <com/ubuntu/location/position.h>
2619 #include <com/ubuntu/location/space_vehicle.h>
2620@@ -104,6 +105,13 @@
2621 class HardwareAbstractionLayer
2622 {
2623 public:
2624+ /** @brief ReferenceTimeSample bundles together the local reference. */
2625+ struct ReferenceTimeSample
2626+ {
2627+ std::chrono::milliseconds since_epoch; /**< Reference wall-clock time since the epoch (UTC). */
2628+ std::chrono::milliseconds since_boot; /**< Reference time since boot. */
2629+ std::chrono::milliseconds uncertainty; /**< Uncertainty estimate of the sample. */
2630+ };
2631
2632 class SuplAssistant
2633 {
2634@@ -304,16 +312,17 @@
2635
2636 /**
2637 * @brief Injects a new reference time to the underlying gps driver/chipset.
2638- * @param reference_time The new reference time.
2639- * @param sample_time When the reference time was sampled.
2640+ * @param sample The reference time sample
2641 * @return true iff the injection was successful, false otherwise.
2642 */
2643- virtual bool inject_reference_time(const std::chrono::microseconds& reference_time,
2644- const std::chrono::microseconds& sample_time) = 0;
2645+ virtual bool inject_reference_time(const ReferenceTimeSample& sample) = 0;
2646
2647 protected:
2648 HardwareAbstractionLayer() = default;
2649 };
2650+
2651+/** @brief operator<< inserts sample into out. */
2652+std::ostream& operator<<(std::ostream& out, const HardwareAbstractionLayer::ReferenceTimeSample& sample);
2653 }
2654 }
2655 }
2656
2657=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp'
2658--- src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 1970-01-01 00:00:00 +0000
2659+++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 2016-03-08 08:03:57 +0000
2660@@ -0,0 +1,210 @@
2661+/*
2662+ * Copyright © 2012-2013 Canonical Ltd.
2663+ *
2664+ * This program is free software: you can redistribute it and/or modify it
2665+ * under the terms of the GNU Lesser General Public License version 3,
2666+ * as published by the Free Software Foundation.
2667+ *
2668+ * This program is distributed in the hope that it will be useful,
2669+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2670+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2671+ * GNU Lesser General Public License for more details.
2672+ *
2673+ * You should have received a copy of the GNU Lesser General Public License
2674+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2675+ *
2676+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2677+ */
2678+
2679+#include <com/ubuntu/location/providers/gps/sntp_client.h>
2680+
2681+#include <com/ubuntu/location/time_since_boot.h>
2682+
2683+#include <boost/asio/ip/udp.hpp>
2684+#include <boost/endian/buffers.hpp>
2685+
2686+#include <bitset>
2687+#include <fstream>
2688+#include <future>
2689+#include <iostream>
2690+#include <thread>
2691+
2692+namespace location = com::ubuntu::location;
2693+namespace gps = location::providers::gps;
2694+namespace ip = boost::asio::ip;
2695+
2696+namespace
2697+{
2698+
2699+template<typename T>
2700+T sync_or_throw(std::future<T>& f)
2701+{
2702+ return f.get();
2703+}
2704+
2705+template<>
2706+void sync_or_throw<>(std::future<void>& f)
2707+{
2708+ f.get();
2709+}
2710+
2711+struct Now
2712+{
2713+ std::chrono::nanoseconds time = std::chrono::duration_cast<std::chrono::milliseconds>(
2714+ std::chrono::system_clock::now().time_since_epoch());
2715+ std::chrono::nanoseconds ticks = location::time_since_boot();
2716+};
2717+}
2718+
2719+const std::chrono::seconds& gps::sntp::offset_1900_to_1970()
2720+{
2721+ static const std::uint64_t secs = ((365ull * 70ull) + 17ull) * 24ull * 60ull * 60ull;
2722+ static const std::chrono::seconds seconds{secs};
2723+ return seconds;
2724+}
2725+
2726+gps::sntp::LeapIndicator gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator() const
2727+{
2728+ return static_cast<LeapIndicator>((livm.value() >> 6) & 0x3);
2729+}
2730+
2731+gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator(LeapIndicator li)
2732+{
2733+ livm = livm.value() | (static_cast<uint8_t>(li) << 6);
2734+ return *this;
2735+}
2736+
2737+std::uint8_t gps::sntp::Packet::LeapIndicatorVersionMode::version() const
2738+{
2739+ return (livm.value() >> 3) & 0x7;
2740+}
2741+
2742+gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::version(std::uint8_t version)
2743+{
2744+ livm = livm.value() | (version << 3);
2745+ return *this;
2746+}
2747+
2748+gps::sntp::Mode gps::sntp::Packet::LeapIndicatorVersionMode::mode() const
2749+{
2750+ return static_cast<Mode>(livm.value() & 0x7);
2751+}
2752+
2753+gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::mode(Mode m)
2754+{
2755+ livm = static_cast<uint8_t>(m) | livm.value();
2756+ return *this;
2757+}
2758+
2759+gps::sntp::Client::Response gps::sntp::Client::request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios)
2760+{
2761+ ip::udp::resolver resolver{ios};
2762+ ip::udp::socket socket{ios};
2763+ bool timed_out{false};
2764+
2765+ std::promise<ip::udp::resolver::iterator> promise_resolve;
2766+ auto future_resolve= promise_resolve.get_future();
2767+
2768+ boost::asio::deadline_timer timer{ios};
2769+ timer.expires_from_now(boost::posix_time::milliseconds{timeout.count()});
2770+ timer.async_wait([&timed_out, &resolver, &socket](const boost::system::error_code& ec)
2771+ {
2772+ if (ec)
2773+ return;
2774+
2775+ timed_out = true;
2776+
2777+ resolver.cancel();
2778+ socket.shutdown(ip::udp::socket::shutdown_both);
2779+ socket.close();
2780+ });
2781+
2782+ ip::udp::resolver::query query{ip::udp::v4(), host, "ntp"};
2783+
2784+ resolver.async_resolve(query, [&promise_resolve](const boost::system::error_code& ec, ip::udp::resolver::iterator it)
2785+ {
2786+ if (ec)
2787+ promise_resolve.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
2788+ else
2789+ promise_resolve.set_value(it);
2790+ });
2791+
2792+ auto it = sync_or_throw(future_resolve);
2793+
2794+ std::promise<void> promise_connect;
2795+ auto future_connect = promise_connect.get_future();
2796+
2797+ socket.async_connect(*it, [&promise_connect](const boost::system::error_code& ec)
2798+ {
2799+ if (ec)
2800+ promise_connect.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
2801+ else
2802+ promise_connect.set_value();
2803+ });
2804+
2805+ sync_or_throw(future_connect);
2806+
2807+ sntp::Packet packet;
2808+
2809+ Now before;
2810+ {
2811+ packet = request(socket);
2812+ timer.cancel();
2813+
2814+ if (timed_out)
2815+ throw std::runtime_error("Operation timed out.");
2816+ }
2817+ Now after;
2818+
2819+ auto originate = packet.originate.to_milliseconds_since_epoch();
2820+ auto receive = packet.receive.to_milliseconds_since_epoch();
2821+ auto transmit = packet.transmit.to_milliseconds_since_epoch();
2822+
2823+ auto rtt = after.ticks - before.ticks - (transmit - receive);
2824+ auto offset = ((receive - originate) + (transmit - after.time))/2;
2825+
2826+ return
2827+ {
2828+ packet,
2829+ std::chrono::duration_cast<std::chrono::milliseconds>(after.time + offset),
2830+ std::chrono::duration_cast<std::chrono::milliseconds>(after.ticks),
2831+ std::chrono::duration_cast<std::chrono::milliseconds>(rtt)
2832+ };
2833+}
2834+
2835+gps::sntp::Packet gps::sntp::Client::request(boost::asio::ip::udp::socket& socket)
2836+{
2837+ sntp::Packet packet;
2838+ packet.transmit.from_milliseconds_since_epoch(
2839+ std::chrono::duration_cast<std::chrono::milliseconds>(
2840+ std::chrono::system_clock::now().time_since_epoch()));
2841+ packet.livm.mode(sntp::Mode::client).version(sntp::version);
2842+
2843+ std::promise<std::size_t> promise_send;
2844+ auto future_send = promise_send.get_future();
2845+
2846+ socket.async_send(boost::asio::buffer(&packet, sizeof(packet)), [&promise_send](const boost::system::error_code& ec, std::size_t transferred)
2847+ {
2848+ if (ec)
2849+ promise_send.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
2850+ else
2851+ promise_send.set_value(transferred);
2852+ });
2853+
2854+ sync_or_throw(future_send);
2855+
2856+ std::promise<std::size_t> promise_receive;
2857+ auto future_receive = promise_receive.get_future();
2858+
2859+ socket.async_receive(boost::asio::buffer(&packet, sizeof(packet)), [&promise_receive](const boost::system::error_code& ec, std::size_t transferred)
2860+ {
2861+ if (ec)
2862+ promise_receive.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
2863+ else
2864+ promise_receive.set_value(transferred);
2865+ });
2866+
2867+ sync_or_throw(future_receive);
2868+
2869+ return packet;
2870+}
2871
2872=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.h'
2873--- src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 1970-01-01 00:00:00 +0000
2874+++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 2016-03-08 08:03:57 +0000
2875@@ -0,0 +1,210 @@
2876+/*
2877+ * Copyright © 2012-2013 Canonical Ltd.
2878+ *
2879+ * This program is free software: you can redistribute it and/or modify it
2880+ * under the terms of the GNU Lesser General Public License version 3,
2881+ * as published by the Free Software Foundation.
2882+ *
2883+ * This program is distributed in the hope that it will be useful,
2884+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2885+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2886+ * GNU Lesser General Public License for more details.
2887+ *
2888+ * You should have received a copy of the GNU Lesser General Public License
2889+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2890+ *
2891+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2892+ */
2893+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_
2894+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_
2895+
2896+#include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h>
2897+
2898+#include <boost/asio.hpp>
2899+#include <boost/endian/buffers.hpp>
2900+
2901+#include <chrono>
2902+#include <string>
2903+
2904+namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps { namespace sntp {
2905+// Please see https://tools.ietf.org/html/rfc4330 for a discussion of sntp
2906+// and for a detailed explanation of the different types and algorithms.
2907+
2908+namespace detail
2909+{
2910+// enum_constant returns a compile-time constant assembled from 4 or at least
2911+// 3 individual characters.
2912+template<std::uint8_t a, std::uint8_t b, std::uint8_t c, std::uint8_t d = 0>
2913+constexpr uint32_t enum_constant()
2914+{
2915+ return (a << 24) | (b << 16) | (c << 8) | d;
2916+}
2917+}
2918+
2919+// offset_1900_to_1970 returns the number of seconds that elapsed between 1900 and 1970.
2920+const std::chrono::seconds& offset_1900_to_1970();
2921+
2922+// LeapIndicator enumerates warnings of an impending
2923+// leap second to be inserted/deleted in the last minute of the current
2924+// day.
2925+enum class LeapIndicator : std::uint8_t
2926+{
2927+ no_warning = 0,
2928+ last_minute_has_61_seconds = 1,
2929+ last_minute_has_59_seconds = 2,
2930+ alarm = 3
2931+};
2932+
2933+// Mode enumerates the different protocol modes.
2934+enum class Mode : std::uint8_t
2935+{
2936+ reserved = 0,
2937+ symmetric_active = 1,
2938+ symmetric_passive = 2,
2939+ client = 3,
2940+ server = 4,
2941+ broadcast = 5,
2942+ reserved_for_control = 6,
2943+ reserved_for_private_use = 7
2944+};
2945+
2946+// ReferenceIdentifier enumerates known references for NTP-servers
2947+// on stratum 0 or 1.
2948+enum class ReferenceIdentifier : std::uint32_t
2949+{
2950+ locl = detail::enum_constant<'L','O','C','L'>(), // uncalibrated local clock
2951+ cesm = detail::enum_constant<'C','E','S','M'>(), // calibrated Cesium clock
2952+ rbdm = detail::enum_constant<'R','B','D','M'>(), // calibrated Rubidium clock
2953+ pps = detail::enum_constant<'P','P','S'>(), // calibrated quartz clock or other pulse-per-second source
2954+ irig = detail::enum_constant<'I','R','I','G'>(), // Inter-Range Instrumentation Group
2955+ acts = detail::enum_constant<'A','C','T','S'>(), // NIST telephone modem service
2956+ usno = detail::enum_constant<'U','S','N','O'>(), // USNO telephone modem service
2957+ ptb = detail::enum_constant<'P','T','B'>(), // PTB (Germany) telephone modem service
2958+ tdf = detail::enum_constant<'T','D','F'>(), // Allouis (France) Radio 164 kHz
2959+ dcf = detail::enum_constant<'D','C','F'>(), // Mainflingen (Germany) Radio 77.5 kHz
2960+ msf = detail::enum_constant<'M','S', 'F'>(), // Rugby (UK) Radio 60 kHz
2961+ wwv = detail::enum_constant<'W','W','V'>(), // Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz
2962+ wwvb = detail::enum_constant<'W','W','V','B'>(), // Boulder (US) Radio 60 kHz
2963+ wwvh = detail::enum_constant<'W','W','V','H'>(), // Kauai Hawaii (US) Radio 2.5, 5, 10, 15 MHz
2964+ chu = detail::enum_constant<'C','H','U'>(), // Ottawa (Canada) Radio 3330, 7335, 14670 kHz
2965+ lorc = detail::enum_constant<'L','O','R','C'>(), // LORAN-C radionavigation system
2966+ omeg = detail::enum_constant<'O','M','E','G'>(), // OMEGA radionavigation system
2967+ gps = detail::enum_constant<'G','P','S'>() // Global Positioning Service
2968+};
2969+
2970+// Timestamp models a fixed-point NTP timestamp relative to 01.01.1900
2971+template<typename Seconds, typename FractionalSeconds = Seconds>
2972+struct Timestamp
2973+{
2974+ // To stay on the safe side, we only allow for the types specified below.
2975+ // With that, we make sure that we only ever use endian-save types.
2976+ static_assert(std::is_same<Seconds, boost::endian::big_int16_buf_t>::value ||
2977+ std::is_same<Seconds, boost::endian::big_uint16_buf_t>::value ||
2978+ std::is_same<Seconds, boost::endian::big_int32_buf_t>::value ||
2979+ std::is_same<Seconds, boost::endian::big_uint32_buf_t>::value,
2980+ "Timestamp<> only supports boost::endian::big_{{u}int{16,32}}_buf_t");
2981+
2982+ // from_milliseconds_since_epoch fills in seconds/fractional_seconds from
2983+ // ms, converting to NTP's reference time.
2984+ void from_milliseconds_since_epoch(const std::chrono::milliseconds& ts)
2985+ {
2986+ using s = std::chrono::seconds;
2987+ using ms = std::chrono::milliseconds;
2988+
2989+ auto secs = std::chrono::duration_cast<s>(ts);
2990+ auto msecs = std::chrono::duration_cast<ms>(ts - secs);
2991+
2992+ secs += offset_1900_to_1970();
2993+
2994+ seconds = secs.count();
2995+ fractional_seconds = msecs.count() * std::numeric_limits<typename FractionalSeconds::value_type>::max() + 1 / 1000;
2996+ }
2997+
2998+ // to_milliseconds_since_epoch returns a unix timestamp calculated from
2999+ // an NTP-timestamp.
3000+ std::chrono::milliseconds to_milliseconds_since_epoch() const
3001+ {
3002+ return std::chrono::seconds{seconds.value()} - offset_1900_to_1970() +
3003+ std::chrono::milliseconds{(fractional_seconds.value() * 1000) / std::numeric_limits<typename FractionalSeconds::value_type>::max()};
3004+ }
3005+
3006+ Seconds seconds;
3007+ FractionalSeconds fractional_seconds;
3008+};
3009+
3010+// Duration is just an alias to an sntp::Timestamp.
3011+template<typename T, typename U>
3012+using Duration = Timestamp<T, U>;
3013+
3014+// Packet models the SNTP wire format.
3015+struct Packet
3016+{
3017+ // LeapIndicatorVersionMode helps in handling the bitfield setup
3018+ // for the first byte of an sntp::Packet in a portable and endianess-safe way.
3019+ struct LeapIndicatorVersionMode
3020+ {
3021+ // leap_indicator extracts the LeapIndicator from the underlying data.
3022+ LeapIndicator leap_indicator() const;
3023+ // leap_indicator sets the value of the leap_indicatorin in the underyling
3024+ // data to li.
3025+ LeapIndicatorVersionMode& leap_indicator(LeapIndicator li);
3026+
3027+ // version extracts the version from the underlying data.
3028+ std::uint8_t version() const;
3029+ // version adjusts the version to version in the underlying data.
3030+ LeapIndicatorVersionMode& version(std::uint8_t version);
3031+
3032+ // mode extracts the mode from the underlying data.
3033+ Mode mode() const;
3034+ // mode adjusts the mode to m in the underlying data.
3035+ LeapIndicatorVersionMode& mode(Mode m);
3036+
3037+ boost::endian::big_uint8_buf_t livm;
3038+ };
3039+
3040+ LeapIndicatorVersionMode livm;
3041+ boost::endian::big_uint8_buf_t stratum;
3042+ boost::endian::big_uint8_buf_t poll_interval;
3043+ boost::endian::big_int8_buf_t precision;
3044+ Duration<boost::endian::big_int16_buf_t, boost::endian::big_uint16_buf_t> root_delay;
3045+ Duration<boost::endian::big_uint16_buf_t, boost::endian::big_uint16_buf_t> root_dispersion;
3046+ boost::endian::big_uint32_buf_t reference_identifier;
3047+ Timestamp<boost::endian::big_uint32_buf_t> reference;
3048+ Timestamp<boost::endian::big_uint32_buf_t> originate;
3049+ Timestamp<boost::endian::big_uint32_buf_t> receive;
3050+ Timestamp<boost::endian::big_uint32_buf_t> transmit;
3051+};
3052+// The SNTP version we are working with.
3053+static constexpr const std::uint8_t version = 3;
3054+
3055+// SntpClient provides access to querying time from an NTP server in
3056+// a unicast scenario.
3057+class Client
3058+{
3059+public:
3060+ // Response is returned in a request for time information.
3061+ struct Response
3062+ {
3063+ // The raw packet that was returned from the request.
3064+ sntp::Packet packet;
3065+ // Time computed from the NTP transaction.
3066+ std::chrono::milliseconds ntp_time;
3067+ // Reference clock value corresponding to the NTP time.
3068+ std::chrono::milliseconds ntp_time_reference;
3069+ // Round-trip time of the last NTP transaction.
3070+ std::chrono::milliseconds round_trip_time;
3071+ };
3072+
3073+ // request_time_with_timeout reaches out to the SNTP server known under host,
3074+ // and tries to determine the current UTC reference time. The operation aborts after
3075+ // timeout milliseconds.
3076+ //
3077+ // std::runtime_error is thrown in case of issues.
3078+ Response request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios);
3079+ sntp::Packet request(boost::asio::ip::udp::socket& socket);
3080+};
3081+}
3082+}
3083+
3084+}}}}
3085+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_
3086
3087=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp'
3088--- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 1970-01-01 00:00:00 +0000
3089+++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 2016-03-08 08:03:57 +0000
3090@@ -0,0 +1,57 @@
3091+/*
3092+ * Copyright © 2012-2013 Canonical Ltd.
3093+ *
3094+ * This program is free software: you can redistribute it and/or modify it
3095+ * under the terms of the GNU Lesser General Public License version 3,
3096+ * as published by the Free Software Foundation.
3097+ *
3098+ * This program is distributed in the hope that it will be useful,
3099+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3100+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3101+ * GNU Lesser General Public License for more details.
3102+ *
3103+ * You should have received a copy of the GNU Lesser General Public License
3104+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3105+ *
3106+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3107+ */
3108+
3109+#include <com/ubuntu/location/providers/gps/sntp_reference_time_source.h>
3110+
3111+#include <com/ubuntu/location/configuration.h>
3112+#include <com/ubuntu/location/service/runtime.h>
3113+
3114+#include <boost/property_tree/ini_parser.hpp>
3115+
3116+#include <future>
3117+
3118+namespace location = com::ubuntu::location;
3119+namespace gps = com::ubuntu::location::providers::gps;
3120+
3121+gps::SntpReferenceTimeSource::Configuration gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(std::istream& in)
3122+{
3123+ gps::SntpReferenceTimeSource::Configuration result;
3124+
3125+ location::Configuration config;
3126+ boost::property_tree::read_ini(in, config);
3127+
3128+ if (config.count("NTP_SERVER") > 0)
3129+ result.host = config.get<std::string>("NTP_SERVER");
3130+
3131+ return result;
3132+}
3133+gps::SntpReferenceTimeSource::SntpReferenceTimeSource(const Configuration& config)
3134+ : config(config)
3135+{
3136+}
3137+
3138+gps::HardwareAbstractionLayer::ReferenceTimeSample gps::SntpReferenceTimeSource::sample()
3139+{
3140+ auto rt = location::service::Runtime::create();
3141+ rt->start();
3142+
3143+ location::providers::gps::sntp::Client sntp_client;
3144+ auto result = sntp_client.request_time(config.host, config.timeout, rt->service());
3145+
3146+ return {result.ntp_time, result.ntp_time_reference, result.round_trip_time};
3147+}
3148
3149=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h'
3150--- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 1970-01-01 00:00:00 +0000
3151+++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 2016-03-08 08:03:57 +0000
3152@@ -0,0 +1,51 @@
3153+/*
3154+ * Copyright © 2016 Canonical Ltd.
3155+ *
3156+ * This program is free software: you can redistribute it and/or modify it
3157+ * under the terms of the GNU Lesser General Public License version 3,
3158+ * as published by the Free Software Foundation.
3159+ *
3160+ * This program is distributed in the hope that it will be useful,
3161+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3162+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3163+ * GNU Lesser General Public License for more details.
3164+ *
3165+ * You should have received a copy of the GNU Lesser General Public License
3166+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3167+ *
3168+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3169+ */
3170+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_
3171+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_
3172+
3173+#include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h>
3174+
3175+#include <com/ubuntu/location/providers/gps/sntp_client.h>
3176+
3177+namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps {
3178+
3179+class SntpReferenceTimeSource : public android::HardwareAbstractionLayer::ReferenceTimeSource
3180+{
3181+public:
3182+
3183+ /** @brief Configuration summarizes default parameter available to implementations. */
3184+ struct Configuration
3185+ {
3186+ /** @brief Reads a configuration from a gps.conf file in INI format. */
3187+ static Configuration from_gps_conf_ini_file(std::istream& in);
3188+
3189+ std::string host{"pool.ntp.org"}; /**< NTP host. */
3190+ std::chrono::milliseconds timeout{5000}; /**< Timeout when querying the NTP server. */
3191+ };
3192+
3193+ SntpReferenceTimeSource(const Configuration& configuration);
3194+
3195+ gps::HardwareAbstractionLayer::ReferenceTimeSample sample() override;
3196+
3197+private:
3198+ const Configuration config;
3199+};
3200+
3201+}}}}}
3202+
3203+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_
3204
3205=== modified file 'src/location_service/com/ubuntu/location/service/runtime.h'
3206--- src/location_service/com/ubuntu/location/service/runtime.h 2015-11-25 09:20:12 +0000
3207+++ src/location_service/com/ubuntu/location/service/runtime.h 2016-03-08 08:03:57 +0000
3208@@ -42,7 +42,7 @@
3209 {
3210 public:
3211 // Our default concurrency setup.
3212- static constexpr const std::uint32_t worker_threads = 2;
3213+ static constexpr const std::uint32_t worker_threads = 4;
3214
3215 // create returns a Runtime instance with pool_size worker threads
3216 // executing the underlying service.
3217
3218=== modified file 'src/location_service/com/ubuntu/location/service/runtime_tests.cpp'
3219--- src/location_service/com/ubuntu/location/service/runtime_tests.cpp 2015-01-26 20:15:05 +0000
3220+++ src/location_service/com/ubuntu/location/service/runtime_tests.cpp 2016-03-08 08:03:57 +0000
3221@@ -16,6 +16,7 @@
3222 * Authored by: Thomas Voß <thomas.voss@canonical.com>
3223 */
3224
3225+#include <com/ubuntu/location/service/runtime.h>
3226 #include <com/ubuntu/location/service/runtime_tests.h>
3227
3228 #include <com/ubuntu/location/clock.h>
3229
3230=== added file 'src/location_service/com/ubuntu/location/time_since_boot.cpp'
3231--- src/location_service/com/ubuntu/location/time_since_boot.cpp 1970-01-01 00:00:00 +0000
3232+++ src/location_service/com/ubuntu/location/time_since_boot.cpp 2016-03-08 08:03:57 +0000
3233@@ -0,0 +1,140 @@
3234+/*
3235+ * Copyright © 2016 Canonical Ltd.
3236+ *
3237+ * This program is free software: you can redistribute it and/or modify it
3238+ * under the terms of the GNU Lesser General Public License version 3,
3239+ * as published by the Free Software Foundation.
3240+ *
3241+ * This program is distributed in the hope that it will be useful,
3242+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3243+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3244+ * GNU Lesser General Public License for more details.
3245+ *
3246+ * You should have received a copy of the GNU Lesser General Public License
3247+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3248+ *
3249+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3250+ */
3251+
3252+#include <com/ubuntu/location/time_since_boot.h>
3253+#include <com/ubuntu/location/logging.h>
3254+
3255+#if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API)
3256+#include <ubuntu/hardware/alarm.h>
3257+#endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API
3258+
3259+#include <fstream>
3260+#include <sstream>
3261+#include <stdexcept>
3262+#include <system_error>
3263+
3264+namespace location = com::ubuntu::location;
3265+
3266+namespace
3267+{
3268+bool have_ubuntu_hardware_alarm()
3269+{
3270+#if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API)
3271+ return true;
3272+#else
3273+ return false;
3274+#endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API
3275+}
3276+
3277+std::chrono::nanoseconds from_ubuntu_hardware_alarm()
3278+{
3279+#if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API)
3280+ struct Scope
3281+ {
3282+ Scope() : alarm{u_hardware_alarm_create()}
3283+ {
3284+ }
3285+
3286+ ~Scope()
3287+ {
3288+ u_hardware_alarm_unref(alarm);
3289+ }
3290+
3291+ UHardwareAlarm alarm{nullptr};
3292+ };
3293+
3294+ static Scope scope;
3295+
3296+ ::timespec ts;
3297+ if (not scope.alarm)
3298+ throw std::runtime_error{"Failed to access UHardwareAlarm subsystem."};
3299+
3300+ if (U_STATUS_SUCCESS != u_hardware_alarm_get_elapsed_real_time(scope.alarm, &ts))
3301+ throw std::runtime_error{"Failed to query time since boot from UHardwareAlarm."};
3302+
3303+ return std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec};
3304+#else
3305+ throw std::logic_error{"not implemented"};
3306+#endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API
3307+}
3308+
3309+
3310+std::chrono::nanoseconds from_clock_boottime()
3311+{
3312+ ::timespec ts;
3313+ if (-1 == clock_gettime(CLOCK_BOOTTIME, &ts))
3314+ throw std::system_error(errno, std::system_category());
3315+
3316+ return std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec};
3317+}
3318+
3319+std::chrono::nanoseconds boot_time()
3320+{
3321+ std::ifstream in{"/proc/stat"};
3322+ std::string line;
3323+
3324+ while (std::getline(in, line))
3325+ {
3326+ if (line.empty())
3327+ continue;
3328+
3329+ std::stringstream ss{line};
3330+ std::string name; ss >> name;
3331+
3332+ if (name != "btime")
3333+ continue;
3334+
3335+ std::uint64_t ts; ss >> ts;
3336+ return std::chrono::nanoseconds{std::chrono::seconds{ts}};
3337+ }
3338+
3339+ throw std::runtime_error{"Failed to determine system boot time."};
3340+}
3341+
3342+std::chrono::nanoseconds from_proc_stat()
3343+{
3344+ static const std::chrono::nanoseconds bt{boot_time()};
3345+ return std::chrono::system_clock::now().time_since_epoch() - bt;
3346+}
3347+}
3348+
3349+std::chrono::nanoseconds location::time_since_boot()
3350+{
3351+ if (have_ubuntu_hardware_alarm())
3352+ {
3353+ try
3354+ {
3355+ return from_ubuntu_hardware_alarm();
3356+ }
3357+ catch (const std::exception& e)
3358+ {
3359+ VLOG(1) << e.what();
3360+ }
3361+ }
3362+
3363+ try
3364+ {
3365+ return from_clock_boottime();
3366+ }
3367+ catch (const std::exception& e)
3368+ {
3369+ VLOG(1) << e.what();
3370+ }
3371+
3372+ return from_proc_stat();
3373+}
3374
3375=== added file 'src/location_service/com/ubuntu/location/time_since_boot.h'
3376--- src/location_service/com/ubuntu/location/time_since_boot.h 1970-01-01 00:00:00 +0000
3377+++ src/location_service/com/ubuntu/location/time_since_boot.h 2016-03-08 08:03:57 +0000
3378@@ -0,0 +1,35 @@
3379+/*
3380+ * Copyright © 2016 Canonical Ltd.
3381+ *
3382+ * This program is free software: you can redistribute it and/or modify it
3383+ * under the terms of the GNU Lesser General Public License version 3,
3384+ * as published by the Free Software Foundation.
3385+ *
3386+ * This program is distributed in the hope that it will be useful,
3387+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3388+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3389+ * GNU Lesser General Public License for more details.
3390+ *
3391+ * You should have received a copy of the GNU Lesser General Public License
3392+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3393+ *
3394+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3395+ */
3396+#ifndef LOCATION_SERVICE_UBUNTU_LOCATION_SERVICE_TIME_SINCE_BOOT_H_
3397+#define LOCATION_SERVICE_UBUNTU_LOCATION_SERVICE_TIME_SINCE_BOOT_H_
3398+
3399+#include <chrono>
3400+
3401+namespace com
3402+{
3403+namespace ubuntu
3404+{
3405+namespace location
3406+{
3407+/** @brief time_since_boot returns the nanoseconds that elapsed since boot. */
3408+std::chrono::nanoseconds time_since_boot();
3409+}
3410+}
3411+}
3412+
3413+#endif // LOCATION_SERVICE_UBUNTU_LOCATION_SERVICE_TIME_SINCE_BOOT_H_
3414
3415=== modified file 'tests/CMakeLists.txt'
3416--- tests/CMakeLists.txt 2015-12-01 14:36:55 +0000
3417+++ tests/CMakeLists.txt 2016-03-08 08:03:57 +0000
3418@@ -98,6 +98,7 @@
3419 if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
3420 include_directories(${CMAKE_SOURCE_DIR}/src/location_service)
3421 LOCATION_SERVICE_ADD_TEST(gps_provider_test gps_provider_test.cpp)
3422+ LOCATION_SERVICE_ADD_TEST(sntp_client_test sntp_client_test.cpp)
3423 endif(LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
3424
3425 if (LOCATION_SERVICE_ENABLE_GEOCLUE_PROVIDERS)
3426
3427=== modified file 'tests/gps_provider_test.cpp'
3428--- tests/gps_provider_test.cpp 2015-10-19 13:04:06 +0000
3429+++ tests/gps_provider_test.cpp 2016-03-08 08:03:57 +0000
3430@@ -81,6 +81,11 @@
3431 MOCK_METHOD1(on_space_vehicles_updated, void(const std::set<location::SpaceVehicle>&));
3432 };
3433
3434+struct MockReferenceTimeSource : public gps::android::HardwareAbstractionLayer::ReferenceTimeSource
3435+{
3436+ MOCK_METHOD0(sample, gps::HardwareAbstractionLayer::ReferenceTimeSample());
3437+};
3438+
3439 struct MockSuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant
3440 {
3441 MockSuplAssistant()
3442@@ -133,9 +138,7 @@
3443 MOCK_METHOD1(set_assistance_mode, bool(gps::AssistanceMode));
3444 MOCK_METHOD1(set_position_mode, bool(gps::PositionMode));
3445 MOCK_METHOD1(inject_reference_position, bool(const location::Position&));
3446- MOCK_METHOD2(inject_reference_time,
3447- bool(const std::chrono::microseconds&,
3448- const std::chrono::microseconds&));
3449+ MOCK_METHOD1(inject_reference_time, bool(const location::providers::gps::HardwareAbstractionLayer::ReferenceTimeSample&));
3450
3451 MockSuplAssistant supl_assistant_;
3452 core::Signal<location::Position> position_updates_;
3453@@ -322,24 +325,54 @@
3454 provider.on_reference_location_updated(pos);
3455 }
3456
3457+TEST(GpsProvider, time_requests_query_reference_time_source)
3458+{
3459+ using namespace ::testing;
3460+
3461+ NiceMock<MockHardwareGps> hardwareGps;
3462+
3463+ auto mock_reference_time_source = std::make_shared<MockReferenceTimeSource>();
3464+ EXPECT_CALL(*mock_reference_time_source, sample())
3465+ .Times(1)
3466+ .WillRepeatedly(Return(gps::HardwareAbstractionLayer::ReferenceTimeSample{}));
3467+
3468+ gps::android::HardwareAbstractionLayer::Configuration configuration;
3469+ configuration.reference_time_source = mock_reference_time_source;
3470+ gps::android::HardwareAbstractionLayer hal(configuration);
3471+
3472+ gps::android::HardwareAbstractionLayer::on_request_utc_time(&hal);
3473+}
3474+
3475 TEST(GpsProvider, time_requests_inject_current_time_into_the_hal)
3476 {
3477 using namespace ::testing;
3478
3479+ auto sample_reference_time = []()
3480+ {
3481+ auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch());
3482+ std::cout << duration.count() << std::endl;
3483+ return gps::HardwareAbstractionLayer::ReferenceTimeSample{duration, duration, std::chrono::milliseconds{0}};
3484+ };
3485+
3486 NiceMock<MockHardwareGps> hardwareGps;
3487
3488+ auto mock_reference_time_source = std::make_shared<MockReferenceTimeSource>();
3489+ EXPECT_CALL(*mock_reference_time_source, sample())
3490+ .Times(1)
3491+ .WillRepeatedly(Invoke(sample_reference_time));
3492+
3493 gps::android::HardwareAbstractionLayer::Configuration configuration;
3494+ configuration.reference_time_source = mock_reference_time_source;
3495 gps::android::HardwareAbstractionLayer hal(configuration);
3496- std::shared_ptr<gps::HardwareAbstractionLayer> hal_ptr(&hal, [](gps::HardwareAbstractionLayer*){});
3497+ hal.capabilities() = U_HARDWARE_GPS_CAPABILITY_ON_DEMAND_TIME;
3498
3499- gps::Provider provider(hal_ptr);
3500 int64_t time = 0;
3501 EXPECT_CALL(hardwareGps, inject_time(_, _, 0)).Times(1).WillOnce(SaveArg<0>(&time));
3502
3503 auto t0 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch());
3504-
3505+ //std::this_thread::sleep_for(std::chrono::milliseconds{10});
3506 gps::android::HardwareAbstractionLayer::on_request_utc_time(&hal);
3507-
3508+ //std::this_thread::sleep_for(std::chrono::milliseconds{10});
3509 auto t1 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch());
3510 EXPECT_THAT(time, AllOf(Ge(t0.count()), Le(t1.count())));
3511 }
3512@@ -929,4 +962,3 @@
3513 static_cast<std::uint64_t>(variance(stats)))).count()
3514 << std::endl;
3515 }
3516-
3517
3518=== added file 'tests/sntp_client_test.cpp'
3519--- tests/sntp_client_test.cpp 1970-01-01 00:00:00 +0000
3520+++ tests/sntp_client_test.cpp 2016-03-08 08:03:57 +0000
3521@@ -0,0 +1,104 @@
3522+/*
3523+ * Copyright © 2016 Canonical Ltd.
3524+ *
3525+ * This program is free software: you can redistribute it and/or modify it
3526+ * under the terms of the GNU Lesser General Public License version 3,
3527+ * as published by the Free Software Foundation.
3528+ *
3529+ * This program is distributed in the hope that it will be useful,
3530+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3531+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3532+ * GNU Lesser General Public License for more details.
3533+ *
3534+ * You should have received a copy of the GNU Lesser General Public License
3535+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3536+ *
3537+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3538+ */
3539+
3540+#include <com/ubuntu/location/providers/gps/sntp_client.h>
3541+#include <com/ubuntu/location/service/runtime.h>
3542+
3543+#include <future>
3544+
3545+#include <core/posix/this_process.h>
3546+
3547+#include <gtest/gtest.h>
3548+
3549+namespace env = core::posix::this_process::env;
3550+namespace location = com::ubuntu::location;
3551+namespace sntp = location::providers::gps::sntp;
3552+
3553+namespace
3554+{
3555+struct SntpClient : public ::testing::Test
3556+{
3557+ void SetUp()
3558+ {
3559+ rt->start();
3560+ }
3561+
3562+ void TearDown()
3563+ {
3564+ rt->stop();
3565+ }
3566+
3567+ std::shared_ptr<location::service::Runtime> rt = location::service::Runtime::create();
3568+ std::string host = env::get("UBUNTU_LOCATION_SERVICE_NTP_HOST_FOR_TESTING", "ntp.ubuntu.com");
3569+};
3570+}
3571+
3572+TEST_F(SntpClient, packet_has_correct_size)
3573+{
3574+ static_assert(sizeof(sntp::Packet) == 48, "");
3575+}
3576+
3577+#pragma GCC diagnostic push
3578+#pragma GCC diagnostic ignored "-Wmultichar"
3579+TEST(EnumConstant, yields_same_value_as_multibyte_constant)
3580+{
3581+ static_assert(sntp::detail::enum_constant<'L','O','C','L'>() == 'LOCL', "");
3582+}
3583+#pragma GCC diagnostic pop
3584+
3585+TEST_F(SntpClient, succeeds_in_querying_time_from_server)
3586+{
3587+ location::providers::gps::sntp::Client sntp_client;
3588+ try
3589+ {
3590+ sntp_client.request_time(host, std::chrono::milliseconds{5000}, rt->service());
3591+ }
3592+ catch(...)
3593+ {
3594+ }
3595+}
3596+
3597+TEST_F(SntpClient, throws_for_timed_out_operation)
3598+{
3599+ location::providers::gps::sntp::Client sntp_client;
3600+ EXPECT_ANY_THROW(sntp_client.request_time(host, std::chrono::milliseconds{1}, rt->service()));
3601+}
3602+
3603+TEST_F(SntpClient, returns_correct_data_in_packet)
3604+{
3605+ for (unsigned int i = 0; i < 10; i++)
3606+ {
3607+ location::providers::gps::sntp::Client sntp_client;
3608+ try
3609+ {
3610+ auto response = sntp_client.request_time(host, std::chrono::milliseconds{1000}, rt->service());
3611+
3612+ EXPECT_LE(0, response.packet.stratum.value());
3613+ if (response.packet.stratum.value() <= 1)
3614+ {
3615+ std::stringstream ss; ss << response.packet.reference_identifier;
3616+ EXPECT_TRUE(ss.str().size() > 0);
3617+ }
3618+ }
3619+ catch(...)
3620+ {
3621+ // We ignore any exception being thrown as we are working against a real-world server
3622+ // in a load-test scenario.
3623+ }
3624+ }
3625+}

Subscribers

People subscribed via source and target branches