| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-04 14:44:34 +10:00
										 |  |  | #include <AK/Concepts.h>
 | 
					
						
							| 
									
										
										
										
											2022-12-04 18:02:33 +00:00
										 |  |  | #include <AK/DeprecatedString.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  | #include <AK/Forward.h>
 | 
					
						
							| 
									
										
										
										
											2020-05-12 18:05:43 +02:00
										 |  |  | #include <AK/NumericLimits.h>
 | 
					
						
							| 
									
										
										
										
											2020-10-03 16:26:09 +03:30
										 |  |  | #include <AK/StdLibExtras.h>
 | 
					
						
							| 
									
										
										
										
											2022-02-01 20:49:29 +01:00
										 |  |  | #include <AK/Try.h>
 | 
					
						
							| 
									
										
										
										
											2022-11-09 17:05:04 +01:00
										 |  |  | #include <AK/TypeList.h>
 | 
					
						
							|  |  |  | #include <AK/Variant.h>
 | 
					
						
							| 
									
										
										
										
											2022-02-01 20:49:29 +01:00
										 |  |  | #include <LibCore/SharedCircularQueue.h>
 | 
					
						
							| 
									
										
										
										
											2022-01-14 13:12:49 +00:00
										 |  |  | #include <LibCore/Stream.h>
 | 
					
						
							| 
									
										
										
										
											2022-02-01 20:49:29 +01:00
										 |  |  | #include <LibIPC/File.h>
 | 
					
						
							| 
									
										
										
										
											2020-05-03 22:15:27 +02:00
										 |  |  | #include <LibIPC/Forward.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  | #include <LibIPC/Message.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace IPC { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<typename T> | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  | inline ErrorOr<void> decode(Decoder&, T&) | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-03 16:26:09 +03:30
										 |  |  |     static_assert(DependentFalse<T>, "Base IPC::decoder() instantiated"); | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY_NOT_REACHED(); | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Decoder { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2022-01-14 13:12:49 +00:00
										 |  |  |     Decoder(InputMemoryStream& stream, Core::Stream::LocalSocket& socket) | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  |         : m_stream(stream) | 
					
						
							| 
									
										
										
										
											2022-01-14 13:12:49 +00:00
										 |  |  |         , m_socket(socket) | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |     ErrorOr<void> decode(bool&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(u8&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(u16&); | 
					
						
							| 
									
										
										
										
											2021-11-29 02:18:58 +01:00
										 |  |  |     ErrorOr<void> decode(unsigned&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(unsigned long&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(unsigned long long&); | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |     ErrorOr<void> decode(i8&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(i16&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(i32&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(i64&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(float&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(double&); | 
					
						
							| 
									
										
										
										
											2022-12-04 18:02:33 +00:00
										 |  |  |     ErrorOr<void> decode(DeprecatedString&); | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |     ErrorOr<void> decode(ByteBuffer&); | 
					
						
							| 
									
										
										
										
											2022-11-07 16:30:55 -05:00
										 |  |  |     ErrorOr<void> decode(JsonValue&); | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |     ErrorOr<void> decode(URL&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(Dictionary&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(File&); | 
					
						
							| 
									
										
										
										
											2022-11-09 17:05:04 +01:00
										 |  |  |     ErrorOr<void> decode(AK::Empty&); | 
					
						
							| 
									
										
										
										
											2020-11-07 23:09:45 +03:30
										 |  |  |     template<typename K, typename V> | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |     ErrorOr<void> decode(HashMap<K, V>& hashmap) | 
					
						
							| 
									
										
										
										
											2020-11-07 23:09:45 +03:30
										 |  |  |     { | 
					
						
							|  |  |  |         u32 size; | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         TRY(decode(size)); | 
					
						
							|  |  |  |         if (size > NumericLimits<i32>::max()) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:57:32 +00:00
										 |  |  |             return Error::from_string_literal("IPC: Invalid HashMap size"); | 
					
						
							| 
									
										
										
										
											2020-11-07 23:09:45 +03:30
										 |  |  | 
 | 
					
						
							|  |  |  |         for (size_t i = 0; i < size; ++i) { | 
					
						
							|  |  |  |             K key; | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |             TRY(decode(key)); | 
					
						
							| 
									
										
										
										
											2020-11-07 23:09:45 +03:30
										 |  |  |             V value; | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |             TRY(decode(value)); | 
					
						
							|  |  |  |             TRY(hashmap.try_set(move(key), move(value))); | 
					
						
							| 
									
										
										
										
											2020-11-07 23:09:45 +03:30
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2020-11-07 23:09:45 +03:30
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-03 00:43:22 +03:00
										 |  |  |     template<typename K, typename V> | 
					
						
							|  |  |  |     ErrorOr<void> decode(OrderedHashMap<K, V>& hashmap) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         u32 size; | 
					
						
							|  |  |  |         TRY(decode(size)); | 
					
						
							|  |  |  |         if (size > NumericLimits<i32>::max()) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:57:32 +00:00
										 |  |  |             return Error::from_string_literal("IPC: Invalid HashMap size"); | 
					
						
							| 
									
										
										
										
											2022-04-03 00:43:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (size_t i = 0; i < size; ++i) { | 
					
						
							|  |  |  |             K key; | 
					
						
							|  |  |  |             TRY(decode(key)); | 
					
						
							|  |  |  |             V value; | 
					
						
							|  |  |  |             TRY(decode(value)); | 
					
						
							|  |  |  |             TRY(hashmap.try_set(move(key), move(value))); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-04 14:44:34 +10:00
										 |  |  |     template<Enum T> | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |     ErrorOr<void> decode(T& enum_value) | 
					
						
							| 
									
										
										
										
											2021-07-04 14:44:34 +10:00
										 |  |  |     { | 
					
						
							|  |  |  |         UnderlyingType<T> inner_value; | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         TRY(decode(inner_value)); | 
					
						
							| 
									
										
										
										
											2021-07-04 14:44:34 +10:00
										 |  |  |         enum_value = T(inner_value); | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2021-07-04 14:44:34 +10:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  |     template<typename T> | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |     ErrorOr<void> decode(T& value) | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-03-29 19:03:13 +02:00
										 |  |  |         return IPC::decode(*this, value); | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-12 18:05:43 +02:00
										 |  |  |     template<typename T> | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |     ErrorOr<void> decode(Vector<T>& vector) | 
					
						
							| 
									
										
										
										
											2020-05-12 18:05:43 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         u64 size; | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         TRY(decode(size)); | 
					
						
							|  |  |  |         if (size > NumericLimits<i32>::max()) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:57:32 +00:00
										 |  |  |             return Error::from_string_literal("IPC: Invalid Vector size"); | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         VERIFY(vector.is_empty()); | 
					
						
							|  |  |  |         TRY(vector.try_ensure_capacity(size)); | 
					
						
							| 
									
										
										
										
											2020-05-12 18:05:43 +02:00
										 |  |  |         for (size_t i = 0; i < size; ++i) { | 
					
						
							|  |  |  |             T value; | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |             TRY(decode(value)); | 
					
						
							|  |  |  |             vector.template unchecked_append(move(value)); | 
					
						
							| 
									
										
										
										
											2020-05-12 18:05:43 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2020-05-12 18:05:43 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-01 20:49:29 +01:00
										 |  |  |     template<typename T, size_t Size> | 
					
						
							|  |  |  |     ErrorOr<void> decode(Core::SharedSingleProducerCircularQueue<T, Size>& queue) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // FIXME: We don't support decoding into valid queues.
 | 
					
						
							|  |  |  |         VERIFY(!queue.is_valid()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         IPC::File anon_file; | 
					
						
							|  |  |  |         TRY(decode(anon_file)); | 
					
						
							|  |  |  |         queue = TRY((Core::SharedSingleProducerCircularQueue<T, Size>::try_create(anon_file.take_fd()))); | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-09 17:05:04 +01:00
										 |  |  |     template<typename... VariantTypes> | 
					
						
							|  |  |  |     ErrorOr<void> decode(Variant<VariantTypes...>& variant) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         typename AK::Variant<VariantTypes...>::IndexType type_index; | 
					
						
							|  |  |  |         TRY(decode(type_index)); | 
					
						
							|  |  |  |         if (type_index >= sizeof...(VariantTypes)) | 
					
						
							|  |  |  |             return Error::from_string_literal("IPC: Invalid variant index"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         TRY((decode_variant<0, sizeof...(VariantTypes), VariantTypes...>(type_index, variant))); | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-12 19:02:44 +02:00
										 |  |  |     template<typename T> | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |     ErrorOr<void> decode(Optional<T>& optional) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:02:44 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         bool has_value; | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         TRY(decode(has_value)); | 
					
						
							| 
									
										
										
										
											2020-05-12 19:02:44 +02:00
										 |  |  |         if (!has_value) { | 
					
						
							|  |  |  |             optional = {}; | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-05-12 19:02:44 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         T value; | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         TRY(decode(value)); | 
					
						
							| 
									
										
										
										
											2020-05-12 19:02:44 +02:00
										 |  |  |         optional = move(value); | 
					
						
							| 
									
										
										
										
											2021-11-28 11:56:31 +01:00
										 |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2020-05-12 19:02:44 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2022-11-09 17:05:04 +01:00
										 |  |  |     template<size_t CurrentIndex, size_t Max, typename... VariantTypes> | 
					
						
							|  |  |  |     ErrorOr<void> decode_variant(size_t index, Variant<VariantTypes...>& variant) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if constexpr (CurrentIndex < Max) { | 
					
						
							|  |  |  |             if (index == CurrentIndex) { | 
					
						
							|  |  |  |                 typename TypeList<VariantTypes...>::template Type<CurrentIndex> element; | 
					
						
							|  |  |  |                 TRY(decode(element)); | 
					
						
							|  |  |  |                 variant.set(move(element)); | 
					
						
							|  |  |  |                 return {}; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return decode_variant<CurrentIndex + 1, Max, VariantTypes...>(index, variant); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-20 13:00:54 +02:00
										 |  |  |     InputMemoryStream& m_stream; | 
					
						
							| 
									
										
										
										
											2022-01-14 13:12:49 +00:00
										 |  |  |     Core::Stream::LocalSocket& m_socket; | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |