Add ControlInfo parse 91/213591/2
authorGilbok Lee <gilbok.lee@samsung.com>
Mon, 9 Sep 2019 05:40:42 +0000 (14:40 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Mon, 9 Sep 2019 05:52:21 +0000 (14:52 +0900)
Change-Id: I63f784bcd8701c260c8feb89286f00abf2e4e83d

include/rose_tizen.h
include/rose_tizen_ctlinfo_parse.h [new file with mode: 0644]
include/rose_tizen_parse_xml.h
include/rose_tizen_priv.h
packaging/capi-media-rose-tizen.spec
src/rose_tizen.c
src/rose_tizen_ctlinfo_parse.c [new file with mode: 0644]
src/rose_tizen_parse_xml.c
test/rose_tizen_test.c

index c84ee48cb650428755e88116f2924501421c3499..dd96ee5f66a9a28525e9bcfe206d58492c17a783 100644 (file)
@@ -37,6 +37,7 @@ typedef enum {
        ROSE_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */
        ROSE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED,         /**< Not supported */
        ROSE_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+       ROSE_ERROR_INVALID_STATE,
 } rose_error;
 
 typedef enum {
@@ -67,6 +68,7 @@ int rose_get_play_position(rose_h rose, int *msec);
 int rose_set_display(rose_h rose, rose_display_type_e type, void *display);
 int rose_set_sem_path(rose_h rose, const char *path);
 int rose_set_media_path(rose_h rose, const char *path);
+int rose_set_control_info_path(rose_h rose, const char *path);
 
 #ifdef __cplusplus
 }
diff --git a/include/rose_tizen_ctlinfo_parse.h b/include/rose_tizen_ctlinfo_parse.h
new file mode 100644 (file)
index 0000000..29892fc
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+* Copyright (c) 2019 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_MEDIA_ROSE_CTLINFO_H__
+#define __TIZEN_MEDIA_ROSE_CTLINFO_H__
+
+#include <glib.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _rose_control_info rose_control_info;
+typedef struct _rose_sdc_element rose_sdc_element;
+
+typedef struct _rose_sdc_namespace rose_sdc_namespace;
+typedef struct _rose_sdc_light rose_sdc_light;
+typedef struct _rose_sdc_flash rose_sdc_flash;
+typedef struct _rose_sdc_wind rose_sdc_wind;
+typedef struct _rose_sdc_vibration rose_sdc_vibration;
+
+
+/* Sensory Device Capabilitye type */
+typedef enum {
+       SDC_TYPE_NONE,
+       SDC_TYPE_LIGHT,
+       SDC_TYPE_FLASH,
+       SDC_TYPE_WIND,
+       SDC_TYPE_VIBRATION,
+       SDC_TYPE_MAX,
+} rose_sdc_type_e;
+
+struct _rose_sdc_light {
+       gboolean color_flag;
+       gboolean unit_flag;
+       gboolean max_intensity_flag;
+       gboolean num_of_light_levels_flag;
+
+       GList *color;
+       gchar *unit;
+       guint max_intensity;
+       guint num_of_light_levels;
+};
+
+struct _rose_sdc_flash {
+       gboolean max_freq_flag;
+       gboolean num_of_freq_levels_flag;
+       rose_sdc_light *light;
+       gint max_freq;
+       guint num_of_freq_levels;
+};
+
+struct _rose_sdc_wind {
+       gboolean unit_flag;
+       gboolean max_wind_speed_flag;
+       gboolean num_of_levels_flag;
+
+       gchar *unit;
+       guint max_wind_speed;
+       guint num_of_levels;
+};
+
+struct _rose_sdc_vibration {
+       gboolean unit_flag;
+       gboolean max_intensity_flag;
+       gboolean num_of_levels_flag;
+
+       gchar *unit;
+       guint max_intensity;
+       guint num_of_levels;
+};
+
+struct _rose_sdc_namespace {
+       gchar *prefix;
+       gchar *href;
+};
+
+struct _rose_sdc_element {
+       gboolean zerothorderdelaytime_flag;
+       gboolean firstorderdelaytime_flag;
+       gchar *id;
+
+       rose_sdc_type_e sdc_type;
+
+       /* zerothOrderDealyTime (ms) */
+       guint zerothorderdelaytime;
+       /* firstOrderDealyTime (ms) */
+       guint firstorderdelaytime;
+
+       rose_sdc_light *light;
+       rose_sdc_flash *flash;
+       rose_sdc_wind *wind;
+       rose_sdc_vibration *vibration;
+};
+
+struct _rose_control_info {
+       GList *namespace;
+       /* rose_sdc_element */
+       GList *sdc_elements;
+};
+
+int rose_ctl_info_parse(xmlNode * a_node, rose_control_info ** ctl_info);
+void rose_ctl_info_free(rose_control_info * ctl_info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_MEDIA_ROSE_CTLINFO_H__ */
index e1c2b6a1ffbff4b91cdf6cbb9239e7e55f01fef6..4948190a54f6025d392a7ba312920f44eb3438c0 100644 (file)
@@ -27,6 +27,7 @@ extern "C" {
 /* Property parsing */
 gboolean _get_xml_prop_string(xmlNode * node, const gchar * prop_name, gchar ** prop_value);
 gboolean _get_xml_prop_boolean(xmlNode * node, const gchar * prop_name, gboolean * prop_value);
+gboolean _get_xml_prop_signed_integer(xmlNode * node, const gchar * prop_name, gint * prop_value);
 gboolean _get_xml_prop_unsigned_integer(xmlNode * node, const gchar * prop_name, guint * prop_value);
 gboolean _get_xml_prop_float(xmlNode * node, const gchar * prop_name, gfloat * prop_value);
 
index 22e93673cb4b7a4c3be845055c245a929e8a43ce..ec38c836492c09490924a658a542e9e9464d0440 100644 (file)
@@ -21,6 +21,7 @@
 #include <dlog.h>
 #include "rose_tizen.h"
 #include "rose_tizen_sem_parse.h"
+#include "rose_tizen_ctlinfo_parse.h"
 #include "rose_tizen_mplayer_interface.h"
 
 #ifdef __cplusplus
@@ -70,6 +71,7 @@ typedef struct _rose_s {
        gchar *sem_path;
        gchar *media_path;
        rose_sem *sem;
+       rose_control_info *ctl_info;
        mplayer_interface *mplayer_intf;
 } rose_s;
 
index a694e9a4cce24d0941ead4d230d4f4999da9e6f9..723ee690c4f9757e458c50f2444697f36921d319 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-rose-tizen
 Summary:    For RoSE(Representation Of Sensory Effect) APIs
-Version:    0.0.2
+Version:    0.0.3
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 46f94d426041724aedef83fbda0bc38b03b30a64..8d7a5d7478551474528f6c5b043861961c461f32 100644 (file)
@@ -58,6 +58,11 @@ int rose_destroy(rose_h rose)
                handle->sem = NULL;
        }
 
+       if (handle->ctl_info) {
+               rose_ctl_info_free(handle->ctl_info);
+               handle->ctl_info = NULL;
+       }
+
        ret = _rose_mplayer_destroy(handle->mplayer_intf);
        if (ret) // need to check error handling
                LOGE("Failed to destroy mplayer handle %d", ret);
@@ -111,6 +116,50 @@ ERROR:
        return ret;
 }
 
+int rose_set_control_info_path(rose_h rose, const char *path)
+{
+       int ret = ROSE_ERROR_NONE;
+       rose_s *handle = (rose_s *) rose;
+       xmlDocPtr doc = NULL;
+       xmlNodePtr root_element = NULL;
+
+       ROSE_CHECK_INSTANCE(handle);
+       ROSE_CHECK_NULL(path);
+
+       SECURE_LOGD("input control info path is %s", path);
+       // need to check file path is valid
+
+       // check validate ControlInfo
+       doc = xmlReadFile(path, "UTF-8", 0);
+       if (!doc) {
+               LOGE("Failed to parse ControlInfo");
+               return ROSE_ERROR_INVALID_OPERATION;
+       }
+
+       root_element = xmlDocGetRootElement(doc);
+       if (!root_element) {
+               LOGE("Failed to get root element");
+               ret = ROSE_ERROR_INVALID_OPERATION;
+               goto ERROR;
+       }
+
+       if (root_element->type != XML_ELEMENT_NODE
+               || xmlStrstr(root_element->name, (xmlChar *) "ControlInfo") == NULL) {
+               LOGE("can not find the root element ControlInfo, failed to parse the ControlInfo file");
+               ret = ROSE_ERROR_INVALID_OPERATION;
+               goto ERROR;
+       }
+
+       ret = rose_ctl_info_parse(root_element, &handle->ctl_info);
+       if (ret != ROSE_ERROR_NONE)
+               LOGE("Failed to parse ControlInfo data");
+
+ERROR:
+       xmlFreeDoc(doc);
+
+       return ret;
+}
+
 int rose_set_media_path(rose_h rose, const char *path)
 {
        int ret = ROSE_ERROR_NONE;
diff --git a/src/rose_tizen_ctlinfo_parse.c b/src/rose_tizen_ctlinfo_parse.c
new file mode 100644 (file)
index 0000000..bc8393d
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+* Copyright (c) 2019 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 <string.h>
+#include "rose_tizen_priv.h"
+#include "rose_tizen_parse_xml.h"
+
+static gboolean _parse_namespace(xmlNode * node, rose_control_info *ctl_info);
+static void _free_namespace(rose_sdc_namespace * namespace);
+static gboolean _get_xml_prop_sdc_type(xmlNode * node,
+       const gchar * property_name, rose_sdc_type_e * property_value);
+
+static gboolean _parse_sdc_element(xmlNode * node, rose_control_info *ctl_info);
+static gboolean _parse_sdc_list(xmlNode * node, rose_control_info *ctl_info);
+static gboolean _parse_sdc_light_type(xmlNode * node, rose_sdc_light **light);
+static gboolean _parse_sdc_flash_type(xmlNode * node, rose_sdc_flash **flash);
+static gboolean _parse_sdc_wind_type(xmlNode * node, rose_sdc_wind **wind);
+static gboolean _parse_sdc_vibration_type(xmlNode * node, rose_sdc_vibration **vibration);
+
+static void _free_sdc_element(rose_sdc_element * sdc_element);
+static void _free_sdc_light_type(rose_sdc_light *light);
+static void _free_sdc_flash_type(rose_sdc_flash *flash);
+static void _free_sdc_wind_type(rose_sdc_wind *wind);
+static void _free_sdc_vibration_type(rose_sdc_vibration *vibration);
+
+static gboolean _parse_namespace(xmlNode * node, rose_control_info *ctl_info)
+{
+       xmlNs *curr_ns;
+       gboolean exist = FALSE;
+
+       if (!ctl_info || !node)
+               return FALSE;
+
+       g_list_free_full(ctl_info->namespace, (GDestroyNotify) _free_namespace);
+
+       for (curr_ns = node->ns; curr_ns; curr_ns = curr_ns->next) {
+               if (curr_ns->prefix && curr_ns->href) {
+                       rose_sdc_namespace *namespace = g_slice_new0(rose_sdc_namespace);
+                       namespace->prefix = xmlMemStrdup((const gchar *)curr_ns->prefix);
+                       namespace->href = xmlMemStrdup((const gchar *)curr_ns->href);
+                       LOGD(" - %s namespace: %s", curr_ns->prefix, curr_ns->href);
+                       ctl_info->namespace = g_list_append(ctl_info->namespace, namespace);
+                       exist = TRUE;
+               }
+       }
+
+       return exist;
+}
+
+static void _free_namespace(rose_sdc_namespace * namespace)
+{
+       if (!namespace)
+               return;
+
+       if (namespace->prefix)
+               xmlFree(namespace->prefix);
+       if (namespace->href)
+               xmlFree(namespace->href);
+
+       g_slice_free(rose_sdc_namespace, namespace);
+}
+
+int rose_ctl_info_parse(xmlNode * node, rose_control_info ** ctl_info)
+{
+       xmlNode *cur_node;
+       rose_control_info * new_ctl_info;
+       int ret = ROSE_ERROR_NONE;
+       gboolean exist = FALSE;
+
+       rose_ctl_info_free(*ctl_info);
+       *ctl_info = NULL;
+
+       new_ctl_info = g_slice_new0(rose_control_info);
+
+       LOGD("namespaces of root ControlInfo node:");
+       exist |= _parse_namespace(node, new_ctl_info);
+
+       for (cur_node = node->children; cur_node; cur_node = cur_node->next) {
+               if (cur_node->type != XML_ELEMENT_NODE)
+                       continue;
+
+               if (xmlStrstr(cur_node->name, (xmlChar *) "SensoryDeviceCapabilityList")) {
+                       LOGD("Parsing SensoryDeviceCapabilityList");
+                       _parse_sdc_list(cur_node, new_ctl_info);
+               } else {
+                       /* now ctlinfo parse sdc list */
+                       LOGW("there is no node in ControlInfo");
+               }
+       }
+
+       if (!exist) {
+               LOGW("There is no Element");
+               g_slice_free(rose_control_info, new_ctl_info);
+               new_ctl_info = NULL;
+               ret = ROSE_ERROR_INVALID_OPERATION;
+       }
+
+       return ret;
+}
+
+static gboolean _parse_sdc_list(xmlNode * node, rose_control_info *ctl_info)
+{
+       gboolean exist = FALSE;
+       xmlNode *cur_node;
+
+       for (cur_node = node->children; cur_node; cur_node = cur_node->next) {
+               if (cur_node->type != XML_ELEMENT_NODE)
+                       continue;
+
+               if (xmlStrstr(cur_node->name, (xmlChar *) "SensoryDeviceCapability")) {
+                       LOGD("Parsing ReferenceEffect");
+                       exist |= _parse_sdc_element(cur_node, ctl_info);
+               } else {
+                       LOGI("%s is not support now", cur_node->name);
+               }
+       }
+
+       return exist;
+}
+
+static gboolean _parse_sdc_element(xmlNode * node, rose_control_info *ctl_info)
+{
+       rose_sdc_element *new_sdc_element = NULL;
+       gboolean exist = FALSE;
+
+       new_sdc_element = g_slice_new0(rose_sdc_element);
+
+       exist |= _get_xml_prop_string(node, "id", &new_sdc_element->id);
+
+       exist |= new_sdc_element->zerothorderdelaytime_flag
+                       = _get_xml_prop_unsigned_integer(node, "zerothOrderDelayTime",
+                                       &new_sdc_element->zerothorderdelaytime);
+
+       exist |= new_sdc_element->firstorderdelaytime_flag
+                       = _get_xml_prop_unsigned_integer(node, "firstOrderDelayTime",
+                                       &new_sdc_element->firstorderdelaytime);
+
+       exist |= _get_xml_prop_sdc_type(node, "type", &new_sdc_element->sdc_type);
+
+       if (new_sdc_element->sdc_type > SDC_TYPE_NONE) {
+               switch (new_sdc_element->sdc_type) {
+               case SDC_TYPE_LIGHT:
+                       exist |= _parse_sdc_light_type(node, &new_sdc_element->light);
+               case SDC_TYPE_FLASH:
+                       exist |= _parse_sdc_flash_type(node, &new_sdc_element->flash);
+                       break;
+               case SDC_TYPE_WIND:
+                       exist |= _parse_sdc_wind_type(node, &new_sdc_element->wind);
+                       break;
+               case SDC_TYPE_VIBRATION:
+                       exist |= _parse_sdc_vibration_type(node, &new_sdc_element->vibration);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if (!exist) {
+               g_slice_free(rose_sdc_element, new_sdc_element);
+               new_sdc_element = NULL;
+               return FALSE;
+       }
+
+       ctl_info->sdc_elements = g_list_append(ctl_info->sdc_elements, new_sdc_element);
+
+       return exist;
+}
+
+static gboolean _get_xml_prop_sdc_type(xmlNode * node, const gchar * property_name, rose_sdc_type_e * property_value)
+{
+       xmlChar *prop_string;
+       gboolean exists = TRUE;
+
+       ROSE_CHECK_NULL_FALSE(property_value);
+
+       *property_value = SDC_TYPE_NONE;
+       prop_string = xmlGetProp(node, (const xmlChar *)property_name);
+       if (!prop_string)
+               return FALSE;
+
+       if (xmlStrstr(prop_string, (xmlChar *) "LightCapabilityType")) {
+               *property_value = SDC_TYPE_LIGHT;
+               LOGD(" - %s: LightCapabilityType", property_name);
+       } else if (xmlStrstr(prop_string, (xmlChar *) "FlashCapabilityType")) {
+               *property_value = SDC_TYPE_FLASH;
+               LOGD(" - %s: FlashCapabilityType", property_name);
+       } else if (xmlStrstr(prop_string, (xmlChar *) "WindCapabilityType")) {
+               *property_value = SDC_TYPE_WIND;
+               LOGD(" - %s: WindCapabilityType", property_name);
+       } else if (xmlStrstr(prop_string, (xmlChar *) "VibrationCapabilityType")) {
+               *property_value = SDC_TYPE_VIBRATION;
+               LOGD(" - %s: VibrationCapabilityType", property_name);
+       } else {
+               exists = FALSE;
+               LOGW("failed to parse sdc type property %s from xml string %s", property_name, prop_string);
+       }
+
+       xmlFree(prop_string);
+
+       return exists;
+}
+
+static gboolean _parse_sdc_light_type(xmlNode * node, rose_sdc_light **light)
+{
+       rose_sdc_light *new_light = NULL;
+       gboolean exist = FALSE;
+       // xmlNode *cur_node;
+
+       new_light = g_slice_new0(rose_sdc_light);
+
+       exist |= new_light->unit_flag =
+               _get_xml_prop_string(node, "unit", &new_light->unit);
+
+       exist |= new_light->max_intensity_flag
+                       = _get_xml_prop_unsigned_integer(node, "maxIntensity",
+                                       &new_light->max_intensity);
+
+       exist |= new_light->num_of_light_levels_flag
+                       = _get_xml_prop_unsigned_integer(node, "numOfLightLevels",
+                                       &new_light->num_of_light_levels);
+#if 0
+/* need to check color element */
+       for (cur_node = node->children; cur_node; cur_node = cur_node->next) {
+               if (cur_node->type != XML_ELEMENT_NODE)
+                       continue;
+               if (xmlStrstr(cur_node->name, (xmlChar *) "Color")) {
+                       gchar *color = NULL;
+               }
+       }
+#endif
+       if (!exist) {
+               g_slice_free(rose_sdc_light, new_light);
+               new_light = NULL;
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean _parse_sdc_flash_type(xmlNode * node, rose_sdc_flash **flash)
+{
+       rose_sdc_flash *new_flash = NULL;
+       gboolean exist = FALSE;
+
+       new_flash = g_slice_new0(rose_sdc_flash);
+
+       exist |= new_flash->max_freq_flag
+                       = _get_xml_prop_signed_integer(node, "maxFrequency",
+                                       &new_flash->max_freq);
+
+       exist |= new_flash->num_of_freq_levels_flag
+                       = _get_xml_prop_unsigned_integer(node, "numOfFreqLevels",
+                                       &new_flash->num_of_freq_levels);
+       exist |= _parse_sdc_light_type (node, &new_flash->light);
+
+       if (!exist) {
+               g_slice_free(rose_sdc_flash, new_flash);
+               new_flash = NULL;
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean _parse_sdc_wind_type(xmlNode * node, rose_sdc_wind **wind)
+{
+       rose_sdc_wind *new_wind = NULL;
+       gboolean exist = FALSE;
+
+       new_wind = g_slice_new0(rose_sdc_wind);
+
+       exist |= new_wind->unit_flag =
+               _get_xml_prop_string(node, "unit", &new_wind->unit);
+
+       exist |= new_wind->max_wind_speed_flag
+                       = _get_xml_prop_unsigned_integer(node, "maxWindSpeed",
+                                       &new_wind->max_wind_speed);
+
+       exist |= new_wind->num_of_levels_flag
+                       = _get_xml_prop_unsigned_integer(node, "numOfLevels",
+                                       &new_wind->num_of_levels);
+
+       if (!exist) {
+               g_slice_free(rose_sdc_wind, new_wind);
+               new_wind = NULL;
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean _parse_sdc_vibration_type(xmlNode * node, rose_sdc_vibration **vibration)
+{
+       rose_sdc_vibration *new_vibration = NULL;
+       gboolean exist = FALSE;
+
+       new_vibration = g_slice_new0(rose_sdc_vibration);
+
+       exist |= new_vibration->unit_flag =
+               _get_xml_prop_string(node, "unit", &new_vibration->unit);
+
+       exist |= new_vibration->max_intensity_flag
+                       = _get_xml_prop_unsigned_integer(node, "maxIntensity",
+                                       &new_vibration->max_intensity);
+
+       exist |= new_vibration->num_of_levels_flag
+                       = _get_xml_prop_unsigned_integer(node, "numOfLevels",
+                                       &new_vibration->num_of_levels);
+
+       if (!exist) {
+               g_slice_free(rose_sdc_vibration, new_vibration);
+               new_vibration = NULL;
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static void _free_sdc_light_type(rose_sdc_light *light)
+{
+       if (!light)
+               return;
+       g_list_free_full(light->color, g_free);
+       g_free(light->unit);
+       g_slice_free(rose_sdc_light, light);
+}
+
+static void _free_sdc_flash_type(rose_sdc_flash *flash)
+{
+       if (!flash)
+               return;
+       _free_sdc_light_type(flash->light);
+       g_slice_free(rose_sdc_flash, flash);
+}
+
+static void _free_sdc_wind_type(rose_sdc_wind *wind)
+{
+       if (!wind)
+               return;
+       g_free(wind->unit);
+       g_slice_free(rose_sdc_wind, wind);
+}
+
+static void _free_sdc_vibration_type(rose_sdc_vibration *vibration)
+{
+       if (!vibration)
+               return;
+       g_free(vibration->unit);
+       g_slice_free(rose_sdc_vibration, vibration);
+}
+
+static void _free_sdc_element(rose_sdc_element * sdc_element)
+{
+       if (!sdc_element)
+               return;
+       g_free (sdc_element->id);
+       _free_sdc_light_type(sdc_element->light);
+       _free_sdc_flash_type(sdc_element->flash);
+       _free_sdc_wind_type(sdc_element->wind);
+       _free_sdc_vibration_type(sdc_element->vibration);
+
+       g_slice_free(rose_sdc_element, sdc_element);
+}
+
+void rose_ctl_info_free(rose_control_info * ctl_info)
+{
+       if (!ctl_info)
+               return;
+
+       g_list_free_full(ctl_info->namespace, (GDestroyNotify) _free_namespace);
+       g_list_free_full(ctl_info->sdc_elements, (GDestroyNotify) _free_sdc_element);
+
+       g_slice_free(rose_control_info, ctl_info);
+}
+
index 125bdaeb7e3dc3475ada1d0906c9035196413478..e8e5afd9f2069ef5977709d78b06014c4090c983 100644 (file)
@@ -56,6 +56,28 @@ gboolean _get_xml_prop_boolean(xmlNode * node, const gchar * prop_name, gboolean
        return exists;
 }
 
+gboolean _get_xml_prop_signed_integer(xmlNode * node, const gchar * prop_name, gint * prop_value)
+{
+       xmlChar *prop_string;
+       gboolean exists = TRUE;
+
+       prop_string = xmlGetProp(node, (const xmlChar *)prop_name);
+       if (!prop_string)
+               return FALSE;
+
+       if (sscanf((gchar *) prop_string, "%d", prop_value) == 1 && strstr((gchar *) prop_string, "-") == NULL) {
+               LOGD(" - %s: %u", prop_name, *prop_value);
+       } else {
+               exists = FALSE;
+               LOGW("failed to parse signed integer property %s from xml string %s", prop_name, prop_string);
+               /* sscanf might have written to *prop_value. Restore to default */
+       }
+
+       xmlFree(prop_string);
+
+       return exists;
+}
+
 gboolean _get_xml_prop_unsigned_integer(xmlNode * node, const gchar * prop_name, guint * prop_value)
 {
        xmlChar *prop_string;
index 731f6495ed34a02f36ac46155fc81aee30c40fae..3357da3c30cebef033320c3cc01a7022a8458277 100644 (file)
@@ -47,6 +47,7 @@ enum {
        CURRENT_STATUS_MAINMENU,
        CURRENT_STATUS_FILE_PATH,
        CURRENT_STATUS_SEM_FILE_PATH,
+       CURRENT_STATUS_CTL_INFO_FILE_PATH,
        CURRENT_STATUS_DISPLAY_SURFACE_CHANGE,
        CURRENT_STATUS_POSITION_TIME,
        CURRENT_STATUS_POSITION_ACCURATE,
@@ -295,6 +296,14 @@ int test_rose_set_sem_path(const char *path)
        return ret;
 }
 
+int test_rose_set_control_info_path(const char *path)
+{
+       int ret = 0;
+       LOGD("test_rose_set_control_info_path");
+       ret = rose_set_control_info_path(rose, path);
+       return ret;
+}
+
 int test_rose_set_media_path(const char *path)
 {
        int ret = 0;
@@ -382,7 +391,8 @@ static void display_sub_basic()
        g_print("ds. Set display \t");
        g_print("pr. Prepare \n");
        g_print("sm. Set media path \t");
-       g_print("ss. Set SEM path \n");
+       g_print("ss. Set SEM path \t");
+       g_print("sc. Set CTL info path \n");
        g_print("b. Play  \t");
        g_print("c. Stop  \t");
        g_print("e. Pause \n");
@@ -420,6 +430,8 @@ void _interpret_main_menu(char *cmd)
                        g_menu_state = CURRENT_STATUS_FILE_PATH;
                } else if (strncmp(cmd, "ss", 2) == 0) {
                        g_menu_state = CURRENT_STATUS_SEM_FILE_PATH;
+               } else if (strncmp(cmd, "sc", 2) == 0) {
+                       g_menu_state = CURRENT_STATUS_CTL_INFO_FILE_PATH;
                } else if (strncmp(cmd, "pr", 2) == 0) {
                        test_rose_prepare();
                } else if (strncmp(cmd, "un", 2) == 0) {
@@ -439,6 +451,8 @@ static void displaymenu(void)
                display_sub_basic();
        } else if (g_menu_state == CURRENT_STATUS_SEM_FILE_PATH) {
                g_print("*** input SEM path.\n");
+       } else if (g_menu_state == CURRENT_STATUS_CTL_INFO_FILE_PATH) {
+               g_print("*** input control info path.\n");
        } else if (g_menu_state == CURRENT_STATUS_FILE_PATH) {
                g_print("*** input media path.\n");
        } else if (g_menu_state == CURRENT_STATUS_DISPLAY_SURFACE_CHANGE) {
@@ -492,6 +506,15 @@ static void interpret(char *cmd)
                g_menu_state = CURRENT_STATUS_MAINMENU;
                break;
        }
+       case CURRENT_STATUS_CTL_INFO_FILE_PATH: {
+               int ret = 0;
+               ret = test_rose_set_control_info_path(cmd);
+               if (ret != ROSE_ERROR_NONE)
+                       g_print("failed parse CTL info\n");
+
+               g_menu_state = CURRENT_STATUS_MAINMENU;
+               break;
+       }
        case CURRENT_STATUS_DISPLAY_SURFACE_CHANGE: {
                value1 = atoi(cmd);
                change_surface(value1);