diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2024-08-08 18:13:00 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2024-08-15 23:59:08 +0300 |
commit | 50c92cc7e2924009ecab3e4004448b01d687707c (patch) | |
tree | c22b49816a3c79dae4727780962aa0928df42b52 /utils/ipc/generators/libcamera_templates | |
parent | d3bf27180ef1d91b86b7b87a2378e559eaff5455 (diff) |
meson: Move all code generation scripts to utils/codegen/
We have multiple code generation scripts in utils/, mixed with other
miscellaneous utilities, as well as a larger code base based on mojom in
utils/ipc/. To make code sharing easier between the generator scripts,
without creating a mess in the utils/ directory, move all the code
generation code to utils/codegen/.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Diffstat (limited to 'utils/ipc/generators/libcamera_templates')
11 files changed, 0 insertions, 1434 deletions
diff --git a/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl b/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl deleted file mode 100644 index 7f2d0810..00000000 --- a/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl +++ /dev/null @@ -1,37 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} -{%- import "definition_functions.tmpl" as funcs -%} -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * libcamera core definitions for Image Processing Algorithms - * - * This file is auto-generated. Do not edit. - */ - -#pragma once - -{% if has_map %}#include <map>{% endif %} -{% if has_array %}#include <vector>{% endif %} - -#include <libcamera/ipa/ipa_interface.h> - -namespace libcamera { - -{# \todo Use const char * instead of std::string for strings #} -{% for const in consts %} -static const {{const.kind|name}} {{const.mojom_name}} = {{const.value}}; -{% endfor %} - -{% for enum in enums_gen_header %} -{{funcs.define_enum(enum)}} -{% endfor %} - -{%- for struct in structs_gen_header %} -{{funcs.define_struct(struct)}} -{% endfor %} - -} /* namespace libcamera */ diff --git a/utils/ipc/generators/libcamera_templates/core_ipa_serializer.h.tmpl b/utils/ipc/generators/libcamera_templates/core_ipa_serializer.h.tmpl deleted file mode 100644 index 036518f6..00000000 --- a/utils/ipc/generators/libcamera_templates/core_ipa_serializer.h.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} -{%- import "serializer.tmpl" as serializer -%} - -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * Data serializer for core libcamera definitions for IPA - * - * This file is auto-generated. Do not edit. - */ - -#pragma once - -#include <tuple> -#include <vector> - -#include <libcamera/ipa/core_ipa_interface.h> - -#include "libcamera/internal/control_serializer.h" -#include "libcamera/internal/ipa_data_serializer.h" - -namespace libcamera { - -LOG_DECLARE_CATEGORY(IPADataSerializer) -{% for struct in structs_gen_serializer %} -template<> -class IPADataSerializer<{{struct|name}}> -{ -public: -{{- serializer.serializer(struct, "")}} -{%- if struct|has_fd %} -{{serializer.deserializer_fd(struct, "")}} -{%- else %} -{{serializer.deserializer_no_fd(struct, "")}} -{{serializer.deserializer_fd_simple(struct, "")}} -{%- endif %} -}; -{% endfor %} - -} /* namespace libcamera */ diff --git a/utils/ipc/generators/libcamera_templates/definition_functions.tmpl b/utils/ipc/generators/libcamera_templates/definition_functions.tmpl deleted file mode 100644 index 8b8509f3..00000000 --- a/utils/ipc/generators/libcamera_templates/definition_functions.tmpl +++ /dev/null @@ -1,56 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} - -{# - # \brief Generate enum definition - # - # \param enum Enum object whose definition is to be generated - #} -{%- macro define_enum(enum) -%} -enum{{" class" if enum|is_scoped}} {{enum.mojom_name}} { -{%- for field in enum.fields %} - {{field.mojom_name}} = {{field.numeric_value}}, -{%- endfor %} -}; -{%- endmacro -%} - -{# - # \brief Generate struct definition - # - # \param struct Struct object whose definition is to be generated - #} -{%- macro define_struct(struct) -%} -struct {{struct.mojom_name}} -{ -public: -#ifndef __DOXYGEN__ - {{struct.mojom_name}}() {%- if struct|has_default_fields %} - :{% endif %} -{%- for field in struct.fields|with_default_values -%} -{{" " if loop.first}}{{field.mojom_name}}({{field|default_value}}){{", " if not loop.last}} -{%- endfor %} - { - } - - {{struct.mojom_name}}( -{%- for field in struct.fields -%} -{{"const " if not field|is_pod}}{{field|name}} {{"&" if not field|is_pod}}_{{field.mojom_name}}{{", " if not loop.last}} -{%- endfor -%} -) - : -{%- for field in struct.fields -%} -{{" " if loop.first}}{{field.mojom_name}}(_{{field.mojom_name}}){{", " if not loop.last}} -{%- endfor %} - { - } -#endif - -{% for field in struct.fields %} - {{field|name}} {{field.mojom_name}}; -{%- endfor %} -}; -{%- endmacro -%} - - diff --git a/utils/ipc/generators/libcamera_templates/meson.build b/utils/ipc/generators/libcamera_templates/meson.build deleted file mode 100644 index 70664eab..00000000 --- a/utils/ipc/generators/libcamera_templates/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: CC0-1.0 - -mojom_template_files = files([ - 'core_ipa_interface.h.tmpl', - 'core_ipa_serializer.h.tmpl', - 'definition_functions.tmpl', - 'module_ipa_interface.h.tmpl', - 'module_ipa_proxy.cpp.tmpl', - 'module_ipa_proxy.h.tmpl', - 'module_ipa_proxy_worker.cpp.tmpl', - 'module_ipa_serializer.h.tmpl', - 'proxy_functions.tmpl', - 'serializer.tmpl', -]) diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl deleted file mode 100644 index 4d88a3d7..00000000 --- a/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl +++ /dev/null @@ -1,84 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} -{%- import "definition_functions.tmpl" as funcs -%} -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * Image Processing Algorithm interface for {{module_name}} - * - * This file is auto-generated. Do not edit. - */ - -#pragma once - -#include <libcamera/ipa/core_ipa_interface.h> -#include <libcamera/ipa/ipa_interface.h> - -{% if has_map %}#include <map>{% endif %} -{% if has_array %}#include <vector>{% endif %} - -namespace libcamera { -{%- if has_namespace %} -{% for ns in namespace %} -namespace {{ns}} { -{% endfor %} -{%- endif %} - -{% for const in consts %} -const {{const.kind|name}} {{const.mojom_name}} = {{const.value}}; -{% endfor %} - -enum class {{cmd_enum_name}} { - Exit = 0, -{%- for method in interface_main.methods %} - {{method.mojom_name|cap}} = {{loop.index}}, -{%- endfor %} -}; - -enum class {{cmd_event_enum_name}} { -{%- for method in interface_event.methods %} - {{method.mojom_name|cap}} = {{loop.index}}, -{%- endfor %} -}; - -{% for enum in enums %} -{{funcs.define_enum(enum)}} -{% endfor %} - -{%- for struct in structs_nonempty %} -{{funcs.define_struct(struct)}} -{% endfor %} - -{#- -Any consts or #defines should be moved to the mojom file. -#} -class {{interface_name}} : public IPAInterface -{ -public: -{% for method in interface_main.methods %} - virtual {{method|method_return_value}} {{method.mojom_name}}( -{%- for param in method|method_parameters %} - {{param}}{{- "," if not loop.last}} -{%- endfor -%} -) = 0; -{% endfor %} - -{%- for method in interface_event.methods %} - Signal< -{%- for param in method.parameters -%} - {{"const " if not param|is_pod}}{{param|name}}{{" &" if not param|is_pod and not param|is_enum}} - {{- ", " if not loop.last}} -{%- endfor -%} -> {{method.mojom_name}}; -{% endfor -%} -}; - -{%- if has_namespace %} -{% for ns in namespace|reverse %} -} /* namespace {{ns}} */ -{% endfor %} -{%- endif %} -} /* namespace libcamera */ diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl deleted file mode 100644 index ce3cc5ab..00000000 --- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl +++ /dev/null @@ -1,255 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} -{%- import "proxy_functions.tmpl" as proxy_funcs -%} - -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * Image Processing Algorithm proxy for {{module_name}} - * - * This file is auto-generated. Do not edit. - */ - -#include <libcamera/ipa/{{module_name}}_ipa_proxy.h> - -#include <memory> -#include <string> -#include <vector> - -#include <libcamera/ipa/ipa_module_info.h> -#include <libcamera/ipa/{{module_name}}_ipa_interface.h> -#include <libcamera/ipa/{{module_name}}_ipa_serializer.h> - -#include <libcamera/base/log.h> -#include <libcamera/base/thread.h> - -#include "libcamera/internal/control_serializer.h" -#include "libcamera/internal/ipa_data_serializer.h" -#include "libcamera/internal/ipa_module.h" -#include "libcamera/internal/ipa_proxy.h" -#include "libcamera/internal/ipc_pipe.h" -#include "libcamera/internal/ipc_pipe_unixsocket.h" -#include "libcamera/internal/ipc_unixsocket.h" -#include "libcamera/internal/process.h" - -namespace libcamera { - -LOG_DECLARE_CATEGORY(IPAProxy) - -{%- if has_namespace %} -{% for ns in namespace %} -namespace {{ns}} { -{% endfor %} -{%- endif %} - -{{proxy_name}}::{{proxy_name}}(IPAModule *ipam, bool isolate) - : IPAProxy(ipam), isolate_(isolate), - controlSerializer_(ControlSerializer::Role::Proxy), seq_(0) -{ - LOG(IPAProxy, Debug) - << "initializing {{module_name}} proxy: loading IPA from " - << ipam->path(); - - if (isolate_) { - const std::string proxyWorkerPath = resolvePath("{{module_name}}_ipa_proxy"); - if (proxyWorkerPath.empty()) { - LOG(IPAProxy, Error) - << "Failed to get proxy worker path"; - return; - } - - ipc_ = std::make_unique<IPCPipeUnixSocket>(ipam->path().c_str(), - proxyWorkerPath.c_str()); - if (!ipc_->isConnected()) { - LOG(IPAProxy, Error) << "Failed to create IPCPipe"; - return; - } - - ipc_->recv.connect(this, &{{proxy_name}}::recvMessage); - - valid_ = true; - return; - } - - if (!ipam->load()) - return; - - IPAInterface *ipai = ipam->createInterface(); - if (!ipai) { - LOG(IPAProxy, Error) - << "Failed to create IPA context for " << ipam->path(); - return; - } - - ipa_ = std::unique_ptr<{{interface_name}}>(static_cast<{{interface_name}} *>(ipai)); - proxy_.setIPA(ipa_.get()); - -{% for method in interface_event.methods %} - ipa_->{{method.mojom_name}}.connect(this, &{{proxy_name}}::{{method.mojom_name}}Thread); -{%- endfor %} - - valid_ = true; -} - -{{proxy_name}}::~{{proxy_name}}() -{ - if (isolate_) { - IPCMessage::Header header = - { static_cast<uint32_t>({{cmd_enum_name}}::Exit), seq_++ }; - IPCMessage msg(header); - ipc_->sendAsync(msg); - } -} - -{% if interface_event.methods|length > 0 %} -void {{proxy_name}}::recvMessage(const IPCMessage &data) -{ - size_t dataSize = data.data().size(); - {{cmd_event_enum_name}} _cmd = static_cast<{{cmd_event_enum_name}}>(data.header().cmd); - - switch (_cmd) { -{%- for method in interface_event.methods %} - case {{cmd_event_enum_name}}::{{method.mojom_name|cap}}: { - {{method.mojom_name}}IPC(data.data().cbegin(), dataSize, data.fds()); - break; - } -{%- endfor %} - default: - LOG(IPAProxy, Error) << "Unknown command " << static_cast<uint32_t>(_cmd); - } -} -{%- endif %} - -{% for method in interface_main.methods %} -{{proxy_funcs.func_sig(proxy_name, method)}} -{ - if (isolate_) - {{"return " if method|method_return_value != "void"}}{{method.mojom_name}}IPC( -{%- for param in method|method_param_names -%} - {{param}}{{- ", " if not loop.last}} -{%- endfor -%} -); - else - {{"return " if method|method_return_value != "void"}}{{method.mojom_name}}Thread( -{%- for param in method|method_param_names -%} - {{param}}{{- ", " if not loop.last}} -{%- endfor -%} -); -} - -{{proxy_funcs.func_sig(proxy_name, method, "Thread")}} -{ -{%- if method.mojom_name == "stop" %} - {{proxy_funcs.stop_thread_body()}} -{%- elif method.mojom_name == "init" %} - {{ method|method_return_value + " _ret = " if method|method_return_value != "void" -}} - ipa_->{{method.mojom_name}}( - {%- for param in method|method_param_names -%} - {{param}}{{- ", " if not loop.last}} - {%- endfor -%} -); - - proxy_.moveToThread(&thread_); - - return {{ "_ret" if method|method_return_value != "void" }}; -{%- elif method.mojom_name == "start" %} - state_ = ProxyRunning; - thread_.start(); - - {{ "return " if method|method_return_value != "void" -}} - proxy_.invokeMethod(&ThreadProxy::start, ConnectionTypeBlocking - {{- ", " if method|method_param_names}} - {%- for param in method|method_param_names -%} - {{param}}{{- ", " if not loop.last}} - {%- endfor -%} -); -{%- elif not method|is_async %} - {{ "return " if method|method_return_value != "void" -}} - ipa_->{{method.mojom_name}}( - {%- for param in method|method_param_names -%} - {{param}}{{- ", " if not loop.last}} - {%- endfor -%} -); -{% elif method|is_async %} - ASSERT(state_ == ProxyRunning); - proxy_.invokeMethod(&ThreadProxy::{{method.mojom_name}}, ConnectionTypeQueued - {%- for param in method|method_param_names -%} - , {{param}} - {%- endfor -%} -); -{%- endif %} -} - -{{proxy_funcs.func_sig(proxy_name, method, "IPC")}} -{ -{%- if method.mojom_name == "configure" %} - controlSerializer_.reset(); -{%- endif %} -{%- set has_output = true if method|method_param_outputs|length > 0 or method|method_return_value != "void" %} -{%- set cmd = cmd_enum_name + "::" + method.mojom_name|cap %} - IPCMessage::Header _header = { static_cast<uint32_t>({{cmd}}), seq_++ }; - IPCMessage _ipcInputBuf(_header); -{%- if has_output %} - IPCMessage _ipcOutputBuf; -{%- endif %} - -{{proxy_funcs.serialize_call(method|method_param_inputs, '_ipcInputBuf.data()', '_ipcInputBuf.fds()')}} - -{% if method|is_async %} - int _ret = ipc_->sendAsync(_ipcInputBuf); -{%- else %} - int _ret = ipc_->sendSync(_ipcInputBuf -{{- ", &_ipcOutputBuf" if has_output -}} -); -{%- endif %} - if (_ret < 0) { - LOG(IPAProxy, Error) << "Failed to call {{method.mojom_name}}"; -{%- if method|method_return_value != "void" %} - return static_cast<{{method|method_return_value}}>(_ret); -{%- else %} - return; -{%- endif %} - } -{% if method|method_return_value != "void" %} - {{method|method_return_value}} _retValue = IPADataSerializer<{{method|method_return_value}}>::deserialize(_ipcOutputBuf.data(), 0); - -{{proxy_funcs.deserialize_call(method|method_param_outputs, '_ipcOutputBuf.data()', '_ipcOutputBuf.fds()', init_offset = method|method_return_value|byte_width|int)}} - - return _retValue; - -{% elif method|method_param_outputs|length > 0 %} -{{proxy_funcs.deserialize_call(method|method_param_outputs, '_ipcOutputBuf.data()', '_ipcOutputBuf.fds()')}} -{% endif -%} -} - -{% endfor %} - -{% for method in interface_event.methods %} -{{proxy_funcs.func_sig(proxy_name, method, "Thread")}} -{ - ASSERT(state_ != ProxyStopped); - {{method.mojom_name}}.emit({{method.parameters|params_comma_sep}}); -} - -void {{proxy_name}}::{{method.mojom_name}}IPC( - [[maybe_unused]] std::vector<uint8_t>::const_iterator data, - [[maybe_unused]] size_t dataSize, - [[maybe_unused]] const std::vector<SharedFD> &fds) -{ -{%- for param in method.parameters %} - {{param|name}} {{param.mojom_name}}; -{%- endfor %} -{{proxy_funcs.deserialize_call(method.parameters, 'data', 'fds', false, false, true, 'dataSize')}} - {{method.mojom_name}}.emit({{method.parameters|params_comma_sep}}); -} -{% endfor %} - -{%- if has_namespace %} -{% for ns in namespace|reverse %} -} /* namespace {{ns}} */ -{% endfor %} -{%- endif %} -} /* namespace libcamera */ diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl deleted file mode 100644 index e213b18a..00000000 --- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl +++ /dev/null @@ -1,132 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} -{%- import "proxy_functions.tmpl" as proxy_funcs -%} - -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * Image Processing Algorithm proxy for {{module_name}} - * - * This file is auto-generated. Do not edit. - */ - -#pragma once - -#include <libcamera/ipa/ipa_interface.h> -#include <libcamera/ipa/{{module_name}}_ipa_interface.h> - -#include <libcamera/base/object.h> -#include <libcamera/base/thread.h> - -#include "libcamera/internal/control_serializer.h" -#include "libcamera/internal/ipa_proxy.h" -#include "libcamera/internal/ipc_pipe.h" -#include "libcamera/internal/ipc_pipe_unixsocket.h" -#include "libcamera/internal/ipc_unixsocket.h" - -namespace libcamera { -{%- if has_namespace %} -{% for ns in namespace %} -namespace {{ns}} { -{% endfor %} -{%- endif %} - -class {{proxy_name}} : public IPAProxy, public {{interface_name}}, public Object -{ -public: - {{proxy_name}}(IPAModule *ipam, bool isolate); - ~{{proxy_name}}(); - -{% for method in interface_main.methods %} -{{proxy_funcs.func_sig(proxy_name, method, "", false, true)|indent(8, true)}}; -{% endfor %} - -{%- for method in interface_event.methods %} - Signal< -{%- for param in method.parameters -%} - {{"const " if not param|is_pod}}{{param|name}}{{" &" if not param|is_pod and not param|is_enum}} - {{- ", " if not loop.last}} -{%- endfor -%} -> {{method.mojom_name}}; -{% endfor %} - -private: - void recvMessage(const IPCMessage &data); - -{% for method in interface_main.methods %} -{{proxy_funcs.func_sig(proxy_name, method, "Thread", false)|indent(8, true)}}; -{{proxy_funcs.func_sig(proxy_name, method, "IPC", false)|indent(8, true)}}; -{% endfor %} -{% for method in interface_event.methods %} -{{proxy_funcs.func_sig(proxy_name, method, "Thread", false)|indent(8, true)}}; - void {{method.mojom_name}}IPC( - std::vector<uint8_t>::const_iterator data, - size_t dataSize, - const std::vector<SharedFD> &fds); -{% endfor %} - - /* Helper class to invoke async functions in another thread. */ - class ThreadProxy : public Object - { - public: - ThreadProxy() - : ipa_(nullptr) - { - } - - void setIPA({{interface_name}} *ipa) - { - ipa_ = ipa; - } - - void stop() - { - ipa_->stop(); - } -{% for method in interface_main.methods %} -{%- if method|is_async %} - {{proxy_funcs.func_sig(proxy_name, method, "", false)|indent(16)}} - { - ipa_->{{method.mojom_name}}({{method.parameters|params_comma_sep}}); - } -{%- elif method.mojom_name == "start" %} - {{proxy_funcs.func_sig(proxy_name, method, "", false)|indent(16)}} - { -{%- if method|method_return_value != "void" %} - return ipa_->{{method.mojom_name}}({{method.parameters|params_comma_sep}}); -{%- else %} - ipa_->{{method.mojom_name}}({{method.parameters|params_comma_sep}} - {{- ", " if method|method_param_outputs|params_comma_sep -}} - {{- method|method_param_outputs|params_comma_sep}}); -{%- endif %} - } -{%- endif %} -{%- endfor %} - - private: - {{interface_name}} *ipa_; - }; - - Thread thread_; - ThreadProxy proxy_; - std::unique_ptr<{{interface_name}}> ipa_; - - const bool isolate_; - - std::unique_ptr<IPCPipeUnixSocket> ipc_; - - ControlSerializer controlSerializer_; - -{# \todo Move this to IPCPipe #} - uint32_t seq_; -}; - -{%- if has_namespace %} -{% for ns in namespace|reverse %} -} /* namespace {{ns}} */ -{% endfor %} -{%- endif %} -} /* namespace libcamera */ diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl deleted file mode 100644 index 1f990d3f..00000000 --- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl +++ /dev/null @@ -1,246 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} -{%- import "proxy_functions.tmpl" as proxy_funcs -%} - -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * Image Processing Algorithm proxy worker for {{module_name}} - * - * This file is auto-generated. Do not edit. - */ - -{#- \todo Split proxy worker into IPC worker and proxy worker. #} - -#include <algorithm> -#include <iostream> -#include <sys/types.h> -#include <tuple> -#include <unistd.h> - -#include <libcamera/ipa/ipa_interface.h> -#include <libcamera/ipa/{{module_name}}_ipa_interface.h> -#include <libcamera/ipa/{{module_name}}_ipa_serializer.h> -#include <libcamera/logging.h> - -#include <libcamera/base/event_dispatcher.h> -#include <libcamera/base/log.h> -#include <libcamera/base/thread.h> -#include <libcamera/base/unique_fd.h> - -#include "libcamera/internal/camera_sensor.h" -#include "libcamera/internal/control_serializer.h" -#include "libcamera/internal/ipa_data_serializer.h" -#include "libcamera/internal/ipa_module.h" -#include "libcamera/internal/ipa_proxy.h" -#include "libcamera/internal/ipc_pipe.h" -#include "libcamera/internal/ipc_pipe_unixsocket.h" -#include "libcamera/internal/ipc_unixsocket.h" - -using namespace libcamera; - -LOG_DEFINE_CATEGORY({{proxy_worker_name}}) - -{%- if has_namespace %} -{% for ns in namespace -%} -using namespace {{ns}}; -{% endfor %} -{%- endif %} - -class {{proxy_worker_name}} -{ -public: - {{proxy_worker_name}}() - : ipa_(nullptr), - controlSerializer_(ControlSerializer::Role::Worker), - exit_(false) {} - - ~{{proxy_worker_name}}() {} - - void readyRead() - { - IPCUnixSocket::Payload _message; - int _retRecv = socket_.receive(&_message); - if (_retRecv) { - LOG({{proxy_worker_name}}, Error) - << "Receive message failed: " << _retRecv; - return; - } - - IPCMessage _ipcMessage(_message); - - {{cmd_enum_name}} _cmd = static_cast<{{cmd_enum_name}}>(_ipcMessage.header().cmd); - - switch (_cmd) { - case {{cmd_enum_name}}::Exit: { - exit_ = true; - break; - } - -{% for method in interface_main.methods %} - case {{cmd_enum_name}}::{{method.mojom_name|cap}}: { -{%- if method.mojom_name == "configure" %} - controlSerializer_.reset(); -{%- endif %} - {{proxy_funcs.deserialize_call(method|method_param_inputs, '_ipcMessage.data()', '_ipcMessage.fds()', false, true)|indent(16, true)}} -{% for param in method|method_param_outputs %} - {{param|name}} {{param.mojom_name}}; -{% endfor %} -{%- if method|method_return_value != "void" %} - {{method|method_return_value}} _callRet = -{%- endif -%} - ipa_->{{method.mojom_name}}({{method.parameters|params_comma_sep}} -{{- ", " if method|method_param_outputs|params_comma_sep -}} -{%- for param in method|method_param_outputs -%} -&{{param.mojom_name}}{{", " if not loop.last}} -{%- endfor -%} -); -{% if not method|is_async %} - IPCMessage::Header header = { _ipcMessage.header().cmd, _ipcMessage.header().cookie }; - IPCMessage _response(header); -{%- if method|method_return_value != "void" %} - std::vector<uint8_t> _callRetBuf; - std::tie(_callRetBuf, std::ignore) = - IPADataSerializer<{{method|method_return_value}}>::serialize(_callRet); - _response.data().insert(_response.data().end(), _callRetBuf.cbegin(), _callRetBuf.cend()); -{%- endif %} - {{proxy_funcs.serialize_call(method|method_param_outputs, "_response.data()", "_response.fds()")|indent(16, true)}} - int _ret = socket_.send(_response.payload()); - if (_ret < 0) { - LOG({{proxy_worker_name}}, Error) - << "Reply to {{method.mojom_name}}() failed: " << _ret; - } - LOG({{proxy_worker_name}}, Debug) << "Done replying to {{method.mojom_name}}()"; -{%- endif %} - break; - } -{% endfor %} - default: - LOG({{proxy_worker_name}}, Error) << "Unknown command " << _ipcMessage.header().cmd; - } - } - - int init(std::unique_ptr<IPAModule> &ipam, UniqueFD socketfd) - { - if (socket_.bind(std::move(socketfd)) < 0) { - LOG({{proxy_worker_name}}, Error) - << "IPC socket binding failed"; - return EXIT_FAILURE; - } - socket_.readyRead.connect(this, &{{proxy_worker_name}}::readyRead); - - ipa_ = dynamic_cast<{{interface_name}} *>(ipam->createInterface()); - if (!ipa_) { - LOG({{proxy_worker_name}}, Error) - << "Failed to create IPA interface instance"; - return EXIT_FAILURE; - } -{% for method in interface_event.methods %} - ipa_->{{method.mojom_name}}.connect(this, &{{proxy_worker_name}}::{{method.mojom_name}}); -{%- endfor %} - return 0; - } - - void run() - { - EventDispatcher *dispatcher = Thread::current()->eventDispatcher(); - while (!exit_) - dispatcher->processEvents(); - } - - void cleanup() - { - delete ipa_; - socket_.close(); - } - -private: - -{% for method in interface_event.methods %} -{{proxy_funcs.func_sig(proxy_name, method, "", false)|indent(8, true)}} - { - IPCMessage::Header header = { - static_cast<uint32_t>({{cmd_event_enum_name}}::{{method.mojom_name|cap}}), - 0 - }; - IPCMessage _message(header); - - {{proxy_funcs.serialize_call(method|method_param_inputs, "_message.data()", "_message.fds()")}} - - int _ret = socket_.send(_message.payload()); - if (_ret < 0) - LOG({{proxy_worker_name}}, Error) - << "Sending event {{method.mojom_name}}() failed: " << _ret; - - LOG({{proxy_worker_name}}, Debug) << "{{method.mojom_name}} done"; - } -{% endfor %} - - {{interface_name}} *ipa_; - IPCUnixSocket socket_; - - ControlSerializer controlSerializer_; - - bool exit_; -}; - -int main(int argc, char **argv) -{ -{#- \todo Handle enabling debugging more dynamically. #} - /* Uncomment this for debugging. */ -#if 0 - std::string logPath = "/tmp/libcamera.worker." + - std::to_string(getpid()) + ".log"; - logSetFile(logPath.c_str()); -#endif - - if (argc < 3) { - LOG({{proxy_worker_name}}, Error) - << "Tried to start worker with no args: " - << "expected <path to IPA so> <fd to bind unix socket>"; - return EXIT_FAILURE; - } - - UniqueFD fd(std::stoi(argv[2])); - LOG({{proxy_worker_name}}, Info) - << "Starting worker for IPA module " << argv[1] - << " with IPC fd = " << fd.get(); - - std::unique_ptr<IPAModule> ipam = std::make_unique<IPAModule>(argv[1]); - if (!ipam->isValid() || !ipam->load()) { - LOG({{proxy_worker_name}}, Error) - << "IPAModule " << argv[1] << " isn't valid"; - return EXIT_FAILURE; - } - - /* - * Shutdown of proxy worker can be pre-empted by events like - * SIGINT/SIGTERM, even before the pipeline handler can request - * shutdown. Hence, assign a new gid to prevent signals on the - * application being delivered to the proxy. - */ - if (setpgid(0, 0) < 0) { - int err = errno; - LOG({{proxy_worker_name}}, Warning) - << "Failed to set new gid: " << strerror(err); - } - - {{proxy_worker_name}} proxyWorker; - int ret = proxyWorker.init(ipam, std::move(fd)); - if (ret < 0) { - LOG({{proxy_worker_name}}, Error) - << "Failed to initialize proxy worker"; - return ret; - } - - LOG({{proxy_worker_name}}, Debug) << "Proxy worker successfully initialized"; - - proxyWorker.run(); - - proxyWorker.cleanup(); - - return 0; -} diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_serializer.h.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_serializer.h.tmpl deleted file mode 100644 index cd5a65a9..00000000 --- a/utils/ipc/generators/libcamera_templates/module_ipa_serializer.h.tmpl +++ /dev/null @@ -1,45 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} -{%- import "serializer.tmpl" as serializer -%} - -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * Image Processing Algorithm data serializer for {{module_name}} - * - * This file is auto-generated. Do not edit. - */ - -#pragma once - -#include <tuple> -#include <vector> - -#include <libcamera/ipa/{{module_name}}_ipa_interface.h> -#include <libcamera/ipa/core_ipa_serializer.h> - -#include "libcamera/internal/control_serializer.h" -#include "libcamera/internal/ipa_data_serializer.h" - -namespace libcamera { - -LOG_DECLARE_CATEGORY(IPADataSerializer) -{% for struct in structs_nonempty %} -template<> -class IPADataSerializer<{{struct|name_full}}> -{ -public: -{{- serializer.serializer(struct, namespace_str)}} -{%- if struct|has_fd %} -{{serializer.deserializer_fd(struct, namespace_str)}} -{%- else %} -{{serializer.deserializer_no_fd(struct, namespace_str)}} -{{serializer.deserializer_fd_simple(struct, namespace_str)}} -{%- endif %} -}; -{% endfor %} - -} /* namespace libcamera */ diff --git a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl deleted file mode 100644 index b5797b14..00000000 --- a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl +++ /dev/null @@ -1,202 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} -{# - # \brief Generate function prototype - # - # \param class Class name - # \param method mojom Method object - # \param suffix Suffix to append to \a method function name - # \param need_class_name If true, generate class name with function - # \param override If true, generate override tag after the function prototype - #} -{%- macro func_sig(class, method, suffix = "", need_class_name = true, override = false) -%} -{{method|method_return_value}} {{class + "::" if need_class_name}}{{method.mojom_name}}{{suffix}}( -{%- for param in method|method_parameters %} - {{param}}{{- "," if not loop.last}} -{%- endfor -%} -){{" override" if override}} -{%- endmacro -%} - -{# - # \brief Generate function body for IPA stop() function for thread - #} -{%- macro stop_thread_body() -%} - ASSERT(state_ != ProxyStopping); - if (state_ != ProxyRunning) - return; - - state_ = ProxyStopping; - - proxy_.invokeMethod(&ThreadProxy::stop, ConnectionTypeBlocking); - - thread_.exit(); - thread_.wait(); - - Thread::current()->dispatchMessages(Message::Type::InvokeMessage); - - state_ = ProxyStopped; -{%- endmacro -%} - - -{# - # \brief Serialize multiple objects into data buffer and fd vector - # - # Generate code to serialize multiple objects, as specified in \a params - # (which are the parameters to some function), into \a buf data buffer and - # \a fds fd vector. - # This code is meant to be used by the proxy, for serializing prior to IPC calls. - # - # \todo Avoid intermediate vectors - #} -{%- macro serialize_call(params, buf, fds) %} -{%- for param in params %} -{%- if param|is_enum %} - static_assert(sizeof({{param|name_full}}) <= 4); -{%- endif %} - std::vector<uint8_t> {{param.mojom_name}}Buf; -{%- if param|has_fd %} - std::vector<SharedFD> {{param.mojom_name}}Fds; - std::tie({{param.mojom_name}}Buf, {{param.mojom_name}}Fds) = -{%- else %} - std::tie({{param.mojom_name}}Buf, std::ignore) = -{%- endif %} -{%- if param|is_flags %} - IPADataSerializer<{{param|name_full}}>::serialize({{param.mojom_name}} -{%- elif param|is_enum %} - IPADataSerializer<uint32_t>::serialize(static_cast<uint32_t>({{param.mojom_name}}) -{%- else %} - IPADataSerializer<{{param|name}}>::serialize({{param.mojom_name}} -{% endif -%} -{{- ", &controlSerializer_" if param|needs_control_serializer -}} -); -{%- endfor %} - -{%- if params|length > 1 %} -{%- for param in params %} - appendPOD<uint32_t>({{buf}}, {{param.mojom_name}}Buf.size()); -{%- if param|has_fd %} - appendPOD<uint32_t>({{buf}}, {{param.mojom_name}}Fds.size()); -{%- endif %} -{%- endfor %} -{%- endif %} - -{%- for param in params %} - {{buf}}.insert({{buf}}.end(), {{param.mojom_name}}Buf.begin(), {{param.mojom_name}}Buf.end()); -{%- endfor %} - -{%- for param in params %} -{%- if param|has_fd %} - {{fds}}.insert({{fds}}.end(), {{param.mojom_name}}Fds.begin(), {{param.mojom_name}}Fds.end()); -{%- endif %} -{%- endfor %} -{%- endmacro -%} - - -{# - # \brief Deserialize a single object from data buffer and fd vector - # - # \param pointer If true, deserialize the object into a dereferenced pointer - # \param iter If true, treat \a buf as an iterator instead of a vector - # \param data_size Variable that holds the size of the vector referenced by \a buf - # - # Generate code to deserialize a single object, as specified in \a param, - # from \a buf data buffer and \a fds fd vector. - # This code is meant to be used by macro deserialize_call. - #} -{%- macro deserialize_param(param, pointer, loop, buf, fds, iter, data_size) -%} -{{"*" if pointer}}{{param.mojom_name}} = -{%- if param|is_flags %} -IPADataSerializer<{{param|name_full}}>::deserialize( -{%- elif param|is_enum %} -static_cast<{{param|name_full}}>(IPADataSerializer<uint32_t>::deserialize( -{%- else %} -IPADataSerializer<{{param|name}}>::deserialize( -{%- endif %} - {{buf}}{{- ".cbegin()" if not iter}} + {{param.mojom_name}}Start, -{%- if loop.last and not iter %} - {{buf}}.cend() -{%- elif not iter %} - {{buf}}.cbegin() + {{param.mojom_name}}Start + {{param.mojom_name}}BufSize -{%- elif iter and loop.length == 1 %} - {{buf}} + {{data_size}} -{%- else %} - {{buf}} + {{param.mojom_name}}Start + {{param.mojom_name}}BufSize -{%- endif -%} -{{- "," if param|has_fd}} -{%- if param|has_fd %} - {{fds}}.cbegin() + {{param.mojom_name}}FdStart, -{%- if loop.last %} - {{fds}}.cend() -{%- else %} - {{fds}}.cbegin() + {{param.mojom_name}}FdStart + {{param.mojom_name}}FdsSize -{%- endif -%} -{%- endif -%} -{{- "," if param|needs_control_serializer}} -{%- if param|needs_control_serializer %} - &controlSerializer_ -{%- endif -%} -){{")" if param|is_enum and not param|is_flags}}; -{%- endmacro -%} - - -{# - # \brief Deserialize multiple objects from data buffer and fd vector - # - # \param pointer If true, deserialize objects into pointers, and adds a null check. - # \param declare If true, declare the objects in addition to deserialization. - # \param iter if true, treat \a buf as an iterator instead of a vector - # \param data_size Variable that holds the size of the vector referenced by \a buf - # - # Generate code to deserialize multiple objects, as specified in \a params - # (which are the parameters to some function), from \a buf data buffer and - # \a fds fd vector. - # This code is meant to be used by the proxy, for deserializing after IPC calls. - # - # \todo Avoid intermediate vectors - #} -{%- macro deserialize_call(params, buf, fds, pointer = true, declare = false, iter = false, data_size = '', init_offset = 0) -%} -{% set ns = namespace(size_offset = init_offset) %} -{%- if params|length > 1 %} -{%- for param in params %} - [[maybe_unused]] const size_t {{param.mojom_name}}BufSize = readPOD<uint32_t>({{buf}}, {{ns.size_offset}} -{%- if iter -%} -, {{buf}} + {{data_size}} -{%- endif -%} -); - {%- set ns.size_offset = ns.size_offset + 4 %} -{%- if param|has_fd %} - [[maybe_unused]] const size_t {{param.mojom_name}}FdsSize = readPOD<uint32_t>({{buf}}, {{ns.size_offset}} -{%- if iter -%} -, {{buf}} + {{data_size}} -{%- endif -%} -); - {%- set ns.size_offset = ns.size_offset + 4 %} -{%- endif %} -{%- endfor %} -{%- endif %} -{% for param in params %} -{%- if loop.first %} - const size_t {{param.mojom_name}}Start = {{ns.size_offset}}; -{%- else %} - const size_t {{param.mojom_name}}Start = {{loop.previtem.mojom_name}}Start + {{loop.previtem.mojom_name}}BufSize; -{%- endif %} -{%- endfor %} -{% for param in params|with_fds %} -{%- if loop.first %} - const size_t {{param.mojom_name}}FdStart = 0; -{%- else %} - const size_t {{param.mojom_name}}FdStart = {{loop.previtem.mojom_name}}FdStart + {{loop.previtem.mojom_name}}FdsSize; -{%- endif %} -{%- endfor %} -{% for param in params %} - {%- if pointer %} - if ({{param.mojom_name}}) { -{{deserialize_param(param, pointer, loop, buf, fds, iter, data_size)|indent(16, True)}} - } - {%- else %} - {{param|name + " " if declare}}{{deserialize_param(param, pointer, loop, buf, fds, iter, data_size)|indent(8)}} - {%- endif %} -{% endfor %} -{%- endmacro -%} diff --git a/utils/ipc/generators/libcamera_templates/serializer.tmpl b/utils/ipc/generators/libcamera_templates/serializer.tmpl deleted file mode 100644 index 323e1293..00000000 --- a/utils/ipc/generators/libcamera_templates/serializer.tmpl +++ /dev/null @@ -1,319 +0,0 @@ -{#- - # SPDX-License-Identifier: LGPL-2.1-or-later - # Copyright (C) 2020, Google Inc. --#} -{# - # \brief Verify that there is enough bytes to deserialize - # - # Generate code that verifies that \a size is not greater than \a dataSize. - # Otherwise log an error with \a name and \a typename. - #} -{%- macro check_data_size(size, dataSize, name, typename) %} - if ({{dataSize}} < {{size}}) { - LOG(IPADataSerializer, Error) - << "Failed to deserialize " << "{{name}}" - << ": not enough {{typename}}, expected " - << ({{size}}) << ", got " << ({{dataSize}}); - return ret; - } -{%- endmacro %} - - -{# - # \brief Serialize a field into return vector - # - # Generate code to serialize \a field into retData, including size of the - # field and fds (where appropriate). - # This code is meant to be used by the IPADataSerializer specialization. - # - # \todo Avoid intermediate vectors - #} -{%- macro serializer_field(field, namespace, loop) %} -{%- if field|is_pod or field|is_enum %} - std::vector<uint8_t> {{field.mojom_name}}; - std::tie({{field.mojom_name}}, std::ignore) = - {%- if field|is_pod %} - IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}}); - {%- elif field|is_flags %} - IPADataSerializer<{{field|name_full}}>::serialize(data.{{field.mojom_name}}); - {%- elif field|is_enum_scoped %} - IPADataSerializer<uint{{field|bit_width}}_t>::serialize(static_cast<uint{{field|bit_width}}_t>(data.{{field.mojom_name}})); - {%- elif field|is_enum %} - IPADataSerializer<uint{{field|bit_width}}_t>::serialize(data.{{field.mojom_name}}); - {%- endif %} - retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end()); -{%- elif field|is_fd %} - std::vector<uint8_t> {{field.mojom_name}}; - std::vector<SharedFD> {{field.mojom_name}}Fds; - std::tie({{field.mojom_name}}, {{field.mojom_name}}Fds) = - IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}}); - retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end()); - retFds.insert(retFds.end(), {{field.mojom_name}}Fds.begin(), {{field.mojom_name}}Fds.end()); -{%- elif field|is_controls %} - if (data.{{field.mojom_name}}.size() > 0) { - std::vector<uint8_t> {{field.mojom_name}}; - std::tie({{field.mojom_name}}, std::ignore) = - IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}}, cs); - appendPOD<uint32_t>(retData, {{field.mojom_name}}.size()); - retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end()); - } else { - appendPOD<uint32_t>(retData, 0); - } -{%- elif field|is_plain_struct or field|is_array or field|is_map or field|is_str %} - std::vector<uint8_t> {{field.mojom_name}}; - {%- if field|has_fd %} - std::vector<SharedFD> {{field.mojom_name}}Fds; - std::tie({{field.mojom_name}}, {{field.mojom_name}}Fds) = - {%- else %} - std::tie({{field.mojom_name}}, std::ignore) = - {%- endif %} - {%- if field|is_array or field|is_map %} - IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}}, cs); - {%- elif field|is_str %} - IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}}); - {%- else %} - IPADataSerializer<{{field|name_full}}>::serialize(data.{{field.mojom_name}}, cs); - {%- endif %} - appendPOD<uint32_t>(retData, {{field.mojom_name}}.size()); - {%- if field|has_fd %} - appendPOD<uint32_t>(retData, {{field.mojom_name}}Fds.size()); - {%- endif %} - retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end()); - {%- if field|has_fd %} - retFds.insert(retFds.end(), {{field.mojom_name}}Fds.begin(), {{field.mojom_name}}Fds.end()); - {%- endif %} -{%- else %} - /* Unknown serialization for {{field.mojom_name}}. */ -{%- endif %} -{%- endmacro %} - - -{# - # \brief Deserialize a field into return struct - # - # Generate code to deserialize \a field into object ret. - # This code is meant to be used by the IPADataSerializer specialization. - #} -{%- macro deserializer_field(field, namespace, loop) %} -{% if field|is_pod or field|is_enum %} - {%- set field_size = (field|bit_width|int / 8)|int %} - {{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}} - {%- if field|is_pod %} - ret.{{field.mojom_name}} = IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field_size}}); - {%- elif field|is_flags %} - ret.{{field.mojom_name}} = IPADataSerializer<{{field|name_full}}>::deserialize(m, m + {{field_size}}); - {%- else %} - ret.{{field.mojom_name}} = static_cast<{{field|name_full}}>(IPADataSerializer<uint{{field|bit_width}}_t>::deserialize(m, m + {{field_size}})); - {%- endif %} - {%- if not loop.last %} - m += {{field_size}}; - dataSize -= {{field_size}}; - {%- endif %} -{% elif field|is_fd %} - {%- set field_size = 4 %} - {{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}} - ret.{{field.mojom_name}} = IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field_size}}, n, n + 1, cs); - {%- if not loop.last %} - m += {{field_size}}; - dataSize -= {{field_size}}; - n += ret.{{field.mojom_name}}.isValid() ? 1 : 0; - fdsSize -= ret.{{field.mojom_name}}.isValid() ? 1 : 0; - {%- endif %} -{% elif field|is_controls %} - {%- set field_size = 4 %} - {{- check_data_size(field_size, 'dataSize', field.mojom_name + 'Size', 'data')}} - const size_t {{field.mojom_name}}Size = readPOD<uint32_t>(m, 0, dataEnd); - m += {{field_size}}; - dataSize -= {{field_size}}; - {%- set field_size = field.mojom_name + 'Size' -%} - {{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}} - if ({{field.mojom_name}}Size > 0) - ret.{{field.mojom_name}} = - IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field.mojom_name}}Size, cs); - {%- if not loop.last %} - m += {{field_size}}; - dataSize -= {{field_size}}; - {%- endif %} -{% elif field|is_plain_struct or field|is_array or field|is_map or field|is_str %} - {%- set field_size = 4 %} - {{- check_data_size(field_size, 'dataSize', field.mojom_name + 'Size', 'data')}} - const size_t {{field.mojom_name}}Size = readPOD<uint32_t>(m, 0, dataEnd); - m += {{field_size}}; - dataSize -= {{field_size}}; - {%- if field|has_fd %} - {%- set field_size = 4 %} - {{- check_data_size(field_size, 'dataSize', field.mojom_name + 'FdsSize', 'data')}} - const size_t {{field.mojom_name}}FdsSize = readPOD<uint32_t>(m, 0, dataEnd); - m += {{field_size}}; - dataSize -= {{field_size}}; - {{- check_data_size(field.mojom_name + 'FdsSize', 'fdsSize', field.mojom_name, 'fds')}} - {%- endif %} - {%- set field_size = field.mojom_name + 'Size' -%} - {{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}} - ret.{{field.mojom_name}} = - {%- if field|is_str %} - IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field.mojom_name}}Size); - {%- elif field|has_fd and (field|is_array or field|is_map) %} - IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field.mojom_name}}Size, n, n + {{field.mojom_name}}FdsSize, cs); - {%- elif field|has_fd and (not (field|is_array or field|is_map)) %} - IPADataSerializer<{{field|name_full}}>::deserialize(m, m + {{field.mojom_name}}Size, n, n + {{field.mojom_name}}FdsSize, cs); - {%- elif (not field|has_fd) and (field|is_array or field|is_map) %} - IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field.mojom_name}}Size, cs); - {%- else %} - IPADataSerializer<{{field|name_full}}>::deserialize(m, m + {{field.mojom_name}}Size, cs); - {%- endif %} - {%- if not loop.last %} - m += {{field_size}}; - dataSize -= {{field_size}}; - {%- if field|has_fd %} - n += {{field.mojom_name}}FdsSize; - fdsSize -= {{field.mojom_name}}FdsSize; - {%- endif %} - {%- endif %} -{% else %} - /* Unknown deserialization for {{field.mojom_name}}. */ -{%- endif %} -{%- endmacro %} - - -{# - # \brief Serialize a struct - # - # Generate code for IPADataSerializer specialization, for serializing - # \a struct. - #} -{%- macro serializer(struct, namespace) %} - static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>> - serialize(const {{struct|name_full}} &data, -{%- if struct|needs_control_serializer %} - ControlSerializer *cs) -{%- else %} - [[maybe_unused]] ControlSerializer *cs = nullptr) -{%- endif %} - { - std::vector<uint8_t> retData; -{%- if struct|has_fd %} - std::vector<SharedFD> retFds; -{%- endif %} -{%- for field in struct.fields %} -{{serializer_field(field, namespace, loop)}} -{%- endfor %} -{% if struct|has_fd %} - return {retData, retFds}; -{%- else %} - return {retData, {}}; -{%- endif %} - } -{%- endmacro %} - - -{# - # \brief Deserialize a struct that has fds - # - # Generate code for IPADataSerializer specialization, for deserializing - # \a struct, in the case that \a struct has file descriptors. - #} -{%- macro deserializer_fd(struct, namespace) %} - static {{struct|name_full}} - deserialize(std::vector<uint8_t> &data, - std::vector<SharedFD> &fds, -{%- if struct|needs_control_serializer %} - ControlSerializer *cs) -{%- else %} - ControlSerializer *cs = nullptr) -{%- endif %} - { - return IPADataSerializer<{{struct|name_full}}>::deserialize(data.cbegin(), data.cend(), fds.cbegin(), fds.cend(), cs); - } - -{# \todo Don't inline this function #} - static {{struct|name_full}} - deserialize(std::vector<uint8_t>::const_iterator dataBegin, - std::vector<uint8_t>::const_iterator dataEnd, - std::vector<SharedFD>::const_iterator fdsBegin, - std::vector<SharedFD>::const_iterator fdsEnd, -{%- if struct|needs_control_serializer %} - ControlSerializer *cs) -{%- else %} - [[maybe_unused]] ControlSerializer *cs = nullptr) -{%- endif %} - { - {{struct|name_full}} ret; - std::vector<uint8_t>::const_iterator m = dataBegin; - std::vector<SharedFD>::const_iterator n = fdsBegin; - - size_t dataSize = std::distance(dataBegin, dataEnd); - [[maybe_unused]] size_t fdsSize = std::distance(fdsBegin, fdsEnd); -{%- for field in struct.fields -%} -{{deserializer_field(field, namespace, loop)}} -{%- endfor %} - return ret; - } -{%- endmacro %} - -{# - # \brief Deserialize a struct that has fds, using non-fd - # - # Generate code for IPADataSerializer specialization, for deserializing - # \a struct, in the case that \a struct has no file descriptors but requires - # deserializers with file descriptors. - #} -{%- macro deserializer_fd_simple(struct, namespace) %} - static {{struct|name_full}} - deserialize(std::vector<uint8_t> &data, - [[maybe_unused]] std::vector<SharedFD> &fds, - ControlSerializer *cs = nullptr) - { - return IPADataSerializer<{{struct|name_full}}>::deserialize(data.cbegin(), data.cend(), cs); - } - - static {{struct|name_full}} - deserialize(std::vector<uint8_t>::const_iterator dataBegin, - std::vector<uint8_t>::const_iterator dataEnd, - [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin, - [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd, - ControlSerializer *cs = nullptr) - { - return IPADataSerializer<{{struct|name_full}}>::deserialize(dataBegin, dataEnd, cs); - } -{%- endmacro %} - - -{# - # \brief Deserialize a struct that has no fds - # - # Generate code for IPADataSerializer specialization, for deserializing - # \a struct, in the case that \a struct does not have file descriptors. - #} -{%- macro deserializer_no_fd(struct, namespace) %} - static {{struct|name_full}} - deserialize(std::vector<uint8_t> &data, -{%- if struct|needs_control_serializer %} - ControlSerializer *cs) -{%- else %} - ControlSerializer *cs = nullptr) -{%- endif %} - { - return IPADataSerializer<{{struct|name_full}}>::deserialize(data.cbegin(), data.cend(), cs); - } - -{# \todo Don't inline this function #} - static {{struct|name_full}} - deserialize(std::vector<uint8_t>::const_iterator dataBegin, - std::vector<uint8_t>::const_iterator dataEnd, -{%- if struct|needs_control_serializer %} - ControlSerializer *cs) -{%- else %} - [[maybe_unused]] ControlSerializer *cs = nullptr) -{%- endif %} - { - {{struct|name_full}} ret; - std::vector<uint8_t>::const_iterator m = dataBegin; - - size_t dataSize = std::distance(dataBegin, dataEnd); -{%- for field in struct.fields -%} -{{deserializer_field(field, namespace, loop)}} -{%- endfor %} - return ret; - } -{%- endmacro %} |