| 
									
										
										
										
											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>
 | 
					
						
							| 
									
										
										
										
											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>
 | 
					
						
							| 
									
										
										
										
											2020-05-12 18:05:43 +02:00
										 |  |  | #include <AK/String.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: | 
					
						
							| 
									
										
										
										
											2020-11-21 21:59:12 +03:00
										 |  |  |     Decoder(InputMemoryStream& stream, int sockfd) | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  |         : m_stream(stream) | 
					
						
							| 
									
										
										
										
											2020-11-21 21:59:12 +03:00
										 |  |  |         , m_sockfd(sockfd) | 
					
						
							| 
									
										
										
										
											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&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(String&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(ByteBuffer&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(URL&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(Dictionary&); | 
					
						
							|  |  |  |     ErrorOr<void> decode(File&); | 
					
						
							| 
									
										
										
										
											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()) | 
					
						
							|  |  |  |             return Error::from_string_literal("IPC: Invalid HashMap size"sv); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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()) | 
					
						
							|  |  |  |             return Error::from_string_literal("IPC: Invalid Vector size"sv); | 
					
						
							|  |  |  |         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
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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: | 
					
						
							| 
									
										
										
										
											2020-09-20 13:00:54 +02:00
										 |  |  |     InputMemoryStream& m_stream; | 
					
						
							| 
									
										
										
										
											2020-11-21 21:59:12 +03:00
										 |  |  |     int m_sockfd { -1 }; | 
					
						
							| 
									
										
										
										
											2020-02-15 12:04:35 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |