+++ /dev/null
-install_headers(
- 'mmi-primitive-value.h',
- 'mmi-data.h',
- 'mmi-attribute.h',
- 'mmi-error.h',
- 'mmi-workflow.h',
- 'mmi-node.h',
- 'mmi-node-source.h',
- 'mmi-node-processor.h',
- 'mmi-node-logic.h',
- 'mmi-node-controller.h',
- 'mmi-node-action.h',
- 'mmi-node-custom.h',
- 'mmi-port.h',
- 'mmi-signal.h',
- 'mmi-defines.h',
- 'mmi-plugin-module.h',
- 'mmi-plugin-storage.h',
- 'mmi.h',
- 'mmi-config-parser.h',
- )
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_ATTRIBUTE_H__
-#define __TIZEN_UIX_MMI_ATTRIBUTE_H__
-
-
-#include "mmi-platform-config.h"
-#include <stdlib.h>
-#include <mmi-primitive-value.h>
-
-
-/**
-* @file mmi-attribute.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct mmi_attribute_s* mmi_attribute_h;
-
-
-int mmi_attribute_create(mmi_primitive_value_h value, const char *name, mmi_attribute_h *attribute);
-
-int mmi_attribute_set_name(mmi_attribute_h attribute, const char *name);
-
-int mmi_attribute_get_name(mmi_attribute_h attribute, char **name);
-
-int mmi_attribute_get_value(mmi_attribute_h attribute, mmi_primitive_value_h *value);
-
-int mmi_attribute_clone(mmi_attribute_h attribute, mmi_attribute_h *cloned);
-
-int mmi_attribute_destroy(mmi_attribute_h attribute);
-
-int mmi_attribute_to_bytes(mmi_attribute_h attribute, unsigned char **bytes, size_t *length);
-
-int mmi_attribute_from_bytes(const unsigned char *bytes, size_t length, mmi_attribute_h *attribute);
-
-/* Utility functions */
-int mmi_attribute_create_string_array(const char *name, const char *strings[], size_t count, mmi_attribute_h *attribute);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_ATTRIBUTE_H__ */
+++ /dev/null
-/*
- * Copyright © 2023 Samsung Electronics co., Ltd. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef __MMI_CONFIG_PARSER_H_
-#define __MMI_CONFIG_PARSER_H_
-
-#include <glib.h>
-#include <libxml/parser.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef struct {
- float confidence;
-} mmi_config_s;
-
-int mmi_parser_initialize(void);
-int mmi_parser_deinitialize(void);
-int mmi_parser_get_confidence(float *confidence);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MMI_CONFIG_PARSER_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_DATA_H__
-#define __TIZEN_UIX_MMI_DATA_H__
-
-
-#include "mmi-platform-config.h"
-#include <stdlib.h>
-
-
-/**
-* @file mmi-data.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef enum {
- MMI_DATA_TYPE_BOOLEAN,
- MMI_DATA_TYPE_INTEGER,
- MMI_DATA_TYPE_FLOAT,
- MMI_DATA_TYPE_TEXT,
- MMI_DATA_TYPE_JSON,
- MMI_DATA_TYPE_USER_IDENTIFICATION,
- MMI_DATA_TYPE_AUDIO,
- MMI_DATA_TYPE_VIDEO,
- MMI_DATA_TYPE_COORDINATE,
- MMI_DATA_TYPE_BOUNDING_BOX,
- MMI_DATA_TYPE_ARRAY,
- MMI_DATA_TYPE_STRUCT,
- MMI_DATA_TYPE_ANY,
-} mmi_data_type_e;
-
-/* Data Format */
-/*
-- MMI_DATA_BOOLEAN
- data : pointer to a byte
- datalen : 1 byte
- description : false if all bits are 0, true otherwise
-
-- MMI_DATA_INTEGER
- data : pointer to a signed integer type
- datalen : 4 bytes
- description : cast 'data' to a 32-bit signed integer (e.g. int)
-
-- MMI_DATA_FLOAT
- data : pointer to a floating-point type
- datalen : 4 bytes
- description : cast 'data' to a 32-bit floating-point type (e.g. float)
-
-- MMI_DATA_TEXT
- data : pointer to a null-terminated string
- datalen : length of the text
- description : cast 'data' to a char*
-
-- MMI_DATA_JSON
- data : pointer to a null-terminated string
- datalen : length of the json string
- description : cast 'data' to a char*
-
-- MMI_DATA_USER_IDENTIFICATION
- data : pointer to a platform-dependent id for a user
- datalen : platform-dependent
- description : this value can be used to acquire platform-dependent user information
-
-- MMI_DATA_AUDIO
- data : pointer to bytes
- datalen : size of 'data' in bytes
- format:
- {
- "bitrate" : 48000,
- "format" : {
- "signed" : true,
- "bits" : 16
- },
- "channels" : 1
- }
- description : audio frame data
-
-- MMI_DATA_VIDEO
- data : pointer to bytes
- datalen : size of 'data' in bytes
- format:
- {
- "width":1920,
- "height":1080,
- "encoding":"mp4"
- }
- description : video frame data
-
-- MMI_DATA_COORDINATE
- data : pointer to an array of 2 signed integers
- datalen : 8 bytes
- description : data is composed in below order
- [ x , y ]
-
-- MMI_DATA_BOUNDING_BOX
- data : pointer to an array of 4 signed integers
- datalen : 16 bytes
- description : data is composed in below order
- [ x , y , w , h ]
-
-- MMI_DATA_ARRAY
- data : pointer to an array of mmi_data_h struct
- datalen : size of a pointer * number of items
- description : A container that can hold multiple mmi_data_h with the same type.
-
-- MMI_DATA_STRUCT
- data : pointer to an array of mmi_data_h struct
- datalen : size of a pointer * number of items * 2 (one for key, one for value)
- description : A container that can hold multiple mmi_data_h with different types.
- A key is a MMI_DATA_TEXT that identifies the value.
-- MMI_DATA_ANY
- data : pointer to an mmi_data_h struct
- datalen : size of a pointer
- description : Represents a data type that can be any of the above types.
-*/
-
-
-
-
-typedef struct mmi_data_timestamp_s *mmi_data_timestamp_h;
-
-typedef struct mmi_data_s *mmi_data_h;
-
-int mmi_data_create_bool(bool value, mmi_data_h *data);
-
-int mmi_data_create_int(int value, mmi_data_h *data);
-
-int mmi_data_create_float(float value, mmi_data_h *data);
-
-int mmi_data_create_text(const char *value, mmi_data_h *data);
-
-int mmi_data_create_audio(const void *ptr, size_t len, mmi_data_h *data);
-
-int mmi_data_create_video(const void *ptr, size_t len, mmi_data_h *data);
-
-int mmi_data_create_user_identification(const void *ptr, size_t len, mmi_data_h *data);
-
-int mmi_data_create_coordinate(int x, int y, mmi_data_h *data);
-
-int mmi_data_create_bounding_box(int x, int y, int w, int h, mmi_data_h *data);
-
-int mmi_data_create_array(mmi_data_h *array_handle);
-
-int mmi_data_add_array_element(mmi_data_h array_handle, mmi_data_h element);
-
-int mmi_data_create_struct(mmi_data_h *struct_handle);
-
-int mmi_data_set_struct_element(mmi_data_h struct_handle, const char *name, mmi_data_h element);
-
-int mmi_data_get_type(mmi_data_h data, mmi_data_type_e *type);
-
-int mmi_data_get_bool(mmi_data_h data, bool *value);
-
-int mmi_data_get_int(mmi_data_h data, int *value);
-
-int mmi_data_get_float(mmi_data_h data, float *value);
-
-int mmi_data_get_text(mmi_data_h data, const char **string);
-
-int mmi_data_get_audio(mmi_data_h data, const void **ptr, size_t *len);
-
-int mmi_data_get_video(mmi_data_h data, const void **ptr, size_t *len);
-
-int mmi_data_get_user_identification(mmi_data_h data, const void **ptr, size_t *len);
-
-int mmi_data_get_coordinate(mmi_data_h data, int *x, int *y);
-
-int mmi_data_get_bounding_box(mmi_data_h data, int *x, int *y, int *w, int *h);
-
-int mmi_data_get_array_count(mmi_data_h array, size_t *count);
-
-int mmi_data_get_array_element(mmi_data_h array, size_t index, mmi_data_h *element);
-
-int mmi_data_get_struct_element(mmi_data_h struct_handle, const char *name, mmi_data_h *element);
-
-int mmi_data_get_struct_count(mmi_data_h struct_handle, size_t *count);
-
-int mmi_data_get_struct_element_name(mmi_data_h struct_handle, size_t index, const char **string);
-
-int mmi_data_get_struct_element_value(mmi_data_h struct_handle, size_t index, mmi_data_h *element);
-
-int mmi_data_get_node_timestamp(mmi_data_h data, mmi_data_timestamp_h *timestamp);
-
-int mmi_data_get_source_timestamp(mmi_data_h data, mmi_data_timestamp_h *timestamp);
-
-int mmi_data_set_source_timestamp(mmi_data_h data, mmi_data_timestamp_h timestamp);
-
-int mmi_data_to_bytes(mmi_data_h data, unsigned char **bytes, size_t *length);
-
-int mmi_data_from_bytes(unsigned char *bytes, size_t length, mmi_data_h *data);
-
-int mmi_data_destroy(mmi_data_h data);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_DATA_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_DEFINES_H__
-#define __TIZEN_UIX_MMI_DEFINES_H__
-
-
-/**
-* @file mmi-defines.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define MMI_NAME_MAX_LENGTH 32
-#define MMI_PARAMETER_MAX_COUNT 32
-#define MMI_PORT_MAX_COUNT 32
-#define MMI_NODE_MAX_COUNT 128
-#define MMI_LINK_MAX_COUNT 128
-#define MMI_OUTPUT_MAX_COUNT 32
-#define MMI_WORKFLOW_MAX_COUNT 64
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_DEFINES_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_ERROR_H__
-#define __TIZEN_UIX_MMI_ERROR_H__
-
-
-#include "mmi-platform-config.h"
-
-
-/**
-* @file mmi-error.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef enum {
- MMI_ERROR_NONE = PLATFORM_ERROR_NONE, /**< Successful */
- MMI_ERROR_OUT_OF_MEMORY = PLATFORM_ERROR_OUT_OF_MEMORY, /**< Out of Memory */
- MMI_ERROR_IO_ERROR = PLATFORM_ERROR_IO_ERROR, /**< I/O error */
- MMI_ERROR_INVALID_PARAMETER = PLATFORM_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- MMI_ERROR_TIMED_OUT = PLATFORM_ERROR_TIMED_OUT, /**< No answer from the daemon */
- MMI_ERROR_PERMISSION_DENIED = PLATFORM_ERROR_PERMISSION_DENIED, /**< Permission denied */
- MMI_ERROR_NOT_SUPPORTED = PLATFORM_ERROR_NOT_SUPPORTED, /**< MMI NOT supported */
- MMI_ERROR_OPERATION_FAILED = PLATFORM_ERROR_OPERATION_FAILED, /**< Operation failed */
- MMI_ERROR_RESOURCE_BUSY = PLATFORM_ERROR_RESOURCE_BUSY, /**< Resource busy */
-} mmi_error_e;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_ERROR_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_NODE_ACTION_H__
-#define __TIZEN_UIX_MMI_NODE_ACTION_H__
-
-
-
-#include <mmi-node.h>
-
-/**
-* @file mmi-node-action.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-enum mmi_node_action_type_e {
- MMI_NODE_ACTION_TYPE_NONE,
-
- /* - Description : Emits a mouse event
- - Attributes :
- - "EVENT" : string
- Default : "CLICK"
- Description : The type of mouse event to emit
- Supported values are : "CLICK", "DOWN", "UP"
- - Input Port 1
- Name : "COORDINATE"
- Data Type : MMI_DATA_TYPE_COORDINATE
- Description : When a coordinate data is received, emits a mouse event
- */
- MMI_NODE_ACTION_TYPE_MOUSE_EVENT,
-
- MMI_NODE_ACTION_TYPE_KEY_EVENT,
-};
-
-int mmi_node_create_action(mmi_node_action_type_e type, mmi_node_h *node);
-
-int mmi_node_get_action_type(mmi_node_h node, mmi_node_action_type_e *type);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_NODE_LOGIC_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_NODE_CONTROLLER_H__
-#define __TIZEN_UIX_MMI_NODE_CONTROLLER_H__
-
-
-
-#include <mmi-node.h>
-
-/**
-* @file mmi-node-controller.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-enum mmi_node_controller_type_e {
- MMI_NODE_CONTROLLER_TYPE_NONE,
-
- /* - Description : Turns the node with a name specified in the attribute "TARGET" on or off
- - Attributes :
- "TARGET" : string
- - Input Port 1
- Name : "VALUE"
- Data Type : MMI_DATA_TYPE_BOOLEAN
- */
- MMI_NODE_CONTROLLER_TYPE_SWITCH,
-};
-
-int mmi_node_create_controller(mmi_node_controller_type_e type, mmi_node_h *node);
-
-int mmi_node_get_controller_type(mmi_node_h node, mmi_node_controller_type_e *type);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_NODE_LOGIC_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_NODE_CUSTOM_H__
-#define __TIZEN_UIX_MMI_NODE_CUSTOM_H__
-
-
-
-#include <mmi-node.h>
-
-/**
-* @file mmi-node-custom.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int mmi_node_create_custom(const char *custom_type_id, mmi_node_h *node);
-
-int mmi_node_get_custom_type(mmi_node_h node, const char **custom_type_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_NODE_CUSTOM_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_NODE_LOGIC_H__
-#define __TIZEN_UIX_MMI_NODE_LOGIC_H__
-
-
-
-#include <mmi-node.h>
-
-/**
-* @file mmi-node-logic.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-enum mmi_node_logic_type_e {
- MMI_NODE_LOGIC_TYPE_NONE,
-
- /*
- - Description : Compares the text received from the input port 1 ("TEXT") with
- 1) the fixed strings specified in the attribute "CANDIDATES"
- 2) the array of texts received from input port 2 ("TEXT_ARRAY")
- 3) the array of structs received from input port 3 ("STRUCT_ARRAY"),
- for the element specified in the attribute "COMPARAND_STRUCT_ELEMENT"
- ex) if the struct has two elements named "label" and "text", and
- "COMPARAND_STRUCT_ELEMENT" is "label", then the value of
- "label" will be compared with the text received from input port 1
- And outputs the mmi_data_t to the corresponding OUT port when matched.
- ex1) if the text received from input port 1 is "Hello", and the fixed strings
- specified in the attribute "CANDIDATES" is ["Hello", "World"], then the
- text "Hello" will be sent to output port 1.
- ex2) if the text received from input port 1 is "Hello", and the array of texts
- received from input port 2 is ["Hello", "World", "Goodbye"], then the
- text "Hello" will be sent to output port 2.
- ex3) if the text received from input port 1 is "Hello", with the attribute
- "COMPARAND_STRUCT_ELEMENT" set to "label", and the array of structs
- received from input port 3 is like below,
- [
- {"label":"Hello"},
- {"label":"World"},
- {"label":"Goodbye"}
- ]
- then the struct {"label":"Hello"} will be sent to output port 3.
- - Attributes :
- "CANDIDATES" : array [ string ]
- "COMPARAND_STRUCT_ELEMENT" : string
- - Input Port 1
- Name : "TEXT"
- Data Type : MMI_DATA_TYPE_TEXT
- - Input Port 2
- Name : "TEXT_ARRAY"
- Data Type : MMI_DATA_TYPE_ARRAY [ MMI_DATA_TYPE_TEXT ]
- - Input Port 3
- Name : "STRUCT_ARRAY"
- Data Type : MMI_DATA_TYPE_ARRAY [ MMI_DATA_TYPE_STRUCT ]
- - Output Port 1
- Name : "MATCHED_CANDIDATE"
- Data Type : MMI_DATA_TYPE_TEXT
- - Output Port 2
- Name : "MATCHED_TEXT_ARRAY"
- Data Type : MMI_DATA_TYPE_TEXT
- - Output Port 3
- Name : "MATCHED_STRUCT_ARRAY"
- Data Type : MMI_DATA_TYPE_STRUCT
- */
- MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH,
-
- /*
- - Description : Tests if the regex strings specified in the attribute "REGEX" with
- 1) the text received from the input port 1 ("TEXT") matches
- 2) the array of texts received from input port 2 ("TEXT_ARRAY")
- 3) the array of structs received from input port 3 ("STRUCT_ARRAY"),
- for the element specified in the attribute "COMPARAND_STRUCT_ELEMENT"
- - Attributes :
- "REGEX" : array [ string ]
- "COMPARAND_STRUCT_ELEMENT" : string
- - Input Port 1
- Name : "TEXT"
- Data Type : MMI_DATA_TYPE_TEXT
- - Input Port 2
- Name : "TEXT_ARRAY"
- Data Type : MMI_DATA_TYPE_ARRAY [ MMI_DATA_TYPE_TEXT ]
- - Input Port 3
- Name : "STRUCT_ARRAY"
- Data Type : MMI_DATA_TYPE_ARRAY [ MMI_DATA_TYPE_STRUCT ]
- - Output Port 1
- Name : "MATCHED_TEXT"
- Data Type : MMI_DATA_TYPE_TEXT
- - Output Port 2
- Name : "MATCHED_TEXT_ARRAY"
- Data Type : MMI_DATA_TYPE_TEXT
- - Output Port 3
- Name : "MATCHED_STRUCT_ARRAY"
- Data Type : MMI_DATA_TYPE_STRUCT
- */
- MMI_NODE_LOGIC_TYPE_REGEX_STRING_MATCH,
-
-
- /*
- - Description : Compares the User Recognition Struct from each input ports
- and selects the one with the highest score.
- - Input Port 1
- Name : "Port1"
- Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT
- Format of MMI_DATA_TYPE_STRUCT :
- - "USER" : MMI_DATA_TYPE_USER_IDENTIFICATION
- - "SCORE" : MMI_DATA_TYPE_FLOAT
- - Input Port 2
- Name : "Port2"
- Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT
- Format of MMI_DATA_TYPE_STRUCT :
- - "USER" : MMI_DATA_TYPE_USER_IDENTIFICATION
- - "SCORE" : MMI_DATA_TYPE_FLOAT
- - Output Port 1
- Name : "BYPASS_RESULT"
- Data Type : MMI_DATA_TYPE_USER_IDENTIFICATION
- - Output Port 2
- Name : "COMPARISON_RESULT"
- Data Type : MMI_DATA_TYPE_USER_IDENTIFICATION
- */
- MMI_NODE_LOGIC_TYPE_USER_COMPARISON,
-};
-
-int mmi_node_create_logic(mmi_node_logic_type_e type, mmi_node_h *node);
-
-int mmi_node_get_logic_type(mmi_node_h node, mmi_node_logic_type_e *type);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_NODE_LOGIC_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_NODE_PROCESSOR_H__
-#define __TIZEN_UIX_MMI_NODE_PROCESSOR_H__
-
-
-
-#include <mmi-node.h>
-
-/**
-* @file mmi-node-processor.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-enum mmi_node_processor_type_e {
- MMI_NODE_PROCESSOR_TYPE_NONE,
-
- /*
- - Attributes : None
- - Input Port 1
- Name : "AUDIO"
- Data Type : MMI_DATA_TYPE_AUDIO
- - Output Port 1
- Name : "PARTIAL"
- Data Type : MMI_DATA_TYPE_TEXT
- - Output Port 2
- Name : "FINAL"
- Data Type : MMI_DATA_TYPE_TEXT
- */
- MMI_NODE_PROCESSOR_TYPE_ASR,
-
- /*
- - Attributes : None
- - Input Port 1
- Name : "VIDEO_IN"
- Data Type : MMI_DATA_TYPE_VIDEO
- - Output Port 1
- Name : "VIDEO_OUT"
- Data Type : MMI_DATA_TYPE_VIDEO
- */
- MMI_NODE_PROCESSOR_TYPE_VIDEO_CONVERTER,
-
- /*
- - Attributes : None
- - Input Port 1
- Name : "VIDEO"
- Data Type : MMI_DATA_TYPE_VIDEO
- - Output Port 1
- Name : "MATCHED_FACES"
- Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT
- Format of MMI_DATA_TYPE_STRUCT :
- - "USER" : MMI_DATA_TYPE_USER_IDENTIFICATION
- - "SCORE" : MMI_DATA_TYPE_FLOAT
- */
- MMI_NODE_PROCESSOR_TYPE_FACE_RECOGNITION,
-
- /*
- - Attributes : None
- - Input Port 1
- Name : "AUDIO"
- Data Type : MMI_DATA_TYPE_AUDIO
- - Output Port 1
- Name : "MATCHED_SPEAKERS"
- Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT
- Format of MMI_DATA_TYPE_STRUCT :
- - "USER" : MMI_DATA_TYPE_USER_IDENTIFICATION
- - "SCORE" : MMI_DATA_TYPE_FLOAT
- */
- MMI_NODE_PROCESSOR_TYPE_SPEAKER_RECOGNITION,
-
- /*
- - Attributes :
- "GRID_CONFIGURATION" : array [ integer ]
- - Input Port 1
- Name : "SCREEN_INFO"
- Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT
- MMI_DATA_TYPE STRUCT format: {
- "coord_x": MMI_DATA_TYPE_INT,
- "coord_y": MMI_DATA_TYPE_INT,
- "width": MMI_DATA_TYPE_INT,
- "height": MMI_DATA_TYPE_INT,
- "object_id": MMI_DATA_TYPE_TEXT,
- "label": MMI_DATA_TYPE_TEXT,
- "role": MMI_DATA_TYPE_TEXT,
- }
- - Input Port 2
- Name : "MODE_COMMANDS"
- Data Type : MMI_DATA_TYPE_TEXT
- - Input Port 3
- Name : "UTTERANCE"
- Data Type : MMI_DATA_TYPE_TEXT
- - Output Port 1
- Name : "CANDIDATES"
- Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT
- MMI_DATA_TYPE STRUCT format: {
- "mode": MMI_DATA_TYPE_INT,
- "coord_x": MMI_DATA_TYPE_INT,
- "coord_y": MMI_DATA_TYPE_INT,
- "width": MMI_DATA_TYPE_INT,
- "height": MMI_DATA_TYPE_INT,
- "label": MMI_DATA_TYPE_TEXT,
- }
- - Output Port 2
- Name : "MATCHED_RESULT"
- Data Type : MMI_DATA_TYPE_STRUCT
- MMI_DATA_TYPE STRUCT format: {
- "candidate_info": MMI_DATA_TYPE_STRUCT {
- "mode": MMI_DATA_TYPE_INT,
- "coord_x": MMI_DATA_TYPE_INT,
- "coord_y": MMI_DATA_TYPE_INT,
- "width": MMI_DATA_TYPE_INT,
- "height": MMI_DATA_TYPE_INT,
- "label": MMI_DATA_TYPE_TEXT,
- },
- "click_info": MMI_DATA_TYPE_STRUCT {
- "x": MMI_DATA_TYPE_INT,
- "y": MMI_DATA_TYPE_INT,
- "object_id": MMI_DATA_TYPE_TEXT,
- }
- }
- - Output Port 3
- Name : "REJECTED"
- Data Type : MMI_DATA_TYPE_TEXT
- */
- MMI_NODE_PROCESSOR_TYPE_VOICE_TOUCH,
-
- /*
- - Attributes : None
- - Input Port 1
- Name : "AUDIO"
- Data Type : MMI_DATA_TYPE_AUDIO
- - Output Port 1
- Name : "DETECTED_BOS"
- Data Type : MMI_DATA_TYPE_BOOLEAN
- - Output Port 2
- Name : "DETECTED_EOS"
- Data Type : MMI_DATA_TYPE_BOOLEAN
- */
- MMI_NODE_PROCESSOR_TYPE_VOICE_ACTIVITY_DETECTOR,
-};
-
-int mmi_node_create_processor(mmi_node_processor_type_e type, mmi_node_h *node);
-
-int mmi_node_get_processor_type(mmi_node_h node, mmi_node_processor_type_e *type);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_NODE_PROCESSOR_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_NODE_SOURCE_H__
-#define __TIZEN_UIX_MMI_NODE_SOURCE_H__
-
-
-
-#include <mmi-node.h>
-
-/**
-* @file mmi-node-source.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum mmi_node_source_type_e {
- MMI_NODE_SOURCE_TYPE_NONE,
-
- /*
- - Description : A microphone that captures sound all the time.
- - Attributes :
- - "UNFOCUSED_ONLY" : bool
- Default : false
- Description : If true, the node will be activated only when there is
- no other application currently acquired sound focus.
- - Output Port 1
- Name : "AUDIO"
- Type : OUT
- Data Type : MMI_DATA_TYPE_AUDIO
- */
- MMI_NODE_SOURCE_TYPE_MIC_AMBIENT,
-
- /*
- - Description : A camera that captures video.
- - Output Port 1
- Name : "VIDEO"
- Type : OUT
- Data Type : MMI_DATA_TYPE_VIDEO
- */
- MMI_NODE_SOURCE_TYPE_CAMERA,
-
- /*
- - Description : A screen analyzer that gets screen info when rescanning occur.
- // FIXME: temporary attribute for replacing signal
- - Attributes :
- - "RESCANNING" : bool
- Default : false
- Description : If true, the node will rescan the screen and make screen info
- - Output Port 1
- Name : "SCREEN_INFO"
- Type : OUT
- Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT
- MMI_DATA_TYPE STRUCT format: {
- "coord_x": MMI_DATA_TYPE_INT,
- "coord_y": MMI_DATA_TYPE_INT,
- "width": MMI_DATA_TYPE_INT,
- "height": MMI_DATA_TYPE_INT,
- "object_id": MMI_DATA_TYPE_TEXT,
- "label": MMI_DATA_TYPE_TEXT,
- "role": MMI_DATA_TYPE_TEXT,
- }
- */
- MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER,
-};
-
-int mmi_node_create_source(mmi_node_source_type_e type, mmi_node_h *node);
-
-int mmi_node_get_source_type(mmi_node_h node, mmi_node_source_type_e *type);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_NODE_SOURCE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_NODE_H__
-#define __TIZEN_UIX_MMI_NODE_H__
-
-
-#include "mmi-platform-config.h"
-
-#include <mmi-attribute.h>
-#include <mmi-data.h>
-#include <mmi-error.h>
-#include <mmi-port.h>
-#include <mmi-signal.h>
-
-/**
-* @file mmi-node.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum mmi_node_type_e {
- MMI_NODE_TYPE_NONE,
- MMI_NODE_TYPE_SOURCE,
- MMI_NODE_TYPE_PROCESSOR,
- MMI_NODE_TYPE_LOGIC,
- MMI_NODE_TYPE_CONTROLLER,
- MMI_NODE_TYPE_ACTION,
- MMI_NODE_TYPE_CUSTOM,
-};
-
-typedef void* mmi_node_instance_h;
-
-typedef int (*mmi_node_initialized_cb)(mmi_node_instance_h instance);
-typedef int (*mmi_node_deinitialized_cb)(mmi_node_instance_h instance);
-typedef int (*mmi_node_attribute_set_cb)(mmi_node_instance_h instance, mmi_attribute_h attribute);
-typedef int (*mmi_node_activated_cb)(mmi_node_instance_h instance);
-typedef int (*mmi_node_deactivated_cb)(mmi_node_instance_h instance);
-typedef int (*mmi_node_signal_received_cb)(mmi_node_instance_h instance, mmi_signal_h signal);
-
-typedef struct {
- mmi_node_initialized_cb initialized_cb;
- mmi_node_deinitialized_cb deinitialized_cb;
- mmi_node_attribute_set_cb attribute_set_cb;
- mmi_node_activated_cb activated_cb;
- mmi_node_deactivated_cb deactivated_cb;
- mmi_node_signal_received_cb signal_received_cb;
-} mmi_node_callbacks;
-
-typedef struct {
- mmi_node_type_e type;
- int sub_type;
- char custom_type_id[MMI_NAME_MAX_LENGTH];
- mmi_port_h *ports;
- size_t port_count;
- mmi_node_callbacks callbacks;
-} mmi_node_s;
-
-typedef mmi_node_s* mmi_node_h;
-
-/* Adds a static port to a static node. The port has to be already created before calling this function. */
-int mmi_node_add_port(mmi_node_h node, mmi_port_h port);
-
-/* Finds a port in a node matching the given name and type. */
-int mmi_node_find_port(mmi_node_h node, mmi_port_type_e port_type, const char *port_name, mmi_port_h *port);
-
-/* Retrieves the type of a node. */
-int mmi_node_get_type(mmi_node_h node, mmi_node_type_e *type);
-
-/* Retrieves the number of ports in a node. */
-int mmi_node_get_port_count(mmi_node_h node, size_t *port_count);
-
-/* Retrieves the port at the given index. */
-int mmi_node_get_port(mmi_node_h node, size_t index, mmi_port_h *port);
-
-/* Get the callbacks of a node */
-int mmi_node_get_callbacks(mmi_node_h node, mmi_node_callbacks *callbacks);
-
-/* Set the callbacks of a node */
-int mmi_node_set_callbacks(mmi_node_h node, mmi_node_callbacks callbacks);
-
-/* Registers a node. */
-int mmi_node_register(mmi_node_h node);
-
-/* Clones a node. */
-int mmi_node_clone(mmi_node_h node, mmi_node_h *cloned);
-
-/* Destroys a node. */
-int mmi_node_destroy(mmi_node_h node);
-
-/* Provide a attribute to a node instance. */
-int mmi_node_instance_set_attribute(mmi_node_instance_h instance, mmi_attribute_h attribute);
-
-/* Provide a attribute bundle to a node instance. */
-//int mmi_node_instance_attribute_bundle_set(mmi_node_instance_h instance, mmi_attribute_bundle_h bundle);
-
-/* Retrieve a port instance of a node instance. */
-int mmi_node_instance_find_port(mmi_node_instance_h instance, mmi_port_type_e port_type, const char *port_name, mmi_port_instance_h *port);
-
-/* Retrieve a sibiling port instance of a port instance in a node, that matches the given name. */
-int mmi_node_instance_find_sibling_port(mmi_port_instance_h instance, const char *sibling_name, mmi_port_instance_h *sibling);
-
-/* Emits a signal from a node instance. */
-int mmi_node_instance_emit_signal(mmi_node_instance_h instance, mmi_signal_h signal);
-
-/* If the correct result could not be returned on last activate_cb() call, it needs to be updated afterwards using this function. */
-int mmi_node_instance_update_pending_activation_result(mmi_error_e result);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_NODE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_PLUGIN_MODULE_H__
-#define __TIZEN_UIX_MMI_PLUGIN_MODULE_H__
-
-
-#include <mmi.h>
-
-/**
-* @file mmi-plugin-module.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* If a plugin module wants to provide Nodes to mmi framework,
- * it should implement a function named "mmi_plugin_module_get_node_list",
- * with the following prototype. */
-#define MMI_PLUGIN_MODULE_GET_NODE_LIST_FUNC_NAME "mmi_plugin_module_get_node_list"
-typedef void (*mmi_plugin_module_get_node_list_func)();
-
-/* If a plugin module wants to provide Workflows to mmi framework,
- * it should implement a function named "mmi_plugin_module_get_workflow_list",
- * with the following prototype. */
-#define MMI_PLUGIN_MODULE_GET_WORKFLOW_LIST_FUNC_NAME "mmi_plugin_module_get_workflow_list"
-typedef void (*mmi_plugin_module_get_workflow_list_func)();
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_PLUGIN_MODULE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__
-#define __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__
-
-
-#include <mmi.h>
-#include <mmi-defines.h>
-#include <mmi-node.h>
-#include <mmi-node-source.h>
-#include <mmi-node-processor.h>
-#include <mmi-node-logic.h>
-#include <mmi-node-controller.h>
-#include <mmi-node-action.h>
-#include <mmi-node-custom.h>
-#include <mmi-workflow.h>
-
-/**
-* @file mmi-plugin-storage.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The functions and structs below are used by MMI framework */
-
-typedef struct {
- mmi_node_h *nodes;
- size_t node_count;
-} mmi_plugin_module_node_list_s;
-
-typedef struct {
- mmi_workflow_h *workflows;
- size_t workflow_count;
-} mmi_plugin_module_workflow_list_s;
-
-
-typedef struct {
- char name[MMI_NAME_MAX_LENGTH];
- mmi_port_instance_h port;
-} mmi_plugin_module_port_instance_info_s;
-
-typedef struct {
- mmi_node_instance_h node;
- mmi_plugin_module_port_instance_info_s port_infos[MMI_PORT_MAX_COUNT];
- size_t port_info_count;
-} mmi_plugin_module_node_instance_info_s;
-
-typedef void (*mmi_plugin_module_port_instance_output_handler_func)(
- mmi_port_instance_h port, mmi_data_h data, void *user_data);
-
-typedef void (*mmi_plugin_module_switch_node_event_handler_func)(
- mmi_node_instance_h node, const char *controllee, bool state, void *user_data);
-
-typedef struct {
- mmi_plugin_module_port_instance_output_handler_func port_instance_output_handler;
- mmi_plugin_module_switch_node_event_handler_func switch_node_event_handler;
-} mmi_plugin_module_event_handler_info_s;
-
-/* MMI Manager will invoke this function to set the current identifier of the plugin module. */
-void mmi_plugin_storage_set_current_module_identifier(const char *identifier);
-
-/* Each plugin modules will call this functino to get the current identifier of the plugin module. */
-const char* mmi_plugin_storage_get_current_module_identifier();
-
-/* Each plugin modules will call these functions to register their nodes and workflows. */
-void mmi_plugin_storage_set_node_list(mmi_plugin_module_node_list_s node_list);
-void mmi_plugin_storage_set_workflow_list(mmi_plugin_module_workflow_list_s workflow_list);
-
-/* MMI Manager will invoke these functions to get the node list of the plugin module. */
-mmi_plugin_module_node_list_s mmi_plugin_storage_get_node_list(const char *identifier);
-mmi_plugin_module_workflow_list_s mmi_plugin_storage_get_workflow_list(const char *identifier);
-
-/* MMI Manager will invoke these function to notify the node instance addition and removal. */
-void mmi_plugin_storage_add_node_instance_info(mmi_plugin_module_node_instance_info_s *info);
-void mmi_plugin_storage_remove_node_instance_info(mmi_node_instance_h node_instance);
-
-/* Each plugin modules will call this function to find appropriate port instance */
-mmi_port_instance_h mmi_plugin_storage_find_port_instance(
- mmi_node_instance_h node_instance, const char *port_name);
-mmi_node_instance_h mmi_plugin_storage_find_node_instance_by_port_instance(mmi_port_instance_h port_instance);
-
-/* MMI Manager will invoke these function to register / unregister the event handlers */
-void mmi_plugin_storage_set_plugin_module_event_handler(
- mmi_plugin_module_event_handler_info_s handler_info, void *user_data);
-void mmi_plugin_storage_unset_plugin_module_event_handler();
-
-/* Each plugin modules will call this function to notify the plugin module events */
-mmi_plugin_module_event_handler_info_s mmi_plugin_storage_get_plugin_module_event_handler();
-void* mmi_plugin_storage_get_plugin_module_event_handler_user_data();
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_PORT_H__
-#define __TIZEN_UIX_MMI_PORT_H__
-
-
-#include "mmi-platform-config.h"
-
-#include <mmi-data.h>
-#include <mmi-defines.h>
-#include <mmi-error.h>
-
-/**
-* @file mmi-port.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum mmi_port_type_e {
- MMI_PORT_TYPE_IN,
- MMI_PORT_TYPE_OUT
-};
-
-typedef void* mmi_port_instance_h;
-
-typedef int (*mmi_port_output_format_requested_cb)(mmi_port_instance_h instance, const char *format);
-typedef int (*mmi_port_input_data_received_cb)(mmi_port_instance_h instance, mmi_data_h data);
-
-typedef struct {
- mmi_port_output_format_requested_cb output_format_requested_cb;
- mmi_port_input_data_received_cb input_data_received_cb;
-} mmi_port_callbacks;
-
-typedef struct {
- char name[MMI_NAME_MAX_LENGTH];
- mmi_port_type_e type;
- mmi_data_type_e data_type;
- mmi_port_callbacks callbacks;
-} mmi_port_s;
-
-typedef mmi_port_s* mmi_port_h;
-
-/* Create a port */
-int mmi_port_create(mmi_port_h *port);
-
-/* Get the name of a port */
-int mmi_port_get_name(mmi_port_h port, char **name, size_t *length);
-
-/* Get the type of a port */
-int mmi_port_get_type(mmi_port_h port, mmi_port_type_e *type);
-
-/* Get the data type of a port */
-int mmi_port_get_data_type(mmi_port_h port, mmi_data_type_e *data_type);
-
-/* Get the callbacks of a port */
-int mmi_port_get_callbacks(mmi_port_h port, mmi_port_callbacks *callbacks);
-
-/* Set the name of a port */
-int mmi_port_set_name(mmi_port_h port, const char *name);
-
-/* Set the type of a port */
-int mmi_port_set_type(mmi_port_h port, mmi_port_type_e type);
-
-/* Set the data type of a port */
-int mmi_port_set_data_type(mmi_port_h port, mmi_data_type_e data_type);
-
-/* Set the callbacks of a port */
-int mmi_port_set_callbacks(mmi_port_h port, mmi_port_callbacks callbacks);
-
-/* Clones a port */
-int mmi_port_clone(mmi_port_h port, mmi_port_h *cloned);
-
-/* Destroy a port */
-int mmi_port_destroy(mmi_port_h port);
-
-/* Provide a link information between two static ports. */
-// int mmi_port_link(mmi_port_h out, mmi_port_h in);
-
-/* Registers a port with the given type, data type, and callbacks. */
-// int mmi_port_register(mmi_port_type_e port_type, mmi_data_type_e data_type, mmi_port_callbacks *callbacks, mmi_port_h port);
-
-/* Generates data to the port with the given port instance. */
-int mmi_port_instance_generate_output(mmi_port_instance_h instance, mmi_data_h data);
-
-/* Requests the port instance to transform the data to the given format. */
-int mmi_port_instance_request_auto_transform(mmi_port_instance_h instance, const char *from_format, const char *to_format);
-
-/* Requests the port instance to retrieve the data with the given format. */
-int mmi_port_instance_request_input_data_format(mmi_port_instance_h instance, const char *format);
-
-/* Announce the data format to the port instance. */
-int mmi_port_instance_announce_output_data_format(mmi_port_instance_h instance, const char *format);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_PORT_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_PRIMITIVE_VALUE_H__
-#define __TIZEN_UIX_MMI_PRIMITIVE_VALUE_H__
-
-
-#include "mmi-platform-config.h"
-#include <stdlib.h>
-
-
-/**
-* @file mmi-primitive-value.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef enum {
- MMI_PRIMITIVE_VALUE_TYPE_INT,
- MMI_PRIMITIVE_VALUE_TYPE_FLOAT,
- MMI_PRIMITIVE_VALUE_TYPE_STRING,
- MMI_PRIMITIVE_VALUE_TYPE_BOOL,
- MMI_PRIMITIVE_VALUE_TYPE_ARRAY,
-} mmi_primitive_value_type_e;
-
-
-typedef struct mmi_primitive_value_s* mmi_primitive_value_h;
-
-
-int mmi_primitive_value_create_int(int data, mmi_primitive_value_h *handle);
-
-int mmi_primitive_value_create_float(float data, mmi_primitive_value_h *handle);
-
-int mmi_primitive_value_create_string(const char *data, mmi_primitive_value_h *handle);
-
-int mmi_primitive_value_create_bool(bool data, mmi_primitive_value_h *handle);
-
-int mmi_primitive_value_create_array(mmi_primitive_value_h *handle);
-
-int mmi_primitive_value_add_array_element(mmi_primitive_value_h array, mmi_primitive_value_h element);
-
-int mmi_primitive_value_get_type(mmi_primitive_value_h handle, mmi_primitive_value_type_e *type);
-
-int mmi_primitive_value_get_int(mmi_primitive_value_h handle, int *value);
-
-int mmi_primitive_value_get_float(mmi_primitive_value_h handle, float *value);
-
-int mmi_primitive_value_get_string(mmi_primitive_value_h handle, const char **string);
-
-int mmi_primitive_value_get_bool(mmi_primitive_value_h handle, bool *value);
-
-int mmi_primitive_value_get_array_count(mmi_primitive_value_h array, size_t *count);
-
-int mmi_primitive_value_get_array_element(mmi_primitive_value_h array, size_t index, mmi_primitive_value_h *element);
-
-int mmi_primitive_value_clone(mmi_primitive_value_h handle, mmi_primitive_value_h *cloned);
-
-int mmi_primitive_value_destroy(mmi_primitive_value_h handle);
-
-int mmi_primitive_value_to_bytes(mmi_primitive_value_h handle, unsigned char **bytes, size_t *size);
-
-int mmi_primitive_value_from_bytes(unsigned char *bytes, size_t size, mmi_primitive_value_h *handle);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_PRIMITIVE_VALUE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_SIGNAL_H__
-#define __TIZEN_UIX_MMI_SIGNAL_H__
-
-
-#include "mmi-platform-config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <mmi-defines.h>
-#include <mmi-primitive-value.h>
-
-/**
-* @file mmi-port.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct {
- char name[MMI_NAME_MAX_LENGTH];
- mmi_primitive_value_h value;
-} mmi_signal_parameter_s;
-
-typedef mmi_signal_parameter_s* mmi_signal_parameter_h;
-
-typedef struct {
- char name[MMI_NAME_MAX_LENGTH];
- mmi_signal_parameter_h parameters[MMI_PARAMETER_MAX_COUNT];
- int parameter_count;
-} mmi_signal_s;
-
-typedef mmi_signal_s* mmi_signal_h;
-
-int mmi_signal_parameter_create(mmi_primitive_value_h value, const char *name, mmi_signal_parameter_h *parameter);
-
-int mmi_signal_parameter_get_name(mmi_signal_parameter_h parameter, char **name);
-
-int mmi_signal_parameter_get_value(mmi_signal_parameter_h parameter, mmi_primitive_value_h *value);
-
-int mmi_signal_parameter_clone(mmi_signal_parameter_h parameter, mmi_signal_parameter_h *cloned);
-
-int mmi_signal_parameter_destroy(mmi_signal_parameter_h parameter);
-
-int mmi_signal_create(const char *name, mmi_signal_h *handle);
-
-int mmi_signal_add_parameter(mmi_signal_h handle, mmi_signal_parameter_h parameter);
-
-int mmi_signal_get_name(mmi_signal_h handle, char **name);
-
-int mmi_signal_get_parameter_count(mmi_signal_h handle, int *count);
-
-int mmi_signal_get_parameter(mmi_signal_h handle, int index, mmi_signal_parameter_h *parameter);
-
-int mmi_signal_destroy(mmi_signal_h handle);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_SIGNAL_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __TIZEN_UIX_MMI_WORKFLOW_H__
-#define __TIZEN_UIX_MMI_WORKFLOW_H__
-
-
-#include "mmi-platform-config.h"
-
-#include <mmi-attribute.h>
-#include <mmi-data.h>
-#include <mmi-node.h>
-
-
-/**
-* @file mmi-workflow.h
-*/
-
-
-/**
-* @addtogroup CAPI_UIX_MMI_MODULE
-* @{
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- MMI_STANDARD_WORKFLOW_NONE,
- MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND,
- MMI_STANDARD_WORKFLOW_VOICE_TOUCH,
- MMI_STANDARD_WORKFLOW_USER_RECOGNITION,
-} mmi_standard_workflow_type_e;
-
-
-/* Functions to define a workflow prototype. Mostly used by workflow developers. */
-
-typedef struct {
- char name[MMI_NAME_MAX_LENGTH];
- mmi_node_h node;
-} mmi_workflow_node_info_s;
-
-typedef struct {
- char from_node_name[MMI_NAME_MAX_LENGTH];
- char from_port_name[MMI_NAME_MAX_LENGTH];
- char to_node_name[MMI_NAME_MAX_LENGTH];
- char to_port_name[MMI_NAME_MAX_LENGTH];
-} mmi_workflow_link_info_s;
-
-typedef struct {
- char attribute_name[MMI_NAME_MAX_LENGTH];
- char target_node_name[MMI_NAME_MAX_LENGTH];
- char target_attribute_name[MMI_NAME_MAX_LENGTH];
-} mmi_workflow_attribute_assignment_info_s;
-
-typedef struct {
- size_t serialized_default_value_size;
- unsigned char *serialized_default_value;
-} mmi_workflow_attribute_default_value_info_s;
-
-typedef struct {
- char signal_name[MMI_NAME_MAX_LENGTH];
- char target_node_name[MMI_NAME_MAX_LENGTH];
- char target_signal_name[MMI_NAME_MAX_LENGTH];
-} mmi_workflow_signal_assignment_info_s;
-
-typedef struct {
- char output_name[MMI_NAME_MAX_LENGTH];
- char from_node_name[MMI_NAME_MAX_LENGTH];
- char from_port_name[MMI_NAME_MAX_LENGTH];
-} mmi_workflow_output_assignment_info_s;
-
-typedef struct {
- mmi_standard_workflow_type_e type;
- mmi_workflow_node_info_s *node_infos;
- size_t node_info_count;
- mmi_workflow_link_info_s *link_infos;
- size_t link_info_count;
- mmi_workflow_attribute_assignment_info_s *attribute_assignment_infos;
- size_t attribute_assignment_info_count;
- mmi_workflow_attribute_default_value_info_s *attribute_default_value_infos;
- size_t attribute_default_value_info_count;
- mmi_workflow_signal_assignment_info_s *signal_assignment_infos;
- size_t signal_assignment_info_count;
- mmi_workflow_output_assignment_info_s *output_assignment_infos;
- size_t output_assignment_info_count;
-} mmi_workflow_s;
-
-typedef mmi_workflow_s* mmi_workflow_h;
-
-/* Create a workflow prototype */
-int mmi_workflow_create(mmi_workflow_h *workflow);
-
-/* Set the type of a workflow prototype */
-int mmi_workflow_set_type(mmi_workflow_h workflow, mmi_standard_workflow_type_e type);
-
-/* Get the type of a workflow prototype */
-int mmi_workflow_get_type(mmi_workflow_h workflow, mmi_standard_workflow_type_e *type);
-
-/* Add a node to a workflow prototype */
-int mmi_workflow_node_add(mmi_workflow_h workflow, const char *node_name, mmi_node_h node);
-
-/* A convinience function to link two nodes by automatically finding the appropriate ports in the nodes. */
-/* The linking succeeds only if there is exactly one pair of compatible input and output ports in the nodes. */
-/* int mmi_workflow_link_nodes(mmi_node_h from_node, mmi_node_h to_node); */
-
-/* Link two nodes with specifying the port names. */
-/* FIXME: It would be better to use handles instead of names. */
-int mmi_workflow_link_nodes_by_names(mmi_workflow_h workflow, const char *from_node_name, const char *from_port_name, const char *to_node_name, const char *to_port_name);
-
-/* Assign an attribute of a workflow to an attribute of a specific node in a workflow prototype */
-/* FIXME: It would be better to use handles instead of names. */
-int mmi_workflow_attribute_assign(mmi_workflow_h workflow, const char *attribute_name, const char *target_node_name, const char *target_attribute_name);
-
-/* Set the default value of an attribute of a workflow */
-int mmi_workflow_attribute_set_default_value(mmi_workflow_h workflow, mmi_attribute_h default_value);
-
-/* Assign a signal of a workflow to a signal of a specific node in a workflow prototype */
-int mmi_workflow_signal_assign(mmi_workflow_h workflow, const char *signal_name, const char *target_node_name, const char *target_signal_name);
-
-/* Assign an output of a workflow to a OUT port of a specific node in a workflow prototype */
-/* FIXME: It would be better to use handles instead of names. */
-int mmi_workflow_output_assign(mmi_workflow_h workflow, const char *workflow_output, const char *out_node_name, const char *node_out_port_name);
-
-/* Assign an output of a workflow to a OUT port of a specific node in a workflow prototype, with a port handle */
-int mmi_workflow_output_assign_by_port(mmi_workflow_h workflow, const char *workflow_output, mmi_port_h port);
-
-/* Register a standard workflow prototype to the workflow manager */
-int mmi_standard_workflow_register(mmi_workflow_h workflow);
-
-/* Clones a workflow. */
-int mmi_workflow_clone(mmi_workflow_h workflow, mmi_workflow_h *cloned);
-
-/* Create a workflow prototype from a script */
-int mmi_workflow_create_from_script(const char *script, mmi_workflow_h *workflow);
-
-/* Create a workflow prototype from a script file */
-int mmi_workflow_create_from_script_file(const char *script_path, mmi_workflow_h *workflow);
-
-/* Generate a workflow script from a workflow prototype */
-int mmi_workflow_generate_script(mmi_workflow_h workflow, const char **script);
-
-/* Destroy a workflow prototype */
-int mmi_workflow_destroy(mmi_workflow_h workflow);
-
-/* Functions to create a workflow instance. Mostly used by application developers. */
-
-typedef void* mmi_workflow_instance_h;
-
-/* Callback function for workflow output */
-typedef void (*mmi_workflow_output_cb)(mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data);
-
-/* Callback function for workflow signal */
-// typedef void (*mmi_workflow_signal_cb)(const char *name, mmi_signal_parameter_h parameter, void *user_data);
-
-/* Instantiate a workflow from a workflow prototype */
-int mmi_standard_workflow_instance_create(mmi_standard_workflow_type_e type, mmi_workflow_instance_h *instance);
-
-/* Instantiate a workflow from a custom workflow prototype */
-int mmi_custom_workflow_instance_create(mmi_workflow_h workflow, mmi_workflow_instance_h *instance);
-
-/* Destroy a workflow instance */
-int mmi_workflow_instance_destroy(mmi_workflow_instance_h instance);
-
-/* Start a workflow instance */
-int mmi_workflow_instance_activate(mmi_workflow_instance_h instance);
-
-/* Stop a workflow instance */
-int mmi_workflow_instance_deactivate(mmi_workflow_instance_h instance);
-
-/* Set an attribute of a workflow instance */
-int mmi_workflow_instance_set_attribute(mmi_workflow_instance_h instance, mmi_attribute_h attribute);
-
-/* Emit a signal to a workflow instance */
-int mmi_workflow_instance_emit_signal(mmi_workflow_instance_h instance, mmi_signal_h signal);
-
-/* Feed data to a port of a node with given name pair */
-int mmi_workflow_instance_feed_data(mmi_workflow_instance_h instance, const char *node_name, const char *port_name, mmi_data_h data);
-
-/* Set a callback function to receive workflow output */
-int mmi_workflow_instance_set_output_callback(mmi_workflow_instance_h instance, const char *name, mmi_workflow_output_cb callback, void *user_data);
-
-/* Set a callback function to receive workflow signal */
-// int mmi_workflow_instance_set_signal_callback(mmi_workflow_instance_h instance, const char *name, mmi_workflow_signal_cb callback, void *user_data);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/**
- * @}
- */
-
-
-#endif /* __TIZEN_UIX_MMI_WORKFLOW_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __MMI_H__
-#define __MMI_H__
-
-#include "mmi-platform-config.h"
-
-#define MMI_API __attribute__ ((visibility("default")))
-
-#include <mmi-defines.h>
-#include <mmi-error.h>
-#include <mmi-data.h>
-#include <mmi-primitive-value.h>
-#include <mmi-attribute.h>
-#include <mmi-workflow.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef enum {
- MMI_STATE_NONE = 0,
- MMI_STATE_READY,
-} mmi_state_e;
-
-typedef int (*mmi_state_changed_cb)(mmi_state_e state, void *user_data);
-
-/** @brief Initialize MMI framework
- *
- * @return 0 on success, otherwise a negative error value
- */
-int mmi_initialize();
-
-/** @brief Deinitialize MMI framework
- *
- * @return 0 on success, otherwise a negative error value
- */
-int mmi_deinitialize();
-
-/** @brief Set callback for state change
- *
- * @param[in] callback The callback function to be called when state is changed
- * @param[in] user_data The user data to be passed to the callback function
- *
- * @return 0 on success, otherwise a negative error value
- * @see mmi_state_changed_cb
- */
-int mmi_set_state_changed_cb(mmi_state_changed_cb callback, void *user_data);
-
-/** @brief Unset callback for state change
- *
- * @param[in] callback The callback function to be unset
- *
- * @return 0 on success, otherwise a negative error value
- */
-int mmi_unset_state_changed_cb(mmi_state_changed_cb callback);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-#endif //__MMI_H__
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE32_CROCKFORD
+#define CPPCODEC_BASE32_CROCKFORD
+
+#include "detail/codec.hpp"
+#include "detail/base32.hpp"
+
+namespace cppcodec {
+
+namespace detail {
+
+static constexpr const char base32_crockford_alphabet[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // at index 10
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 18 - no I
+ 'J', 'K', // 20 - no L
+ 'M', 'N', // 22 - no O
+ 'P', 'Q', 'R', 'S', 'T', // 27 - no U
+ 'V', 'W', 'X', 'Y', 'Z' // 32
+};
+
+class base32_crockford_base
+{
+public:
+ static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() {
+ static_assert(sizeof(base32_crockford_alphabet) == 32, "base32 alphabet must have 32 values");
+ return sizeof(base32_crockford_alphabet);
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx)
+ {
+ return base32_crockford_alphabet[idx];
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c)
+ {
+ // Hex decoding is always case-insensitive (even in RFC 4648), the question
+ // is only for encoding whether to use upper-case or lower-case letters.
+ return (c == 'O' || c == 'o') ? '0'
+ : (c == 'I' || c == 'i' || c == 'L' || c == 'l') ? '1'
+ : (c >= 'a' && c <= 'z') ? (c - 'a' + 'A')
+ : c;
+ }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return false; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return false; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char) { return false; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char c) {
+ return c == '-'; // "Hyphens (-) can be inserted into strings [for readability]."
+ }
+};
+
+// base32_crockford is a concatenative iterative (i.e. streaming) interpretation of Crockford base32.
+// It interprets the statement "zero-extend the number to make its bit-length a multiple of 5"
+// to mean zero-extending it on the right.
+// (The other possible interpretation is base32_crockford_num, a place-based single number encoding system.
+// See http://merrigrove.blogspot.ca/2014/04/what-heck-is-base64-encoding-really.html for more info.)
+class base32_crockford : public base32_crockford_base
+{
+public:
+ template <typename Codec> using codec_impl = stream_codec<Codec, base32_crockford>;
+};
+
+} // namespace detail
+
+using base32_crockford = detail::codec<detail::base32<detail::base32_crockford>>;
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_BASE32_CROCKFORD
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE32_DEFAULT_CROCKFORD
+#define CPPCODEC_BASE32_DEFAULT_CROCKFORD
+
+#include "base32_crockford.hpp"
+
+using base32 = cppcodec::base32_crockford;
+
+#endif // CPPCODEC_BASE32_DEFAULT_CROCKFORD
--- /dev/null
+/**
+ * Copyright (C) 2015, 2016 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE32_DEFAULT_HEX
+#define CPPCODEC_BASE32_DEFAULT_HEX
+
+#include "base32_hex.hpp"
+
+using base32 = cppcodec::base32_hex;
+
+#endif // CPPCODEC_BASE32_DEFAULT_HEX
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE32_DEFAULT_RFC4648
+#define CPPCODEC_BASE32_DEFAULT_RFC4648
+
+#include "base32_rfc4648.hpp"
+
+using base32 = cppcodec::base32_rfc4648;
+
+#endif // CPPCODEC_BASE32_DEFAULT_RFC4648
--- /dev/null
+/**
+ * Copyright (C) 2015, 2016 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE32_HEX
+#define CPPCODEC_BASE32_HEX
+
+#include "detail/codec.hpp"
+#include "detail/base32.hpp"
+
+namespace cppcodec {
+
+namespace detail {
+
+// RFC 4648 also specifies a hex encoding system which uses 0-9, then A-V.
+static constexpr const char base32_hex_alphabet[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'
+};
+
+class base32_hex
+{
+public:
+ template <typename Codec> using codec_impl = stream_codec<Codec, base32_hex>;
+
+ static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() {
+ static_assert(sizeof(base32_hex_alphabet) == 32, "base32 alphabet must have 32 values");
+ return sizeof(base32_hex_alphabet);
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx)
+ {
+ return base32_hex_alphabet[idx];
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c)
+ {
+ // Lower-case letters are accepted, though not generally expected.
+ return (c >= 'a' && c <= 'v') ? (c - 'a' + 'A') : c;
+ }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return true; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return true; }
+ static CPPCODEC_ALWAYS_INLINE constexpr char padding_symbol() { return '='; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char c) { return c == '='; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; }
+
+ // RFC4648 does not specify any whitespace being allowed in base32 encodings.
+ static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; }
+};
+
+} // namespace detail
+
+using base32_hex = detail::codec<detail::base32<detail::base32_hex>>;
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_BASE32_HEX
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE32_RFC4648
+#define CPPCODEC_BASE32_RFC4648
+
+#include "detail/codec.hpp"
+#include "detail/base32.hpp"
+
+namespace cppcodec {
+
+namespace detail {
+
+// RFC 4648 uses a simple alphabet: A-Z starting at index 0, then 2-7 starting at index 26.
+static constexpr const char base32_rfc4648_alphabet[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', // at index 26
+ '2', '3', '4', '5', '6', '7'
+};
+
+class base32_rfc4648
+{
+public:
+ template <typename Codec> using codec_impl = stream_codec<Codec, base32_rfc4648>;
+
+ static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() {
+ static_assert(sizeof(base32_rfc4648_alphabet) == 32, "base32 alphabet must have 32 values");
+ return sizeof(base32_rfc4648_alphabet);
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx)
+ {
+ return base32_rfc4648_alphabet[idx];
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c)
+ {
+ // Lower-case letters are accepted, though not generally expected.
+ return (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') : c;
+ }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return true; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return true; }
+ static CPPCODEC_ALWAYS_INLINE constexpr char padding_symbol() { return '='; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char c) { return c == '='; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; }
+
+ // RFC4648 does not specify any whitespace being allowed in base32 encodings.
+ static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; }
+};
+
+} // namespace detail
+
+using base32_rfc4648 = detail::codec<detail::base32<detail::base32_rfc4648>>;
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_BASE32_RFC4648
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE64_DEFAULT_RFC4648
+#define CPPCODEC_BASE64_DEFAULT_RFC4648
+
+#include "base64_rfc4648.hpp"
+
+using base64 = cppcodec::base64_rfc4648;
+
+#endif // CPPCODEC_BASE64_DEFAULT_RFC4648
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE64_DEFAULT_URL
+#define CPPCODEC_BASE64_DEFAULT_URL
+
+#include "base64_url.hpp"
+
+using base64 = cppcodec::base64_url;
+
+#endif // CPPCODEC_BASE64_DEFAULT_URL
--- /dev/null
+/**
+ * Copyright (C) 2016 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE64_DEFAULT_URL_UNPADDED
+#define CPPCODEC_BASE64_DEFAULT_URL_UNPADDED
+
+#include "base64_url_unpadded.hpp"
+
+using base64 = cppcodec::base64_url_unpadded;
+
+#endif // CPPCODEC_BASE64_DEFAULT_URL_UNPADDED
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE64_RFC4648
+#define CPPCODEC_BASE64_RFC4648
+
+#include "detail/codec.hpp"
+#include "detail/base64.hpp"
+
+namespace cppcodec {
+
+namespace detail {
+
+static constexpr const char base64_rfc4648_alphabet[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+};
+
+class base64_rfc4648
+{
+public:
+ template <typename Codec> using codec_impl = stream_codec<Codec, base64_rfc4648>;
+
+ static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() {
+ static_assert(sizeof(base64_rfc4648_alphabet) == 64, "base64 alphabet must have 64 values");
+ return sizeof(base64_rfc4648_alphabet);
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx)
+ {
+ return base64_rfc4648_alphabet[idx];
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c) { return c; }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return true; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return true; }
+ static CPPCODEC_ALWAYS_INLINE constexpr char padding_symbol() { return '='; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char c) { return c == '='; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; }
+
+ // RFC4648 does not specify any whitespace being allowed in base64 encodings.
+ static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; }
+};
+
+} // namespace detail
+
+using base64_rfc4648 = detail::codec<detail::base64<detail::base64_rfc4648>>;
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_BASE64_RFC4648
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE64_URL
+#define CPPCODEC_BASE64_URL
+
+#include "detail/codec.hpp"
+#include "detail/base64.hpp"
+
+namespace cppcodec {
+
+namespace detail {
+
+// The URL and filename safe alphabet is also specified by RFC4648, named "base64url".
+// We keep the underscore ("base64_url") for consistency with the other codec variants.
+static constexpr const char base64_url_alphabet[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
+};
+
+class base64_url
+{
+public:
+ template <typename Codec> using codec_impl = stream_codec<Codec, base64_url>;
+
+ static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() {
+ static_assert(sizeof(base64_url_alphabet) == 64, "base64 alphabet must have 64 values");
+ return sizeof(base64_url_alphabet);
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx)
+ {
+ return base64_url_alphabet[idx];
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c) { return c; }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return true; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return true; }
+ static CPPCODEC_ALWAYS_INLINE constexpr char padding_symbol() { return '='; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char c) { return c == '='; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; }
+
+ // RFC4648 does not specify any whitespace being allowed in base64 encodings.
+ static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; }
+};
+
+} // namespace detail
+
+using base64_url = detail::codec<detail::base64<detail::base64_url>>;
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_BASE64_URL
--- /dev/null
+/**
+ * Copyright (C) 2016 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_BASE64_URL_UNPADDED
+#define CPPCODEC_BASE64_URL_UNPADDED
+
+#include "base64_url.hpp"
+
+namespace cppcodec {
+
+namespace detail {
+
+class base64_url_unpadded : public base64_url
+{
+public:
+ template <typename Codec> using codec_impl = stream_codec<Codec, base64_url_unpadded>;
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return false; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return false; }
+};
+
+} // namespace detail
+
+using base64_url_unpadded = detail::codec<detail::base64<detail::base64_url_unpadded>>;
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_BASE64_URL_UNPADDED
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * Copyright (C) 2018 Jakob Petsovits
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_DETAIL_DATA_ACCESS
+#define CPPCODEC_DETAIL_DATA_ACCESS
+
+#include <stdint.h> // for size_t
+#include <string> // for static_assert() checking that string will be optimized
+#include <type_traits> // for std::enable_if, std::remove_reference, and such
+#include <utility> // for std::declval
+#include <vector> // for static_assert() checking that vector will be optimized
+
+#include "../detail/config.hpp" // for CPPCODEC_ALWAYS_INLINE
+
+namespace cppcodec {
+namespace data {
+
+// This file contains a number of templated data accessors that can be
+// implemented in the cppcodec::data namespace for types that don't fulfill
+// the default type requirements:
+// For result types: init(Result&, ResultState&, size_t capacity),
+// put(Result&, ResultState&, char), finish(Result&, State&)
+// For const (read-only) types: char_data(const T&)
+// For both const and result types: size(const T&)
+
+template <typename T>
+CPPCODEC_ALWAYS_INLINE size_t size(const T& t) { return t.size(); }
+
+template <typename T, size_t N>
+CPPCODEC_ALWAYS_INLINE constexpr size_t size(const T (&t)[N]) noexcept {
+ return (void)t, N * sizeof(t[0]);
+}
+
+class general_t {};
+class specific_t : public general_t {};
+
+class empty_result_state {
+ template <typename Result>
+ CPPCODEC_ALWAYS_INLINE void size(const Result& result) { return size(result); }
+};
+
+// SFINAE: Generic fallback in case no specific state function applies.
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE empty_result_state create_state(Result&, general_t)
+{
+ return empty_result_state();
+}
+
+//
+// Generic templates for containers: Use these init()/put()/finish()
+// implementations if no specialization was found.
+//
+
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE void init(Result& result, empty_result_state&, size_t capacity)
+{
+ result.resize(0);
+ result.reserve(capacity);
+}
+
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE void finish(Result&, empty_result_state&)
+{
+ // Default is to push_back(), which already increases the size.
+}
+
+// For the put() default implementation, we try calling push_back() with either uint8_t or char,
+// whichever compiles. Scary-fancy template magic from http://stackoverflow.com/a/1386390.
+namespace fallback {
+ struct flag { char c[2]; }; // sizeof > 1
+ flag put_uint8(...);
+
+ int operator,(flag, flag);
+ template <typename T> void operator,(flag, T&); // map everything else to void
+ char operator,(int, flag); // sizeof 1
+}
+
+template <typename Result> inline void put_uint8(Result& result, uint8_t c) { result.push_back(c); }
+
+template <bool> struct put_impl;
+template <> struct put_impl<true> { // put_uint8() available
+ template<typename Result>
+ static CPPCODEC_ALWAYS_INLINE void put(Result& result, uint8_t c)
+ {
+ put_uint8(result, c);
+ }
+};
+template <> struct put_impl<false> { // put_uint8() not available
+ template<typename Result>
+ static CPPCODEC_ALWAYS_INLINE void put(Result& result, uint8_t c)
+ {
+ result.push_back(static_cast<char>(c));
+ }
+};
+
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE void put(Result& result, empty_result_state&, uint8_t c)
+{
+ using namespace fallback;
+ put_impl<sizeof(fallback::flag(), put_uint8(result, c), fallback::flag()) != 1>::put(result, c);
+}
+
+//
+// Specialization for container types with direct mutable data access,
+// e.g. std::vector<uint8_t>.
+//
+// The expected way to specialize is to draft a new xyz_result_state type and
+// return an instance of it from a create_state() template specialization.
+// You can then create overloads for init(), put() and finish()
+// for the new result state type.
+//
+// If desired, a non-templated overload for both specific types
+// (result & state) can be added to tailor it to that particular result type.
+//
+
+template <typename T>
+constexpr auto data_is_mutable(T* t) -> decltype(t->data()[size_t(0)] = 'x', bool())
+{
+ return (void)t, true;
+}
+constexpr bool data_is_mutable(...) { return false; }
+
+template <typename Result>
+class direct_data_access_result_state
+{
+public:
+ CPPCODEC_ALWAYS_INLINE void init(Result& result, size_t capacity)
+ {
+ // reserve() may not actually allocate the storage right away,
+ // and it isn't guaranteed that it will be untouched upon the
+ //.next resize(). In that light, resize from the start and
+ // slightly reduce the size at the end if necessary.
+ result.resize(capacity);
+
+ // result.data() may perform a calculation to retrieve the address.
+ // E.g. std::string (since C++11) will use small string optimization,
+ // so it needs to check if it's using allocated data or (ab)using
+ // its own member variables interpreted as char array.
+ // (This result_state is used for std::string starting with C++17.)
+ // Conditional code paths are slow so we only do it once, at the start.
+ m_buffer = result.data();
+ }
+ CPPCODEC_ALWAYS_INLINE void put(Result&, char c)
+ {
+ m_buffer[m_offset++] = c;
+ }
+ CPPCODEC_ALWAYS_INLINE void finish(Result& result)
+ {
+ result.resize(m_offset);
+ }
+ CPPCODEC_ALWAYS_INLINE size_t size(const Result&)
+ {
+ return m_offset;
+ }
+private:
+ // Make sure to get the mutable buffer decltype by using assignment.
+ typename std::remove_reference<
+ decltype(std::declval<Result>().data()[size_t(0)] = 'x')>::type* m_buffer;
+ size_t m_offset = 0;
+};
+
+// SFINAE: Select a specific state based on the result type and possible result state type.
+// Implement this if direct data access (`result.data()[0] = 'x') isn't already possible
+// and you want to specialize it for your own result type.
+// Note: The enable_if should ideally be part of the class declaration,
+// but Visual Studio C++ will not compile it that way.
+// Have it here in the factory function instead.
+template <typename Result,
+ typename = typename std::enable_if<
+ data_is_mutable(static_cast<Result*>(nullptr))>::type>
+CPPCODEC_ALWAYS_INLINE direct_data_access_result_state<Result> create_state(Result&, specific_t)
+{
+ return direct_data_access_result_state<Result>();
+}
+
+static_assert(std::is_same<
+ decltype(create_state(*static_cast<std::vector<uint8_t>*>(nullptr), specific_t())),
+ direct_data_access_result_state<std::vector<uint8_t>>>::value,
+ "std::vector<uint8_t> must be handled by direct_data_access_result_state");
+
+// Specialized init(), put() and finish() functions for direct_data_access_result_state.
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE void init(Result& result, direct_data_access_result_state<Result>& state, size_t capacity)
+{
+ state.init(result, capacity);
+}
+
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE void put(Result& result, direct_data_access_result_state<Result>& state, char c)
+{
+ state.put(result, c);
+}
+
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE void finish(Result& result, direct_data_access_result_state<Result>& state)
+{
+ state.finish(result);
+}
+
+//
+// Specialization for container types with direct mutable array access,
+// e.g. std::string. This is generally faster because bound checks are
+// minimal and operator[] is more likely noexcept. In addition,
+// std::string::push_back() needs to write a null character on every
+// expansion, which should be more efficient when done in bulk by resize().
+//
+// Compared to the above, tracking an extra offset variable is cheap.
+//
+
+template <typename T>
+constexpr auto array_access_is_mutable(T* t) -> decltype((*t)[size_t(0)] = 'x', bool())
+{
+ return (void)t, true;
+}
+constexpr bool array_access_is_mutable(...) { return false; }
+
+template <typename Result>
+class array_access_result_state
+{
+public:
+ CPPCODEC_ALWAYS_INLINE void init(Result& result, size_t capacity)
+ {
+ // reserve() may not actually allocate the storage right away,
+ // and it isn't guaranteed that it will be untouched upon the
+ //.next resize(). In that light, resize from the start and
+ // slightly reduce the size at the end if necessary.
+ result.resize(capacity);
+ }
+ CPPCODEC_ALWAYS_INLINE void put(Result& result, char c)
+ {
+ result[m_offset++] = c;
+ }
+ CPPCODEC_ALWAYS_INLINE void finish(Result& result)
+ {
+ result.resize(m_offset);
+ }
+ CPPCODEC_ALWAYS_INLINE size_t size(const Result&)
+ {
+ return m_offset;
+ }
+private:
+ size_t m_offset = 0;
+};
+
+// SFINAE: Select a specific state based on the result type and possible result state type.
+// Note: The enable_if should ideally be part of the class declaration,
+// but Visual Studio C++ will not compile it that way.
+// Have it here in the factory function instead.
+template <typename Result,
+ typename = typename std::enable_if<
+ !data_is_mutable(static_cast<Result*>(nullptr)) // no more than one template option
+ && array_access_is_mutable(static_cast<Result*>(nullptr))>::type>
+CPPCODEC_ALWAYS_INLINE array_access_result_state<Result> create_state(Result&, specific_t)
+{
+ return array_access_result_state<Result>();
+}
+
+#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L)
+static_assert(std::is_same<
+ decltype(create_state(*static_cast<std::string*>(nullptr), specific_t())),
+ direct_data_access_result_state<std::string>>::value,
+ "std::string (C++17 and later) must be handled by direct_data_access_result_state");
+#elif __cplusplus < 201703 && !defined(_MSVC_LANG) // we can't trust MSVC to set this right
+static_assert(std::is_same<
+ decltype(create_state(*static_cast<std::string*>(nullptr), specific_t())),
+ array_access_result_state<std::string>>::value,
+ "std::string (pre-C++17) must be handled by array_access_result_state");
+#endif
+
+// Specialized init(), put() and finish() functions for array_access_result_state.
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE void init(Result& result, array_access_result_state<Result>& state, size_t capacity)
+{
+ state.init(result, capacity);
+}
+
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE void put(Result& result, array_access_result_state<Result>& state, char c)
+{
+ state.put(result, c);
+}
+
+template <typename Result>
+CPPCODEC_ALWAYS_INLINE void finish(Result& result, array_access_result_state<Result>& state)
+{
+ state.finish(result);
+}
+
+// char_data() is only used to read, not for result buffers.
+template <typename T> inline const char* char_data(const T& t)
+{
+ return reinterpret_cast<const char*>(t.data());
+}
+template <typename T, size_t N> inline const char* char_data(const T (&t)[N]) noexcept
+{
+ return reinterpret_cast<const char*>(&(t[0]));
+}
+
+template <typename T> inline const uint8_t* uchar_data(const T& t)
+{
+ return reinterpret_cast<const uint8_t*>(char_data(t));
+}
+
+} // namespace data
+} // namespace cppcodec
+
+#endif
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_DETAIL_RAW_RESULT_BUFFER
+#define CPPCODEC_DETAIL_RAW_RESULT_BUFFER
+
+#include <stdint.h> // for size_t
+#include <stdlib.h> // for abort()
+
+#include "access.hpp"
+
+namespace cppcodec {
+namespace data {
+
+class raw_result_buffer
+{
+public:
+ raw_result_buffer(char* data, size_t capacity)
+ : m_ptr(data + capacity)
+ , m_begin(data)
+ {
+ }
+
+ CPPCODEC_ALWAYS_INLINE void push_back(char c) { *m_ptr = c; ++m_ptr; }
+ CPPCODEC_ALWAYS_INLINE size_t size() const { return m_ptr - m_begin; }
+ CPPCODEC_ALWAYS_INLINE void resize(size_t size) { m_ptr = m_begin + size; }
+
+private:
+ char* m_ptr;
+ char* m_begin;
+};
+
+
+template <> inline void init<raw_result_buffer>(
+ raw_result_buffer& result, empty_result_state&, size_t capacity)
+{
+ // This version of init() doesn't do a reserve(), and instead checks whether the
+ // initial size (capacity) is enough before resetting m_ptr to m_begin.
+ // The codec is expected not to exceed this capacity.
+ if (capacity > result.size()) {
+ abort();
+ }
+ result.resize(0);
+}
+template <> inline void finish<raw_result_buffer>(raw_result_buffer&, empty_result_state&) { }
+
+} // namespace data
+} // namespace cppcodec
+
+#endif
--- /dev/null
+/**
+ * Copyright (C) 2015 Trustifier Inc.
+ * Copyright (C) 2015 Ahmed Masud
+ * Copyright (C) 2015 Topology LP
+ * Copyright (C) 2018 Jakob Petsovits
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Adapted from https://github.com/ahmed-masud/libbase32,
+ * commit 79761b2b79b0545697945efe0987a8d3004512f9.
+ * Quite different now.
+ */
+
+#ifndef CPPCODEC_DETAIL_BASE32
+#define CPPCODEC_DETAIL_BASE32
+
+#include <stdint.h>
+#include <stdlib.h> // for abort()
+
+#include "../data/access.hpp"
+#include "../parse_error.hpp"
+#include "config.hpp"
+#include "stream_codec.hpp"
+
+namespace cppcodec {
+namespace detail {
+
+template <typename CodecVariant>
+class base32 : public CodecVariant::template codec_impl<base32<CodecVariant>>
+{
+public:
+ static inline constexpr uint8_t binary_block_size() { return 5; }
+ static inline constexpr uint8_t encoded_block_size() { return 8; }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr uint8_t num_encoded_tail_symbols(uint8_t num_bytes)
+ {
+ return (num_bytes == 1) ? 2 // 2 symbols, 6 padding characters
+ : (num_bytes == 2) ? 4 // 4 symbols, 4 padding characters
+ : (num_bytes == 3) ? 5 // 5 symbols, 3 padding characters
+ : (num_bytes == 4) ? 7 // 7 symbols, 1 padding characters
+ : throw std::domain_error("invalid number of bytes in a tail block");
+ }
+
+ template <uint8_t I>
+ static CPPCODEC_ALWAYS_INLINE constexpr uint8_t index(
+ const uint8_t* b /*binary block*/) noexcept
+ {
+ static_assert(I >= 0 && I < encoded_block_size(),
+ "invalid encoding symbol index in a block");
+
+ return (I == 0) ? ((b[0] >> 3) & 0x1F) // first 5 bits
+ : (I == 1) ? (((b[0] << 2) & 0x1C) | ((b[1] >> 6) & 0x3))
+ : (I == 2) ? ((b[1] >> 1) & 0x1F)
+ : (I == 3) ? (((b[1] << 4) & 0x10) | ((b[2] >> 4) & 0xF))
+ : (I == 4) ? (((b[2] << 1) & 0x1E) | ((b[3] >> 7) & 0x1))
+ : (I == 5) ? ((b[3] >> 2) & 0x1F)
+ : (I == 6) ? (((b[3] << 3) & 0x18) | ((b[4] >> 5) & 0x7))
+ : /*I == 7*/ (b[4] & 0x1F); // last 5 bits;
+ }
+
+ template <bool B>
+ using uint8_if = typename std::enable_if<B, uint8_t>::type;
+
+ template <uint8_t I>
+ static CPPCODEC_ALWAYS_INLINE constexpr
+ uint8_if<I == 1 || I == 3 || I == 4 || I == 6> index_last(
+ const uint8_t* b /*binary block*/) noexcept
+ {
+ return (I == 1) ? ((b[0] << 2) & 0x1C) // abbreviated 2nd symbol
+ : (I == 3) ? ((b[1] << 4) & 0x10) // abbreviated 4th symbol
+ : (I == 4) ? ((b[2] << 1) & 0x1E) // abbreviated 5th symbol
+ : /*I == 6*/ ((b[3] << 3) & 0x18); // abbreviated 7th symbol
+ }
+
+ template <uint8_t I>
+ static CPPCODEC_ALWAYS_INLINE
+ uint8_if<I != 1 && I != 3 && I != 4 && I != 6> index_last(
+ const uint8_t* /*binary block*/)
+ {
+ throw std::domain_error("invalid last encoding symbol index in a tail");
+ }
+
+ template <typename Result, typename ResultState>
+ static CPPCODEC_ALWAYS_INLINE void decode_block(
+ Result& decoded, ResultState&, const alphabet_index_t* idx);
+
+ template <typename Result, typename ResultState>
+ static CPPCODEC_ALWAYS_INLINE void decode_tail(
+ Result& decoded, ResultState&, const alphabet_index_t* idx, size_t idx_len);
+};
+
+//
+// 11111111 10101010 10110011 10111100 10010100
+// => 11111 11110 10101 01011 00111 01111 00100 10100
+//
+
+template <typename CodecVariant>
+template <typename Result, typename ResultState>
+CPPCODEC_ALWAYS_INLINE void base32<CodecVariant>::decode_block(
+ Result& decoded, ResultState& state, const alphabet_index_t* idx)
+{
+ put(decoded, state, static_cast<uint8_t>(((idx[0] << 3) & 0xF8) | ((idx[1] >> 2) & 0x7)));
+ put(decoded, state, static_cast<uint8_t>(((idx[1] << 6) & 0xC0) | ((idx[2] << 1) & 0x3E) | ((idx[3] >> 4) & 0x1)));
+ put(decoded, state, static_cast<uint8_t>(((idx[3] << 4) & 0xF0) | ((idx[4] >> 1) & 0xF)));
+ put(decoded, state, static_cast<uint8_t>(((idx[4] << 7) & 0x80) | ((idx[5] << 2) & 0x7C) | ((idx[6] >> 3) & 0x3)));
+ put(decoded, state, static_cast<uint8_t>(((idx[6] << 5) & 0xE0) | (idx[7] & 0x1F)));
+}
+
+template <typename CodecVariant>
+template <typename Result, typename ResultState>
+CPPCODEC_ALWAYS_INLINE void base32<CodecVariant>::decode_tail(
+ Result& decoded, ResultState& state, const alphabet_index_t* idx, size_t idx_len)
+{
+ if (idx_len == 1) {
+ throw invalid_input_length(
+ "invalid number of symbols in last base32 block: found 1, expected 2, 4, 5 or 7");
+ }
+ if (idx_len == 3) {
+ throw invalid_input_length(
+ "invalid number of symbols in last base32 block: found 3, expected 2, 4, 5 or 7");
+ }
+ if (idx_len == 6) {
+ throw invalid_input_length(
+ "invalid number of symbols in last base32 block: found 6, expected 2, 4, 5 or 7");
+ }
+
+ // idx_len == 2: decoded size 1
+ put(decoded, state, static_cast<uint8_t>(((idx[0] << 3) & 0xF8) | ((idx[1] >> 2) & 0x7)));
+ if (idx_len == 2) {
+ return;
+ }
+ // idx_len == 4: decoded size 2
+ put(decoded, state, static_cast<uint8_t>(((idx[1] << 6) & 0xC0) | ((idx[2] << 1) & 0x3E) | ((idx[3] >> 4) & 0x1)));
+ if (idx_len == 4) {
+ return;
+ }
+ // idx_len == 5: decoded size 3
+ put(decoded, state, static_cast<uint8_t>(((idx[3] << 4) & 0xF0) | ((idx[4] >> 1) & 0xF)));
+ if (idx_len == 5) {
+ return;
+ }
+ // idx_len == 7: decoded size 4
+ put(decoded, state, static_cast<uint8_t>(((idx[4] << 7) & 0x80) | ((idx[5] << 2) & 0x7C) | ((idx[6] >> 3) & 0x3)));
+}
+
+} // namespace detail
+} // namespace cppcodec
+
+#endif // CPPCODEC_DETAIL_BASE32
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * Copyright (C) 2013 Adam Rudd (bit calculations)
+ * Copyright (C) 2018 Jakob Petsovits
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Bit calculations adapted from https://github.com/adamvr/arduino-base64,
+ * commit 999595783185a0afcba156d7276dfeaa9cb5382f.
+ */
+
+#ifndef CPPCODEC_DETAIL_BASE64
+#define CPPCODEC_DETAIL_BASE64
+
+#include <stdexcept>
+#include <stdint.h>
+
+#include "../data/access.hpp"
+#include "../parse_error.hpp"
+#include "config.hpp"
+#include "stream_codec.hpp"
+
+namespace cppcodec {
+namespace detail {
+
+template <typename CodecVariant>
+class base64 : public CodecVariant::template codec_impl<base64<CodecVariant>>
+{
+public:
+ static inline constexpr uint8_t binary_block_size() { return 3; }
+ static inline constexpr uint8_t encoded_block_size() { return 4; }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr uint8_t num_encoded_tail_symbols(uint8_t num_bytes)
+ {
+ return (num_bytes == 1) ? 2 // 2 symbols, 2 padding characters
+ : (num_bytes == 2) ? 3 // 3 symbols, 1 padding character
+ : throw std::domain_error("invalid number of bytes in a tail block");
+ }
+
+ template <uint8_t I>
+ static CPPCODEC_ALWAYS_INLINE constexpr uint8_t index(
+ const uint8_t* b /*binary block*/) noexcept
+ {
+ static_assert(I >= 0 && I < encoded_block_size(),
+ "invalid encoding symbol index in a block");
+
+ return (I == 0) ? (b[0] >> 2) // first 6 bits
+ : (I == 1) ? (((b[0] & 0x3) << 4) | (b[1] >> 4))
+ : (I == 2) ? (((b[1] & 0xF) << 2) | (b[2] >> 6))
+ : /*I == 3*/ (b[2] & 0x3F); // last 6 bits
+ }
+
+ template <bool B>
+ using uint8_if = typename std::enable_if<B, uint8_t>::type;
+
+ template <uint8_t I>
+ static CPPCODEC_ALWAYS_INLINE constexpr uint8_if<I == 1 || I == 2> index_last(
+ const uint8_t* b /*binary block*/) noexcept
+ {
+ return (I == 1) ? ((b[0] & 0x3) << 4) // abbreviated 2nd symbol
+ : /*I == 2*/ ((b[1] & 0xF) << 2); // abbreviated 3rd symbol
+ }
+
+ template <uint8_t I>
+ static CPPCODEC_ALWAYS_INLINE uint8_if<I != 1 && I != 2> index_last(
+ const uint8_t* /*binary block*/)
+ {
+ throw std::domain_error("invalid last encoding symbol index in a tail");
+ }
+
+ template <typename Result, typename ResultState>
+ static CPPCODEC_ALWAYS_INLINE void decode_block(
+ Result& decoded, ResultState&, const alphabet_index_t* idx);
+
+ template <typename Result, typename ResultState>
+ static CPPCODEC_ALWAYS_INLINE void decode_tail(
+ Result& decoded, ResultState&, const alphabet_index_t* idx, size_t idx_len);
+};
+
+
+template <typename CodecVariant>
+template <typename Result, typename ResultState>
+CPPCODEC_ALWAYS_INLINE void base64<CodecVariant>::decode_block(
+ Result& decoded, ResultState& state, const alphabet_index_t* idx)
+{
+ uint_fast32_t dec = (idx[0] << 18) | (idx[1] << 12) | (idx[2] << 6) | idx[3];
+ data::put(decoded, state, static_cast<uint8_t>(dec >> 16));
+ data::put(decoded, state, static_cast<uint8_t>((dec >> 8) & 0xFF));
+ data::put(decoded, state, static_cast<uint8_t>(dec & 0xFF));
+}
+
+template <typename CodecVariant>
+template <typename Result, typename ResultState>
+CPPCODEC_ALWAYS_INLINE void base64<CodecVariant>::decode_tail(
+ Result& decoded, ResultState& state, const alphabet_index_t* idx, size_t idx_len)
+{
+ if (idx_len == 1) {
+ throw invalid_input_length(
+ "invalid number of symbols in last base64 block: found 1, expected 2 or 3");
+ }
+
+ // idx_len == 2: decoded size 1
+ data::put(decoded, state, static_cast<uint8_t>((idx[0] << 2) + ((idx[1] & 0x30) >> 4)));
+ if (idx_len == 2) {
+ return;
+ }
+
+ // idx_len == 3: decoded size 2
+ data::put(decoded, state, static_cast<uint8_t>(((idx[1] & 0xF) << 4) + ((idx[2] & 0x3C) >> 2)));
+}
+
+} // namespace detail
+} // namespace cppcodec
+
+#endif // CPPCODEC_DETAIL_BASE64
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_DETAIL_CODEC
+#define CPPCODEC_DETAIL_CODEC
+
+#include <assert.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "../data/access.hpp"
+#include "../data/raw_result_buffer.hpp"
+
+namespace cppcodec {
+namespace detail {
+
+// SFINAE: Templates sometimes beat sensible overloads - make sure we don't call the wrong one.
+template <typename T>
+struct non_numeric : std::enable_if<!std::is_arithmetic<T>::value> { };
+
+
+/**
+ * Public interface for all the codecs. For API documentation, see README.md.
+ */
+template <typename CodecImpl>
+class codec
+{
+public:
+ //
+ // Encoding
+
+ // Convenient version, returns an std::string.
+ static std::string encode(const uint8_t* binary, size_t binary_size);
+ static std::string encode(const char* binary, size_t binary_size);
+ // static std::string encode(const T& binary); -> provided by template below
+
+ // Convenient version with templated result type.
+ template <typename Result> static Result encode(const uint8_t* binary, size_t binary_size);
+ template <typename Result> static Result encode(const char* binary, size_t binary_size);
+ template <typename Result = std::string, typename T = std::vector<uint8_t>>
+ static Result encode(const T& binary);
+
+ // Reused result container version. Resizes encoded_result before writing to it.
+ template <typename Result>
+ static void encode(Result& encoded_result, const uint8_t* binary, size_t binary_size);
+ template <typename Result>
+ static void encode(Result& encoded_result, const char* binary, size_t binary_size);
+ template <typename Result, typename T, typename non_numeric<T>::type* = nullptr>
+ static void encode(Result& encoded_result, const T& binary);
+
+ // Raw pointer output, assumes pre-allocated memory with size > encoded_size(binary_size).
+ static size_t encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const uint8_t* binary, size_t binary_size) noexcept;
+ static size_t encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const char* binary, size_t binary_size) noexcept;
+ template<typename T>
+ static size_t encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const T& binary) noexcept;
+
+ // Calculate the exact length of the encoded string based on binary size.
+ static constexpr size_t encoded_size(size_t binary_size) noexcept;
+
+ //
+ // Decoding
+
+ // Convenient version, returns an std::vector<uint8_t>.
+ static std::vector<uint8_t> decode(const char* encoded, size_t encoded_size);
+ // static std::vector<uint8_t> decode(const T& encoded); -> provided by template below
+
+ // Convenient version with templated result type.
+ template <typename Result> static Result decode(const char* encoded, size_t encoded_size);
+ template <typename Result = std::vector<uint8_t>, typename T = std::string>
+ static Result decode(const T& encoded);
+
+ // Reused result container version. Resizes binary_result before writing to it.
+ template <typename Result>
+ static void decode(Result& binary_result, const char* encoded, size_t encoded_size);
+ template <typename Result, typename T, typename non_numeric<T>::type* = nullptr>
+ static void decode(Result& binary_result, const T& encoded);
+
+ // Raw pointer output, assumes pre-allocated memory with size > decoded_max_size(encoded_size).
+ static size_t decode(
+ uint8_t* binary_result, size_t binary_buffer_size,
+ const char* encoded, size_t encoded_size);
+ static size_t decode(
+ char* binary_result, size_t binary_buffer_size,
+ const char* encoded, size_t encoded_size);
+ template<typename T> static size_t decode(
+ uint8_t* binary_result, size_t binary_buffer_size, const T& encoded);
+ template<typename T> static size_t decode(
+ char* binary_result, size_t binary_buffer_size, const T& encoded);
+
+ // Calculate the maximum size of the decoded binary buffer based on the encoded string length.
+ static constexpr size_t decoded_max_size(size_t encoded_size) noexcept;
+};
+
+
+//
+// Inline definitions of the above functions, using CRTP to call into CodecImpl
+//
+
+//
+// Encoding
+
+template <typename CodecImpl>
+inline std::string codec<CodecImpl>::encode(const uint8_t* binary, size_t binary_size)
+{
+ return encode<std::string>(binary, binary_size);
+}
+
+template <typename CodecImpl>
+inline std::string codec<CodecImpl>::encode(const char* binary, size_t binary_size)
+{
+ return encode<std::string>(reinterpret_cast<const uint8_t*>(binary), binary_size);
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline Result codec<CodecImpl>::encode(const uint8_t* binary, size_t binary_size)
+{
+ Result encoded_result;
+ encode(encoded_result, binary, binary_size);
+ return encoded_result;
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline Result codec<CodecImpl>::encode(const char* binary, size_t binary_size)
+{
+ return encode<Result>(reinterpret_cast<const uint8_t*>(binary), binary_size);
+}
+
+template <typename CodecImpl>
+template <typename Result, typename T>
+inline Result codec<CodecImpl>::encode(const T& binary)
+{
+ return encode<Result>(data::uchar_data(binary), data::size(binary));
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline void codec<CodecImpl>::encode(
+ Result& encoded_result, const uint8_t* binary, size_t binary_size)
+{
+ // This overload is where we reserve buffer capacity and call into CodecImpl.
+ size_t encoded_buffer_size = encoded_size(binary_size);
+ auto state = data::create_state(encoded_result, data::specific_t());
+ data::init(encoded_result, state, encoded_buffer_size);
+
+ CodecImpl::encode(encoded_result, state, binary, binary_size);
+ data::finish(encoded_result, state);
+ assert(data::size(encoded_result) == encoded_buffer_size);
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline void codec<CodecImpl>::encode(
+ Result& encoded_result, const char* binary, size_t binary_size)
+{
+ encode(encoded_result, reinterpret_cast<const uint8_t*>(binary), binary_size);
+}
+
+template <typename CodecImpl>
+template <typename Result, typename T, typename non_numeric<T>::type*>
+inline void codec<CodecImpl>::encode(Result& encoded_result, const T& binary)
+{
+ encode(encoded_result, data::uchar_data(binary), data::size(binary));
+}
+
+template <typename CodecImpl>
+inline size_t codec<CodecImpl>::encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const uint8_t* binary, size_t binary_size) noexcept
+{
+ // This overload is where we wrap the result pointer & size.
+ data::raw_result_buffer encoded(encoded_result, encoded_buffer_size);
+ encode(encoded, binary, binary_size);
+
+ size_t encoded_size = data::size(encoded);
+ if (encoded_size < encoded_buffer_size) {
+ encoded_result[encoded_size] = '\0';
+ }
+ return encoded_size;
+}
+
+template <typename CodecImpl>
+inline size_t codec<CodecImpl>::encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const char* binary, size_t binary_size) noexcept
+{
+ // This overload is where we wrap the result pointer & size.
+ return encode(encoded_result, encoded_buffer_size,
+ reinterpret_cast<const uint8_t*>(binary), binary_size);
+}
+
+template <typename CodecImpl>
+template <typename T>
+inline size_t codec<CodecImpl>::encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const T& binary) noexcept
+{
+ return encode(encoded_result, encoded_buffer_size, data::uchar_data(binary), data::size(binary));
+}
+
+template <typename CodecImpl>
+inline constexpr size_t codec<CodecImpl>::encoded_size(size_t binary_size) noexcept
+{
+ return CodecImpl::encoded_size(binary_size);
+}
+
+
+//
+// Decoding
+
+template <typename CodecImpl>
+inline std::vector<uint8_t> codec<CodecImpl>::decode(const char* encoded, size_t encoded_size)
+{
+ return decode<std::vector<uint8_t>>(encoded, encoded_size);
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline Result codec<CodecImpl>::decode(const char* encoded, size_t encoded_size)
+{
+ Result result;
+ decode(result, encoded, encoded_size);
+ return result;
+}
+
+template <typename CodecImpl>
+template <typename Result, typename T>
+inline Result codec<CodecImpl>::decode(const T& encoded)
+{
+ return decode<Result>(data::char_data(encoded), data::size(encoded));
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline void codec<CodecImpl>::decode(Result& binary_result, const char* encoded, size_t encoded_size)
+{
+ // This overload is where we reserve buffer capacity and call into CodecImpl.
+ size_t binary_buffer_size = decoded_max_size(encoded_size);
+ auto state = data::create_state(binary_result, data::specific_t());
+ data::init(binary_result, state, binary_buffer_size);
+
+ CodecImpl::decode(binary_result, state, encoded, encoded_size);
+ data::finish(binary_result, state);
+ assert(data::size(binary_result) <= binary_buffer_size);
+}
+
+
+template <typename CodecImpl>
+template <typename Result, typename T, typename non_numeric<T>::type*>
+inline void codec<CodecImpl>::decode(Result& binary_result, const T& encoded)
+{
+ decode(binary_result, data::char_data(encoded), data::size(encoded));
+}
+
+template <typename CodecImpl>
+inline size_t codec<CodecImpl>::decode(
+ uint8_t* binary_result, size_t binary_buffer_size,
+ const char* encoded, size_t encoded_size)
+{
+ return decode(reinterpret_cast<char*>(binary_result), binary_buffer_size, encoded, encoded_size);
+}
+
+template <typename CodecImpl>
+inline size_t codec<CodecImpl>::decode(
+ char* binary_result, size_t binary_buffer_size,
+ const char* encoded, size_t encoded_size)
+{
+ // This overload is where we wrap the result pointer & size.
+ data::raw_result_buffer binary(binary_result, binary_buffer_size);
+ decode(binary, encoded, encoded_size);
+ return data::size(binary);
+}
+
+template <typename CodecImpl>
+template <typename T>
+inline size_t codec<CodecImpl>::decode(
+ uint8_t* binary_result, size_t binary_buffer_size, const T& encoded)
+{
+ return decode(reinterpret_cast<char*>(binary_result), binary_buffer_size, encoded);
+}
+
+template <typename CodecImpl>
+template <typename T>
+inline size_t codec<CodecImpl>::decode(char* binary_result, size_t binary_buffer_size, const T& encoded)
+{
+ return decode(binary_result, binary_buffer_size, data::char_data(encoded), data::size(encoded));
+}
+
+template <typename CodecImpl>
+inline constexpr size_t codec<CodecImpl>::decoded_max_size(size_t encoded_size) noexcept
+{
+ return CodecImpl::decoded_max_size(encoded_size);
+}
+
+
+} // namespace detail
+} // namespace cppcodec
+
+#endif
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_DETAIL_CONFIG_HPP
+#define CPPCODEC_DETAIL_CONFIG_HPP
+
+#ifndef __has_attribute
+ #define __has_attribute(x) 0
+#endif
+
+#if __GNUC__ || __has_attribute(always_inline)
+#define CPPCODEC_ALWAYS_INLINE inline __attribute__((always_inline))
+#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+#define CPPCODEC_ALWAYS_INLINE inline __forceinline
+#else
+#define CPPCODEC_ALWAYS_INLINE inline
+#endif
+
+#endif // CPPCODEC_DETAIL_CONFIG_HPP
+
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * Copyright (C) 2018 Jakob Petsovits
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_DETAIL_HEX
+#define CPPCODEC_DETAIL_HEX
+
+#include <stdint.h>
+#include <stdlib.h> // for abort()
+
+#include "../data/access.hpp"
+#include "../parse_error.hpp"
+#include "stream_codec.hpp"
+
+namespace cppcodec {
+namespace detail {
+
+template <typename CodecVariant>
+class hex : public CodecVariant::template codec_impl<hex<CodecVariant>>
+{
+public:
+ static inline constexpr uint8_t binary_block_size() { return 1; }
+ static inline constexpr uint8_t encoded_block_size() { return 2; }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr uint8_t num_encoded_tail_symbols(uint8_t /*num_bytes*/) noexcept
+ {
+ // Hex encoding only works on full bytes so there are no tails,
+ // no padding characters, and this function should (must) never be called.
+ return 0;
+ }
+
+ template <uint8_t I>
+ static CPPCODEC_ALWAYS_INLINE constexpr uint8_t index(
+ const uint8_t* b /*binary block*/) noexcept
+ {
+ static_assert(I >= 0 && I < encoded_block_size(),
+ "invalid encoding symbol index in a block");
+
+ return (I == 0) ? (b[0] >> 4) // first 4 bits
+ : /*I == 1*/ (b[0] & 0xF); // last 4 bits
+ }
+
+ // With only 2 bytes, enc<1> will always result in a full index() call and
+ // enc<0> will be protected by a not-reached assertion, so we don't actually
+ // care about index_last() except optimizing it out as good as possible.
+ template <bool B>
+ using uint8_if = typename std::enable_if<B, uint8_t>::type;
+
+ template <uint8_t I>
+ static CPPCODEC_ALWAYS_INLINE constexpr uint8_if<I == 0> index_last(
+ const uint8_t* /*binary block*/) noexcept
+ {
+ return 0;
+ }
+
+ template <uint8_t I>
+ static CPPCODEC_ALWAYS_INLINE uint8_if<I != 0> index_last(
+ const uint8_t* /*binary block*/)
+ {
+ throw std::domain_error("invalid last encoding symbol index in a tail");
+ }
+
+ template <typename Result, typename ResultState>
+ static CPPCODEC_ALWAYS_INLINE void decode_block(
+ Result& decoded, ResultState&, const alphabet_index_t* idx);
+
+ template <typename Result, typename ResultState>
+ static CPPCODEC_ALWAYS_INLINE void decode_tail(
+ Result& decoded, ResultState&, const alphabet_index_t* idx, size_t idx_len);
+};
+
+
+template <typename CodecVariant>
+template <typename Result, typename ResultState>
+CPPCODEC_ALWAYS_INLINE void hex<CodecVariant>::decode_block(
+ Result& decoded, ResultState& state, const alphabet_index_t* idx)
+{
+ data::put(decoded, state, static_cast<uint8_t>((idx[0] << 4) | idx[1]));
+}
+
+template <typename CodecVariant>
+template <typename Result, typename ResultState>
+CPPCODEC_ALWAYS_INLINE void hex<CodecVariant>::decode_tail(
+ Result&, ResultState&, const alphabet_index_t*, size_t)
+{
+ throw invalid_input_length(
+ "odd-length hex input is not supported by the streaming octet decoder, "
+ "use a place-based number decoder instead");
+}
+
+} // namespace detail
+} // namespace cppcodec
+
+#endif // CPPCODEC_DETAIL_HEX
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * Copyright (C) 2018 Jakob Petsovits
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_DETAIL_STREAM_CODEC
+#define CPPCODEC_DETAIL_STREAM_CODEC
+
+#include <limits>
+#include <stdlib.h> // for abort()
+#include <stdint.h>
+
+#include "../parse_error.hpp"
+#include "config.hpp"
+
+namespace cppcodec {
+namespace detail {
+
+using alphabet_index_t = uint_fast16_t;
+
+template <typename Codec, typename CodecVariant>
+class stream_codec
+{
+public:
+ template <typename Result, typename ResultState> static void encode(
+ Result& encoded_result, ResultState&, const uint8_t* binary, size_t binary_size);
+
+ template <typename Result, typename ResultState> static void decode(
+ Result& binary_result, ResultState&, const char* encoded, size_t encoded_size);
+
+ static constexpr size_t encoded_size(size_t binary_size) noexcept;
+ static constexpr size_t decoded_max_size(size_t encoded_size) noexcept;
+};
+
+template <bool GeneratesPadding> // default for CodecVariant::generates_padding() == false
+struct padder {
+ template <typename CodecVariant, typename Result, typename ResultState, typename SizeT>
+ static CPPCODEC_ALWAYS_INLINE void pad(Result&, ResultState&, SizeT) { }
+};
+
+template<> // specialization for CodecVariant::generates_padding() == true
+struct padder<true> {
+ template <typename CodecVariant, typename Result, typename ResultState, typename SizeT>
+ static CPPCODEC_ALWAYS_INLINE void pad(
+ Result& encoded, ResultState& state, SizeT num_padding_characters)
+ {
+ for (SizeT i = 0; i < num_padding_characters; ++i) {
+ data::put(encoded, state, CodecVariant::padding_symbol());
+ }
+ }
+};
+
+template <size_t I>
+struct enc {
+ // Block encoding: Go from 0 to (block size - 1), append a symbol for each iteration unconditionally.
+ template <typename Codec, typename CodecVariant, typename Result, typename ResultState>
+ static CPPCODEC_ALWAYS_INLINE void block(Result& encoded, ResultState& state, const uint8_t* src)
+ {
+ using EncodedBlockSizeT = decltype(Codec::encoded_block_size());
+ constexpr static const EncodedBlockSizeT SymbolIndex = static_cast<EncodedBlockSizeT>(I - 1);
+
+ enc<I - 1>().template block<Codec, CodecVariant>(encoded, state, src);
+ data::put(encoded, state, CodecVariant::symbol(Codec::template index<SymbolIndex>(src)));
+ }
+
+ // Tail encoding: Go from 0 until (runtime) num_symbols, append a symbol for each iteration.
+ template <typename Codec, typename CodecVariant, typename Result, typename ResultState,
+ typename EncodedBlockSizeT = decltype(Codec::encoded_block_size())>
+ static CPPCODEC_ALWAYS_INLINE void tail(
+ Result& encoded, ResultState& state, const uint8_t* src, EncodedBlockSizeT num_symbols)
+ {
+ constexpr static const EncodedBlockSizeT SymbolIndex = Codec::encoded_block_size() - I;
+ constexpr static const EncodedBlockSizeT NumSymbols = SymbolIndex + static_cast<EncodedBlockSizeT>(1);
+
+ if (num_symbols == NumSymbols) {
+ data::put(encoded, state, CodecVariant::symbol(Codec::template index_last<SymbolIndex>(src)));
+ return;
+ }
+ data::put(encoded, state, CodecVariant::symbol(Codec::template index<SymbolIndex>(src)));
+ enc<I - 1>().template tail<Codec, CodecVariant>(encoded, state, src, num_symbols);
+ }
+};
+
+template<> // terminating specialization
+struct enc<0> {
+ template <typename Codec, typename CodecVariant, typename Result, typename ResultState>
+ static CPPCODEC_ALWAYS_INLINE void block(Result&, ResultState&, const uint8_t*) { }
+
+ template <typename Codec, typename CodecVariant, typename Result, typename ResultState,
+ typename EncodedBlockSizeT = decltype(Codec::encoded_block_size())>
+ static CPPCODEC_ALWAYS_INLINE void tail(Result&, ResultState&, const uint8_t*, EncodedBlockSizeT)
+ {
+ abort(); // Not reached: block() should be called if num_symbols == block size, not tail().
+ }
+};
+
+template <typename Codec, typename CodecVariant>
+template <typename Result, typename ResultState>
+inline void stream_codec<Codec, CodecVariant>::encode(
+ Result& encoded_result, ResultState& state,
+ const uint8_t* src, size_t src_size)
+{
+ using encoder = enc<Codec::encoded_block_size()>;
+
+ const uint8_t* src_end = src + src_size;
+
+ if (src_size >= Codec::binary_block_size()) {
+ src_end -= Codec::binary_block_size();
+
+ for (; src <= src_end; src += Codec::binary_block_size()) {
+ encoder::template block<Codec, CodecVariant>(encoded_result, state, src);
+ }
+ src_end += Codec::binary_block_size();
+ }
+
+ if (src_end > src) {
+ auto remaining_src_len = src_end - src;
+ if (!remaining_src_len || remaining_src_len >= Codec::binary_block_size()) {
+ abort();
+ return;
+ }
+
+ auto num_symbols = Codec::num_encoded_tail_symbols(
+ static_cast<uint8_t>(remaining_src_len));
+
+ encoder::template tail<Codec, CodecVariant>(encoded_result, state, src, num_symbols);
+
+ padder<CodecVariant::generates_padding()>::template pad<CodecVariant>(
+ encoded_result, state, Codec::encoded_block_size() - num_symbols);
+ }
+}
+
+// Range & lookup table generation, see
+// http://stackoverflow.com/questions/13313980/populate-an-array-using-constexpr-at-compile-time
+// and http://cplusadd.blogspot.ca/2013/02/c11-compile-time-lookup-tablearray-with.html
+
+template<unsigned... Is> struct seq {};
+
+template<unsigned N, unsigned... Is>
+struct gen_seq : gen_seq<N - 4, N - 4, N - 3, N - 2, N - 1, Is...> {
+ // Clang up to 3.6 has a limit of 256 for template recursion,
+ // so pass a few more symbols at once to make it work.
+ static_assert(N % 4 == 0, "I must be divisible by 4 to eventually end at 0");
+};
+template<unsigned... Is>
+struct gen_seq<0, Is...> : seq<Is...> {};
+
+template <size_t N>
+struct lookup_table_t {
+ alphabet_index_t lookup[N];
+ static constexpr size_t size = N;
+};
+
+template<typename LambdaType, unsigned... Is>
+constexpr lookup_table_t<sizeof...(Is)> make_lookup_table(seq<Is...>, LambdaType value_for_index) {
+ return { { value_for_index(Is)... } };
+}
+
+template<unsigned N, typename LambdaType>
+constexpr lookup_table_t<N> make_lookup_table(LambdaType evalFunc) {
+ return make_lookup_table(gen_seq<N>(), evalFunc);
+}
+
+// CodecVariant::symbol() provides a symbol for an index.
+// Use recursive templates to get the inverse lookup table for fast decoding.
+
+template <typename T>
+static CPPCODEC_ALWAYS_INLINE constexpr size_t num_possible_values()
+{
+ return static_cast<size_t>(
+ static_cast<intmax_t>((std::numeric_limits<T>::max)())
+ - static_cast<intmax_t>((std::numeric_limits<T>::min)()) + 1);
+}
+
+template <typename CodecVariant, alphabet_index_t InvalidIdx, size_t I>
+struct index_if_in_alphabet {
+ static CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t for_symbol(char symbol)
+ {
+ return (CodecVariant::symbol(
+ static_cast<alphabet_index_t>(CodecVariant::alphabet_size() - I)) == symbol)
+ ? static_cast<alphabet_index_t>(CodecVariant::alphabet_size() - I)
+ : index_if_in_alphabet<CodecVariant, InvalidIdx, I - 1>::for_symbol(symbol);
+ }
+};
+template <typename CodecVariant, alphabet_index_t InvalidIdx>
+struct index_if_in_alphabet<CodecVariant, InvalidIdx, 0> { // terminating specialization
+ static CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t for_symbol(char)
+ {
+ return InvalidIdx;
+ }
+};
+
+template <typename CodecVariant, size_t I>
+struct padding_searcher {
+ static CPPCODEC_ALWAYS_INLINE constexpr bool exists_padding_symbol()
+ {
+ // Clang up to 3.6 has a limit of 256 for template recursion,
+ // so pass a few more symbols at once to make it work.
+ static_assert(I % 4 == 0, "I must be divisible by 4 to eventually end at 0");
+
+ return CodecVariant::is_padding_symbol(
+ static_cast<char>(num_possible_values<char>() - I - 4))
+ || CodecVariant::is_padding_symbol(
+ static_cast<char>(num_possible_values<char>() - I - 3))
+ || CodecVariant::is_padding_symbol(
+ static_cast<char>(num_possible_values<char>() - I - 2))
+ || CodecVariant::is_padding_symbol(
+ static_cast<char>(num_possible_values<char>() - I - 1))
+ || padding_searcher<CodecVariant, I - 4>::exists_padding_symbol();
+ }
+};
+template <typename CodecVariant>
+struct padding_searcher<CodecVariant, 0> { // terminating specialization
+ static CPPCODEC_ALWAYS_INLINE constexpr bool exists_padding_symbol() { return false; }
+};
+
+template <typename CodecVariant>
+struct alphabet_index_info
+{
+ static constexpr const size_t num_possible_symbols = num_possible_values<char>();
+
+ static constexpr const alphabet_index_t padding_idx = 1 << 8;
+ static constexpr const alphabet_index_t invalid_idx = 1 << 9;
+ static constexpr const alphabet_index_t eof_idx = 1 << 10;
+ static constexpr const alphabet_index_t stop_character_mask = static_cast<alphabet_index_t>(~0xFFu);
+
+ static constexpr const bool padding_allowed = padding_searcher<
+ CodecVariant, num_possible_symbols>::exists_padding_symbol();
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool allows_padding()
+ {
+ return padding_allowed;
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding(alphabet_index_t idx)
+ {
+ return allows_padding() ? (idx == padding_idx) : false;
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_invalid(alphabet_index_t idx) { return idx == invalid_idx; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof(alphabet_index_t idx) { return idx == eof_idx; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_stop_character(alphabet_index_t idx)
+ {
+ return (idx & stop_character_mask) != 0;
+ }
+
+private:
+ static CPPCODEC_ALWAYS_INLINE constexpr
+ alphabet_index_t valid_index_or(alphabet_index_t a, alphabet_index_t b)
+ {
+ return a == invalid_idx ? b : a;
+ }
+
+ using idx_if_in_alphabet = index_if_in_alphabet<
+ CodecVariant, invalid_idx, CodecVariant::alphabet_size()>;
+
+ static CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t index_of(char symbol)
+ {
+ return valid_index_or(idx_if_in_alphabet::for_symbol(symbol),
+ CodecVariant::is_eof_symbol(symbol) ? eof_idx
+ : CodecVariant::is_padding_symbol(symbol) ? padding_idx
+ : invalid_idx);
+ }
+
+ // GCC <= 4.9 has a bug with retaining constexpr when passing a function pointer.
+ // To get around this, we'll create a callable with operator() and pass that one.
+ // Unfortunately, MSVC prior to VS 2017 (for MinSizeRel or Release builds)
+ // chokes on this by compiling the project in 20 minutes instead of seconds.
+ // So let's define two separate variants and remove the old GCC one whenever we
+ // decide not to support GCC < 5.0 anymore.
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
+ struct index_at {
+ CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t operator()(size_t symbol) const {
+ return index_of(CodecVariant::normalized_symbol(static_cast<char>(symbol)));
+ }
+ };
+#else
+ static CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t index_at(size_t symbol)
+ {
+ return index_of(CodecVariant::normalized_symbol(static_cast<char>(symbol)));
+ }
+#endif
+
+public:
+ struct lookup {
+ static CPPCODEC_ALWAYS_INLINE alphabet_index_t for_symbol(char symbol)
+ {
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
+ static constexpr const auto t = make_lookup_table<num_possible_symbols>(index_at());
+#else
+ static constexpr const auto t = make_lookup_table<num_possible_symbols>(&index_at);
+#endif
+ static_assert(t.size == num_possible_symbols,
+ "lookup table must cover each possible (character) symbol");
+ return t.lookup[static_cast<uint8_t>(symbol)];
+ }
+ };
+};
+
+//
+// At long last! The actual decode/encode functions.
+
+template <typename Codec, typename CodecVariant>
+template <typename Result, typename ResultState>
+inline void stream_codec<Codec, CodecVariant>::decode(
+ Result& binary_result, ResultState& state,
+ const char* src_encoded, size_t src_size)
+{
+ using alphabet_index_lookup = typename alphabet_index_info<CodecVariant>::lookup;
+ const char* src = src_encoded;
+ const char* src_end = src + src_size;
+
+ alphabet_index_t alphabet_indexes[Codec::encoded_block_size()] = {};
+ alphabet_indexes[0] = alphabet_index_info<CodecVariant>::eof_idx;
+
+ alphabet_index_t* const alphabet_index_start = &alphabet_indexes[0];
+ alphabet_index_t* const alphabet_index_end = &alphabet_indexes[Codec::encoded_block_size()];
+ alphabet_index_t* alphabet_index_ptr = &alphabet_indexes[0];
+
+ while (src < src_end) {
+ if (CodecVariant::should_ignore(*src)) {
+ ++src;
+ continue;
+ }
+ *alphabet_index_ptr = alphabet_index_lookup::for_symbol(*src);
+ if (alphabet_index_info<CodecVariant>::is_stop_character(*alphabet_index_ptr)) {
+ break;
+ }
+ ++src;
+ ++alphabet_index_ptr;
+
+ if (alphabet_index_ptr == alphabet_index_end) {
+ Codec::decode_block(binary_result, state, alphabet_indexes);
+ alphabet_index_ptr = alphabet_index_start;
+ }
+ }
+
+ if (alphabet_index_info<CodecVariant>::is_invalid(*alphabet_index_ptr)) {
+ throw symbol_error(*src);
+ }
+ ++src;
+
+ alphabet_index_t* last_index_ptr = alphabet_index_ptr;
+ if (alphabet_index_info<CodecVariant>::is_padding(*last_index_ptr)) {
+ if (last_index_ptr == alphabet_index_start) {
+ // Don't accept padding at the start of a block.
+ // The encoder should have omitted that padding altogether.
+ throw padding_error();
+ }
+ // We're in here because we just read a (first) padding character. Try to read more.
+ // Count with last_index_ptr, but store in alphabet_index_ptr so we don't
+ // overflow the array in case the input data is too long.
+ ++last_index_ptr;
+ while (src < src_end) {
+ *alphabet_index_ptr = alphabet_index_lookup::for_symbol(*(src++));
+
+ if (alphabet_index_info<CodecVariant>::is_eof(*alphabet_index_ptr)) {
+ *alphabet_index_ptr = alphabet_index_info<CodecVariant>::padding_idx;
+ break;
+ }
+ if (!alphabet_index_info<CodecVariant>::is_padding(*alphabet_index_ptr)) {
+ throw padding_error();
+ }
+
+ ++last_index_ptr;
+ if (last_index_ptr > alphabet_index_end) {
+ throw padding_error();
+ }
+ }
+ }
+
+ if (last_index_ptr != alphabet_index_start) {
+ if ((CodecVariant::requires_padding()
+ || alphabet_index_info<CodecVariant>::is_padding(*alphabet_index_ptr)
+ ) && last_index_ptr != alphabet_index_end)
+ {
+ // If the input is not a multiple of the block size then the input is incorrect.
+ throw padding_error();
+ }
+ if (alphabet_index_ptr >= alphabet_index_end) {
+ abort();
+ return;
+ }
+ Codec::decode_tail(binary_result, state, alphabet_indexes,
+ static_cast<size_t>(alphabet_index_ptr - alphabet_index_start));
+ }
+}
+
+template <typename Codec, typename CodecVariant>
+inline constexpr size_t stream_codec<Codec, CodecVariant>::encoded_size(size_t binary_size) noexcept
+{
+ using C = Codec;
+
+ // constexpr rules make this a lot harder to read than it actually is.
+ return CodecVariant::generates_padding()
+ // With padding, the encoded size is a multiple of the encoded block size.
+ // To calculate that, round the binary size up to multiple of the binary block size,
+ // then convert to encoded by multiplying with { base32: 8/5, base64: 4/3 }.
+ ? (binary_size + (C::binary_block_size() - 1)
+ - ((binary_size + (C::binary_block_size() - 1)) % C::binary_block_size()))
+ * C::encoded_block_size() / C::binary_block_size()
+ // No padding: only pad to the next multiple of 5 bits, i.e. at most a single extra byte.
+ : (binary_size * C::encoded_block_size() / C::binary_block_size())
+ + (((binary_size * C::encoded_block_size()) % C::binary_block_size()) ? 1 : 0);
+}
+
+template <typename Codec, typename CodecVariant>
+inline constexpr size_t stream_codec<Codec, CodecVariant>::decoded_max_size(size_t encoded_size) noexcept
+{
+ using C = Codec;
+
+ return CodecVariant::requires_padding()
+ ? (encoded_size / C::encoded_block_size() * C::binary_block_size())
+ : (encoded_size / C::encoded_block_size() * C::binary_block_size())
+ + ((encoded_size % C::encoded_block_size())
+ * C::binary_block_size() / C::encoded_block_size());
+}
+
+} // namespace detail
+} // namespace cppcodec
+
+#endif // CPPCODEC_DETAIL_STREAM_CODEC
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_HEX_DEFAULT_LOWER
+#define CPPCODEC_HEX_DEFAULT_LOWER
+
+#include "hex_lower.hpp"
+
+using hex = cppcodec::hex_lower;
+
+#endif // CPPCODEC_HEX_DEFAULT_LOWER
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_HEX_DEFAULT_UPPER
+#define CPPCODEC_HEX_DEFAULT_UPPER
+
+#include "hex_upper.hpp"
+
+using hex = cppcodec::hex_upper;
+
+#endif // CPPCODEC_HEX_DEFAULT_UPPER
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_HEX_LOWER
+#define CPPCODEC_HEX_LOWER
+
+#include "detail/codec.hpp"
+#include "detail/hex.hpp"
+
+namespace cppcodec {
+
+namespace detail {
+
+static constexpr const char hex_lower_alphabet[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // at index 10
+ 'a', 'b', 'c', 'd', 'e', 'f'
+};
+
+class hex_lower
+{
+public:
+ template <typename Codec> using codec_impl = stream_codec<Codec, hex_lower>;
+
+ static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() {
+ static_assert(sizeof(hex_lower_alphabet) == 16, "hex alphabet must have 16 values");
+ return sizeof(hex_lower_alphabet);
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t index)
+ {
+ return hex_lower_alphabet[index];
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c)
+ {
+ // Hex decoding is always case-insensitive (even in RFC 4648), the question
+ // is only for encoding whether to use upper-case or lower-case letters.
+ return (c >= 'A' && c <= 'F') ? (c - 'A' + 'a') : c;
+ }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return false; }
+ // FIXME: doesn't require padding, but requires a multiple of the encoded block size (2)
+ static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return false; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char) { return false; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; }
+
+ // Sometimes hex strings include whitespace, but this variant forbids it.
+ static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; }
+};
+
+} // namespace detail
+
+using hex_lower = detail::codec<detail::hex<detail::hex_lower>>;
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_HEX_LOWER
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_HEX_UPPER
+#define CPPCODEC_HEX_UPPER
+
+#include "detail/codec.hpp"
+#include "detail/hex.hpp"
+
+namespace cppcodec {
+
+namespace detail {
+
+static constexpr const char hex_upper_alphabet[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+class hex_upper
+{
+public:
+ template <typename Codec> using codec_impl = stream_codec<Codec, hex_upper>;
+
+ static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() {
+ static_assert(sizeof(hex_upper_alphabet) == 16, "hex alphabet must have 16 values");
+ return sizeof(hex_upper_alphabet);
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t index)
+ {
+ return hex_upper_alphabet[index];
+ }
+ static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c)
+ {
+ // Hex decoding is always case-insensitive (even in RFC 4648), the question
+ // is only for encoding whether to use upper-case or lower-case letters.
+ return (c >= 'a' && c <= 'f') ? (c - 'a' + 'A') : c;
+ }
+
+ static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return false; }
+ // FIXME: doesn't require padding, but requires a multiple of the encoded block size (2)
+ static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return false; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char) { return false; }
+ static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; }
+
+ // Sometimes hex strings include whitespace, but this variant forbids it.
+ static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; }
+};
+
+} // namespace detail
+
+using hex_upper = detail::codec<detail::hex<detail::hex_upper>>;
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_HEX_UPPER
--- /dev/null
+cppcodec_library_srcs = [
+ 'base32_crockford.hpp',
+ 'base32_default_crockford.hpp',
+ 'base32_default_hex.hpp',
+ 'base32_default_rfc4648.hpp',
+ 'base32_hex.hpp',
+ 'base32_rfc4648.hpp',
+ 'base64_default_rfc4648.hpp',
+ 'base64_default_url.hpp',
+ 'base64_default_url_unpadded.hpp',
+ 'base64_rfc4648.hpp',
+ 'base64_url.hpp',
+ 'base64_url_unpadded.hpp',
+ 'hex_default_lower.hpp',
+ 'hex_default_upper.hpp',
+ 'hex_lower.hpp',
+ 'hex_upper.hpp',
+ 'parse_error.hpp',
+ 'data/access.hpp',
+ 'data/raw_result_buffer.hpp',
+ 'detail/base32.hpp',
+ 'detail/base64.hpp',
+ 'detail/codec.hpp',
+ 'detail/config.hpp',
+ 'detail/hex.hpp',
+ 'detail/stream_codec.hpp',
+ ]
+
+dlog_dep = dependency('dlog', method : 'pkg-config')
+
+cppcodec_deps = [
+ dlog_dep,
+ ]
+
+cppcodec_include_dirs = include_directories(
+ '.',
+ )
+
+cppcodec_library = library('cppcodec',
+ cppcodec_library_srcs,
+ include_directories : [ cppcodec_include_dirs ],
+ dependencies : [cppcodec_deps],
+ install_dir : mmi_prefix_plugindir,
+ install : true
+ )
--- /dev/null
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_PARSE_ERROR
+#define CPPCODEC_PARSE_ERROR
+
+#include <stdexcept>
+#include <string>
+
+namespace cppcodec {
+
+namespace detail {
+// <*stream> headers include a lot of code and noticeably increase compile times.
+// The only thing we want from them really is a char-to-string conversion.
+// That's easy to implement with many less lines of code, so let's do it ourselves.
+template <int N>
+static void uctoa(unsigned char n, char (&s)[N])
+{
+ static_assert(N >= 4, "need at least 4 bytes to convert an unsigned char to string safely");
+ int i = sizeof(s) - 1;
+ int num_chars = 1;
+ s[i--] = '\0';
+ do { // generate digits in reverse order
+ s[i--] = n % 10 + '0'; // get next digit
+ ++num_chars;
+ } while ((n /= 10) > 0); // delete it
+
+ if (num_chars == sizeof(s)) {
+ return;
+ }
+ for (i = 0; i < num_chars; ++i) { // move chars to front of string
+ s[i] = s[i + (sizeof(s) - num_chars)];
+ }
+}
+} // end namespace detail
+
+
+class parse_error : public std::domain_error
+{
+public:
+ using std::domain_error::domain_error;
+};
+
+// Avoids memory allocation, so it can be used in constexpr functions.
+class symbol_error : public parse_error
+{
+public:
+ symbol_error(char c)
+ : parse_error(symbol_error::make_error_message(c))
+ , m_symbol(c)
+ {
+ }
+
+ symbol_error(const symbol_error&) = default;
+
+ char symbol() const noexcept { return m_symbol; }
+
+private:
+ static std::string make_error_message(char c)
+ {
+ char s[4];
+ detail::uctoa(*reinterpret_cast<unsigned char*>(&c), s);
+ return std::string("parse error: character [") + &(s[0]) + " '" + c + "'] out of bounds";
+ }
+
+private:
+ char m_symbol;
+};
+
+class invalid_input_length : public parse_error
+{
+public:
+ using parse_error::parse_error;
+};
+
+class padding_error : public invalid_input_length
+{
+public:
+ padding_error()
+ : invalid_input_length("parse error: codec expects padded input string but padding was invalid")
+ {
+ }
+
+ padding_error(const padding_error&) = default;
+};
+
+} // namespace cppcodec
+
+#endif // CPPCODEC_PARSE_ERROR
--- /dev/null
+# Custom Node Development Guide
+
+## The Basics of Node Development: Standard Node Development Method
+
+Nodes that can be commonly used across various Tizen devices are managed as Standard Nodes,
+and they can easily be added to a Workflow by specifying their enumeration values.
+
+An example using one of these Standard Nodes, the `Fixed String Match` Node, is shown below.
+The `Fixed String Match` Node checks if any data coming into its input port named `TEXT`
+matches with any of the elements within the string array type attribute named `CANDIDATES`.
+If there's a match, the matched data will be outputted from the port named `MATCHED_CANDIDATE`.
+Since this function can be commonly utilized across different Tizen devices,
+it is being managed as a Standard Node.
+
+To use this Node in your Workflow, either write code like this:
+
+```c++
+ mmi_workflow_h workflow = nullptr;
+ mmi_workflow_create(&workflow);
+
+ mmi_node_h node_match = nullptr;
+ mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match);
+ mmi_workflow_node_add(workflow, "MATCH", node_match);
+
+ mmi_node_destroy(node_match);
+
+ mmi_workflow_destroy(workflow);
+```
+
+or create a Workflow script like so:
+
+```
+@node-list
+[Logic] FIXED_STRING_MATCH as MATCH
+```
+
+In order to utilize a Node as a Standard Node, it must be declared as one of the
+Node Enumeration values provided by the MMI Framework, such as:
+
+```c++
+enum mmi_node_logic_type_e {
+ /* Other enumeration types ... */
+ MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH,
+```
+
+When developing a Node Plugin, the above declared Node Enumeration value
+should be used to provide Node information to the MMI Framework.
+
+```c++
+static int node_initialized_cb(mmi_node_instance_h instance)
+{
+ /* Node Callback function implementation */
+ /* ... */
+}
+
+/* Function called by the MMI Framework to query the list of Nodes */
+EXPORT_API void mmi_plugin_module_get_node_list()
+{
+ mmi_node_callbacks_s node_callbacks {
+ node_initialized_cb,
+ node_deinitialized_cb,
+ /* Etc ... */
+ };
+
+ mmi_port_callbacks_s text_port_callbacks {
+ port_output_format_requested_cb,
+ port_input_data_received_cb
+ };
+
+ mmi_port_h match_text_port = nullptr;
+ mmi_port_create(&match_text_port);
+ /* Additional port related configurations ... */
+
+ mmi_port_h match_candidate_port = nullptr;
+ mmi_port_create(&match_candidate_port);
+ /* Additional port related configurations ... */
+
+ mmi_node_h match_node = nullptr;
+ mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &match_node);
+ mmi_node_add_port(match_node, match_text_port);
+ mmi_node_add_port(match_node, match_candidate_port);
+ mmi_node_set_callbacks(match_node, node_callbacks);
+ mmi_node_register(match_node);
+}
+```
+
+## The Need for Developing Custom Nodes
+
+Although we have explored how to develop Standard Nodes, there may be cases where some nodes
+are only needed for specific products or scenarios among the available nodes. In such cases,
+the MMI Framework cannot provide the declaration of Node Enumeration values.
+
+Therefore, registration as a Custom Node rather than a Standard Node is necessary in
+these situations. Each Workflow can make use of them by assigning free-form string
+identifiers instead of relying on enumeration values.
+
+Since free-form string identifiers might clash with other nodes, it is recommended to
+follow a non-overlapping format similar to the Java Package Naming Convention,
+such as "affiliation.organization.projectName".
+
+Reference URL : https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
+
+## Custom Node Development Method
+
+To register a Custom Node with the MMI Framework, the code should be written in a manner similar
+to the Standard Node development described earlier. However, when actually creating the Node,
+the `mmi_node_create_custom()` function needs to be used.
+
+```c++
+/* Function called by the MMI Framework to query the list of Nodes */
+EXPORT_API void mmi_plugin_module_get_node_list()
+{
+ /* Callback / Port related declarations are the same as in the previous example */
+
+ mmi_node_h test_node = nullptr;
+ mmi_node_create_custom("com.samsung.tizen.test-node", &test_node);
+ mmi_node_set_callbacks(test_node, node_callbacks);
+ mmi_node_register(test_node);
+}
+```
+
+## Verifying the Normal Operation of Developed Custom Nodes
+
+The MMI Framework provides a program called `mmi-cli-node-tester` to check whether
+Nodes are operating correctly. By utilizing this program, each Node callback can be
+tested for functionality.
+
+```console
+[root@localhost ~]# dlogutil MMI-MODULE-TEST-NODE &
+
+[root@localhost ~]# mmi-cli-node-tester /usr/share/mmi/plugins/libmmi_module_test_node.so
+tester> load
+
+tester> create
+D/MMI-MODULE-TEST-NODE(160438): mmi-module-test-node.cpp: node_initialized_cb(16) > Node initialize callback is called for 0x557c1abdb0
+
+tester> activate
+D/MMI-MODULE-TEST-NODE(160438): mmi-module-test-node.cpp: node_activated_cb(35) > Node activate callback is called for 0x557c1abdb0
+
+tester> help
+Commands available:
+ - help
+ This help message
+ - exit
+ Quit the session
+ - loop
+ Start ecore main loop
+ - load
+ Load the node module that needs to be tested
+ - unload
+ Unload the currently loaded node module
+ - create
+ Create a new node instance
+ - destroy
+ Destroy the node instance with the given index
+ - activate
+ Activate the node instance with the given index
+ - deactivate
+ Dectivate the node instance with the given index
+ - set_attribute
+ (menu)
+ - push_data
+ (menu)
+
+tester> push_data
+
+push_data> help
+Commands available:
+ - help
+ This help message
+ - exit
+ Quit the session
+ - int
+ Push an integer data
+ - text
+ Push a text data
+ - screen_info
+ Push a screen info data
+ - user_recognition
+ Push a user recognition info data
+ - audio
+ Push audio data from file
+ - video
+ Push video data from file
+ - tester
+ (menu)
+
+push_data> exit
+```
+
+
+## Using Custom Nodes in a Workflow
+
+After completing the development and installation of a Custom Node, it can be used
+by calling the `mmi_node_create_custom()` function in the code:
+```c++
+ mmi_workflow_h workflow = nullptr;
+ mmi_workflow_create(&workflow);
+
+ mmi_node_h node_test = nullptr;
+ mmi_node_create_custom("com.samsung.tizen.test-node", &node_test);
+ mmi_workflow_node_add(workflow, "TEST_NODE", node_test);
+
+ mmi_node_destroy(node_test);
+
+ mmi_workflow_destroy(workflow);
+```
+
+Alternatively, a Workflow Script can be created like so:
+```
+@node-list
+[Custom] com.samsung.tizen.test-node as TEST
+```
+
+For testing a Custom Workflow containing a Custom Node,
+refer to the [Custom Workflow Development Guide](custom-workflow-en.md).
--- /dev/null
+# Custom Node 개발 가이드
+
+## Node 개발의 기본 : Standard Node 개발 방법
+
+다양한 Tizen 기기들에서 공통적으로 사용이 가능한 Node 는 Standard Node 로 관리되고 있으며,
+이들은 enumeration 을 통해 손쉽게 Workflow 에 추가가 가능하다.
+
+아래는 Standard Node 중 하나인 `Fixed String Match Node` 를 사용하는 예제를 보여주고 있다.
+`Fixed String Match Node` 는 INPUT PORT 인 `TEXT` 라는 이름의 Port 로 들어온 데이터가,
+`CANDIDATES` 라는 이름을 가진 String Array 타입의 Attribute 중 하나라도 일치하는 경우
+일치하는 데이터를 `MATCHED_CANDIDATE` 라는 이름의 OUTPUT PORT 로 출력해 주는 역할을 수행하며,
+이러한 기능은 다양한 Tizen 기기들에서 공통적으로 사용될 수 있는 기능이기에
+Standard Node 로 관리되고 있다.
+
+해당 Node 를 Workflow 에서 사용하기 위해서는 아래와 같이 Code 를 작성하거나,
+
+```c++
+ mmi_workflow_h workflow = nullptr;
+ mmi_workflow_create(&workflow);
+
+ mmi_node_h node_match = nullptr;
+ mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match);
+ mmi_workflow_node_add(workflow, "MATCH", node_match);
+
+ mmi_node_destroy(node_match);
+
+ mmi_workflow_destroy(workflow);
+```
+
+혹은 다음과 같이 Workflow Script 를 작성하는 방식으로 사용할 수 있다.
+
+```
+@node-list
+[Logic] FIXED_STRING_MATCH as MATCH
+```
+
+이렇듯 Standard Node 로 사용하기 위해서는, 아래와 같이 MMI Framework 에서 제공하는
+Node Enumeration 값 중 하나로 선언되어 있어야 하며,
+
+```c++
+enum mmi_node_logic_type_e {
+ /* Other enumeration types ... */
+ MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH,
+```
+
+Node Plugin 개발 시 위 선언된 Node Enumeration 값을 사용하여 MMI Framework 에
+Node 정보를 제공하여야 한다.
+
+```c++
+static int node_initialized_cb(mmi_node_instance_h instance)
+{
+ /* Node Callback 함수 구현부 */
+ /* ... */
+}
+
+/* MMI Framework 이 Node 목록을 Query 하기 위해 부르는 함수 */
+EXPORT_API void mmi_plugin_module_get_node_list()
+{
+ mmi_node_callbacks_s node_callbacks {
+ node_initialized_cb,
+ node_deinitialized_cb,
+ /* 기타 등등 ... */
+ };
+
+ mmi_port_callbacks_s text_port_callbacks {
+ port_output_format_requested_cb,
+ port_input_data_received_cb
+ };
+
+ mmi_port_h match_text_port = nullptr;
+ mmi_port_create(&match_text_port);
+ /* 기타 포트 관련 설정 ... */
+
+ mmi_port_h match_candidate_port = nullptr;
+ mmi_port_create(&match_candidate_port);
+ /* 기타 포트 관련 설정 ... */
+
+ mmi_node_h match_node = nullptr;
+ mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &match_node);
+ mmi_node_add_port(match_node, match_text_port);
+ mmi_node_add_port(match_node, match_candidate_port);
+ mmi_node_set_callbacks(match_node, node_callbacks);
+ mmi_node_register(match_node);
+}
+```
+
+## Custom Node 개발의 필요성
+
+위에서 Standard Node 를 개발하기 위한 방법에 대해 알아보았으나, 경우에 따라
+Node 들 중 각 Product 혹은 특정 시나리오에만 필요한 Node 도 있을 수 있으며,
+이러한 Node 들은 Framework 차원에서 Node Enumeration 값 선언을 제공할 수가 없다.
+
+따라서, 이러한 경우에는 Standard Node 가 아닌 Custom Node 로의 등록이 필요하며,
+Enumeration 기반이 아닌 Free-form string identifier 를 부여하여
+각 Workflow 에서 이를 사용할 수 있다.
+
+Free-form string identifier 는 다른 Node 와 중복될 가능성이 있으므로,
+가급적 "소속기관.소속조직.프로젝트이름" 과 같이 Java Package Naming Convention
+과 유사하게 중복되지 않는 형식을 따라 지정하는 것을 권장한다.
+
+참고 : https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
+
+## Custom Node 개발 방법
+
+Custom Node 를 MMI Framework 에 등록하기 위해서는, 위에서 설명한
+Standard Node 개발과 동일하게 코드를 작성하되, 실제 Node 생성시에
+`mmi_node_create_custom()` 함수를 사용하면 된다.
+
+```c++
+/* MMI Framework 이 Node 목록을 Query 하기 위해 부르는 함수 */
+EXPORT_API void mmi_plugin_module_get_node_list()
+{
+ /* 콜백 / 포트 관련 선언 부분은 상단 예제와 동일 */
+
+ mmi_node_h test_node = nullptr;
+ mmi_node_create_custom("com.samsung.tizen.test-node", &test_node);
+ mmi_node_set_callbacks(test_node, node_callbacks);
+ mmi_node_register(test_node);
+}
+```
+
+## 개발된 Custom Node 정상 동작 여부 확인하기
+
+MMI Framework 에서는 Node 의 정상 동작 여부를 확인할 수 있는
+`mmi-cli-node-tester` 라는 프로그램을 제공한다.
+이 프로그램을 활용하여 각 Node Callback 들이 동작을 테스트해볼 수 있다.
+
+```console
+[root@localhost ~]# dlogutil MMI-MODULE-TEST-NODE &
+
+[root@localhost ~]# mmi-cli-node-tester /usr/share/mmi/plugins/libmmi_module_test_node.so
+tester> load
+
+tester> create
+D/MMI-MODULE-TEST-NODE(160438): mmi-module-test-node.cpp: node_initialized_cb(16) > Node initialize callback is called for 0x557c1abdb0
+
+tester> activate
+D/MMI-MODULE-TEST-NODE(160438): mmi-module-test-node.cpp: node_activated_cb(35) > Node activate callback is called for 0x557c1abdb0
+
+tester> help
+Commands available:
+ - help
+ This help message
+ - exit
+ Quit the session
+ - loop
+ Start ecore main loop
+ - load
+ Load the node module that needs to be tested
+ - unload
+ Unload the currently loaded node module
+ - create
+ Create a new node instance
+ - destroy
+ Destroy the node instance with the given index
+ - activate
+ Activate the node instance with the given index
+ - deactivate
+ Dectivate the node instance with the given index
+ - set_attribute
+ (menu)
+ - push_data
+ (menu)
+
+tester> push_data
+
+push_data> help
+Commands available:
+ - help
+ This help message
+ - exit
+ Quit the session
+ - int
+ Push an integer data
+ - text
+ Push a text data
+ - screen_info
+ Push a screen info data
+ - user_recognition
+ Push a user recognition info data
+ - audio
+ Push audio data from file
+ - video
+ Push video data from file
+ - tester
+ (menu)
+
+push_data> exit
+```
+
+
+## Custom Node 를 Workflow 에서 사용하기
+
+개발 및 설치가 완료된 Custom Node 는 `mmi_node_create_custom()` 함수를 Code 에서 호출하거나
+```c++
+ mmi_workflow_h workflow = nullptr;
+ mmi_workflow_create(&workflow);
+
+ mmi_node_h node_test = nullptr;
+ mmi_node_create_custom("com.samsung.tizen.test-node", &node_test);
+ mmi_workflow_node_add(workflow, "TEST_NODE", node_test);
+
+ mmi_node_destroy(node_test);
+
+ mmi_workflow_destroy(workflow);
+```
+
+혹은 다음과 같이 Workflow Script 를 작성하는 방식으로 사용할 수 있다.
+```
+@node-list
+[Custom] com.samsung.tizen.test-node as TEST
+```
+
+Custom Node 를 포함시킨 Custom Workflow 를 테스트하는 방법은
+[Custom Workflow 개발 가이드](custom-workflow-kr.md) 를 참고한다.
--- /dev/null
+# Custom Workflow 개발 가이드
+
+## Standard Workflow 소개
+
+MMI Framework 에서는 사용자에게 유용한 기능을 제공하는
+Standard Workflow 를 제공하고 있으며, 각 App 개발자들은
+해당 Standard Workflow 를 사용 요청하기만 하면 다양한
+Modality 들로부터 수집된 데이터를 해석한 결과를 손쉽게
+받아볼 수 있다.
+
+다음은 호출어 없이도 등록된 음성 명령어를 상시 검출하는
+기능을 제공하는 Wakeupless Command 라는 Workflow 를
+Application 에서 사용하는 예제를 보여주고 있다.
+
+```c++
+mmi_workflow_instance_h instance;
+mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND, &instance);
+mmi_workflow_instance_activate(instance);
+```
+
+## Custom Workflow 개발의 필요성
+
+위에서 Standard Workflow 를 개발하기 위한 방법에 대해 알아보았으나, 경우에 따라
+Application 개발자가 다양한 Node 들로 이루어진 Workflow 를
+특정 시나리오에 맞추어 직접 구성하고 싶은 경우가 있을 수 있다.
+
+이러한 경우, Custom Workflow 를 생성하여 자유롭게 원하는
+Workflow 를 구성하여 실행시킬 수 있다.
+
+## Custom Workflow 생성 방법
+
+Custom Workflow 를 생성하는 방법에는 크게 세가지가 있을 수 있다.
+
+첫번째는, Workflow Script 파일을 작성하고 이를 불러들이는 방법이다.
+
+다음과 같은 Workflow Script 를 "test.mws" 라는 이름으로 저장했다면,
+```
+@workflow
+
+@node-list
+[Source] MIC_AMBIENT as MIC
+[Processor] ASR as ASR
+[Logic] FIXED_STRING_MATCH as MATCH
+
+@link-list
+MIC.AUDIO -> ASR.AUDIO
+ASR.FINAL_ASR -> MATCH.TEXT
+
+@attribute-list
+MATCH.CANDIDATES as COMMANDS
+
+@output-list
+MATCH.COMMAND as MATCHED_CANDIDATE
+```
+Application 에서 다음과 같이 해당 파일을 읽어들여 Workflow Instance 를 생성할 수 있다.
+
+```c++
+mmi_workflow_h workflow;
+mmi_workflow_create_from_script_file("./test.mws", &workflow);
+
+mmi_workflow_instance_h instance;
+mmi_custom_workflow_instance_create(workflow, &instance);
+mmi_workflow_instance_activate(instance);
+```
+
+두번째는, 첫번째와 유사하지만 Workflow Script 를 파일이 아닌, Parameter 로
+직접 전달하여 Workflow Instance 를 생성하는 방법이다.
+
+```c++
+std::string script = R"(
+@workflow
+
+@node-list
+[Source] MIC_AMBIENT as MIC
+[Processor] ASR as ASR
+[Logic] FIXED_STRING_MATCH as MATCH
+
+@link-list
+MIC.AUDIO -> ASR.AUDIO
+ASR.FINAL_ASR -> MATCH.TEXT
+
+@attribute-list
+MATCH.CANDIDATES as COMMANDS
+
+@output-list
+MATCH.COMMAND as MATCHED_CANDIDATE
+)";
+
+mmi_workflow_h workflow;
+mmi_workflow_create_from_script(script.c_str(), &workflow);
+
+mmi_workflow_instance_h instance;
+mmi_custom_workflow_instance_create(workflow, &instance);
+mmi_workflow_instance_activate(instance);
+```
+
+마지막으로는, API 를 통하여 Workflow Prototype 을 생성하는 방법이다.
+
+Code 를 작성하여야 하기에, 위에서 설명한 Workflow Script 작성 방식에 비해
+개발이 까다롭고 유연성이 떨어지지만, Script 에서 지원하지 않는
+다양한 기능을 사용할 수 있다는 장점이 있다.
+
+다음은 이러한 방법을 사용하여 Custom Workflow 를 정의하고
+이 Workflow 의 Instance 를 생성하는 Application 예제 코드이다.
+
+```c++
+mmi_workflow_h workflow;
+mmi_workflow_create(&workflow);
+
+mmi_node_h node_mic = nullptr;
+mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic);
+mmi_workflow_node_add(workflow, "MIC", node_mic);
+
+mmi_node_h node_asr = nullptr;
+mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr);
+mmi_workflow_node_add(workflow, "ASR", node_asr);
+
+mmi_node_h node_match = nullptr;
+mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match);
+mmi_workflow_node_add(workflow, "MATCH", node_match);
+
+mmi_workflow_link_nodes_by_names(workflow, "MIC", "AUDIO", "ASR", "AUDIO");
+mmi_workflow_link_nodes_by_names(workflow, "ASR", "FINAL_ASR", "MATCH", "TEXT");
+
+mmi_workflow_attribute_assign(workflow, "COMMANDS", "MATCH", "CANDIDATES");
+
+mmi_workflow_output_assign(workflow, "COMMAND", "MATCH", "MATCHED_CANDIDATE");
+
+mmi_workflow_instance_h instance;
+mmi_custom_workflow_instance_create(workflow, &instance);
+mmi_workflow_instance_activate(instance);
+```
+
+## Custom Workflow Script 동작 테스트하기
+MMI Framework 에서는 별도의 Client App 을 만들지 않고도 Custom Workflow Script 의
+정상 동작 여부를 확인할 수 있는 `mmi-cli` 라는 프로그램을 제공한다.
+
+```console
+[root@localhost ~]# dlogutil MMIMGR &
+
+[root@localhost ~]# mmi-cli
+
+I/MMIMGR (179925): mmi-ipc-tidl.cpp: on_create(160) > Client(beb68b10-0a83-462f-beef-7960a7e7e2c5@) has been connected !
+I/MMIMGR (179925): mmi-client.cpp: add_client(67) > Add client(beb68b10-0a83-462f-beef-7960a7e7e2c5@)
+D/MMIMGR (179925): mmi-workflow-instance-manager.cpp: handle_client_connected(148) > beb68b10-0a83-462f-beef-7960a7e7e2c5@ connected
+State changed to 1
+
+cli> create_from_file /tmp/test.mws
+
+Creating instance of script with path : /tmp/test.mws
+D/MMIMGR (179925): mmi-plugin-module-registry.cpp: get_plugin_module_proxy(141) > Create plugin module proxy: -1379940944
+D/MMIMGR (179925): mmi-node-instance.cpp: NodeInstance(35) > Node instance is created : MMI_NODE_TYPE_SOURCE MMI_NODE_SOURCE_TYPE_MIC_AMBIENT
+D/MMIMGR (179925): mmi-plugin-module-registry.cpp: get_plugin_module_proxy(130) > Plugin module proxy is expired: 1 /usr/share/mmi/plugins/libmmi_module_mic.so
+D/MMIMGR (179925): mmi-plugin-module-registry.cpp: get_plugin_module_proxy(141) > Create plugin module proxy: 1 /usr/share/mmi/plugins/libmmi_module_mic.so
+D/MMIMGR (179925): mmi-plugin-module-proxy.cpp: load_node_prototypes(109) > node_list.count: 1
+D/MMIMGR (179925): mmi-plugin-module-proxy.cpp: load_node_prototypes(117) > node_info[0].type: 1
+...
+
+cli> activate
+
+Activating instance
+D/MMIMGR (179925): mmi-workflow-instance.cpp: activate(235) > Activating node instance : ASR(0x560499a8b0)
+D/MMIMGR (179925): mmi-workflow-instance.cpp: activate(235) > Activating node instance : MATCH(0x560499d880)
+D/MMIMGR (179925): mmi-workflow-instance.cpp: activate(235) > Activating node instance : MIC(0x5603c95a50)
+```
+++ /dev/null
-<?xml version="1.0"?>
-<mmi-config>
- <confidence>0.5f</confidence>
-</mmi-config>
Name: mmi
-Version: 2.1.0
+Version: 2.1.1
Release: 0
Summary: Multi-modal Interaction Framework
License: MIT
BuildRequires: meson
BuildRequires: tidl
-BuildRequires: pkgconfig(libtzplatform-config)
BuildRequires: pkgconfig(bundle)
BuildRequires: pkgconfig(gio-2.0)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(ecore)
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(libxml-2.0)
+BuildRequires: pkgconfig(json-glib-1.0)
#Build dependencies for tests
BuildRequires: pkgconfig(gmock)
CXXFLAGS+=" -fprofile-arcs -ftest-coverage -DTIZEN_TEST_GCOV"
LDFLAGS+=" -lgcov"
%endif
+%if 0%{?debug:1}
+CFLAGS=$(echo $CFLAGS | sed 's/-O[1-3]/-Og/')
+CXXFLAGS=$(echo $CXXFLAGS | sed 's/-O[1-3]/-Og/')
+CFLAGS=$(echo $CFLAGS | sed 's/-D_FORTIFY_SOURCE=[1-9]/-D_FORTIFY_SOURCE=0/g')
+CXXFLAGS=$(echo $CXXFLAGS | sed 's/-D_FORTIFY_SOURCE=[1-9]/-D_FORTIFY_SOURCE=0/g')
+%endif
meson setup --prefix=/usr \
--bindir %{_bindir} \
%defattr(-,root,root,-)
%license COPYING
%{_datadir}/mmi/plugins/*.so*
-%{_datadir}/mmi/scripts/*.mws
%files cli
%manifest %{name}.manifest
%manifest %{name}.manifest
%defattr(-,root,root,-)
%license COPYING
-%{_includedir}/mmi*.h
+%{_includedir}/mmi/mmi*.h
%{_libdir}/pkgconfig/*
%if 0%{?gcov:1}
mmi_platform_specific_include_directory = 'platform/linux'
install_headers(
- 'mmi-platform-config.h'
+ 'mmi-platform-config.h',
+ 'tizen_error.h',
+ subdir : 'mmi'
)
#define EXPORT_API
[[maybe_unused]] static const char *get_error_message(int err) { return "Unknown"; }
-#define MMI_DEFAULT_CONFIG "/usr/local/mmi/configs/mmi-config.xml"
-
#define MMI_LOG(fmt, ...) \
do { \
printf("%s: %s(%d) > " fmt "\n", \
#define LOGW MMI_LOG
#endif
+#ifndef TIZEN_ERROR_MMI
#define PLATFORM_ERROR_MMI -0x030F0000
+#endif
#define PLATFORM_ERROR_NONE (0)
#define PLATFORM_ERROR_OUT_OF_MEMORY (-1)
--- /dev/null
+#pragma once
+
+#define TIZEN_ERROR_NONE (0)
+#define TIZEN_ERROR_OUT_OF_MEMORY (-1)
+#define TIZEN_ERROR_IO_ERROR (-2)
+#define TIZEN_ERROR_INVALID_PARAMETER (-3)
+#define TIZEN_ERROR_OUT_OF_NETWORK (-4)
+#define TIZEN_ERROR_TIMED_OUT (-5)
+#define TIZEN_ERROR_PERMISSION_DENIED (-6)
+#define TIZEN_ERROR_NOT_SUPPORTED (-7)
mmi_platform = 'tizen'
-mmi_platform_specific_dependencies = ['bundle', 'rpc-port', 'dlog', 'libtzplatform-config']
+mmi_platform_specific_dependencies = ['bundle', 'rpc-port', 'dlog']
mmi_platform_specific_client_files = ['mmi_proxy.c', 'mmi-ipc-tidl.cpp']
mmi_platform_specific_manager_files = ['mmi_stub.c', 'mmi-ipc-tidl.cpp']
mmi_platform_specific_sub_directories = []
mmi_platform_specific_include_directory = 'platform/tizen'
install_headers(
- 'mmi-platform-config.h'
+ 'mmi-platform-config.h',
+ subdir : 'mmi'
)
#include <tizen.h>
#include <dlog.h>
#include <bundle.h>
-#include <tzplatform_config.h>
-
-#define MMI_DEFAULT_CONFIG tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "/mmi/configs/mmi-config.xml")
-
-#define TIZEN_ERROR_MMI -0x030F0000
-
-#define PLATFORM_ERROR_NONE (TIZEN_ERROR_NONE)
-#define PLATFORM_ERROR_OUT_OF_MEMORY (TIZEN_ERROR_OUT_OF_MEMORY)
-#define PLATFORM_ERROR_IO_ERROR (TIZEN_ERROR_IO_ERROR)
-#define PLATFORM_ERROR_INVALID_PARAMETER (TIZEN_ERROR_INVALID_PARAMETER)
-#define PLATFORM_ERROR_OUT_OF_NETWORK (TIZEN_ERROR_NETWORK_DOWN)
-#define PLATFORM_ERROR_TIMED_OUT (TIZEN_ERROR_TIMED_OUT)
-#define PLATFORM_ERROR_PERMISSION_DENIED (TIZEN_ERROR_PERMISSION_DENIED)
-#define PLATFORM_ERROR_NOT_SUPPORTED (TIZEN_ERROR_NOT_SUPPORTED)
-#define PLATFORM_ERROR_OPERATION_FAILED (TIZEN_ERROR_MMI | 0x01)
-#define PLATFORM_ERROR_RESOURCE_BUSY (TIZEN_ERROR_MMI | 0x02)
#ifndef _E
#define _E LOGE
#ifndef _W
#define _W LOGW
-#endif
-
+#endif
\ No newline at end of file
subdir('script-parser')
-subdir('wakeupless-command')
-subdir('voice-touch')
-subdir('user-recognition')
mmi_module_script_parser_include_dirs = include_directories(
'.',
'../../../capi/',
+ '../../../capi/common',
+ '../../../capi/workflow',
+ '../../../capi/node',
)
mmi_module_script_parser_library = library('mmi_module_script_parser',
#include "mmi-log.h"
#include <filesystem>
+#include <fstream>
#include <string>
#include <vector>
auto const ext = entry.path().string().substr(pos + 1);
if (ext == "mws") {
mmi_workflow_h workflow = nullptr;
- mmi_workflow_create_from_script_file(entry.path().string().c_str(), &workflow);
+ std::ifstream ifs(entry.path());
+ std::string content((std::istreambuf_iterator<char>(ifs)),
+ (std::istreambuf_iterator<char>()));
+
+ mmi_workflow_create_from_script(content.c_str(), &workflow);
mmi_standard_workflow_register(workflow);
mmi_workflow_destroy(workflow);
}
+++ /dev/null
-install_data('user-recognition.mws', install_dir : mmi_prefix_scriptdir)
+++ /dev/null
-@workflow
-name : USER_RECOGNITION
-
-@node-list
-[Source] MIC_AMBIENT as MIC
-[Source] CAMERA as CAMERA
-[Processor] VIDEO_CONVERTER as VIDEO_CONVERTER
-[Processor] FACE_RECOGNITION as FACE_RECOGNITION
-[Processor] SPEAKER_RECOGNITION as SPEAKER_RECOGNITION
-[Logic] USER_COMPARISON as USER_COMPARISON
-
-@link-list
-CAMERA.VIDEO -> VIDEO_CONVERTER.VIDEO_IN
-VIDEO_CONVERTER.VIDEO_OUT -> FACE_RECOGNITION.VIDEO
-FACE_RECOGNITION.MATCHED_FACES -> USER_COMPARISON.PORT1
-MIC.AUDIO -> SPEAKER_RECOGNITION.AUDIO
-SPEAKER_RECOGNITION.MATCHED_SPEAKERS -> USER_COMPARISON.PORT2
-
-@attribute-list
-
-@output-list
-USER_COMPARISON.BYPASS_RESULT as SINGLE_MODAL_USER_ID
-USER_COMPARISON.COMPARISON_RESULT as MULTI_MODAL_USER_ID
+++ /dev/null
-mmi_module_voice_touch_library_srcs = [
- 'mmi-module-voice-touch.cpp',
- ]
-
-ecore_dep = dependency('ecore', method : 'pkg-config')
-
-mmi_module_voice_touch_deps = [
- mmi_declared_dep,
- ecore_dep,
- ]
-
-mmi_module_voice_touch_include_dirs = include_directories(
- '.',
- '../../../capi/',
- )
-
-mmi_module_voice_touch_library = library('mmi_module_voice_touch',
- mmi_module_voice_touch_library_srcs,
- include_directories : [ mmi_module_voice_touch_include_dirs ],
- dependencies : [mmi_module_voice_touch_deps],
- install_dir : mmi_prefix_plugindir,
- install : true
- )
+++ /dev/null
-#include <mmi.h>
-#include <mmi-log.h>
-#include <mmi-plugin-storage.h>
-#include <mmi-workflow.h>
-
-#include "mmi-log.h"
-
-#include <string>
-#include <map>
-
-#include <Ecore.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "MMI-MODULE-VOICE-TOUCH"
-
-#define ENABLE_TEMP_RESCAN
-
-extern "C" {
-
- EXPORT_API void mmi_plugin_module_get_workflow_list()
- {
- const char *NODE_NAME_MIC = "MIC";
- const char *NODE_NAME_ASR = "ASR";
- const char *NODE_NAME_MATCH_MODE_COMMANDS = "MATCH_MODE_COMMANDS";
- const char *NODE_NAME_MATCH_PREDEFINED_COMMANDS = "MATCH_PREDEFINED_COMMANDS";
- const char *NODE_NAME_VOICE_TOUCH_PROCESSOR = "VOICE_TOUCH_PROCESSOR";
- const char *NODE_NAME_SCREEN_ANALYZER = "SCREEN_ANALYZER";
-
- mmi_workflow_h workflow = nullptr;
- mmi_workflow_create(&workflow);
-
- mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
-
- mmi_node_h node_mic = nullptr;
- mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic);
- mmi_workflow_node_add(workflow, NODE_NAME_MIC, node_mic);
-
- mmi_node_h node_asr = nullptr;
- mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr);
- mmi_workflow_node_add(workflow, NODE_NAME_ASR, node_asr);
-
- mmi_node_h node_match_mode_commands = nullptr;
- mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match_mode_commands);
- mmi_workflow_node_add(workflow, NODE_NAME_MATCH_MODE_COMMANDS, node_match_mode_commands);
-
- mmi_node_h node_match_predefined_commands = nullptr;
- mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match_predefined_commands);
- mmi_workflow_node_add(workflow, NODE_NAME_MATCH_PREDEFINED_COMMANDS, node_match_predefined_commands);
-
- mmi_node_h node_voice_touch = nullptr;
- mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_VOICE_TOUCH, &node_voice_touch);
- mmi_workflow_node_add(workflow, NODE_NAME_VOICE_TOUCH_PROCESSOR, node_voice_touch);
-
- mmi_node_h node_screen_analyzer = nullptr;
- mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &node_screen_analyzer);
- mmi_workflow_node_add(workflow, NODE_NAME_SCREEN_ANALYZER, node_screen_analyzer);
-
-#ifdef ENABLE_TEMP_RESCAN
- /* This is a temporary node for rescanning the screen, it will be removed when the signal mechanism is ready */
- mmi_node_h temp_node_match_rescan_command = nullptr;
- mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &temp_node_match_rescan_command);
- mmi_workflow_node_add(workflow, "TEMP_RESCAN", temp_node_match_rescan_command);
-#endif
-
- mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_MIC, "AUDIO", NODE_NAME_ASR, "AUDIO");
-
-#ifdef ENABLE_TEMP_RESCAN
- mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_ASR, "FINAL_ASR", "TEMP_RESCAN", "TEXT");
- mmi_workflow_link_nodes_by_names(workflow, "TEMP_RESCAN", "REJECTED", NODE_NAME_MATCH_MODE_COMMANDS, "TEXT");
-#elif
- mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_ASR, "FINAL_ASR", NODE_NAME_MATCH_MODE_COMMANDS, "TEXT");
-#endif
-
- mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_MATCH_MODE_COMMANDS, "MATCHED_CANDIDATE", NODE_NAME_VOICE_TOUCH_PROCESSOR, "MODE_COMMANDS");
- mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_MATCH_MODE_COMMANDS, "REJECTED", NODE_NAME_MATCH_PREDEFINED_COMMANDS, "TEXT");
-
- mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_MATCH_PREDEFINED_COMMANDS, "REJECTED", NODE_NAME_VOICE_TOUCH_PROCESSOR, "UTTERANCE");
-
- mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_SCREEN_ANALYZER, "SCREEN_INFO", NODE_NAME_VOICE_TOUCH_PROCESSOR, "SCREEN_INFO");
-
-#ifdef ENABLE_TEMP_RESCAN
- /* These are temporary links for rescanning the screen, it will be removed when the signal mechanism is ready */
- mmi_workflow_link_nodes_by_names(workflow, "TEMP_RESCAN", "MATCHED_CANDIDATE", NODE_NAME_SCREEN_ANALYZER, "RESCAN");
-#endif
-
- // INFO: Attribute assigning
- mmi_workflow_attribute_assign(workflow, "PREDEFINED_COMMANDS", NODE_NAME_MATCH_PREDEFINED_COMMANDS, "CANDIDATES");
- mmi_workflow_attribute_assign(workflow, "__MODE_COMMANDS", NODE_NAME_MATCH_MODE_COMMANDS, "CANDIDATES");
- mmi_workflow_attribute_assign(workflow, "GRID_CONFIGURATION", NODE_NAME_VOICE_TOUCH_PROCESSOR, "GRID_CONFIGURATION");
- mmi_workflow_attribute_assign(workflow, "ASR_STOP_METHOD", NODE_NAME_ASR, "STOP_METHOD");
-
-#ifdef ENABLE_TEMP_RESCAN
- /* These are temporary attributes for rescanning the screen, it will be removed when the signal mechanism is ready */
- mmi_workflow_attribute_assign(workflow, "REFRESH", NODE_NAME_SCREEN_ANALYZER, "RESCANNING");
- mmi_workflow_attribute_assign(workflow, "TEMP_RESCAN_COMMAND", "TEMP_RESCAN", "CANDIDATES");
-#endif
-
- mmi_workflow_output_assign(workflow, "PARTIAL_RESULT", NODE_NAME_ASR, "PARTIAL_ASR");
- mmi_workflow_output_assign(workflow, "FINAL_RESULT", NODE_NAME_ASR, "FINAL_ASR");
-
- mmi_workflow_output_assign(workflow, "MATCHED_COMMAND", NODE_NAME_MATCH_PREDEFINED_COMMANDS, "MATCHED_CANDIDATE");
-
- mmi_workflow_output_assign(workflow, "REJECTED", NODE_NAME_VOICE_TOUCH_PROCESSOR, "REJECTED");
- mmi_workflow_output_assign(workflow, "CANDIDATES", NODE_NAME_VOICE_TOUCH_PROCESSOR, "CANDIDATES");
- mmi_workflow_output_assign(workflow, "MATCHED_RESULT", NODE_NAME_VOICE_TOUCH_PROCESSOR, "MATCHED_RESULT");
-
- const char *modes[] = {
- "숫자 보여줘",
- "텍스트 보여줘",
- "그리드 보여줘",
- };
-
- mmi_attribute_h attribute = nullptr;
- mmi_attribute_create_string_array("__MODE_COMMANDS", modes, sizeof(modes) / sizeof(const char *), &attribute);
- mmi_workflow_attribute_set_default_value(workflow, attribute);
- mmi_attribute_destroy(attribute);
-
-#ifdef ENABLE_TEMP_RESCAN
- /* This is a temporary attribute for rescanning the screen, it will be removed when the signal mechanism is ready */
- const char *rescans[] = {
- "새로고침",
- "새로 고침",
- };
-
- mmi_attribute_h temp_attribute = nullptr;
- mmi_attribute_create_string_array("TEMP_RESCAN_COMMAND", rescans, sizeof(rescans) / sizeof(const char *), &temp_attribute);
- mmi_workflow_attribute_set_default_value(workflow, temp_attribute);
- mmi_attribute_destroy(temp_attribute);
-#endif
-
- mmi_standard_workflow_register(workflow);
-
-#ifdef ENABLE_TEMP_RESCAN
- /* This is a temporary node for rescanning the screen, it will be removed when the signal mechanism is ready */
- mmi_node_destroy(temp_node_match_rescan_command);
-#endif
-
- mmi_node_destroy(node_mic);
- mmi_node_destroy(node_asr);
- mmi_node_destroy(node_match_mode_commands);
- mmi_node_destroy(node_match_predefined_commands);
- mmi_node_destroy(node_voice_touch);
- mmi_node_destroy(node_screen_analyzer);
-
- mmi_workflow_destroy(workflow);
- }
-
-} // extern "C"
+++ /dev/null
-mmi_module_wakeupless_command_library_srcs = [
- 'mmi-module-wakeupless-command.cpp',
- ]
-
-ecore_dep = dependency('ecore', method : 'pkg-config')
-
-mmi_module_wakeupless_command_deps = [
- mmi_declared_dep,
- ecore_dep,
- ]
-
-mmi_module_wakeupless_command_include_dirs = include_directories(
- '.',
- '../../../capi/',
- )
-
-mmi_module_wakeupless_command_library = library('mmi_module_wakeupless_command',
- mmi_module_wakeupless_command_library_srcs,
- include_directories : [ mmi_module_wakeupless_command_include_dirs ],
- dependencies : [mmi_module_wakeupless_command_deps],
- install_dir : mmi_prefix_plugindir,
- install : true
- )
+++ /dev/null
-#include <mmi.h>
-#include <mmi-log.h>
-#include <mmi-plugin-storage.h>
-#include <mmi-workflow.h>
-
-#include <string>
-#include <map>
-
-#include <Ecore.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "MMI-MODULE-WAKEUPLESS-COMMAND"
-
-extern "C" {
-
- EXPORT_API void mmi_plugin_module_get_workflow_list()
- {
- mmi_workflow_h workflow = nullptr;
- mmi_workflow_create(&workflow);
-
- mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
-
- mmi_node_h node_mic = nullptr;
- /* FIXME: node should be 'found' instead of 'created' */
- mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic);
- mmi_workflow_node_add(workflow, "MIC", node_mic);
-
- mmi_node_h node_asr = nullptr;
- mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr);
- mmi_workflow_node_add(workflow, "ASR", node_asr);
-
- mmi_node_h node_match = nullptr;
- mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match);
- mmi_workflow_node_add(workflow, "MATCH", node_match);
-
- mmi_workflow_link_nodes_by_names(workflow, "MIC", "AUDIO", "ASR", "AUDIO");
- mmi_workflow_link_nodes_by_names(workflow, "ASR", "FINAL_ASR", "MATCH", "TEXT");
-
- mmi_workflow_attribute_assign(workflow, "COMMANDS", "MATCH", "CANDIDATES");
- mmi_workflow_attribute_assign(workflow, "LANGUAGE", "ASR", "LANGUAGE");
- mmi_workflow_attribute_assign(workflow, "STOP_METHOD", "ASR", "STOP_METHOD");
- mmi_workflow_attribute_assign(workflow, "ASR_START", "ASR", "ASR_START");
-
- mmi_workflow_output_assign(workflow, "COMMAND", "MATCH", "MATCHED_CANDIDATE");
- mmi_workflow_output_assign(workflow, "UTTERANCE", "ASR", "PARTIAL_ASR");
- mmi_workflow_output_assign(workflow, "UTTERANCE", "ASR", "FINAL_ASR");
-
- mmi_workflow_signal_assign(workflow, "CONTROL", "ASR", "CONTROL");
-
- mmi_standard_workflow_register(workflow);
-
- mmi_node_destroy(node_mic);
- mmi_node_destroy(node_asr);
- mmi_node_destroy(node_match);
-
- mmi_workflow_destroy(workflow);
- }
-
-} // extern "C"
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MMI_COMMON_H__
+#define __MMI_COMMON_H__
+
+#include "mmi-log.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MMI_API __attribute__ ((visibility("default")))
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__MMI_COMMON_H__
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef __TIZEN_UIX_MMI_PLUGIN_MODULE_H__
+#define __TIZEN_UIX_MMI_PLUGIN_MODULE_H__
+
+
+#include <mmi.h>
+
+/**
+* @file mmi-plugin-module.h
+*/
+
+
+/**
+* @addtogroup CAPI_UIX_MMI_MODULE
+* @{
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* If a plugin module wants to provide Nodes to mmi framework,
+ * it should implement a function named "mmi_plugin_module_get_node_list",
+ * with the following prototype. */
+#define MMI_PLUGIN_MODULE_GET_NODE_LIST_FUNC_NAME "mmi_plugin_module_get_node_list"
+typedef void (*mmi_plugin_module_get_node_list_func)();
+
+/* If a plugin module wants to provide Workflows to mmi framework,
+ * it should implement a function named "mmi_plugin_module_get_workflow_list",
+ * with the following prototype. */
+#define MMI_PLUGIN_MODULE_GET_WORKFLOW_LIST_FUNC_NAME "mmi_plugin_module_get_workflow_list"
+typedef void (*mmi_plugin_module_get_workflow_list_func)();
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __TIZEN_UIX_MMI_PLUGIN_MODULE_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__
+#define __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__
+
+
+#include <mmi.h>
+#include <mmi-defines.h>
+#include <mmi-node.h>
+#include <mmi-node-types.h>
+#include <mmi-workflow.h>
+
+/**
+* @file mmi-plugin-storage.h
+*/
+
+
+/**
+* @addtogroup CAPI_UIX_MMI_MODULE
+* @{
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The functions and structs below are used by MMI framework */
+
+typedef struct {
+ mmi_node_h *nodes;
+ size_t node_count;
+} mmi_plugin_module_node_list_s;
+
+typedef struct {
+ mmi_workflow_h *workflows;
+ size_t workflow_count;
+} mmi_plugin_module_workflow_list_s;
+
+
+typedef struct {
+ char name[MMI_NAME_MAX_LENGTH];
+ mmi_port_instance_h port;
+} mmi_plugin_module_port_instance_info_s;
+
+typedef struct {
+ mmi_node_instance_h node;
+ mmi_plugin_module_port_instance_info_s port_infos[MMI_PORT_MAX_COUNT];
+ size_t port_info_count;
+} mmi_plugin_module_node_instance_info_s;
+
+typedef void (*mmi_plugin_module_port_instance_output_handler_func)(
+ mmi_port_instance_h port, mmi_data_h data, void *user_data);
+
+typedef void (*mmi_plugin_module_switch_node_event_handler_func)(
+ mmi_node_instance_h node, const char *controllee, bool state, void *user_data);
+
+typedef struct {
+ mmi_plugin_module_port_instance_output_handler_func port_instance_output_handler;
+ mmi_plugin_module_switch_node_event_handler_func switch_node_event_handler;
+} mmi_plugin_module_event_handler_info_s;
+
+/* MMI Manager will invoke this function to set the current identifier of the plugin module. */
+void mmi_plugin_storage_set_current_module_identifier(const char *identifier);
+
+/* Each plugin modules will call this functino to get the current identifier of the plugin module. */
+const char* mmi_plugin_storage_get_current_module_identifier();
+
+/* Each plugin modules will call these functions to register their nodes and workflows. */
+void mmi_plugin_storage_set_node_list(mmi_plugin_module_node_list_s node_list);
+void mmi_plugin_storage_set_workflow_list(mmi_plugin_module_workflow_list_s workflow_list);
+
+/* MMI Manager will invoke these functions to get the node list of the plugin module. */
+mmi_plugin_module_node_list_s mmi_plugin_storage_get_node_list(const char *identifier);
+mmi_plugin_module_workflow_list_s mmi_plugin_storage_get_workflow_list(const char *identifier);
+
+/* MMI Manager will invoke these function to notify the node instance addition and removal. */
+void mmi_plugin_storage_add_node_instance_info(mmi_plugin_module_node_instance_info_s *info);
+void mmi_plugin_storage_remove_node_instance_info(mmi_node_instance_h node_instance);
+
+/* Each plugin modules will call this function to find appropriate port instance */
+mmi_port_instance_h mmi_plugin_storage_find_port_instance(
+ mmi_node_instance_h node_instance, const char *port_name);
+mmi_node_instance_h mmi_plugin_storage_find_node_instance_by_port_instance(mmi_port_instance_h port_instance);
+
+/* MMI Manager will invoke these function to register / unregister the event handlers */
+void mmi_plugin_storage_set_plugin_module_event_handler(
+ mmi_plugin_module_event_handler_info_s handler_info, void *user_data);
+void mmi_plugin_storage_unset_plugin_module_event_handler();
+
+/* Each plugin modules will call this function to notify the plugin module events */
+mmi_plugin_module_event_handler_info_s mmi_plugin_storage_get_plugin_module_event_handler();
+void* mmi_plugin_storage_get_plugin_module_event_handler_user_data();
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__ */
ecore_dep = dependency('ecore', method : 'pkg-config')
dl_dep = meson.get_compiler('c').find_library('dl', required : true)
+json_dep = dependency('json-glib-1.0', method : 'pkg-config')
mmi_cli_deps = [
mmi_declared_dep,
ecore_dep,
dl_dep,
+ json_dep,
]
foreach platform_specific_dependency : mmi_platform_specific_dependencies
'.',
'../common/',
'../../capi/',
+ '../../capi/common',
+ '../../capi/workflow',
+ '../../capi/node',
'../../external/',
mmi_extra_include_dir,
)
#include "cli/cli.h"
#include "mmi.h"
+#include "mmi-defines.h"
#include "mmi-plugin-module.h"
#include "mmi-plugin-storage.h"
std::string m_name;
mmi_port_type_e m_port_type;
mmi_data_type_e m_data_type;
- mmi_port_callbacks m_callbacks{{nullptr}, {nullptr}};
+ mmi_port_callbacks_s m_callbacks{{nullptr}, {nullptr}};
};
struct NodeInstance
{
mmi_node_type_e m_node_type;
- mmi_node_callbacks m_callbacks{{nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}};
+ mmi_node_callbacks_s m_callbacks{{nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}};
std::vector<PortInstance*> m_ports;
};
try {
value = std::stoi(input);
} catch (std::invalid_argument& e) {
- _E("Invalid argument: %s", e.what());
+ MMI_CLI_LOG_("Invalid argument: %s", e.what());
return;
} catch (std::out_of_range& e) {
- _E("Out of range: %s", e.what());
+ MMI_CLI_LOG_("Out of range: %s", e.what());
return;
}
mmi_primitive_value_h primitive_value = nullptr;
try {
value = std::stoi(input);
} catch (std::invalid_argument& e) {
- _E("Invalid argument: %s", e.what());
+ MMI_CLI_LOG_("Invalid argument: %s", e.what());
return;
} catch (std::out_of_range& e) {
- _E("Out of range: %s", e.what());
+ MMI_CLI_LOG_("Out of range: %s", e.what());
return;
}
mmi_primitive_value_h primitive_value = nullptr;
int value = program->read_int_value("Enter data value: ");
mmi_data_create_int(value, &data);
if (data) {
- port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data);
+ port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data, nullptr);
mmi_data_destroy(data);
}
}
std::string value = program->read_string_value("Enter data value: ");
mmi_data_create_text(value.c_str(), &data);
if (data) {
- port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data);
+ port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data, nullptr);
mmi_data_destroy(data);
}
}
mmi_data_add_array_element(data, struct_data);
}
if (data) {
- port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data);
+ port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data, nullptr);
mmi_data_destroy(data);
}
}
mmi_data_set_struct_element(data, "recognizedCandidates", candidates);
if (data) {
- port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data);
+ port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data, nullptr);
mmi_data_destroy(data);
}
}
mmi_data_h data = nullptr;
mmi_data_create_audio(frame_buf, size, &data);
if (data) {
- port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data);
+ port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data, nullptr);
mmi_data_destroy(data);
}
}
fclose(fp);
} else {
- _E("Failed to open file %s", value.c_str());
+ MMI_CLI_LOG_("Failed to open file %s", value.c_str());
}
}
},
mmi_data_h data = nullptr;
mmi_data_create_video(frame_buf, size, &data);
if (data) {
- port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data);
+ port_instance->m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(port_instance), data, nullptr);
mmi_data_destroy(data);
}
}
fclose(fp);
} else {
- _E("Failed to open file %s", value.c_str());
+ MMI_CLI_LOG_("Failed to open file %s", value.c_str());
}
}
},
{
bool value;
mmi_data_get_bool(data, &value);
- _D("Port %s generated data type %d (BOOLEAN), value %d", port_instance->m_name.c_str(), type, value);
+ MMI_CLI_LOG_("Port %s generated data type %d (BOOLEAN), value %d", port_instance->m_name.c_str(), type, value);
}
break;
case MMI_DATA_TYPE_INTEGER:
{
int value;
mmi_data_get_int(data, &value);
- _D("Port %s generated data type %d (INTEGER), value %d", port_instance->m_name.c_str(), type, value);
+ MMI_CLI_LOG_("Port %s generated data type %d (INTEGER), value %d", port_instance->m_name.c_str(), type, value);
}
break;
case MMI_DATA_TYPE_FLOAT:
{
float value;
mmi_data_get_float(data, &value);
- _D("Port %s generated data type %d (FLOAT), value %f", port_instance->m_name.c_str(), type, value);
+ MMI_CLI_LOG_("Port %s generated data type %d (FLOAT), value %f", port_instance->m_name.c_str(), type, value);
}
break;
case MMI_DATA_TYPE_TEXT:
{
const char *value = nullptr;
mmi_data_get_text(data, &value);
- _D("Port %s generated data type %d (TEXT), value %s", port_instance->m_name.c_str(), type, value);
+ MMI_CLI_LOG_("Port %s generated data type %d (TEXT), value %s", port_instance->m_name.c_str(), type, value);
}
break;
case MMI_DATA_TYPE_USER_IDENTIFICATION:
snprintf(buf, sizeof(buf), "%02x", ((unsigned char*)ptr)[i]);
hex_string += buf;
}
- _D("Port %s generated data type %d (USER_IDENTIFICATION), size %zu, hex %s",
+ MMI_CLI_LOG_("Port %s generated data type %d (USER_IDENTIFICATION), size %zu, hex %s",
port_instance->m_name.c_str(), type, len, hex_string.c_str());
}
break;
for (size_t i = 0; i < count; i++) {
mmi_data_h element = nullptr;
mmi_data_get_array_element(data, i, &element);
- _D("Array Element %zu", i);
+ MMI_CLI_LOG_("Array Element %zu", i);
log_mmi_data(port_instance, element);
}
}
for (size_t i = 0; i < count; i++) {
const char *element_name = nullptr;
mmi_data_get_struct_element_name(data, i, &element_name);
- _D("Struct Element %zu : %s", i, element_name);
+ MMI_CLI_LOG_("Struct Element %zu : %s", i, element_name);
mmi_data_h element_value = nullptr;
mmi_data_get_struct_element_value(data, i, &element_value);
log_mmi_data(port_instance, element_value);
}
break;
default:
- _D("Port %s generated data type %d", port_instance->m_name.c_str(), type);
+ MMI_CLI_LOG_("Port %s generated data type %d", port_instance->m_name.c_str(), type);
break;
}
}
void Program::port_instance_output_handler(mmi_port_instance_h port, mmi_data_h data, void *user_data) {
if (port == nullptr || data == nullptr) {
- _E("Invalid parameter : port(%p), data(%p)", port, data);
+ MMI_CLI_LOG_("Invalid parameter : port(%p), data(%p)", port, data);
return;
}
m_handle = dlopen(path.c_str(), RTLD_NOW);
if (!m_handle) {
- _E("Failed to load plugin module: %s", dlerror());
+ MMI_CLI_LOG_("Failed to load plugin module: %s", dlerror());
return;
}
auto prepare_node_list = reinterpret_cast<mmi_plugin_module_get_node_list_func>(
dlsym(m_handle, MMI_PLUGIN_MODULE_GET_NODE_LIST_FUNC_NAME));
if (!prepare_node_list) {
- _E("Failed to find symbol: %s", dlerror());
+ MMI_CLI_LOG_("Failed to find symbol: %s", dlerror());
return;
}
m_node_list = mmi_plugin_storage_get_node_list(path.c_str());
/* Dump node_list */
- _D("node_list.count: %zu", m_node_list.node_count);
+ MMI_CLI_LOG_("node_list.count: %zu", m_node_list.node_count);
for (size_t i = 0;i < m_node_list.node_count;i++) {
mmi_node_h node = m_node_list.nodes[i];
mmi_node_type_e type;
mmi_node_get_type(node, &type);
- mmi_node_callbacks callbacks;
+ mmi_node_callbacks_s callbacks;
mmi_node_get_callbacks(node, &callbacks);
size_t port_count;
- _D("node_info[%zu].type: %d", i, type);
- _D("node_info[%zu].callbacks : %p %p %p %p %p %p", i,
+ MMI_CLI_LOG_("node_info[%zu].type: %d", i, type);
+ MMI_CLI_LOG_("node_info[%zu].callbacks : %p %p %p %p %p %p", i,
callbacks.initialized_cb,
callbacks.deinitialized_cb,
callbacks.attribute_set_cb,
callbacks.deactivated_cb,
callbacks.signal_received_cb);
mmi_node_get_port_count(node, &port_count);
- _D("node_info[%zu].port_list.count: %zu", i, port_count);
+ MMI_CLI_LOG_("node_info[%zu].port_list.count: %zu", i, port_count);
for (size_t j = 0;j < port_count;j++) {
mmi_port_h port;
mmi_node_get_port(node, j, &port);
mmi_port_get_type(port, &port_type);
mmi_data_type_e data_type;
mmi_port_get_data_type(port, &data_type);
- mmi_port_callbacks port_callbacks;
+ mmi_port_callbacks_s port_callbacks;
mmi_port_get_callbacks(port, &port_callbacks);
- _D("node_info[%zu].port_info[%zu].name: %s", i, j, name);
- _D("node_info[%zu].port_info[%zu].type: %d", i, j, port_type);
- _D("node_info[%zu].port_info[%zu].data_type: %d", i, j, data_type);
- _D("node_info[%zu].port_info[%zu].callbacks: %p %p", i, j,
+ MMI_CLI_LOG_("node_info[%zu].port_info[%zu].name: %s", i, j, name);
+ MMI_CLI_LOG_("node_info[%zu].port_info[%zu].type: %d", i, j, port_type);
+ MMI_CLI_LOG_("node_info[%zu].port_info[%zu].data_type: %d", i, j, data_type);
+ MMI_CLI_LOG_("node_info[%zu].port_info[%zu].callbacks: %p %p", i, j,
port_callbacks.output_format_requested_cb,
port_callbacks.input_data_received_cb);
}
std::string Program::read_string_value(std::string prompt) {
if (!m_session) {
- _E("Session is not created");
+ MMI_CLI_LOG_("Session is not created");
return "";
}
std::cout << prompt;
try {
value = std::stoi(string_value);
} catch (std::invalid_argument& e) {
- _E("Invalid argument: %s", e.what());
+ MMI_CLI_LOG_("Invalid argument: %s", e.what());
return -1;
} catch (std::out_of_range& e) {
- _E("Out of range: %s", e.what());
+ MMI_CLI_LOG_("Out of range: %s", e.what());
return -1;
}
return value;
mmi_node_h node = m_node_list.nodes[0];
mmi_node_type_e type;
mmi_node_get_type(node, &type);
- mmi_node_callbacks callbacks;
+ mmi_node_callbacks_s callbacks;
mmi_node_get_callbacks(node, &callbacks);
node_instance->m_node_type = type;
mmi_port_get_type(port, &port_type);
mmi_data_type_e data_type;
mmi_port_get_data_type(port, &data_type);
- mmi_port_callbacks port_callbacks;
+ mmi_port_callbacks_s port_callbacks;
mmi_port_get_callbacks(port, &port_callbacks);
PortInstance *port_instance = new PortInstance();
mmi_plugin_storage_add_node_instance_info(&node_instance_info);
m_node_instance_map[m_node_instance_index] = node_instance;
- node_instance->m_callbacks.initialized_cb(static_cast<mmi_node_instance_h>(node_instance));
+ node_instance->m_callbacks.initialized_cb(static_cast<mmi_node_instance_h>(node_instance), nullptr);
- _D("Created node instance: %zu", m_node_instance_index);
+ MMI_CLI_LOG_("Created node instance: %zu", m_node_instance_index);
m_node_instance_index++;
}
int index = read_int_value("Enter instance id: ");
auto it = m_node_instance_map.find(index);
if (it == m_node_instance_map.end()) {
- _E("Failed to find node instance: %d", index);
+ MMI_CLI_LOG_("Failed to find node instance: %d", index);
return nullptr;
}
node_instance = it->second;
NodeInstance *node_instance = get_node_instance();
if (!node_instance) return;
- node_instance->m_callbacks.deinitialized_cb(static_cast<mmi_node_instance_h>(node_instance));
+ node_instance->m_callbacks.deinitialized_cb(static_cast<mmi_node_instance_h>(node_instance), nullptr);
mmi_plugin_storage_remove_node_instance_info(static_cast<mmi_node_instance_h>(node_instance));
for (auto port_instance : node_instance->m_ports) {
delete port_instance;
NodeInstance *node_instance = get_node_instance();
if (!node_instance) return;
- node_instance->m_callbacks.activated_cb(static_cast<mmi_node_instance_h>(node_instance));
+ node_instance->m_callbacks.activated_cb(static_cast<mmi_node_instance_h>(node_instance), nullptr);
}
void Program::deactivate_node_instance() {
NodeInstance *node_instance = get_node_instance();
if (!node_instance) return;
- node_instance->m_callbacks.deactivated_cb(static_cast<mmi_node_instance_h>(node_instance));
+ node_instance->m_callbacks.deactivated_cb(static_cast<mmi_node_instance_h>(node_instance), nullptr);
}
void Program::set_attribute(AttributeTestType type) {
mmi_attribute_h attribute = nullptr;
if (type >= AttributeTestType::MaxCount) {
- _E("Invalid attribute type");
+ MMI_CLI_LOG_("Invalid attribute type");
return;
}
}
}
if (entry_index == static_cast<size_t>(AttributeTestType::MaxCount)) {
- _E("Failed to find attribute type: %zu", static_cast<size_t>(type));
+ MMI_CLI_LOG_("Failed to find attribute type: %zu", static_cast<size_t>(type));
return;
}
g_attribute_test_entries[entry_index].attribute_generator(this, &attribute);
- node_instance->m_callbacks.attribute_set_cb(static_cast<mmi_node_instance_h>(node_instance), attribute);
+ node_instance->m_callbacks.attribute_set_cb(static_cast<mmi_node_instance_h>(node_instance), attribute, nullptr);
mmi_attribute_destroy(attribute);
}
if (!node_instance) return;
if (type >= DataTestType::MaxCount) {
- _E("Invalid data type");
+ MMI_CLI_LOG_("Invalid data type");
return;
}
}
}
if (entry_index == static_cast<size_t>(DataTestType::MaxCount)) {
- _E("Failed to find data type");
+ MMI_CLI_LOG_("Failed to find data type");
return;
}
g_data_test_entries[entry_index].data_generator(this, port_instance);
+#include <fstream>
#include <iostream>
#include <memory>
+#include "adishavit/argh.h"
+#include "magic_enum/magic_enum.hpp"
+
#include "cliecoresession.h"
#include "cli/cli.h"
#include "mmi.h"
+#ifdef USE_VOICE_TOUCH_TV
+#include <json-glib/json-glib.h>
+#include "cppcodec/base64_rfc4648.hpp"
+
+using base64 = cppcodec::base64_rfc4648;
+
+std::string convert(std::string &input)
+{
+ std::string upperCaseInput = input;
+ transform(upperCaseInput.begin(), upperCaseInput.end(), upperCaseInput.begin(), ::toupper);
+
+ switch (upperCaseInput[0]) {
+ case 'U':
+ return "MoveUpCommand";
+ case 'D':
+ return "MoveDownCommand";
+ case 'R':
+ return "MoveRightCommand";
+ case 'L':
+ return "MoveLeftCommand";
+ default:
+ break;
+ }
+
+ return "";
+}
+
+static char *get_title_viv_response(std::string &value)
+{
+ JsonBuilder *builder = json_builder_new();
+ JsonNode *node = NULL;
+ JsonGenerator *generator = NULL;
+ gsize length = 0;
+ gchar *data = NULL;
+ std::string uri = "bixby://com.samsung.tv.vif/tvVoiceInteraction.SendContentTitle/punchOut?titles=";
+ uri += value;
+
+ json_builder_begin_object(builder);
+ json_builder_set_member_name(builder, "type");
+ json_builder_add_int_value(builder, 14);
+
+ json_builder_set_member_name(builder, "viv");
+ json_builder_begin_object(builder);
+ json_builder_set_member_name(builder, "ClientFunctionCall");
+ json_builder_begin_object(builder);
+
+ json_builder_set_member_name(builder, "argumentsJson");
+ json_builder_begin_object(builder);
+ json_builder_set_member_name(builder, "uri");
+
+ json_builder_add_string_value(builder, uri.c_str());
+ json_builder_end_object(builder);
+ json_builder_end_object(builder);
+ json_builder_end_object(builder);
+ json_builder_end_object(builder);
+
+ node = json_builder_get_root(builder);
+ g_object_unref(builder);
+
+ generator = json_generator_new();
+ json_generator_set_root(generator, node);
+
+ // convert json data into string
+ data = json_generator_to_data(generator, &length);
+
+ json_node_free(node);
+ g_object_unref(generator);
+ return data;
+}
+
+static char *get_ordinal_viv_response(std::string value)
+{
+ JsonBuilder *builder = json_builder_new();
+ JsonNode *node = NULL;
+ JsonGenerator *generator = NULL;
+ gsize length = 0;
+ gchar *data = NULL;
+ std::string uri = "bixby://com.samsung.tv.vif/tvVoiceInteraction.SendOrdinalNumber/punchOut?OrdinalNumber=";
+ uri += value;
+
+ json_builder_begin_object(builder);
+ json_builder_set_member_name(builder, "type");
+ json_builder_add_int_value(builder, 14);
+
+ json_builder_set_member_name(builder, "viv");
+ json_builder_begin_object(builder);
+ json_builder_set_member_name(builder, "ClientFunctionCall");
+ json_builder_begin_object(builder);
+
+ json_builder_set_member_name(builder, "serviceCallId");
+ json_builder_add_string_value(builder, "199ba17e-6a4b-4302-9a0a-59cf13562133");
+
+ json_builder_set_member_name(builder, "actionId");
+ json_builder_add_string_value(builder, "1.0.109-samsung.tvVoiceInteraction.SendOrdinalNumber");
+
+ json_builder_set_member_name(builder, "argumentsJson");
+ json_builder_begin_object(builder);
+ json_builder_set_member_name(builder, "uri");
+
+ json_builder_add_string_value(builder, uri.c_str());
+ json_builder_end_object(builder);
+ json_builder_end_object(builder);
+ json_builder_end_object(builder);
+ json_builder_end_object(builder);
+
+ node = json_builder_get_root(builder);
+ g_object_unref(builder);
+
+ generator = json_generator_new();
+ json_generator_set_root(generator, node);
+
+ // convert json data into string
+ data = json_generator_to_data(generator, &length);
+
+ json_node_free(node);
+ g_object_unref(generator);
+ return data;
+}
+
+static char *get_navigation_viv_response(std::string direction, std::string repeat)
+{
+ JsonBuilder *builder = json_builder_new();
+ JsonNode *node = NULL;
+ JsonGenerator *generator = NULL;
+ gsize length = 0;
+ gchar *data = NULL;
+ std::string uri = "bixby://com.samsung.tv.vif/tvVoiceInteraction.SendNavCommand/punchOut?NavCommand=";
+ uri += convert(direction);
+ uri += "&NavUnit=Focus&RepeatCnt=";
+ uri += repeat;
+
+ json_builder_begin_object(builder);
+ json_builder_set_member_name(builder, "type");
+ json_builder_add_int_value(builder, 23);
+
+ json_builder_set_member_name(builder, "viv");
+ json_builder_begin_object(builder);
+ json_builder_set_member_name(builder, "AppLaunch");
+ json_builder_begin_object(builder);
+
+ json_builder_set_member_name(builder, "uri");
+ json_builder_add_string_value(builder, uri.c_str());
+
+ json_builder_set_member_name(builder, "text");
+ json_builder_add_string_value(builder, "{}");
+
+ json_builder_end_object(builder);
+ json_builder_end_object(builder);
+ json_builder_end_object(builder);
+
+ node = json_builder_get_root(builder);
+ g_object_unref(builder);
+
+ generator = json_generator_new();
+ json_generator_set_root(generator, node);
+
+ // convert json data into string
+ data = json_generator_to_data(generator, &length);
+
+ json_node_free(node);
+ g_object_unref(generator);
+ return data;
+}
+#endif
+
+static std::string to_string(mmi_data_h data)
+{
+ mmi_data_type_e type;
+ mmi_data_get_type(data, &type);
+ if (type == MMI_DATA_TYPE_TEXT) {
+ const char *value = nullptr;
+ mmi_data_get_text(data, &value);
+ return std::string(value ? value : "NULL");
+ } else if (type == MMI_DATA_TYPE_FLOAT) {
+ float value;
+ mmi_data_get_float(data, &value);
+ return std::to_string(value);
+ } else if (type == MMI_DATA_TYPE_BOOLEAN) {
+ bool value;
+ mmi_data_get_bool(data, &value);
+ return std::string(value ? "TRUE" : "FALSE");
+ } else if (type == MMI_DATA_TYPE_INTEGER) {
+ int value;
+ mmi_data_get_int(data, &value);
+ return std::to_string(value);
+ }
+ return std::string("Unknown");
+}
+
class Program
{
public:
std::cout << "Creating instance of type " << type << std::endl;
mmi_standard_workflow_instance_create(
static_cast<mmi_standard_workflow_type_e>(type), &m_instance);
- mmi_workflow_instance_set_output_callback(m_instance, "COMMAND",
+ mmi_workflow_instance_set_output_cb(m_instance, "COMMAND",
[](mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data) {
- std::cout << "OUTPUT data received : " << std::string(name ? name : "") << std::endl;
+ mmi_data_type_e type;
+ mmi_data_get_type(data, &type);
+ std::cout <<
+ "OUTPUT data received : " <<
+ "[Name:" << std::string(name ? name : "") << "]" <<
+ "[Type:" << std::string(magic_enum::enum_name(type)) << "]" <<
+ "[Value:" << to_string(data) << "]" <<
+ std::endl;
},
nullptr);
- mmi_workflow_instance_set_output_callback(m_instance, "UTTERANCE",
+ mmi_workflow_instance_set_output_cb(m_instance, "UTTERANCE",
[](mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data) {
const char *value = nullptr;
mmi_data_get_text(data, &value);
mmi_workflow_h workflow;
mmi_workflow_create_from_script(script.c_str(), &workflow);
mmi_custom_workflow_instance_create(workflow, &m_instance);
- mmi_workflow_instance_set_output_callback(m_instance, "COMMAND",
+ mmi_workflow_instance_set_output_cb(m_instance, "COMMAND",
[](mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data) {
std::cout << "OUTPUT data received : " << std::string(name ? name : "") << std::endl;
},
}
std::cout << "Creating instance of script with path : " << path << std::endl;
- //mmi_custom_workflow_instance_create_from_script_file(path.c_str(), &m_instance);
- mmi_workflow_instance_set_output_callback(m_instance, "COMMAND",
- [](mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data) {
- std::cout << "OUTPUT data received : " << std::string(name ? name : "") << std::endl;
- },
- nullptr);
+ std::ifstream script_file(path);
+ if (!script_file.is_open()) {
+ std::cout << "Could not open file : " << path << std::endl;
+ return;
+ }
+
+ std::string script;
+ std::string line;
+ while(std::getline(script_file, line)) {
+ script += line;
+ script += '\n';
+ }
+ mmi_workflow_h workflow;
+ mmi_workflow_create_from_script(script.c_str(), &workflow);
+ mmi_custom_workflow_instance_create(workflow, &m_instance);
}
void destroy_instance() {
if (!m_instance) {
mmi_attribute_destroy(attribute);
}
}
- void emit_signal() {
+ void emit_signal(std::string signal_name) {
if (!m_instance) {
std::cout << "No instance to set attribute" << std::endl;
return;
std::cout << "Emitting signal " << std::endl;
- mmi_primitive_value_h signal_parameter_value_1 = nullptr;
- mmi_signal_parameter_h signal_parameter_1 = nullptr;
- mmi_primitive_value_h signal_parameter_value_2 = nullptr;
- mmi_signal_parameter_h signal_parameter_2 = nullptr;
mmi_signal_h signal = nullptr;
- mmi_primitive_value_create_int(6, &signal_parameter_value_1);
- mmi_signal_parameter_create(signal_parameter_value_1,
- "signal_parameter_1", &signal_parameter_1);
- mmi_primitive_value_create_int(3, &signal_parameter_value_2);
- mmi_signal_parameter_create(signal_parameter_value_2,
- "signal_parameter_2", &signal_parameter_2);
- mmi_signal_create("CONTROL", &signal);
- mmi_signal_add_parameter(signal, signal_parameter_1);
- mmi_signal_add_parameter(signal, signal_parameter_2);
+ mmi_signal_create(signal_name.c_str(), &signal);
mmi_workflow_instance_emit_signal(m_instance, signal);
mmi_signal_destroy(signal);
- mmi_signal_parameter_destroy(signal_parameter_1);
- mmi_primitive_value_destroy(signal_parameter_value_1);
- mmi_signal_parameter_destroy(signal_parameter_2);
- mmi_primitive_value_destroy(signal_parameter_value_2);
}
void feed_data(std::string node_name, std::string port_name, std::string type, std::string value) {
if (!m_instance) {
mmi_data_destroy(data);
}
+ void feed_data(std::string node_name, std::string port_name, std::string type, std::string value1, std::string value2) {
+ if (!m_instance) {
+ std::cout << "No instance to feed data" << std::endl;
+ return;
+ }
+
+ std::cout << "Feeding data " << std::endl;
+
+ mmi_data_h data = nullptr;
+ if (type.compare("coord") == 0) {
+ mmi_data_create_coordinate(std::stoi(value1), std::stoi(value2), &data);
+ }
+ mmi_workflow_instance_feed_data(m_instance, node_name.c_str(), port_name.c_str(), data);
+ mmi_data_destroy(data);
+ }
+
+#ifdef USE_VOICE_TOUCH_TV
+ void title_selection(std::string value) {
+ if (!m_instance) {
+ std::cout << "No instance to select title" << std::endl;
+ return;
+ }
+
+ std::cout << "Title Selection" << std::endl;
+
+ std::string encoded = base64::encode(value);
+
+ char *json = get_title_viv_response(encoded);
+ std::cout << "json :" << json << std::endl;
+
+ mmi_data_h data = nullptr;
+ mmi_data_create_text(json, &data);
+
+ mmi_workflow_instance_feed_data(m_instance, "PARSER", "COMMAND", data);
+ mmi_data_destroy(data);
+ free(json);
+ }
+
+ void ordinal_selection(int value) {
+ if (!m_instance) {
+ std::cout << "No instance to select ordinal" << std::endl;
+ return;
+ }
+ mmi_data_h data = nullptr;
+ char *json = get_ordinal_viv_response(std::to_string(value).c_str());
+ std::cout << "json :" << json << std::endl;
+ mmi_data_create_text(json, &data);
+
+ mmi_workflow_instance_feed_data(m_instance, "PARSER", "COMMAND", data);
+ mmi_data_destroy(data);
+ free(json);
+ }
+
+ void navigation(std::string direction, int repeat) {
+ if (!m_instance) {
+ std::cout << "No instance to run navigation" << std::endl;
+ return;
+ }
+
+ mmi_data_h data = nullptr;
+ char *json = get_navigation_viv_response(direction, std::to_string(repeat).c_str());
+ std::cout << "json :" << json << std::endl;
+ mmi_data_create_text(json, &data);
+
+ mmi_workflow_instance_feed_data(m_instance, "PARSER", "COMMAND", data);
+ mmi_data_destroy(data);
+ free(json);
+ }
+#endif
static int state_changed_cb(mmi_state_e state, void *user_data) {
Program *program = static_cast<Program*>(user_data);
program->m_state = state;
static Program g_program;
-int main(void)
+void process_file(std::string filename)
{
+ std::ifstream file(filename);
+ if (!file.is_open()) {
+ std::cout << "Failed to open file: " << filename << std::endl;
+ return;
+ }
+
+ std::vector<std::string> lines;
+ std::string line;
+ while (std::getline(file, line)) {
+ std::string token;
+ std::istringstream stream(line);
+
+ std::cout << "Processing line : " << line << std::endl;
+
+ if (std::getline(stream, token, ' ')) {
+ std::string command = token;
+ std::vector<std::string> parameters;
+ while (std::getline(stream, token, ' ')) {
+ parameters.push_back(token);
+ }
+ try {
+ if (command.compare("sleep") == 0) {
+ sleep(std::stoi(parameters.at(0)));
+ } else if (command.compare("create") == 0) {
+ g_program.create_instance(std::stoi(parameters.at(0)));
+ } else if (command.compare("create_from_script") == 0) {
+ g_program.create_instance_from_script();
+ } else if (command.compare("create_from_file") == 0) {
+ g_program.create_instance_from_file(parameters.at(0));
+ } else if (command.compare("destroy") == 0) {
+ g_program.destroy_instance();
+ } else if (command.compare("set_attribute") == 0) {
+ g_program.set_attribute(
+ parameters.at(0), parameters.at(1), parameters.at(2));
+ } else if (command.compare("feed_data") == 0) {
+ if (parameters.size() == 5) {
+ g_program.feed_data(
+ parameters.at(0), parameters.at(1), parameters.at(2), parameters.at(3), parameters.at(4));
+ } else {
+ g_program.feed_data(
+ parameters.at(0), parameters.at(1), parameters.at(2), parameters.at(3));
+ }
+ } else if (command.compare("emit_signal") == 0) {
+ g_program.emit_signal(parameters.at(0));
+ } else if (command.compare("activate") == 0) {
+ g_program.activate_instance();
+ } else if (command.compare("deactivate") == 0) {
+ g_program.deactivate_instance();
+ }
+ } catch (std::out_of_range &e) {
+ std::cout << e.what() << std::endl;
+ }
+ }
+
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ argh::parser cmdl(argv);
+
+ std::string filename;
+ if (cmdl("file") >> filename) {
+ process_file(filename);
+ return 0;
+ }
+
try {
cli::SetColor();
},
"Set attributes for the current workflow instance");
- rootMenu->Insert("emit_signal", [](std::ostream& out) {
- g_program.emit_signal();
+ rootMenu->Insert("feed_data", [](std::ostream& out, std::string node_name, std::string port_name, std::string type, std::string value1, std::string value2) {
+ g_program.feed_data(node_name, port_name, type, value1, value2);
+ },
+ "Set attributes for the current workflow instance");
+
+ rootMenu->Insert("emit_signal", [](std::ostream& out, std::string signal_name) {
+ g_program.emit_signal(signal_name);
},
"Set attributes for the current workflow instance");
},
"Deactivates the current workflow instance");
+#ifdef USE_VOICE_TOUCH_TV
+ rootMenu->Insert("title_selection", [](std::ostream& out, std::string value) {
+ g_program.title_selection(value);
+ },
+ "Find and execute the selected title on the screen");
+
+ rootMenu->Insert("ordinal_selection", [](std::ostream& out, int value) {
+ g_program.ordinal_selection(value);
+ },
+ "Select an item with the input value at the focused point on the screen");
+
+ rootMenu->Insert("navigation", [](std::ostream& out, std::string direction, int repeat) {
+ g_program.navigation(direction, repeat);
+ },
+ "Move in the input direction as many times as specified");
+#endif
cli::Cli cli(std::move(rootMenu));
cli::CliEcoreSession session(cli);
'.',
'../common/',
'../../capi/',
+ '../../capi/common',
+ '../../capi/workflow',
+ '../../capi/node',
'../../external/',
mmi_extra_include_dir,
)
+++ /dev/null
-/*
-* Copyright © 2021 Samsung Electronics co., Ltd. All Rights Reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining a
-* copy of this software and associated documentation files (the "Software"),
-* to deal in the Software without restriction, including without limitation
-* the rights to use, copy, modify, merge, publish, distribute, sublicense,
-* and/or sell copies of the Software, and to permit persons to whom the
-* Software is furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice (including the next
-* paragraph) shall be included in all copies or substantial portions of the
-* Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-* DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef __MMI_COMMON_H__
-#define __MMI_COMMON_H__
-
-#include <stdbool.h>
-#include "mmi-platform-config.h"
-
-#ifndef MMI_API
-#define MMI_API __attribute__ ((visibility("default")))
-#endif
-
-#endif //__MMI_COMMON_H__
size_t name_length = 0;
mmi_port_get_name(port, &name, &name_length);
- mmi_port_callbacks callbacks;
+ mmi_port_callbacks_s callbacks;
mmi_port_get_callbacks(port, &callbacks);
if (strncmp(name, port_info.name.c_str(), name_length) == 0) {
m_plugin_module_proxy->add_node_instance_info(&plugin_module_node_instance_info);
if (m_callbacks.initialized_cb != nullptr) {
- m_callbacks.initialized_cb(static_cast<mmi_node_instance_h>(this));
+ m_callbacks.initialized_cb(static_cast<mmi_node_instance_h>(this), nullptr);
}
// LCOV_EXCL_STOP
bool NodeInstance::deinitialize() {
if (m_callbacks.deinitialized_cb != nullptr) {
- m_callbacks.deinitialized_cb(static_cast<mmi_node_instance_h>(this));
+ m_callbacks.deinitialized_cb(static_cast<mmi_node_instance_h>(this), nullptr);
}
if (m_plugin_module_proxy) {
_E("Activate callback is not set");
return false;
}
- m_callbacks.activated_cb(static_cast<mmi_node_instance_h>(this));
+ m_callbacks.activated_cb(static_cast<mmi_node_instance_h>(this), nullptr);
return true;
}
_E("Deactivate callback is not set");
return false;
}
- m_callbacks.deactivated_cb(static_cast<mmi_node_instance_h>(this));
+ m_callbacks.deactivated_cb(static_cast<mmi_node_instance_h>(this), nullptr);
return true;
}
m_suspended = true;
if (m_activated) {
if (m_callbacks.deactivated_cb != nullptr) {
- m_callbacks.deactivated_cb(static_cast<mmi_node_instance_h>(this));
+ m_callbacks.deactivated_cb(static_cast<mmi_node_instance_h>(this), nullptr);
}
}
return true;
m_suspended = false;
if (m_activated) {
if (m_callbacks.activated_cb != nullptr) {
- m_callbacks.activated_cb(static_cast<mmi_node_instance_h>(this));
+ m_callbacks.activated_cb(static_cast<mmi_node_instance_h>(this), nullptr);
}
}
return true;
_E("Set attribute callback is not set");
return false;
}
- m_callbacks.attribute_set_cb(static_cast<mmi_node_instance_h>(this), attribute);
+ m_callbacks.attribute_set_cb(static_cast<mmi_node_instance_h>(this), attribute, nullptr);
return true;
}
// LCOV_EXCL_STOP
_E("Set signal callback is not set");
return false;
}
- m_callbacks.signal_received_cb(static_cast<mmi_node_instance_h>(this), signal);
+ m_callbacks.signal_received_cb(static_cast<mmi_node_instance_h>(this), signal, nullptr);
return true;
}
mmi_node_type_e m_node_type;
mmi_node_sub_type_e m_node_sub_type;
- mmi_node_callbacks m_callbacks{{nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}};
+ mmi_node_callbacks_s m_callbacks{{nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}};
bool m_suspended{false};
bool m_activated{false};
#include "mmi-common.h"
#include "mmi-node.h"
-#include "mmi-node-source.h"
-#include "mmi-node-processor.h"
-#include "mmi-node-logic.h"
-#include "mmi-node-controller.h"
-#include "mmi-node-action.h"
-#include "mmi-node-custom.h"
+#include "mmi-node-types.h"
#include "mmi-plugin-module-proxy.h"
#include "mmi-manager-log.h"
*/
#include "mmi-plugin-module-proxy.h"
-#include "mmi-manager-log.h"
#include <dlfcn.h>
+#include "mmi-manager-log.h"
+#include "mmi-workflow-internal.h"
+
namespace mmi {
// LCOV_EXCL_START
mmi_node_h node = node_list.nodes[i];
mmi_node_type_e type;
mmi_node_get_type(node, &type);
- mmi_node_callbacks callbacks;
+ mmi_node_callbacks_s callbacks;
mmi_node_get_callbacks(node, &callbacks);
size_t port_count;
_D("node_info[%zu].type: %d", i, type);
mmi_port_get_type(port, &port_type);
mmi_data_type_e data_type;
mmi_port_get_data_type(port, &data_type);
- mmi_port_callbacks port_callbacks;
+ mmi_port_callbacks_s port_callbacks;
mmi_port_get_callbacks(port, &port_callbacks);
_D("node_info[%zu].port_info[%zu].name: %s", i, j, name);
_D("node_info[%zu].port_info[%zu].type: %d", i, j, port_type);
PortInstance::~PortInstance() {
}
-void PortInstance::set_port_callbacks(mmi_port_callbacks callbacks) {
+void PortInstance::set_port_callbacks(mmi_port_callbacks_s callbacks) {
_D("PortInstance[%p] set_port_callbacks : %p %p", this,
callbacks.output_format_requested_cb, callbacks.input_data_received_cb);
m_callbacks = callbacks;
void PortInstance::on_output_data_received(mmi_data_h data) {
if (m_callbacks.input_data_received_cb) {
- m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(this), data);
+ m_callbacks.input_data_received_cb(static_cast<mmi_port_instance_h>(this), data, nullptr);
}
}
PortInstance();
virtual ~PortInstance();
- void set_port_callbacks(mmi_port_callbacks callbacks);
+ void set_port_callbacks(mmi_port_callbacks_s callbacks);
void add_linked_port_instance(std::shared_ptr<PortInstance> port_instance);
void add_data_gateway(std::shared_ptr<DataGateway> gateway);
void on_output_data_received(mmi_data_h data);
private:
std::string m_name;
- mmi_port_callbacks m_callbacks{{nullptr}, {nullptr}};
+ mmi_port_callbacks_s m_callbacks{{nullptr}, {nullptr}};
std::vector<std::shared_ptr<PortInstance>> m_linked_port_instances;
std::vector<std::shared_ptr<DataGateway>> m_data_gateways;
TestNodePluginModule::~TestNodePluginModule() {
}
-int TestNodePluginModule::node_initialized_cb(mmi_node_instance_h instance) {
+int TestNodePluginModule::node_initialized_cb(mmi_node_instance_h instance, void *user_data) {
_D("Node initialize callback is called for %p", instance);
return MMI_ERROR_NONE;
}
-int TestNodePluginModule::node_deinitialized_cb(mmi_node_instance_h instance) {
+int TestNodePluginModule::node_deinitialized_cb(mmi_node_instance_h instance, void *user_data) {
_D("Node deinitialize callback is called for %p", instance);
return MMI_ERROR_NONE;
}
-int TestNodePluginModule::node_attribute_set_cb(mmi_node_instance_h instance, mmi_attribute_h attribute) {
+int TestNodePluginModule::node_attribute_set_cb(mmi_node_instance_h instance, mmi_attribute_h attribute, void *user_data) {
_D("Node attribute set callback is called for %p", instance);
return MMI_ERROR_NONE;
}
-int TestNodePluginModule::node_activated_cb(mmi_node_instance_h instance) {
+int TestNodePluginModule::node_activated_cb(mmi_node_instance_h instance, void *user_data) {
_D("Node activate callback is called for %p", instance);
return MMI_ERROR_NONE;
}
-int TestNodePluginModule::node_deactivated_cb(mmi_node_instance_h instance) {
+int TestNodePluginModule::node_deactivated_cb(mmi_node_instance_h instance, void *user_data) {
_D("Node deactivate callback is called for %p", instance);
return MMI_ERROR_NONE;
}
-int TestNodePluginModule::node_signal_received_cb(mmi_node_instance_h instance, mmi_signal_h signal) {
+int TestNodePluginModule::node_signal_received_cb(mmi_node_instance_h instance, mmi_signal_h signal, void *user_data) {
_D("Node signal received callback is called for %p", instance);
return MMI_ERROR_NONE;
}
-int TestNodePluginModule::port_output_format_requested_cb(mmi_port_instance_h instance, const char *format) {
+int TestNodePluginModule::port_output_format_requested_cb(mmi_port_instance_h instance, const char **format, void *user_data) {
_D("Port output format request callback is called for %p", instance);
return MMI_ERROR_NONE;
}
-int TestNodePluginModule::port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data) {
+int TestNodePluginModule::port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data) {
_D("Port input data callback is called for %p", instance);
return MMI_ERROR_NONE;
}
-TestNodePluginModuleMIC::TestNodePluginModuleMIC() {
+TestNodePluginModuleScreenAnalyzer::TestNodePluginModuleScreenAnalyzer() {
m_node_callbacks = default_node_callbacks;
m_node_callbacks.activated_cb = node_activated_cb;
- m_audio_port_callbacks = default_port_callbacks;
+ m_screen_info_port_callbacks = default_port_callbacks;
}
-int TestNodePluginModuleMIC::node_activated_cb(mmi_node_instance_h instance) {
+int TestNodePluginModuleScreenAnalyzer::node_activated_cb(mmi_node_instance_h instance, void *user_data) {
_D("[MIC] Node activate callback is called for %p", instance);
/* In shared object plugin module, the output data can be generated using the API
mmi library API is not allowed. So, we have to find the output port using
the port instance map. */
- std::string output_port_name{"AUDIO"};
+ std::string output_port_name{"SCREEN_INFO"};
mmi_port_instance_h output_port = nullptr;
for (const auto &elem : g_node_instance_info_map) {
const mmi_plugin_module_node_instance_info_s &node_instance_info = elem.second;
if (node_instance_info.node == instance) {
for (size_t i = 0; i < node_instance_info.port_info_count; ++i) {
if (output_port_name.compare(std::string(node_instance_info.port_infos[i].name)) == 0) {
- _D("[MIC] Found output port %p", node_instance_info.port_infos[i].port);
+ _D("[SCREEN_INFO] Found output port %p", node_instance_info.port_infos[i].port);
output_port = node_instance_info.port_infos[i].port;
break;
}
PortInstance *port_instance = reinterpret_cast<PortInstance*>(output_port);
if (port_instance) {
- _D("[MIC] Generating an output %d to %p", value, port_instance);
+ _D("[SCREEN_INFO] Generating an output %d to %p", value, port_instance);
port_instance->on_output_data_generated(output_data);
}
return MMI_ERROR_NONE;
}
-TestNodePluginModuleASR::TestNodePluginModuleASR() {
+TestNodePluginModuleMatch::TestNodePluginModuleMatch() {
m_node_callbacks = default_node_callbacks;
- m_audio_port_callbacks = default_port_callbacks;
- m_audio_port_callbacks.input_data_received_cb = audio_port_input_data_received_cb;
+ m_text_port_callbacks = default_port_callbacks;
+ m_text_port_callbacks.input_data_received_cb = text_port_input_data_received_cb;
}
-int TestNodePluginModuleASR::audio_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data) {
+int TestNodePluginModuleMatch::text_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data) {
/* In shared object plugin module, the output port can be found using the API
mmi_node_instance_sibling_port_find() function. However, in this test
plugin module, calling mmi library API is not allowed. So, we have to find the
output port using the node instance info map. */
- std::string output_port_name{"FINAL_RESULT"};
+
+ std::string output_port_name{"MATCHED_CANDIDATE"};
mmi_port_instance_h output_port = nullptr;
const mmi_plugin_module_node_instance_info_s &node_instance_info = g_node_instance_info_map[instance];
for (size_t i = 0; i < node_instance_info.port_info_count; ++i) {
int *ptr = reinterpret_cast<int*>(data);
if (ptr) value = *ptr;
- _D("[ASR] Audio input data callback is called: %p %d", instance, value);
+ _D("[Match] Text input data callback is called: %p %d", instance, value);
value++;
ptr = &value;
PortInstance *port_instance = reinterpret_cast<PortInstance*>(output_port);
if (port_instance) {
- _D("[ASR] Generating an output %d to %p", value, port_instance);
+ _D("[Match] Generating an output %d to %p", value, port_instance);
port_instance->on_output_data_generated(output_data);
}
return MMI_ERROR_NONE;
}
-int TestNodePluginModuleMatch::text_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data) {
- /* In shared object plugin module, the output port can be found using the API
- mmi_node_instance_sibling_port_find() function. However, in this test
- plugin module, calling mmi library API is not allowed. So, we have to find the
- output port using the node instance info map. */
-
- std::string output_port_name{"MATCHED_CANDIDATE"};
- mmi_port_instance_h output_port = nullptr;
- const mmi_plugin_module_node_instance_info_s &node_instance_info = g_node_instance_info_map[instance];
- for (size_t i = 0; i < node_instance_info.port_info_count; ++i) {
- if (output_port_name.compare(std::string(node_instance_info.port_infos[i].name)) == 0) {
- output_port = node_instance_info.port_infos[i].port;
- break;
- }
- }
+TestNodePluginModuleKeyEvent::TestNodePluginModuleKeyEvent() {
+ m_node_callbacks = default_node_callbacks;
+ m_key_event_port_callbacks = default_port_callbacks;
+ m_key_event_port_callbacks.input_data_received_cb = key_event_port_input_data_received_cb;
+}
+int TestNodePluginModuleKeyEvent::key_event_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data) {
int value = -1;
int *ptr = reinterpret_cast<int*>(data);
if (ptr) value = *ptr;
- _D("[Match] Text input data callback is called: %p %d", instance, value);
-
- value++;
- ptr = &value;
-
- mmi_data_h output_data = reinterpret_cast<mmi_data_h>(ptr);
-
- /* In shared object plugin module, the output data can be generated using the API
- mmi_port_instance_output_generate() function. However, in this test plugin module,
- calling mmi library API is not allowed. So, we have to generate the output
- using the port instance handle directly. */
-
- PortInstance *port_instance = reinterpret_cast<PortInstance*>(output_port);
- if (port_instance) {
- _D("[Match] Generating an output %d to %p", value, port_instance);
- port_instance->on_output_data_generated(output_data);
- }
+ _D("[KEY_EVENT] key event input data callback is called: %p %d", instance, value);
return MMI_ERROR_NONE;
}
-TestNodePluginModuleMatch::TestNodePluginModuleMatch() {
- m_node_callbacks = default_node_callbacks;
- m_text_port_callbacks = default_port_callbacks;
- m_text_port_callbacks.input_data_received_cb = text_port_input_data_received_cb;
-}
-
PluginModuleProxySelfContainerTest::PluginModuleProxySelfContainerTest() {
}
/* Self-contained port information */
- mmi_port_h mic_audio_port = nullptr;
- mmi_port_create(&mic_audio_port);
- mmi_port_set_name(mic_audio_port, "AUDIO");
- mmi_port_set_type(mic_audio_port, MMI_PORT_TYPE_OUT);
- mmi_port_set_data_type(mic_audio_port, MMI_DATA_TYPE_AUDIO);
- mmi_port_set_callbacks(mic_audio_port, m_node_mic.m_audio_port_callbacks);
-
- mmi_node_h mic_node = nullptr;
- mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &mic_node);
- mmi_node_add_port(mic_node, mic_audio_port);
- mmi_node_set_callbacks(mic_node, m_node_mic.m_node_callbacks);
- mmi_node_register(mic_node);
-
- mmi_node_destroy(mic_node);
-
- mmi_port_h asr_audio_port = nullptr;
- mmi_port_create(&asr_audio_port);
- mmi_port_set_name(asr_audio_port, "AUDIO");
- mmi_port_set_type(asr_audio_port, MMI_PORT_TYPE_IN);
- mmi_port_set_data_type(asr_audio_port, MMI_DATA_TYPE_AUDIO);
- mmi_port_set_callbacks(asr_audio_port, m_node_asr.m_audio_port_callbacks);
-
- mmi_port_h asr_partial_result_port = nullptr;
- mmi_port_create(&asr_partial_result_port);
- mmi_port_set_name(asr_partial_result_port, "PARTIAL_RESULT");
- mmi_port_set_type(asr_partial_result_port, MMI_PORT_TYPE_OUT);
- mmi_port_set_data_type(asr_partial_result_port, MMI_DATA_TYPE_TEXT);
- mmi_port_set_callbacks(asr_partial_result_port, m_node_asr.m_audio_port_callbacks);
-
- mmi_port_h asr_final_result_port = nullptr;
- mmi_port_create(&asr_final_result_port);
- mmi_port_set_name(asr_final_result_port, "FINAL_RESULT");
- mmi_port_set_type(asr_final_result_port, MMI_PORT_TYPE_OUT);
- mmi_port_set_data_type(asr_final_result_port, MMI_DATA_TYPE_TEXT);
- mmi_port_set_callbacks(asr_final_result_port, m_node_asr.m_audio_port_callbacks);
-
- mmi_node_h asr_node = nullptr;
- mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &asr_node);
- mmi_node_add_port(asr_node, asr_audio_port);
- mmi_node_add_port(asr_node, asr_partial_result_port);
- mmi_node_add_port(asr_node, asr_final_result_port);
- mmi_node_set_callbacks(asr_node, m_node_asr.m_node_callbacks);
- mmi_node_register(asr_node);
-
- mmi_node_destroy(asr_node);
+ mmi_port_h screen_info_port = nullptr;
+ mmi_port_create(&screen_info_port);
+ mmi_port_set_name(screen_info_port, "SCREEN_INFO");
+ mmi_port_set_type(screen_info_port, MMI_PORT_TYPE_OUT);
+ mmi_port_set_data_type(screen_info_port, MMI_DATA_TYPE_TEXT);
+ mmi_port_set_callbacks(screen_info_port, m_node_screen_analyzer.m_screen_info_port_callbacks, nullptr);
+
+ mmi_node_h screen_anlayzer_node = nullptr;
+ mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &screen_anlayzer_node);
+ mmi_node_add_port(screen_anlayzer_node, screen_info_port);
+ mmi_node_set_callbacks(screen_anlayzer_node, m_node_screen_analyzer.m_node_callbacks, nullptr);
+ mmi_node_register(screen_anlayzer_node);
+
+ mmi_node_destroy(screen_anlayzer_node);
mmi_port_h match_text_port = nullptr;
mmi_port_create(&match_text_port);
mmi_port_set_name(match_text_port, "TEXT");
mmi_port_set_type(match_text_port, MMI_PORT_TYPE_IN);
mmi_port_set_data_type(match_text_port, MMI_DATA_TYPE_TEXT);
- mmi_port_set_callbacks(match_text_port, m_node_match.m_text_port_callbacks);
+ mmi_port_set_callbacks(match_text_port, m_node_match.m_text_port_callbacks, nullptr);
mmi_port_h match_candidate_port = nullptr;
mmi_port_create(&match_candidate_port);
mmi_port_set_name(match_candidate_port, "MATCHED_CANDIDATE");
mmi_port_set_type(match_candidate_port, MMI_PORT_TYPE_OUT);
mmi_port_set_data_type(match_candidate_port, MMI_DATA_TYPE_TEXT);
- mmi_port_set_callbacks(match_candidate_port, m_node_match.m_text_port_callbacks);
+ mmi_port_set_callbacks(match_candidate_port, m_node_match.m_text_port_callbacks, nullptr);
mmi_node_h match_node = nullptr;
mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &match_node);
mmi_node_add_port(match_node, match_text_port);
mmi_node_add_port(match_node, match_candidate_port);
- mmi_node_set_callbacks(match_node, m_node_match.m_node_callbacks);
+ mmi_node_set_callbacks(match_node, m_node_match.m_node_callbacks, nullptr);
mmi_node_register(match_node);
mmi_node_destroy(match_node);
+ mmi_port_h key_event_port = nullptr;
+ mmi_port_create(&key_event_port);
+ mmi_port_set_name(key_event_port, "KEY_EVENT");
+ mmi_port_set_type(key_event_port, MMI_PORT_TYPE_IN);
+ mmi_port_set_data_type(key_event_port, MMI_DATA_TYPE_TEXT);
+ mmi_port_set_callbacks(key_event_port, m_node_key_event.m_key_event_port_callbacks, nullptr);
+
+ mmi_node_h key_event_node = nullptr;
+ mmi_node_create_action(MMI_NODE_ACTION_TYPE_KEY_EVENT, &key_event_node);
+ mmi_node_add_port(key_event_node, key_event_port);
+ mmi_node_set_callbacks(key_event_node, m_node_key_event.m_node_callbacks, nullptr);
+ mmi_node_register(key_event_node);
+
+ mmi_node_destroy(key_event_node);
+
const char *identifier = mmi_plugin_storage_get_current_module_identifier();
mmi_plugin_module_node_list_s list = mmi_plugin_storage_get_node_list(identifier);
mmi_workflow_h workflow = nullptr;
mmi_workflow_create(&workflow);
- mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
-
- mmi_node_h node_mic = nullptr;
- mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic);
- mmi_workflow_node_add(workflow, "MIC", node_mic);
+ mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
- mmi_node_h node_asr = nullptr;
- mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr);
- mmi_workflow_node_add(workflow, "ASR", node_asr);
+ mmi_node_h node_screen_analyzer = nullptr;
+ mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &node_screen_analyzer);
+ mmi_workflow_node_add(workflow, "SCREEN_ANALYZER", node_screen_analyzer);
mmi_node_h node_match = nullptr;
mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match);
mmi_workflow_node_add(workflow, "MATCH", node_match);
- mmi_workflow_link_nodes_by_names(workflow, "MIC", "AUDIO", "ASR", "AUDIO");
- mmi_workflow_link_nodes_by_names(workflow, "ASR", "FINAL_RESULT", "MATCH", "TEXT");
+ mmi_node_h node_key_event = nullptr;
+ mmi_node_create_action(MMI_NODE_ACTION_TYPE_KEY_EVENT, &node_key_event);
+ mmi_workflow_node_add(workflow, "KEY_EVENT", node_key_event);
+
+ mmi_workflow_link_nodes_by_names(workflow, "SCREEN_ANALYZER", "SCREEN_INFO", "MATCH", "TEXT");
+ mmi_workflow_link_nodes_by_names(workflow, "MATCH", "MATCHED_CANDIDATE", "KEY_EVENT", "KEY_EVENT");
mmi_workflow_output_assign(workflow, "OUTPUT", "MATCH", "MATCHED_CANDIDATE");
mmi_standard_workflow_register(workflow);
+ mmi_node_destroy(node_key_event);
mmi_node_destroy(node_match);
- mmi_node_destroy(node_asr);
- mmi_node_destroy(node_mic);
+ mmi_node_destroy(node_screen_analyzer);
mmi_workflow_destroy(workflow);
for (size_t i = 0; i < node_instance_info->port_info_count; i++) {
g_node_instance_info_map[node_instance_info->port_infos[i].port] = *node_instance_info;
}
+ mmi_plugin_storage_add_node_instance_info(node_instance_info);
}
void PluginModuleProxySelfContainerTest::remove_node_instance_info(mmi_node_instance_h node_instance) {
+ mmi_plugin_storage_remove_node_instance_info(node_instance);
for (auto it = g_node_instance_info_map.begin(); it != g_node_instance_info_map.end();) {
if (it->second.node == node_instance) {
it = g_node_instance_info_map.erase(it);
TestNodePluginModule();
virtual ~TestNodePluginModule();
- static int node_initialized_cb(mmi_node_instance_h instance);
- static int node_deinitialized_cb(mmi_node_instance_h instance);
- static int node_attribute_set_cb(mmi_node_instance_h instance, mmi_attribute_h attribute);
- static int node_activated_cb(mmi_node_instance_h instance);
- static int node_deactivated_cb(mmi_node_instance_h instance);
- static int node_signal_received_cb(mmi_node_instance_h instance, mmi_signal_h signal);
- static int port_output_format_requested_cb(mmi_port_instance_h instance, const char *format);
- static int port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data);
-
- mmi_node_callbacks default_node_callbacks;
- mmi_port_callbacks default_port_callbacks;
+ static int node_initialized_cb(mmi_node_instance_h instance, void *user_data);
+ static int node_deinitialized_cb(mmi_node_instance_h instance, void *user_data);
+ static int node_attribute_set_cb(mmi_node_instance_h instance, mmi_attribute_h attribute, void *user_data);
+ static int node_activated_cb(mmi_node_instance_h instance, void *user_data);
+ static int node_deactivated_cb(mmi_node_instance_h instance, void *user_data);
+ static int node_signal_received_cb(mmi_node_instance_h instance, mmi_signal_h signal, void *user_data);
+ static int port_output_format_requested_cb(mmi_port_instance_h instance, const char **format, void *user_data);
+ static int port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data);
+
+ mmi_node_callbacks_s default_node_callbacks;
+ mmi_port_callbacks_s default_port_callbacks;
};
class TestWorkflowPluginModuleWakeuplessCommand : TestWorkflowPluginModule {
};
-class TestNodePluginModuleMIC : public TestNodePluginModule {
+class TestNodePluginModuleScreenAnalyzer : public TestNodePluginModule {
public:
- TestNodePluginModuleMIC();
- static int node_activated_cb(mmi_node_instance_h instance);
+ TestNodePluginModuleScreenAnalyzer();
+ static int node_activated_cb(mmi_node_instance_h instance, void *user_data);
- mmi_node_callbacks m_node_callbacks;
- mmi_port_callbacks m_audio_port_callbacks;
+ mmi_node_callbacks_s m_node_callbacks;
+ mmi_port_callbacks_s m_screen_info_port_callbacks;
};
-class TestNodePluginModuleASR : public TestNodePluginModule {
+class TestNodePluginModuleMatch : public TestNodePluginModule {
public:
- TestNodePluginModuleASR();
+ TestNodePluginModuleMatch();
- static int audio_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data);
+ static int text_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data);
- mmi_node_callbacks m_node_callbacks;
- mmi_port_callbacks m_audio_port_callbacks;
+ mmi_node_callbacks_s m_node_callbacks;
+ mmi_port_callbacks_s m_text_port_callbacks;
};
-class TestNodePluginModuleMatch : public TestNodePluginModule {
+class TestNodePluginModuleKeyEvent : public TestNodePluginModule {
public:
- TestNodePluginModuleMatch();
+ TestNodePluginModuleKeyEvent();
- static int text_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data);
+ static int key_event_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data);
- mmi_node_callbacks m_node_callbacks;
- mmi_port_callbacks m_text_port_callbacks;
+ mmi_node_callbacks_s m_node_callbacks;
+ mmi_port_callbacks_s m_key_event_port_callbacks;
};
class PluginModuleProxySelfContainerTest : public IPluginModuleProxy {
private:
TestWorkflowPluginModuleWakeuplessCommand m_workflow_wakeupless_command;
- TestNodePluginModuleMIC m_node_mic;
- TestNodePluginModuleASR m_node_asr;
+ TestNodePluginModuleScreenAnalyzer m_node_screen_analyzer;
TestNodePluginModuleMatch m_node_match;
+ TestNodePluginModuleKeyEvent m_node_key_event;
};
class PluginModuleProxyFactorySelfContainerTest : public IPluginModuleProxyFactory {
#define __MMI_WORKFLOW_PROTOTYPE_MANAGER_H__
#include "mmi-workflow.h"
+#include "mmi-workflow-internal.h"
#include "mmi-workflow-prototype.h"
#include <memory>
'mmi-workflow-instance.cpp',
'mmi-workflow-script.cpp',
'mmi-log.h',
+ 'mmi-defines.h',
'mmi-primitive-value.cpp',
'mmi-data.cpp',
'mmi-attribute.cpp',
'mmi-node.cpp',
- 'mmi-node-source.cpp',
- 'mmi-node-processor.cpp',
- 'mmi-node-logic.cpp',
- 'mmi-node-controller.cpp',
- 'mmi-node-action.cpp',
- 'mmi-node-custom.cpp',
+ 'mmi-node-types.cpp',
'mmi-port.cpp',
'mmi-signal.cpp',
'mmi-plugin-storage.cpp',
- 'mmi-config-parser.cpp',
]
foreach platform_specific_client_file : mmi_platform_specific_client_files
'.',
'../common',
'../../capi',
+ '../../capi/common',
+ '../../capi/workflow',
+ '../../capi/node',
'../../external',
mmi_extra_include_dir,
)
+++ /dev/null
-/*
- * Copyright © 2023 Samsung Electronics co., Ltd. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/inotify.h>
-#include <Ecore.h>
-#include <fcntl.h>
-#include "mmi-config-parser.h"
-#include "mmi-log.h"
-
-
-#define MMI_TAG_CONFIG_BASE_TAG "mmi-config"
-#define MMI_TAG_CONFIG_CONFIDENCE "confidence"
-
-static Ecore_Fd_Handler* g_config_fd_handler_noti = NULL;
-static int g_config_fd_noti;
-static int g_config_wd_noti;
-
-static xmlDocPtr g_config_doc = NULL;
-static mmi_config_s* g_config_info = NULL;
-
-
-static int mmi_parser_load_config(void)
-{
- xmlDocPtr doc = NULL;
- xmlNodePtr cur = NULL;
-
- /* For Thread safety */
- xmlInitParser();
-
- if (0 == access(MMI_DEFAULT_CONFIG, F_OK)) {
- doc = xmlParseFile(MMI_DEFAULT_CONFIG);
- if (doc == NULL) {
- LOGE("[ERROR] Fail to parse file error : %s", MMI_DEFAULT_CONFIG);
- xmlCleanupParser();
- return -1;
- }
- }
-
- cur = xmlDocGetRootElement(doc);
- if (cur == NULL) {
- LOGE("[ERROR] Empty document(%p)", doc);
- xmlFreeDoc(doc);
- doc = NULL;
- xmlCleanupParser();
- return -1;
- }
-
- if (xmlStrcmp(cur->name, (const xmlChar *) MMI_TAG_CONFIG_BASE_TAG)) {
- LOGE("[ERROR] The wrong type, root node is NOT %s. doc(%p)", MMI_TAG_CONFIG_BASE_TAG, doc);
- xmlFreeDoc(doc);
- doc = NULL;
- xmlCleanupParser();
- return -1;
- }
-
- cur = cur->xmlChildrenNode;
- if (cur == NULL) {
- LOGE("[ERROR] Empty document(%p)", doc);
- xmlFreeDoc(doc);
- doc = NULL;
- xmlCleanupParser();
- return -1;
- }
-
- mmi_config_s* temp;
- temp = (mmi_config_s*)calloc(1, sizeof(mmi_config_s));
- if (NULL == temp) {
- LOGE("[ERROR] Out of memory(%p)", doc);
- xmlFreeDoc(doc);
- doc = NULL;
- xmlCleanupParser();
- return -1;
- }
-
- while (cur != NULL) {
- if (0 == xmlStrcmp(cur->name, (const xmlChar *)MMI_TAG_CONFIG_CONFIDENCE)) {
- xmlChar *key = xmlNodeGetContent(cur);
- if (NULL != key) {
- temp->confidence = atof((char*)key);
- xmlFree(key);
- key = NULL;
- } else {
- LOGD("[ERROR] confidence is NULL");
- }
- }
- cur = cur->next;
- }
-
- g_config_info = temp;
- g_config_doc = doc;
-
- return 0;
-}
-
-static int mmi_parser_unload_config(void)
-{
- if (NULL != g_config_doc) {
- LOGD("[DEBUG] Free g_config_doc(%p)", g_config_doc);
- xmlFreeDoc(g_config_doc);
- g_config_doc = NULL;
- }
-
- if (NULL != g_config_info) {
- LOGE("[DEBUG] Free config_info(%p)", g_config_info);
- free(g_config_info);
- g_config_info = NULL;
- }
-
- xmlCleanupParser();
- return 0;
-}
-
-static Eina_Bool mmi_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
-{
- LOGD("into mmi_config_mgr_inotify_event_cb");
-
- int length;
- struct inotify_event event;
- memset(&event, '\0', sizeof(struct inotify_event));
-
- length = read(g_config_fd_noti, &event, sizeof(struct inotify_event));
- if (0 > length) {
- LOGE("[ERROR] Empty Inotify event");
- return ECORE_CALLBACK_DONE;
- }
-
- if (IN_CLOSE_WRITE == event.mask) {
- /* check config changed state */
- if (0 != mmi_parser_load_config())
- return ECORE_CALLBACK_PASS_ON;
-
- } else if (IN_DELETE_SELF == event.mask) {
- LOGE("[ERROR] IN_DELETE_SELF event");
-
- mmi_parser_unload_config();
- mmi_parser_load_config();
- } else {
- LOGE("[ERROR] Undefined event (0x%x)", event.mask);
- }
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static int mmi_config_mgr_register_config_event()
-{
- /* get file notification handler */
- int fd;
- int wd;
-
- fd = inotify_init();
- if (fd < 0) {
- LOGE("[ERROR] Fail get inotify fd");
- return -1;
- }
- g_config_fd_noti = fd;
-
- wd = inotify_add_watch(fd, MMI_DEFAULT_CONFIG, IN_CLOSE_WRITE|IN_DELETE_SELF);
- g_config_wd_noti = wd;
-
- g_config_fd_handler_noti = ecore_main_fd_handler_add(fd, ECORE_FD_READ,
- (Ecore_Fd_Cb)mmi_config_mgr_inotify_event_cb, NULL, NULL, NULL);
- if (NULL == g_config_fd_handler_noti) {
- LOGE("[ERROR] Fail to get handler_noti");
- return -1;
- }
-
- /* Set non-blocking mode of file */
- int value;
- value = fcntl(fd, F_GETFL, 0);
- value |= O_NONBLOCK;
-
- if (0 > fcntl(fd, F_SETFL, value)) {
- LOGE("[WARNING] Fail to set non-block mode");
- }
-
- return 0;
-}
-
-static int mmi_config_mgr_unregister_config_event()
-{
- /* delete inotify variable */
- ecore_main_fd_handler_del(g_config_fd_handler_noti);
- inotify_rm_watch(g_config_fd_noti, g_config_wd_noti);
- close(g_config_fd_noti);
-
- return 0;
-}
-
-int mmi_parser_initialize(void)
-{
- if (0 != mmi_config_mgr_register_config_event()) {
- LOGE("Fail to mmi_config_mgr_register_config_event");
- }
-
- if (0 != mmi_parser_load_config()) {
- LOGE("Fail to mmi_parser_load_config");
- }
- return 0;
-}
-
-int mmi_parser_deinitialize(void)
-{
- if (0 != mmi_config_mgr_unregister_config_event()) {
- LOGE("Fail to mmi_config_mgr_unregister_config_event");
- }
-
- if (0 != mmi_parser_unload_config()) {
- LOGE("Fail to mmi_parser_unload_config");
- }
- return 0;
-}
-
-int mmi_parser_get_confidence(float *confidence)
-{
- LOGD("[DEBUG] Get confidence");
-
- if (g_config_info) {
- *confidence = g_config_info->confidence;
- } else {
- LOGE("[ERROR] g_config_info is NULL");
- return -1;
- }
-
- return 0;
-}
}
new_data->type = MMI_DATA_TYPE_TEXT;
- new_data->data = reinterpret_cast<void *>(strdup(value));
+ new_data->datalen = strlen(value) + 1;
+ new_data->data = reinterpret_cast<void *>(malloc(new_data->datalen));
if (nullptr == new_data->data) {
_E("[ERROR] Fail to allocate memory for raw data");
free(new_data);
return MMI_ERROR_OUT_OF_MEMORY;
}
-
- new_data->datalen = strlen(value);
+ memcpy(new_data->data, value, new_data->datalen);
*data = new_data;
}
// LCOV_EXCL_STOP
-int mmi_data_get_text(mmi_data_h data, const char **string) {
- if (nullptr == data || nullptr == string) {
+int mmi_data_get_text(mmi_data_h data, const char **text) {
+ if (nullptr == data || nullptr == text) {
_E("[ERROR] Some parameters are invalid");
return MMI_ERROR_INVALID_PARAMETER;
}
return MMI_ERROR_INVALID_PARAMETER;
}
- *string = reinterpret_cast<char *>(data->data);
+ *text = reinterpret_cast<char *>(data->data);
return MMI_ERROR_NONE;
}
return MMI_ERROR_NONE;
}
-// LCOV_EXCL_START
-int mmi_data_get_node_timestamp(mmi_data_h data, mmi_data_timestamp_h *timestamp) {
- if (nullptr == data || nullptr == timestamp) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
-
- *timestamp = (mmi_data_timestamp_s*)(data->data);
- return MMI_ERROR_NONE;
-}
-
-int mmi_data_get_source_timestamp(mmi_data_h data, mmi_data_timestamp_h *timestamp) {
- if (nullptr == data || nullptr == timestamp) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
-
- *timestamp = (mmi_data_timestamp_s*)(data->data);
- return MMI_ERROR_NONE;
-}
-
-int mmi_data_set_source_timestamp(mmi_data_h data, mmi_data_timestamp_h timestamp) {
- if (nullptr == data || nullptr == timestamp) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
-
- data->data = timestamp;
- return MMI_ERROR_NONE;
-}
-
int mmi_data_to_bytes(mmi_data_h data, unsigned char **bytes, size_t *length) {
if (nullptr == data || nullptr == bytes || nullptr == length) {
_E("[ERROR] Some parameters are invalid");
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef __TIZEN_UIX_MMI_DEFINES_H__
+#define __TIZEN_UIX_MMI_DEFINES_H__
+
+
+/**
+* @file mmi-defines.h
+*/
+
+
+/**
+* @addtogroup CAPI_UIX_MMI_MODULE
+* @{
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define MMI_NAME_MAX_LENGTH 32
+#define MMI_PARAMETER_MAX_COUNT 32
+#define MMI_PORT_MAX_COUNT 32
+#define MMI_NODE_MAX_COUNT 128
+#define MMI_LINK_MAX_COUNT 128
+#define MMI_OUTPUT_MAX_COUNT 32
+#define MMI_WORKFLOW_MAX_COUNT 64
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __TIZEN_UIX_MMI_DEFINES_H__ */
#include "mmi-log.h"
#include "mmi-workflow-instance-manager.h"
-#include <tzplatform_config.h>
#include <unistd.h>
#include <rpc-port.h>
#include <rpc-port-internal.h>
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include "mmi.h"
-#include "mmi-node-action.h"
-
-#include "mmi-log.h"
-
-int mmi_node_create_action(mmi_node_action_type_e type, mmi_node_h *node) {
- if (nullptr == node) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *node = new mmi_node_s;
- (*node)->type = MMI_NODE_TYPE_ACTION;
- (*node)->sub_type = (int)type;
- (*node)->custom_type_id[0] = '\0';
- (*node)->ports = nullptr;
- (*node)->port_count = 0;
- memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks));
- return MMI_ERROR_NONE;
-}
-
-int mmi_node_get_action_type(mmi_node_h node, mmi_node_action_type_e *type) {
- if (nullptr == node || nullptr == type) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *type = (mmi_node_action_type_e)node->sub_type;
- return MMI_ERROR_NONE;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include "mmi.h"
-#include "mmi-node-controller.h"
-
-#include "mmi-log.h"
-
-int mmi_node_create_controller(mmi_node_controller_type_e type, mmi_node_h *node) {
- if (nullptr == node) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *node = new mmi_node_s;
- (*node)->type = MMI_NODE_TYPE_CONTROLLER;
- (*node)->sub_type = (int)type;
- (*node)->custom_type_id[0] = '\0';
- (*node)->ports = nullptr;
- (*node)->port_count = 0;
- memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks));
- return MMI_ERROR_NONE;
-}
-
-int mmi_node_get_controller_type(mmi_node_h node, mmi_node_controller_type_e *type) {
- if (nullptr == node || nullptr == type) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *type = (mmi_node_controller_type_e)node->sub_type;
- return MMI_ERROR_NONE;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include "mmi.h"
-#include "mmi-node-custom.h"
-
-#include "mmi-log.h"
-
-
-
-int mmi_node_create_custom(const char *custom_type_id, mmi_node_h *node) {
- if (nullptr == node) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *node = new mmi_node_s;
- (*node)->type = MMI_NODE_TYPE_CUSTOM;
- (*node)->sub_type = 0;
- strncpy((*node)->custom_type_id, custom_type_id, MMI_NAME_MAX_LENGTH);
- (*node)->custom_type_id[MMI_NAME_MAX_LENGTH - 1] = '\0';
- (*node)->ports = nullptr;
- (*node)->port_count = 0;
- memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks));
- return MMI_ERROR_NONE;
-}
-
-int mmi_node_get_custom_type(mmi_node_h node, const char **custom_type_id) {
- if (nullptr == node || nullptr == custom_type_id) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *custom_type_id = node->custom_type_id;
- return MMI_ERROR_NONE;
-}
-
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef __TIZEN_UIX_MMI_NODE_INTERNAL_H__
+#define __TIZEN_UIX_MMI_NODE_INTERNAL_H__
+
+#include <mmi-node.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct mmi_node_s {
+ mmi_node_type_e type;
+ int sub_type;
+ char custom_type_id[MMI_NAME_MAX_LENGTH];
+ mmi_port_h *ports;
+ size_t port_count;
+ mmi_node_callbacks_s callbacks;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* __TIZEN_UIX_MMI_NODE_INTERNAL_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include "mmi.h"
-#include "mmi-node-logic.h"
-
-#include "mmi-log.h"
-
-int mmi_node_create_logic(mmi_node_logic_type_e type, mmi_node_h *node) {
- if (nullptr == node) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *node = new mmi_node_s;
- (*node)->type = MMI_NODE_TYPE_LOGIC;
- (*node)->sub_type = (int)type;
- (*node)->custom_type_id[0] = '\0';
- (*node)->ports = nullptr;
- (*node)->port_count = 0;
- memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks));
- return MMI_ERROR_NONE;
-}
-
-int mmi_node_get_logic_type(mmi_node_h node, mmi_node_logic_type_e *type) {
- if (nullptr == node) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *type = (mmi_node_logic_type_e)node->sub_type;
- return MMI_ERROR_NONE;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include "mmi.h"
-#include "mmi-node-processor.h"
-
-#include "mmi-log.h"
-
-int mmi_node_create_processor(mmi_node_processor_type_e type, mmi_node_h *node) {
- if (nullptr == node) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *node = new mmi_node_s;
- (*node)->type = MMI_NODE_TYPE_PROCESSOR;
- (*node)->sub_type = (int)type;
- (*node)->custom_type_id[0] = '\0';
- (*node)->ports = nullptr;
- (*node)->port_count = 0;
- memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks));
- return MMI_ERROR_NONE;
-}
-
-int mmi_node_get_processor_type(mmi_node_h node, mmi_node_processor_type_e *type) {
- if (nullptr == node || nullptr == type) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *type = (mmi_node_processor_type_e)node->sub_type;
- return MMI_ERROR_NONE;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include "mmi.h"
-#include "mmi-node-source.h"
-
-#include "mmi-log.h"
-
-int mmi_node_create_source(mmi_node_source_type_e type, mmi_node_h *node) {
- if (nullptr == node) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *node = new mmi_node_s;
- (*node)->type = MMI_NODE_TYPE_SOURCE;
- (*node)->sub_type = (int)type;
- (*node)->custom_type_id[0] = '\0';
- (*node)->ports = nullptr;
- (*node)->port_count = 0;
- memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks));
- return MMI_ERROR_NONE;
-}
-
-int mmi_node_get_source_type(mmi_node_h node, mmi_node_source_type_e *type) {
- if (nullptr == type || nullptr == node) {
- return MMI_ERROR_INVALID_PARAMETER;
- }
- *type = (mmi_node_source_type_e)node->sub_type;
- return MMI_ERROR_NONE;
-}
-
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#include "mmi.h"
+#include "mmi-node-internal.h"
+#include "mmi-node-types.h"
+
+#include "mmi-log.h"
+
+int mmi_node_create_source(mmi_node_source_type_e type, mmi_node_h *node) {
+ if (nullptr == node) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *node = new mmi_node_s;
+ (*node)->type = MMI_NODE_TYPE_SOURCE;
+ (*node)->sub_type = (int)type;
+ (*node)->custom_type_id[0] = '\0';
+ (*node)->ports = nullptr;
+ (*node)->port_count = 0;
+ memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s));
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_get_source_type(mmi_node_h node, mmi_node_source_type_e *type) {
+ if (nullptr == type || nullptr == node) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *type = (mmi_node_source_type_e)node->sub_type;
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_create_processor(mmi_node_processor_type_e type, mmi_node_h *node) {
+ if (nullptr == node) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *node = new mmi_node_s;
+ (*node)->type = MMI_NODE_TYPE_PROCESSOR;
+ (*node)->sub_type = (int)type;
+ (*node)->custom_type_id[0] = '\0';
+ (*node)->ports = nullptr;
+ (*node)->port_count = 0;
+ memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s));
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_get_processor_type(mmi_node_h node, mmi_node_processor_type_e *type) {
+ if (nullptr == node || nullptr == type) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *type = (mmi_node_processor_type_e)node->sub_type;
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_create_logic(mmi_node_logic_type_e type, mmi_node_h *node) {
+ if (nullptr == node) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *node = new mmi_node_s;
+ (*node)->type = MMI_NODE_TYPE_LOGIC;
+ (*node)->sub_type = (int)type;
+ (*node)->custom_type_id[0] = '\0';
+ (*node)->ports = nullptr;
+ (*node)->port_count = 0;
+ memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s));
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_get_logic_type(mmi_node_h node, mmi_node_logic_type_e *type) {
+ if (nullptr == node) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *type = (mmi_node_logic_type_e)node->sub_type;
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_create_controller(mmi_node_controller_type_e type, mmi_node_h *node) {
+ if (nullptr == node) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *node = new mmi_node_s;
+ (*node)->type = MMI_NODE_TYPE_CONTROLLER;
+ (*node)->sub_type = (int)type;
+ (*node)->custom_type_id[0] = '\0';
+ (*node)->ports = nullptr;
+ (*node)->port_count = 0;
+ memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s));
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_get_controller_type(mmi_node_h node, mmi_node_controller_type_e *type) {
+ if (nullptr == node || nullptr == type) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *type = (mmi_node_controller_type_e)node->sub_type;
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_create_action(mmi_node_action_type_e type, mmi_node_h *node) {
+ if (nullptr == node) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *node = new mmi_node_s;
+ (*node)->type = MMI_NODE_TYPE_ACTION;
+ (*node)->sub_type = (int)type;
+ (*node)->custom_type_id[0] = '\0';
+ (*node)->ports = nullptr;
+ (*node)->port_count = 0;
+ memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s));
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_get_action_type(mmi_node_h node, mmi_node_action_type_e *type) {
+ if (nullptr == node || nullptr == type) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *type = (mmi_node_action_type_e)node->sub_type;
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_create_custom(const char *custom_type_id, mmi_node_h *node) {
+ if (nullptr == node) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *node = new mmi_node_s;
+ (*node)->type = MMI_NODE_TYPE_CUSTOM;
+ (*node)->sub_type = 0;
+ strncpy((*node)->custom_type_id, custom_type_id, MMI_NAME_MAX_LENGTH);
+ (*node)->custom_type_id[MMI_NAME_MAX_LENGTH - 1] = '\0';
+ (*node)->ports = nullptr;
+ (*node)->port_count = 0;
+ memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s));
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_get_custom_type(mmi_node_h node, const char **custom_type_id) {
+ if (nullptr == node || nullptr == custom_type_id) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *custom_type_id = node->custom_type_id;
+ return MMI_ERROR_NONE;
+}
+
#include "mmi.h"
#include "mmi-node.h"
+#include "mmi-node-internal.h"
#include "mmi-plugin-storage.h"
#include "mmi-log.h"
return MMI_ERROR_NONE;
}
-int mmi_node_get_callbacks(mmi_node_h node, mmi_node_callbacks *callbacks) {
+int mmi_node_get_callbacks(mmi_node_h node, mmi_node_callbacks_s *callbacks) {
if (nullptr == node || nullptr == callbacks) {
LOGE("[ERROR] parameter is null");
return MMI_ERROR_INVALID_PARAMETER;
return MMI_ERROR_NONE;
}
-int mmi_node_set_callbacks(mmi_node_h node, mmi_node_callbacks callbacks) {
+int mmi_node_set_callbacks(mmi_node_h node, mmi_node_callbacks_s callbacks, void *user_data) {
if (nullptr == node) {
LOGE("[ERROR] parameter is null");
return MMI_ERROR_INVALID_PARAMETER;
return MMI_ERROR_NONE;
}
-int mmi_node_instance_find_port(mmi_node_instance_h instance, mmi_port_type_e port_type, const char *port_name, mmi_port_instance_h *port) {
- if (instance == NULL || port_name == NULL || port == NULL) {
+int mmi_node_instance_find_port_instance(mmi_node_instance_h node_instance, mmi_port_type_e port_type, const char *port_name, mmi_port_instance_h *port_instance) {
+ if (node_instance == NULL || port_name == NULL || port_instance == NULL) {
return MMI_ERROR_INVALID_PARAMETER;
}
- *port = mmi_plugin_storage_find_port_instance(instance, port_name);
+ *port_instance = mmi_plugin_storage_find_port_instance(node_instance, port_name);
return MMI_ERROR_NONE;
}
-int mmi_node_instance_find_sibling_port(mmi_port_instance_h instance, const char *port_name, mmi_port_instance_h *sibling) {
+int mmi_node_instance_find_by_port_instance(mmi_port_instance_h port_instance, mmi_node_instance_h *node_instance) {
+ if (port_instance == NULL || node_instance == NULL) {
+ return MMI_ERROR_INVALID_PARAMETER;
+ }
+ *node_instance = mmi_plugin_storage_find_node_instance_by_port_instance(port_instance);
+ return MMI_ERROR_NONE;
+}
+
+int mmi_node_instance_find_sibling_port_instance(mmi_port_instance_h instance, const char *port_name, mmi_port_instance_h *sibling) {
if (instance == NULL || port_name == NULL || sibling == NULL) {
return MMI_ERROR_INVALID_PARAMETER;
}
#include "mmi.h"
-#include "mmi-log.h"
+#include "mmi-common.h"
#include "mmi-port.h"
#include "mmi-plugin-storage.h"
}
// LCOV_EXCL_START
-MMI_API int mmi_port_get_callbacks(mmi_port_h port, mmi_port_callbacks *callbacks) {
+MMI_API int mmi_port_get_callbacks(mmi_port_h port, mmi_port_callbacks_s *callbacks) {
if (nullptr == port || nullptr == callbacks) {
LOGE("[ERROR] parameter is null");
return MMI_ERROR_INVALID_PARAMETER;
return MMI_ERROR_NONE;
}
-MMI_API int mmi_port_set_callbacks(mmi_port_h port, mmi_port_callbacks callbacks) {
+MMI_API int mmi_port_set_callbacks(mmi_port_h port, mmi_port_callbacks_s callbacks, void *user_data) {
if (nullptr == port) {
LOGE("[ERROR] parameter is null");
return MMI_ERROR_INVALID_PARAMETER;
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef __TIZEN_UIX_MMI_SIGNAL_INTERNAL_H__
+#define __TIZEN_UIX_MMI_SIGNAL_INTERNAL_H__
+
+#include <mmi-primitive-value.h>
+#include <mmi-signal.h>
+
+#include "mmi-defines.h"
+
+/**
+* @file mmi-port-internal.h
+*/
+
+
+/**
+* @addtogroup CAPI_UIX_MMI_COMMON_MODULE
+* @ingroup CAPI_UIX_MMI_MODULE
+* @{
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct mmi_signal_parameter_s {
+ char name[MMI_NAME_MAX_LENGTH];
+ mmi_primitive_value_h value;
+};
+
+struct mmi_signal_s {
+ char name[MMI_NAME_MAX_LENGTH];
+ mmi_signal_parameter_h parameters[MMI_PARAMETER_MAX_COUNT];
+ int parameter_count;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __TIZEN_UIX_MMI_SIGNAL_INTERNAL_H__ */
#include "mmi.h"
#include "mmi-signal.h"
+#include "mmi-signal-internal.h"
-#include "mmi-log.h"
+#include "mmi-common.h"
#include <stdio.h>
#include "mmi-plugin-storage.h"
#include "mmi-client-manager.h"
-#include "mmi-log.h"
+#include "mmi-common.h"
#include "mmi-workflow-instance-manager.h"
#include "mmi-workflow-script-generator.h"
}
// LCOV_EXCL_START
-MMI_API int mmi_workflow_instance_set_output_callback(mmi_workflow_instance_h instance, const char *name, mmi_workflow_output_cb callback, void *user_data) {
+MMI_API int mmi_workflow_instance_set_output_cb(mmi_workflow_instance_h instance, const char *name, mmi_workflow_output_cb callback, void *user_data) {
if (nullptr == instance) {
LOGE("[ERROR] parameter is null");
return MMI_ERROR_INVALID_PARAMETER;
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef __TIZEN_UIX_MMI_WORKFLOW_INTERNAL_H__
+#define __TIZEN_UIX_MMI_WORKFLOW_INTERNAL_H__
+
+
+#include <mmi-data.h>
+#include <mmi-node.h>
+#include "mmi-defines.h"
+
+
+/**
+* @file mmi-workflow.h
+*/
+
+
+/**
+* @addtogroup CAPI_UIX_MMI_MODULE
+* @{
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Functions to define a workflow prototype. Mostly used by workflow developers. */
+
+struct mmi_workflow_node_info_s {
+ char name[MMI_NAME_MAX_LENGTH];
+ mmi_node_h node;
+};
+
+struct mmi_workflow_link_info_s {
+ char from_node_name[MMI_NAME_MAX_LENGTH];
+ char from_port_name[MMI_NAME_MAX_LENGTH];
+ char to_node_name[MMI_NAME_MAX_LENGTH];
+ char to_port_name[MMI_NAME_MAX_LENGTH];
+};
+
+struct mmi_workflow_attribute_assignment_info_s {
+ char attribute_name[MMI_NAME_MAX_LENGTH];
+ char target_node_name[MMI_NAME_MAX_LENGTH];
+ char target_attribute_name[MMI_NAME_MAX_LENGTH];
+};
+
+struct mmi_workflow_attribute_default_value_info_s {
+ size_t serialized_default_value_size;
+ unsigned char *serialized_default_value;
+};
+
+struct mmi_workflow_signal_assignment_info_s {
+ char signal_name[MMI_NAME_MAX_LENGTH];
+ char target_node_name[MMI_NAME_MAX_LENGTH];
+ char target_signal_name[MMI_NAME_MAX_LENGTH];
+};
+
+struct mmi_workflow_output_assignment_info_s {
+ char output_name[MMI_NAME_MAX_LENGTH];
+ char from_node_name[MMI_NAME_MAX_LENGTH];
+ char from_port_name[MMI_NAME_MAX_LENGTH];
+};
+
+struct mmi_workflow_s {
+ mmi_standard_workflow_type_e type;
+ mmi_workflow_node_info_s *node_infos;
+ size_t node_info_count;
+ mmi_workflow_link_info_s *link_infos;
+ size_t link_info_count;
+ mmi_workflow_attribute_assignment_info_s *attribute_assignment_infos;
+ size_t attribute_assignment_info_count;
+ mmi_workflow_attribute_default_value_info_s *attribute_default_value_infos;
+ size_t attribute_default_value_info_count;
+ mmi_workflow_signal_assignment_info_s *signal_assignment_infos;
+ size_t signal_assignment_info_count;
+ mmi_workflow_output_assignment_info_s *output_assignment_infos;
+ size_t output_assignment_info_count;
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __TIZEN_UIX_MMI_WORKFLOW_INTERNAL_H__ */
NODE_LIST,
LINK_LIST,
ATTRIBUTE_LIST,
+ SIGNAL_LIST,
OUTPUT_LIST,
};
{WorkflowScriptSection::NODE_LIST, "@node-list"},
{WorkflowScriptSection::LINK_LIST, "@link-list"},
{WorkflowScriptSection::ATTRIBUTE_LIST, "@attribute-list"},
+ {WorkflowScriptSection::SIGNAL_LIST, "@signal-list"},
{WorkflowScriptSection::OUTPUT_LIST, "@output-list"},
};
};
#define __MMI_WORKFLOW_SCRIPT_GENERATOR_H__
#include "mmi-log.h"
-#include "mmi-node-source.h"
-#include "mmi-node-processor.h"
-#include "mmi-node-logic.h"
-#include "mmi-node-controller.h"
-#include "mmi-node-action.h"
-#include "mmi-node-custom.h"
+#include "mmi-node-types.h"
+#include "mmi-workflow-internal.h"
#include "mmi-workflow-script-common.h"
#include "magic_enum/magic_enum.hpp"
}
return section_script;
}
+ std::string generate_signal_list_section(mmi_workflow_s *workflow) {
+ std::string section_script;
+ auto found_section_name = std::find_if(
+ m_workflow_script_helper.section_names.begin(),
+ m_workflow_script_helper.section_names.end(),
+ [](WorkflowScriptSectionName section_name) { return section_name.section == WorkflowScriptSection::SIGNAL_LIST; });
+ if (found_section_name != m_workflow_script_helper.section_names.end()) {
+ section_script += found_section_name->name + "\n";
+ for (size_t i = 0; i < workflow->signal_assignment_info_count; i++) {
+ section_script +=
+ std::string(workflow->signal_assignment_infos[i].target_node_name) +
+ "." +
+ std::string(workflow->signal_assignment_infos[i].target_signal_name) +
+ " as " +
+ std::string(workflow->signal_assignment_infos[i].signal_name) +
+ "\n";
+ }
+ }
+ return section_script;
+ }
std::string generate_output_list_section(mmi_workflow_s *workflow) {
std::string section_script;
auto found_section_name = std::find_if(
script += "\n";
script += generate_attribute_list_section(workflow_ptr);
script += "\n";
+ script += generate_signal_list_section(workflow_ptr);
+ script += "\n";
script += generate_output_list_section(workflow_ptr);
script += "\n";
#include <vector>
#include "mmi-log.h"
-#include "mmi-node-source.h"
-#include "mmi-node-processor.h"
-#include "mmi-node-logic.h"
-#include "mmi-node-controller.h"
-#include "mmi-node-action.h"
-#include "mmi-node-custom.h"
+#include "mmi-node-types.h"
+#include "mmi-workflow-internal.h"
#include "mmi-workflow-script-common.h"
#include "magic_enum/magic_enum.hpp"
m_section_patterns.push_back({WorkflowScriptSection::NODE_LIST, std::regex("^\\[([a-zA-Z]+)\\] ([a-zA-Z_\\-.]+) as ([a-zA-Z0-9_]+)$")});
m_section_patterns.push_back({WorkflowScriptSection::LINK_LIST, std::regex("^([a-zA-Z0-9_.]+) -> ([a-zA-Z0-9_.]+)$")});
m_section_patterns.push_back({WorkflowScriptSection::ATTRIBUTE_LIST, std::regex("^([a-zA-Z0-9_.]+) as ([a-zA-Z0-9_]+)$")});
+ m_section_patterns.push_back({WorkflowScriptSection::SIGNAL_LIST, std::regex("^([a-zA-Z0-9_.]+) as ([a-zA-Z0-9_]+)$")});
m_section_patterns.push_back({WorkflowScriptSection::OUTPUT_LIST, std::regex("^([a-zA-Z0-9_.]+) as ([a-zA-Z0-9_]+)$")});
int loop;
return true;
}
+ bool process_signal_section(std::smatch matches, mmi_workflow_h workflow) {
+ if (matches.size() == 3) {
+ std::ssub_match sub_match_name = matches[1];
+ std::string identifier = sub_match_name.str();
+
+ std::ssub_match sub_match_value = matches[2];
+ std::string alias = sub_match_value.str();
+
+ LOGD("identifier: %s, alias: %s", identifier.c_str(), alias.c_str());
+
+ size_t pos = identifier.find(".");
+ if (pos != std::string::npos) {
+ std::string node_name = identifier.substr(0, pos);
+ std::string signal_name = identifier.substr(pos + 1);
+
+ LOGD("node_name: %s, signal_name: %s", node_name.c_str(), signal_name.c_str());
+
+ mmi_workflow_signal_assign(workflow, alias.c_str(), node_name.c_str(), signal_name.c_str());
+ }
+ }
+ return true;
+ }
+
bool process_output_section(std::smatch matches, mmi_workflow_h workflow) {
if (matches.size() == 3) {
std::ssub_match sub_match_name = matches[1];
return false;
}
break;
+ case WorkflowScriptSection::SIGNAL_LIST:
+ if (process_signal_section(matches, workflow) == false) {
+ LOGE("[ERROR] Failed to process attribute section");
+ return false;
+ }
+ break;
case WorkflowScriptSection::OUTPUT_LIST:
if (process_output_section(matches, workflow) == false) {
LOGE("[ERROR] Failed to process output section");
#include "mmi.h"
-#include "mmi-log.h"
+#include "mmi-common.h"
#include "mmi-workflow.h"
#include "mmi-workflow-script-parser.h"
#include "mmi.h"
#include "mmi-plugin-storage.h"
-#include "mmi-log.h"
+#include "mmi-common.h"
+#include "mmi-workflow-internal.h"
MMI_API int mmi_workflow_create(mmi_workflow_h *workflow) {
if (nullptr == workflow) {
#include <Ecore.h>
-#include "mmi-log.h"
+#include "mmi-common.h"
#include "mmi-client-manager.h"
virtual std::shared_ptr<NodePrototype> get_node_prototype(
mmi_node_type_e type, mmi_node_sub_type_e sub_type) override {
last_query = std::make_pair(type, sub_type);
+
+ if (type == MMI_NODE_TYPE_LOGIC &&
+ std::get<mmi_node_logic_type_e>(sub_type) == MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH) {
+ auto prototype = std::make_shared<NodePrototype>();
+ prototype->set_type(MMI_NODE_TYPE_LOGIC);
+ prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
+ PortInfo port_info_text{"TEXT", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_TEXT, "Text Data"};
+ PortInfo port_info_matched_candidate{"MATCHED_CANDIDATE", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_TEXT, "Matched Data"};
+ prototype->add_port_info(port_info_matched_candidate);
+ prototype->add_port_info(port_info_text);
+ return prototype;
+ }
+
return nullptr;
}
std::shared_ptr<IPluginModuleProxy> proxy;
};
+class PortInstanceManagerDummy : public IPortInstanceManager {
+public:
+ std::shared_ptr<PortInstance> create_port_instance() override {
+ return std::make_shared<PortInstance>();
+ }
+ bool destroy_port_instance(
+ std::shared_ptr<PortInstance> port_instance) override {
+ return true;
+ }
+ bool link_port_instances(
+ std::shared_ptr<PortInstance> out_port,
+ std::shared_ptr<PortInstance> in_port) override {
+ return true;
+ }
+};
+
class NodeInstanceManagerTest : public testing::Test {
public:
NodeInstanceManagerTest() {
void SetUp() override {
prototype_store = std::make_shared<NodePrototypeStoreDummy>();
plugin_module_proxy_provider = std::make_shared<PluginModuleProxyProviderDummy>();
+ port_instance_manager = std::make_shared<PortInstanceManagerDummy>();
manager.set_node_prototype_store(prototype_store);
manager.set_plugin_module_proxy_provider(plugin_module_proxy_provider);
+ manager.set_port_instance_manager(port_instance_manager);
ASSERT_NE(prototype_store, nullptr);
ASSERT_NE(plugin_module_proxy_provider, nullptr);
std::shared_ptr<NodePrototypeStoreDummy> prototype_store;
std::shared_ptr<PluginModuleProxyProviderDummy> plugin_module_proxy_provider;
+ std::shared_ptr<PortInstanceManagerDummy> port_instance_manager;
};
TEST_F(NodeInstanceManagerTest, ProperNodePrototypeQueriedWhenCreatingNodeInstance) {
MMI_NODE_TYPE_NONE, std::monostate{});
std::shared_ptr<NodeInstance> instance = manager.create_node_instance(
- MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR );
+ MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
+
+ ASSERT_EQ(prototype_store->last_query.first, MMI_NODE_TYPE_LOGIC);
+ ASSERT_EQ(prototype_store->last_query.second, mmi_node_sub_type_e{MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH});
+}
+
+TEST_F(NodeInstanceManagerTest, NodeInstanceFoundByChildPortInstance) {
+ std::shared_ptr<NodeInstance> instance = manager.create_node_instance(
+ MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
+
+ mmi_node_instance_h node_instance = static_cast<mmi_node_instance_h>(instance.get());
+
+ mmi_port_instance_h port_instance_text = nullptr;
+ mmi_port_instance_h port_instance_matched_candidate = nullptr;
+ mmi_node_instance_find_port_instance(node_instance, MMI_PORT_TYPE_IN, "TEXT", &port_instance_text);
+ mmi_node_instance_find_port_instance(node_instance, MMI_PORT_TYPE_OUT, "MATCHED_CANDIDATE", &port_instance_matched_candidate);
+
+ mmi_node_instance_h found_by_text = nullptr;
+ mmi_node_instance_h found_by_matched_candidate = nullptr;
+ mmi_node_instance_find_by_port_instance(port_instance_text, &found_by_text);
+ mmi_node_instance_find_by_port_instance(port_instance_matched_candidate, &found_by_matched_candidate);
+
+ ASSERT_EQ(node_instance, found_by_matched_candidate);
+ ASSERT_EQ(node_instance, found_by_text);
+}
+
+TEST_F(NodeInstanceManagerTest, NodeInstanceNotMatchByDifferentChildPortInstance) {
+ std::shared_ptr<NodeInstance> instance_1 = manager.create_node_instance(
+ MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
+ std::shared_ptr<NodeInstance> instance_2 = manager.create_node_instance(
+ MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
+
+ mmi_node_instance_h node_instance_1 = static_cast<mmi_node_instance_h>(instance_1.get());
+ mmi_node_instance_h node_instance_2 = static_cast<mmi_node_instance_h>(instance_2.get());
+
+ mmi_port_instance_h port_instance_text_1 = nullptr;
+ mmi_port_instance_h port_instance_matched_candidate_2 = nullptr;
+ mmi_node_instance_find_port_instance(node_instance_1, MMI_PORT_TYPE_IN, "TEXT", &port_instance_text_1);
+ mmi_node_instance_find_port_instance(node_instance_2, MMI_PORT_TYPE_OUT, "MATCHED_CANDIDATE", &port_instance_matched_candidate_2);
+
+ mmi_node_instance_h found_by_text_1 = nullptr;
+ mmi_node_instance_h found_by_matched_candidate_2 = nullptr;
+ mmi_node_instance_find_by_port_instance(port_instance_text_1, &found_by_text_1);
+ mmi_node_instance_find_by_port_instance(port_instance_matched_candidate_2, &found_by_matched_candidate_2);
- ASSERT_EQ(prototype_store->last_query.first, MMI_NODE_TYPE_PROCESSOR);
- ASSERT_EQ(prototype_store->last_query.second, mmi_node_sub_type_e{MMI_NODE_PROCESSOR_TYPE_ASR});
+ ASSERT_NE(found_by_matched_candidate_2, found_by_text_1);
}
} // namespace
PluginModuleInfo{mmi_plugin_module_type_e::SHARED_LIBRARY, "test.so"});
valid_prototype->set_type(MMI_NODE_TYPE_SOURCE);
- valid_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT);
+ valid_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER);
ASSERT_TRUE(valid_prototype->is_valid());
}
auto invalid_prototype = std::make_shared<NodePrototype>();
invalid_prototype->set_type(MMI_NODE_TYPE_SOURCE);
- invalid_prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR);
+ invalid_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER);
manager.add_node_prototype(invalid_prototype);
PluginModuleInfo{mmi_plugin_module_type_e::SHARED_LIBRARY, "test.so"});
prototype->set_type(MMI_NODE_TYPE_SOURCE);
- prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT);
- ASSERT_TRUE(prototype->is_valid());
-
- prototype->set_type(MMI_NODE_TYPE_PROCESSOR);
- prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR);
+ prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER);
ASSERT_TRUE(prototype->is_valid());
prototype->set_type(MMI_NODE_TYPE_LOGIC);
prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
ASSERT_TRUE(prototype->is_valid());
+ prototype->set_type(MMI_NODE_TYPE_ACTION);
+ prototype->set_sub_type(MMI_NODE_ACTION_TYPE_KEY_EVENT);
+ ASSERT_TRUE(prototype->is_valid());
+
prototype->set_type(MMI_NODE_TYPE_CUSTOM);
prototype->set_sub_type("com.samsung.tizen.custom-node-llm");
ASSERT_TRUE(prototype->is_valid());
prototype->set_type(MMI_NODE_TYPE_SOURCE);
/* PROCESSOR sub type for SOURCE type */
- prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR);
+ prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
ASSERT_FALSE(prototype->is_valid());
}
/* No plugin module identifier provided */
prototype->set_type(MMI_NODE_TYPE_SOURCE);
- prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT);
+ prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER);
ASSERT_FALSE(prototype->is_valid());
}
mmi_node_sub_type_e sub_type;
prototype->set_type(MMI_NODE_TYPE_SOURCE);
- prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT);
+ prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER);
type = prototype->get_type();
sub_type = prototype->get_sub_type();
ASSERT_EQ(type, MMI_NODE_TYPE_SOURCE);
- ASSERT_EQ(std::get<mmi_node_source_type_e>(sub_type), MMI_NODE_SOURCE_TYPE_MIC_AMBIENT);
-
- prototype->set_type(MMI_NODE_TYPE_PROCESSOR);
- prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR);
- type = prototype->get_type();
- sub_type = prototype->get_sub_type();
- ASSERT_EQ(type, MMI_NODE_TYPE_PROCESSOR);
- ASSERT_EQ(std::get<mmi_node_processor_type_e>(sub_type), MMI_NODE_PROCESSOR_TYPE_ASR);
+ ASSERT_EQ(std::get<mmi_node_source_type_e>(sub_type), MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER);
prototype->set_type(MMI_NODE_TYPE_LOGIC);
prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
ASSERT_EQ(type, MMI_NODE_TYPE_LOGIC);
ASSERT_EQ(std::get<mmi_node_logic_type_e>(sub_type), MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
+ prototype->set_type(MMI_NODE_TYPE_ACTION);
+ prototype->set_sub_type(MMI_NODE_ACTION_TYPE_KEY_EVENT);
+ type = prototype->get_type();
+ sub_type = prototype->get_sub_type();
+ ASSERT_EQ(type, MMI_NODE_TYPE_ACTION);
+ ASSERT_EQ(std::get<mmi_node_action_type_e>(sub_type), MMI_NODE_ACTION_TYPE_KEY_EVENT);
+
prototype->set_type(MMI_NODE_TYPE_CUSTOM);
prototype->set_sub_type("com.samsung.tizen.custom-node-llm");
type = prototype->get_type();
bool ret = registry.load_node_prototypes();
ASSERT_TRUE(ret);
- auto asr_node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR);
- ASSERT_NE(nullptr, asr_node);
-
auto match_node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
ASSERT_NE(nullptr, match_node);
+ auto key_event_node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_ACTION, MMI_NODE_ACTION_TYPE_KEY_EVENT);
+ ASSERT_NE(nullptr, key_event_node);
+
registry.deinitialize();
}
bool ret = registry.load_node_prototypes();
ASSERT_TRUE(ret);
- auto node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_NONE);
+ auto node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_ACTION, MMI_NODE_PROCESSOR_TYPE_NONE);
ASSERT_EQ(nullptr, node);
registry.deinitialize();
bool ret = registry.load_workflow_prototypes();
ASSERT_TRUE(ret);
- auto workflow = workflow_prototype_store->get_workflow_prototype(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ auto workflow = workflow_prototype_store->get_workflow_prototype(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
ASSERT_NE(nullptr, workflow);
registry.deinitialize();
NodeInstanceManagerDummy() {
node_prototype_store = std::make_shared<NodePrototypeStoreDummy>();
- auto mic_prototype = std::make_shared<NodePrototype>();
- mic_prototype->set_type(MMI_NODE_TYPE_SOURCE);
- mic_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT);
- PortInfo mic_audio{"AUDIO", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_AUDIO, "audio data"};
- mic_prototype->add_port_info(mic_audio);
- node_prototype_store->add_node_prototype(mic_prototype);
-
- auto asr_prototype = std::make_shared<NodePrototype>();
- asr_prototype->set_type(MMI_NODE_TYPE_PROCESSOR);
- asr_prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR);
- PortInfo asr_audio{"AUDIO", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_AUDIO, "audio data"};
- asr_prototype->add_port_info(asr_audio);
- node_prototype_store->add_node_prototype(asr_prototype);
+ auto screen_analyzer_prototype = std::make_shared<NodePrototype>();
+ screen_analyzer_prototype->set_type(MMI_NODE_TYPE_SOURCE);
+ screen_analyzer_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER);
+ PortInfo mic_audio{"SCREEN_INFO", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_TEXT, "screen info"};
+ screen_analyzer_prototype->add_port_info(mic_audio);
+ node_prototype_store->add_node_prototype(screen_analyzer_prototype);
+
+ auto match_prototype = std::make_shared<NodePrototype>();
+ match_prototype->set_type(MMI_NODE_TYPE_LOGIC);
+ match_prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
+ PortInfo asr_audio{"TEXT", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_TEXT, "text data"};
+ match_prototype->add_port_info(asr_audio);
+ node_prototype_store->add_node_prototype(match_prototype);
}
virtual std::shared_ptr<NodeInstance> create_node_instance(
ClientMessageWorkflowInstanceCreate msg;
msg.sender = std::string{"client-1"};
msg.local_workflow_instance_id = 0;
- msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&msg));
ClientMessageWorkflowInstanceCreate msg;
msg.sender = std::string{"client-1"};
msg.local_workflow_instance_id = 0;
- msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&msg));
ClientMessageWorkflowInstanceCreate msg;
msg.sender = std::string{"client-1"};
msg.local_workflow_instance_id = 0;
- msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&msg));
ASSERT_EQ(node_instance_manager->create_requests.size(), 0);
auto prototype = std::make_shared<WorkflowPrototype>();
- prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
/* Add 2 nodes to the workflow prototype */
prototype->add_node_info(mmi::NodeInfo{
- "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT});
+ "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER});
prototype->add_node_info(mmi::NodeInfo{
- "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR});
+ "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH});
workflow_prototype_store->add_workflow_prototype(prototype);
ClientMessageWorkflowInstanceCreate msg;
msg.sender = std::string{"client-1"};
msg.local_workflow_instance_id = 0;
- msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&msg));
TEST_F(WorkflowInstanceManagerTest, NodeInstanceDestroyRequestedOnWorkflowDestruction_p) {
auto prototype = std::make_shared<WorkflowPrototype>();
- prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
/* Add 2 nodes to the workflow prototype */
prototype->add_node_info(mmi::NodeInfo{
- "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT});
+ "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER});
prototype->add_node_info(mmi::NodeInfo{
- "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR});
+ "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH});
workflow_prototype_store->add_workflow_prototype(prototype);
ClientMessageWorkflowInstanceCreate create_msg;
create_msg.sender = std::string{"client-1"};
create_msg.local_workflow_instance_id = 0;
- create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&create_msg));
TEST_F(WorkflowInstanceManagerTest, NodeInstanceDestroyRequestedOnClientDisconnection_p) {
auto prototype = std::make_shared<WorkflowPrototype>();
- prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
/* Add 2 nodes to the workflow prototype */
prototype->add_node_info(mmi::NodeInfo{
- "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT});
+ "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER});
prototype->add_node_info(mmi::NodeInfo{
- "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR});
+ "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH});
workflow_prototype_store->add_workflow_prototype(prototype);
ClientMessageWorkflowInstanceCreate create_msg;
create_msg.sender = std::string{"client-1"};
create_msg.local_workflow_instance_id = 0;
- create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&create_msg));
TEST_F(WorkflowInstanceManagerTest, LinkCreatedIfLinkInfoIsProvided_p) {
auto prototype = std::make_shared<WorkflowPrototype>();
- prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
/* Add 2 nodes to the workflow prototype */
prototype->add_node_info(mmi::NodeInfo{
- "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT});
+ "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER});
prototype->add_node_info(mmi::NodeInfo{
- "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR});
+ "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH});
prototype->add_link_info(mmi::LinkInfo{
- "MIC", "AUDIO", "ASR", "AUDIO"});
+ "SCREEN_ANALYZER", "SCREEN_INFO", "MATCH", "TEXT"});
workflow_prototype_store->add_workflow_prototype(prototype);
ClientMessageWorkflowInstanceCreate create_msg;
create_msg.sender = std::string{"client-1"};
create_msg.local_workflow_instance_id = 0;
- create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&create_msg));
TEST_F(WorkflowInstanceManagerTest, LinkNotCreatedIfLinkInfoIsNotProvided_n) {
auto prototype = std::make_shared<WorkflowPrototype>();
- prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
/* Add 2 nodes to the workflow prototype */
prototype->add_node_info(mmi::NodeInfo{
- "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT});
+ "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER});
prototype->add_node_info(mmi::NodeInfo{
- "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR});
+ "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH});
workflow_prototype_store->add_workflow_prototype(prototype);
ClientMessageWorkflowInstanceCreate create_msg;
create_msg.sender = std::string{"client-1"};
create_msg.local_workflow_instance_id = 0;
- create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&create_msg));
TEST_F(WorkflowInstanceManagerTest, LinkNotCreatedIfPortNameIsInvalid_n) {
auto prototype = std::make_shared<WorkflowPrototype>();
- prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
/* Add 2 nodes to the workflow prototype */
prototype->add_node_info(mmi::NodeInfo{
- "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT});
+ "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER});
prototype->add_node_info(mmi::NodeInfo{
- "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR});
+ "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH});
prototype->add_link_info(mmi::LinkInfo{
- "MIC", "UNKNOWN_PORT", "ASR", "AUDIO"});
+ "SCREEN_ANALYZER", "UNKNOWN_PORT", "MATCH", "TEXT"});
workflow_prototype_store->add_workflow_prototype(prototype);
ClientMessageWorkflowInstanceCreate create_msg;
create_msg.sender = std::string{"client-1"};
create_msg.local_workflow_instance_id = 0;
- create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&create_msg));
TEST_F(WorkflowInstanceManagerTest, LinkNotCreatedIfNodeNameIsInvalid_n) {
auto prototype = std::make_shared<WorkflowPrototype>();
- prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
/* Add 2 nodes to the workflow prototype */
prototype->add_node_info(mmi::NodeInfo{
- "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT});
+ "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER});
prototype->add_node_info(mmi::NodeInfo{
- "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR});
+ "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH});
prototype->add_link_info(mmi::LinkInfo{
- "UNKNOWN_NODE", "AUDIO", "ASR", "AUDIO"});
+ "UNKNOWN_NODE", "SCREEN_INFO", "MATCH", "TEXT"});
workflow_prototype_store->add_workflow_prototype(prototype);
ClientMessageWorkflowInstanceCreate create_msg;
create_msg.sender = std::string{"client-1"};
create_msg.local_workflow_instance_id = 0;
- create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND;
+ create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH;
channel.notify_observers(
COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast<Message*>(&create_msg));
mmi_primitive_value_destroy(value);
auto prototype = std::make_shared<WorkflowPrototype>();
- prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
/* Add 2 nodes to the workflow prototype */
prototype->add_node_info(mmi::NodeInfo{
- "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT});
+ "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER});
prototype->add_node_info(mmi::NodeInfo{
- "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR});
+ "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH});
AttributeAssignmentInfo attribute_assignment_info;
- attribute_assignment_info.attribute_name = "COMMAND";
- attribute_assignment_info.target_node_name = "ASR";
- attribute_assignment_info.target_attribute_name = "CANDIDATE";
+ attribute_assignment_info.attribute_name = "CANDIDATES";
+ attribute_assignment_info.target_node_name = "MATCH";
+ attribute_assignment_info.target_attribute_name = "CANDIDATES";
prototype->add_attribute_assignment_info(attribute_assignment_info);
prototype->add_attribute_default_value_info(attribute_default_value_info);
NodeInstanceManagerDummy() {
node_prototype_store = std::make_shared<NodePrototypeStoreDummy>();
- auto mic_prototype = std::make_shared<NodePrototype>();
- mic_prototype->set_type(MMI_NODE_TYPE_SOURCE);
- mic_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT);
- PortInfo mic_audio{"AUDIO", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_AUDIO, "audio data"};
- mic_prototype->add_port_info(mic_audio);
- node_prototype_store->add_node_prototype(mic_prototype);
-
- auto asr_prototype = std::make_shared<NodePrototype>();
- asr_prototype->set_type(MMI_NODE_TYPE_PROCESSOR);
- asr_prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR);
- PortInfo asr_audio{"AUDIO", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_AUDIO, "audio data"};
- asr_prototype->add_port_info(asr_audio);
- node_prototype_store->add_node_prototype(asr_prototype);
+ auto screen_analyzer_prototype = std::make_shared<NodePrototype>();
+ screen_analyzer_prototype->set_type(MMI_NODE_TYPE_SOURCE);
+ screen_analyzer_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER);
+ PortInfo screen_info{"SCREEN_INFO", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_TEXT, "screen info"};
+ screen_analyzer_prototype->add_port_info(screen_info);
+ node_prototype_store->add_node_prototype(screen_analyzer_prototype);
+
+ auto match_prototype = std::make_shared<NodePrototype>();
+ match_prototype->set_type(MMI_NODE_TYPE_LOGIC);
+ match_prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
+ PortInfo match_text{"TEXT", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_TEXT, "text data"};
+ match_prototype->add_port_info(match_text);
+ node_prototype_store->add_node_prototype(match_prototype);
}
virtual std::shared_ptr<NodeInstance> create_node_instance(
void SetUp() override {
workflow_instance = std::make_shared<WorkflowInstance>();
if (workflow_instance) {
- workflow_instance->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ workflow_instance->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
workflow_instance->set_workflow_prototype_store(workflow_prototype_store);
workflow_instance->set_plugin_module_proxy_provider(plugin_module_proxy_provider);
mmi_primitive_value_h value = nullptr;
mmi_primitive_value_create_string("Hello", &value);
mmi_attribute_h attribute = nullptr;
- mmi_attribute_create(value, "COMMAND", &attribute);
+ mmi_attribute_create(value, "CANDIDATES", &attribute);
EXPECT_TRUE(workflow_instance->set_attribute(attribute));
- EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_PROCESSOR);
- EXPECT_TRUE(std::holds_alternative<mmi_node_processor_type_e>(g_last_node_attribute_set_history.m_sub_type));
- EXPECT_EQ(std::get<mmi_node_processor_type_e>(g_last_node_attribute_set_history.m_sub_type),
- MMI_NODE_PROCESSOR_TYPE_ASR);
+ EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_LOGIC);
+ EXPECT_TRUE(std::holds_alternative<mmi_node_logic_type_e>(g_last_node_attribute_set_history.m_sub_type));
+ EXPECT_EQ(std::get<mmi_node_logic_type_e>(g_last_node_attribute_set_history.m_sub_type),
+ MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
EXPECT_TRUE(g_last_node_attribute_set_history.m_attribute != nullptr);
mmi_primitive_value_h history_item_value;
workflow_instance.reset();
workflow_instance = std::make_shared<WorkflowInstance>();
if (workflow_instance) {
- workflow_instance->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ workflow_instance->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
workflow_instance->set_workflow_prototype_store(workflow_prototype_store);
workflow_instance->set_plugin_module_proxy_provider(plugin_module_proxy_provider);
mmi_attribute_h attribute = nullptr;
mmi_attribute_create(value, "COMMAND", &attribute);
EXPECT_TRUE(workflow_instance->set_attribute(attribute));
- EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_PROCESSOR);
- EXPECT_TRUE(std::holds_alternative<mmi_node_processor_type_e>(g_last_node_attribute_set_history.m_sub_type));
- EXPECT_EQ(std::get<mmi_node_processor_type_e>(g_last_node_attribute_set_history.m_sub_type),
- MMI_NODE_PROCESSOR_TYPE_ASR);
+ EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_LOGIC);
+ EXPECT_TRUE(std::holds_alternative<mmi_node_logic_type_e>(g_last_node_attribute_set_history.m_sub_type));
+ EXPECT_EQ(std::get<mmi_node_logic_type_e>(g_last_node_attribute_set_history.m_sub_type),
+ MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
EXPECT_TRUE(g_last_node_attribute_set_history.m_attribute != nullptr);
mmi_primitive_value_h history_item_value;
EXPECT_NE(workflow_instance, nullptr);
workflow_instance->initialize();
- EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_PROCESSOR);
- EXPECT_TRUE(std::holds_alternative<mmi_node_processor_type_e>(g_last_node_attribute_set_history.m_sub_type));
- EXPECT_EQ(std::get<mmi_node_processor_type_e>(g_last_node_attribute_set_history.m_sub_type),
- MMI_NODE_PROCESSOR_TYPE_ASR);
+ EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_LOGIC);
+ EXPECT_TRUE(std::holds_alternative<mmi_node_logic_type_e>(g_last_node_attribute_set_history.m_sub_type));
+ EXPECT_EQ(std::get<mmi_node_logic_type_e>(g_last_node_attribute_set_history.m_sub_type),
+ MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
EXPECT_TRUE(g_last_node_attribute_set_history.m_attribute != nullptr);
mmi_primitive_value_h history_item_value;
EXPECT_NE(workflow_instance, nullptr);
workflow_instance->initialize();
- EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_PROCESSOR);
- EXPECT_TRUE(std::holds_alternative<mmi_node_processor_type_e>(g_last_node_attribute_set_history.m_sub_type));
- EXPECT_EQ(std::get<mmi_node_processor_type_e>(g_last_node_attribute_set_history.m_sub_type),
- MMI_NODE_PROCESSOR_TYPE_ASR);
+ EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_LOGIC);
+ EXPECT_TRUE(std::holds_alternative<mmi_node_logic_type_e>(g_last_node_attribute_set_history.m_sub_type));
+ EXPECT_EQ(std::get<mmi_node_logic_type_e>(g_last_node_attribute_set_history.m_sub_type),
+ MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH);
EXPECT_TRUE(g_last_node_attribute_set_history.m_attribute != nullptr);
char *name = nullptr;
prototype->set_plugin_module_info(
PluginModuleInfo{mmi_plugin_module_type_e::SHARED_LIBRARY, "test.so"});
- prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
ASSERT_TRUE(prototype->is_valid());
}
wait_until_connected(1000);
mmi_workflow_instance_h instance = nullptr;
- res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND, &instance);
+ res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_VOICE_TOUCH, &instance);
EXPECT_EQ(res, MMI_ERROR_NONE);
res = mmi_unset_state_changed_cb(state_changed_cb);
wait_until_connected(1000);
mmi_workflow_instance_h instance = nullptr;
- res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND, &instance);
+ res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_VOICE_TOUCH, &instance);
EXPECT_EQ(res, MMI_ERROR_NONE);
mmi_attribute_h attribute = nullptr;
wait_until_connected(1000);
mmi_workflow_instance_h instance = nullptr;
- res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND, &instance);
+ res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_VOICE_TOUCH, &instance);
EXPECT_EQ(res, MMI_ERROR_NONE);
res = mmi_workflow_instance_activate(instance);
#include <gmock/gmock.h>
#include <mmi-workflow.h>
-#include <mmi-node-source.h>
-#include <mmi-node-processor.h>
-#include <mmi-node-logic.h>
+#include <mmi-node-types.h>
#include "mmi-workflow-script-parser.h"
void SetUp(void) override {
mmi_workflow_create(&m_workflow);
- mmi_workflow_set_type(m_workflow, MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ mmi_workflow_set_type(m_workflow, MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
- m_node_mic = nullptr;
+ m_node_screen_analyzer = nullptr;
/* FIXME: node should be 'found' instead of 'created' */
- mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &m_node_mic);
- mmi_workflow_node_add(m_workflow, "MIC", m_node_mic);
-
- m_node_asr = nullptr;
- mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &m_node_asr);
- mmi_workflow_node_add(m_workflow, "ASR", m_node_asr);
+ mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &m_node_screen_analyzer);
+ mmi_workflow_node_add(m_workflow, "SCREEN_ANALYZER", m_node_screen_analyzer);
m_node_match = nullptr;
mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &m_node_match);
mmi_workflow_node_add(m_workflow, "MATCH", m_node_match);
- mmi_workflow_link_nodes_by_names(m_workflow, "MIC", "AUDIO", "ASR", "AUDIO");
- mmi_workflow_link_nodes_by_names(m_workflow, "ASR", "FINAL_RESULT", "MATCH", "TEXT");
+ m_node_key_event = nullptr;
+ mmi_node_create_action(MMI_NODE_ACTION_TYPE_KEY_EVENT, &m_node_key_event);
+ mmi_workflow_node_add(m_workflow, "KEY_EVENT", m_node_key_event);
+
+ mmi_workflow_link_nodes_by_names(m_workflow, "SCREEN_ANALYZER", "SCREEN_INFO", "MATCH", "TEXT");
+ mmi_workflow_link_nodes_by_names(m_workflow, "MATCH", "MATCHED_CANDIDATE", "KEY_EVENT", "KEY_EVENT");
mmi_workflow_attribute_assign(m_workflow, "COMMANDS", "MATCH", "CANDIDATES");
}
void TearDown(void) override {
+ mmi_node_destroy(m_node_key_event);
mmi_node_destroy(m_node_match);
- mmi_node_destroy(m_node_asr);
- mmi_node_destroy(m_node_mic);
+ mmi_node_destroy(m_node_screen_analyzer);
mmi_workflow_destroy(m_workflow);
}
mmi_workflow_h m_workflow{nullptr};
- mmi_node_h m_node_mic{nullptr};
- mmi_node_h m_node_asr{nullptr};
+ mmi_node_h m_node_screen_analyzer{nullptr};
mmi_node_h m_node_match{nullptr};
+ mmi_node_h m_node_key_event{nullptr};
};
static bool compare_workflow_prototype(mmi_workflow_h first, mmi_workflow_h second) {
mmi_workflow_create(&workflow);
- mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND);
+ mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_VOICE_TOUCH);
- mmi_node_h node_mic = nullptr;
+ mmi_node_h node_screen_analyzer = nullptr;
/* FIXME: node should be 'found' instead of 'created' */
- mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic);
- mmi_workflow_node_add(workflow, "MIC", node_mic);
-
- mmi_node_h node_asr = nullptr;
- mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr);
- mmi_workflow_node_add(workflow, "ASR", node_asr);
+ mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &node_screen_analyzer);
+ mmi_workflow_node_add(workflow, "SCREEN_ANALYZER", node_screen_analyzer);
mmi_node_h node_match = nullptr;
mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match);
mmi_workflow_node_add(workflow, "MATCH", node_match);
- mmi_workflow_link_nodes_by_names(workflow, "MIC", "AUDIO", "ASR", "AUDIO");
- mmi_workflow_link_nodes_by_names(workflow, "ASR", "FINAL_RESULT", "MATCH", "TEXT");
+ mmi_node_h node_key_event = nullptr;
+ mmi_node_create_action(MMI_NODE_ACTION_TYPE_KEY_EVENT, &node_key_event);
+ mmi_workflow_node_add(workflow, "KEY_EVENT", node_key_event);
+
+ mmi_workflow_link_nodes_by_names(workflow, "SCREEN_ANALYZER", "SCREEN_INFO", "MATCH", "TEXT");
+ mmi_workflow_link_nodes_by_names(workflow, "MATCH", "MATCHED_CANDIDATE", "ACTION", "KEY_EVENT");
mmi_workflow_attribute_assign(workflow, "COMMANDS", "MATCH", "CANDIDATES");
EXPECT_TRUE(compare_workflow_prototype(m_workflow, workflow));
+ mmi_node_destroy(node_key_event);
mmi_node_destroy(node_match);
- mmi_node_destroy(node_asr);
- mmi_node_destroy(node_mic);
+ mmi_node_destroy(node_screen_analyzer);
mmi_workflow_destroy(workflow);
}
mmi_workflow_clone(m_workflow, &workflow);
- mmi_node_h node_regex_match = nullptr;
- mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_REGEX_STRING_MATCH, &node_regex_match);
- mmi_workflow_node_add(workflow, "REGEX_MATCH", node_regex_match);
+ mmi_node_h node_click_event = nullptr;
+ mmi_node_create_action(MMI_NODE_ACTION_TYPE_MOUSE_EVENT, &node_click_event);
+ mmi_workflow_node_add(workflow, "MOUSE_EVENT", node_click_event);
EXPECT_FALSE(compare_workflow_prototype(m_workflow, workflow));
- mmi_node_destroy(node_regex_match);
+ mmi_node_destroy(node_click_event);
mmi_workflow_destroy(workflow);
}
@node-list
[Source] MIC_AMBIENT as MIC
-[Processor] ASR as ASR
[Logic] FIXED_STRING_MATCH as MATCH
+[Action] KEY_EVENT as KEY_EVENT
@link-list
-MIC.AUDIO -> ASR.AUDIO
-ASR.FINAL_RESULT -> MATCH.TEXT
+MIC.AUDIO -> MATCH.TEXT
+MATCH.MATCHED_CANDIDATES -> KEY_EVENT.KEY_EVENT
@attribute-list
MATCH.CANDIDATES as COMMANDS