/src/arduinojson/src/ArduinoJson/Deserialization/deserialize.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // ArduinoJson - https://arduinojson.org |
2 | | // Copyright © 2014-2024, Benoit BLANCHON |
3 | | // MIT License |
4 | | |
5 | | #pragma once |
6 | | |
7 | | #include <ArduinoJson/Deserialization/DeserializationError.hpp> |
8 | | #include <ArduinoJson/Deserialization/DeserializationOptions.hpp> |
9 | | #include <ArduinoJson/Deserialization/Reader.hpp> |
10 | | #include <ArduinoJson/Polyfills/utility.hpp> |
11 | | |
12 | | ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE |
13 | | |
14 | | // A meta-function that returns the first type of the parameter pack |
15 | | // or void if empty |
16 | | template <typename...> |
17 | | struct first_or_void { |
18 | | using type = void; |
19 | | }; |
20 | | template <typename T, typename... Rest> |
21 | | struct first_or_void<T, Rest...> { |
22 | | using type = T; |
23 | | }; |
24 | | |
25 | | // A meta-function that returns true if T is a valid destination type for |
26 | | // deserialize() |
27 | | template <class T, class = void> |
28 | | struct is_deserialize_destination : false_type {}; |
29 | | |
30 | | template <class T> |
31 | | struct is_deserialize_destination< |
32 | | T, enable_if_t<is_same<decltype(VariantAttorney::getResourceManager( |
33 | | detail::declval<T&>())), |
34 | | ResourceManager*>::value>> : true_type {}; |
35 | | |
36 | | template <typename TDestination> |
37 | | inline void shrinkJsonDocument(TDestination&) { |
38 | | // no-op by default |
39 | | } |
40 | | |
41 | | #if ARDUINOJSON_AUTO_SHRINK |
42 | 2.40k | inline void shrinkJsonDocument(JsonDocument& doc) { |
43 | 2.40k | doc.shrinkToFit(); |
44 | 2.40k | } |
45 | | #endif |
46 | | |
47 | | template <template <typename> class TDeserializer, typename TDestination, |
48 | | typename TReader, typename TOptions> |
49 | | DeserializationError doDeserialize(TDestination&& dst, TReader reader, |
50 | 2.40k | TOptions options) { |
51 | 2.40k | auto data = VariantAttorney::getOrCreateData(dst); |
52 | 2.40k | if (!data) |
53 | 0 | return DeserializationError::NoMemory; |
54 | 2.40k | auto resources = VariantAttorney::getResourceManager(dst); |
55 | 2.40k | dst.clear(); |
56 | 2.40k | auto err = TDeserializer<TReader>(resources, reader) |
57 | 2.40k | .parse(*data, options.filter, options.nestingLimit); |
58 | 2.40k | shrinkJsonDocument(dst); |
59 | 2.40k | return err; |
60 | 2.40k | } |
61 | | |
62 | | template <template <typename> class TDeserializer, typename TDestination, |
63 | | typename TStream, typename... Args, |
64 | | typename = enable_if_t< // issue #1897 |
65 | | !is_integral<typename first_or_void<Args...>::type>::value>> |
66 | | DeserializationError deserialize(TDestination&& dst, TStream&& input, |
67 | | Args... args) { |
68 | | return doDeserialize<TDeserializer>( |
69 | | dst, makeReader(detail::forward<TStream>(input)), |
70 | | makeDeserializationOptions(args...)); |
71 | | } |
72 | | |
73 | | template <template <typename> class TDeserializer, typename TDestination, |
74 | | typename TChar, typename Size, typename... Args, |
75 | | typename = enable_if_t<is_integral<Size>::value>> |
76 | | DeserializationError deserialize(TDestination&& dst, TChar* input, |
77 | 2.40k | Size inputSize, Args... args) { |
78 | 2.40k | return doDeserialize<TDeserializer>(dst, makeReader(input, size_t(inputSize)), |
79 | 2.40k | makeDeserializationOptions(args...)); |
80 | 2.40k | } |
81 | | |
82 | | ARDUINOJSON_END_PRIVATE_NAMESPACE |