--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(unifiedstorage-format C)
+
+INCLUDE_DIRECTORIES(include)
+
+FILE(GLOB UNIFIED_STORAGE_FORMAT_API
+ include/unified_storage_accounts.h
+ include/unified_storage_utils.h
+ include/unified_storage_error_codes.h
+ include/unified_storage_log.h
+ include/unified_storage_format.h
+ include/unified_storage_format_log.h
+)
+
+FILE(GLOB UNIFIED_STORAGE_FORMAT_DB_MANAGER_API
+ include/db_manager/db_manager.h
+)
+
+FILE(GLOB UNIFIED_STORAGE_FORMAT_THUMBNAIL_MANAGER_API
+ include/thumbnail_manager/thumbnail_manager.h
+)
+
+FILE(GLOB UNIFIED_STORAGE_FORMAT_METADATA_MANAGER_API
+ include/metadata_manager/metadata_manager.h
+)
+
+FILE(GLOB SRCS src/*.c
+ src/db_manager/*.c
+ src/thumbnail_manager/*.c
+ src/metadata_manager/*.c)
+
+message("${PROJECT_NAME} Build target profile : ${TARGET_PROFILE_NAME}")
+if (TARGET_PROFILE_NAME STREQUAL "mobile")
+ message("mobile feature enable (UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE)")
+ add_definitions("-DUNIFIED_FORMAT_MOBILE_FEATURE_ENABLE")
+else()
+ message("Another profile")
+endif (TARGET_PROFILE_NAME STREQUAL "mobile")
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(BINDIR "/bin")
+SET(LIBDIR "/lib")
+SET(PCDIR "/lib/pkgconfig")
+SET(APIDIR "/include/unifiedstorage-format")
+ADD_DEFINITIONS("-DUNIFIED_STORAGE_ENABLED")
+ADD_DEFINITIONS("-DCLOUDBOX_ENABLED")
+
+IF(NOT DEFINED MANIFESTDIR)
+ SET(MANIFESTDIR "/opt/share/packages")
+ENDIF(NOT DEFINED MANIFESTDIR)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+ glib-2.0
+ capi-media-thumbnail-util
+ capi-media-metadata-extractor
+ capi-content-media-content
+ capi-media-image-util
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUNIFIED_STORAGE_FORMAT_DLL -DUNIFIED_STORAGE_FORMAT_DLL_EXPORTS")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -fvisibility=hidden -fPIC -D_GNU_SOURCE")
+SET(CMAKE_C_FLAGS_DEBUG "-g -fPIC")
+SET(CMAKE_C_FLAGS_RELEASE "-O2 -fPIC")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR})
+INSTALL(FILES ${UNIFIED_STORAGE_FORMAT_API} DESTINATION ${APIDIR})
+INSTALL(FILES ${UNIFIED_STORAGE_FORMAT_DB_MANAGER_API} DESTINATION ${APIDIR}/db_manager)
+INSTALL(FILES ${UNIFIED_STORAGE_FORMAT_THUMBNAIL_MANAGER_API} DESTINATION ${APIDIR}/thumbnail_manager)
+INSTALL(FILES ${UNIFIED_STORAGE_FORMAT_METADATA_MANAGER_API} DESTINATION ${APIDIR}/metadata_manager)
+
+CONFIGURE_FILE(unifiedstorage-format.pc.in ${CMAKE_BINARY_DIR}/unifiedstorage-format.pc @ONLY)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/unifiedstorage-format.pc DESTINATION ${PCDIR})
+
+# uninstall target
+CONFIGURE_FILE(
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ IMMEDIATE @ONLY)
+
+ADD_CUSTOM_TARGET(uninstall
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
--- /dev/null
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
--- /dev/null
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.Apache-2.0 file for Apache License terms and conditions.
--- /dev/null
+if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
+endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+
+file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+string(REGEX REPLACE "\n" ";" files "${files}")
+string(REGEX REPLACE ";$" "" files "${files}")
+list(REVERSE files)
+foreach (file ${files})
+ message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
+ if (EXISTS "$ENV{DESTDIR}${file}")
+ execute_process(
+ COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}"
+ OUTPUT_VARIABLE rm_out
+ RESULT_VARIABLE rm_retval
+ )
+ if(NOT ${rm_retval} EQUAL 0)
+ message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
+ endif (NOT ${rm_retval} EQUAL 0)
+ else (EXISTS "$ENV{DESTDIR}${file}")
+ message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
+ endif (EXISTS "$ENV{DESTDIR}${file}")
+endforeach(file)
+
--- /dev/null
+/*
+* Copyright (c) 2011 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 __DB_MANAGER_H__
+#define __DB_MANAGER_H__
+
+#include <glib.h>
+#include <stdint.h>
+
+#include "unified_storage_format.h"
+
+/**
+ * @brief Insert content information to media db
+ * @param content_info Content information
+ * @param media_uuid Media unique ID
+ * @return 0 on success, -1 otherwise
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int db_manager_insert_media_info(content_info_s* content_info, char** media_uuid);
+
+/**
+ * @brief Updates content information to media db
+ * @param content_info Content information
+ * @param media_uuid Media unique ID
+ * @return 0 on success, -1 otherwise
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int db_manager_update_media_info(content_info_s* content_info, char** media_uuid);
+
+/**
+ * @brief Deletes cloud file info from media db
+ * @param media_uuid Media unique ID
+ * @return 0 on success, -1 otherwise
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int db_manager_delete_media_info(const char* media_uuid);
+
+/**
+ * @brief Inserts storage information into Storage DB
+ * @param storage_id Storage ID
+ * @param storage_name Storage name
+ * @param default_path Default path
+ * @return 0 on success, -1 otherwise
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int db_manager_insert_storage_info(const char *storage_name, const char *default_path, const char *storage_account, char **storage_id);
+
+/**
+ * @brief Deletes storage information from Storage DB
+ * @param storage_id Storage ID
+ * @param storage_name Storage name
+ * @param default_path Default path
+ * @return 0 on success, -1 otherwise
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int db_manager_delete_storage_info(const char* storage_id);
+
+/**
+ * @brief Initialises DB Manager
+ * @return 0 on success, -1 otherwise
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int db_manager_init();
+
+/**
+ * @brief Deinitialises DB Manager
+ * @return 0 on success, -1 otherwise
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int db_manager_deinit();
+
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int db_manager_get_storage_uuid(const char* cloud_name, const char* cloud_account, char** storage_uuid);
+
+#endif /* __DB_MANAGER_H__ */
--- /dev/null
+/*
+* Copyright (c) 2011 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 __METADATA_MANAGER_H__
+#define __METADATA_MANAGER_H__
+
+#include "unified_storage_format.h"
+
+/**
+ * Read metadata from file and extract it to attribute_info_s structure.
+ * This function invokes metadata extractor library function in order to fetch
+ * meta information from given file and update the DB.
+ * @param file_path path to file.
+ * @param file_info structure to extract metadata to.
+ * @return 0 - success, -1 - file does not exist, -2 - cannot create metadata extractor -3 file path error.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int metadata_manager_extract_metadata(const char *file_path, attribute_info_s *file_info);
+
+#endif /* __METADATA_MANAGER_H__ */
--- /dev/null
+/*
+* Copyright (c) 2011 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 __MEDIA_THUMB_HASH_H__
+#define __MEDIA_THUMB_HASH_H__
+
+int thumbnail_generate_hash_code(const char *origin_path, char *hash_code, int max_length);
+
+#endif
--- /dev/null
+/*
+* Copyright (c) 2011 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 __THUMBNAIL_MANAGER_H__
+#define __THUMBNAIL_MANAGER_H__
+
+#include "unified_storage_format.h"
+
+/**
+ * Thumbnail size information
+ */
+typedef struct
+{
+ size_t height;
+ size_t width;
+} thumbnail_size_s;
+
+// TODO check this enum
+typedef enum
+{
+ UNIFIED_STORAGE_THUMB_LARGE,
+ UNIFIED_STORAGE_THUMB_SMALL,
+} media_thumb_type_e;
+
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int thumbnail_manager_init(void);
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int thumbnail_manager_deinit(void);
+
+/**
+ * @brief Sets thumbnail size
+ * @param thumbnail_size Thumbnail size
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void thumbnail_manager_set_thumbnail_size(const thumbnail_size_s *thumbnail_size);
+
+/**
+ * @brief Gets thumbnail size
+ * @param thumbnail_size Thumbnail size
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void thumbnail_manager_get_thumbnail_size(thumbnail_size_s *thumbnail_size);
+
+/**
+ * @brief Generate hash name for thumbnail file
+ * @param origin_path File path
+ * @param hash_code Generated hash name for thumbnail file
+ * @param max_length Max length of has name to be generated
+ * @return 0 on success, -1 otherwise
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int thumbnail_manager_generate_hash(const char *origin_path, char *hash_code, int max_length);
+
+/**
+ * Creates thumbnail file for image file
+ * @param file_path File path
+ * @param thumb_type Thumbnail type
+ * @param thumb_path Thumbnail path
+ * @return 0 on success, -1 otherwise
+ */
+// TODO check this function
+UNIFIED_STORAGE_FORMAT_PUBLIC_API int create_thumbnail_file_for_image_file(const char *file_path, const char *thumb_path);
+//UNIFIED_STORAGE_FORMAT_PUBLIC_API int create_thumbnail_file_for_image_file(const char *file_path, media_thumb_type_e thumb_type, const char *thumb_path);
+
+#endif /* __THUMBNAIL_MANAGER_H__ */
--- /dev/null
+/*
+* Copyright (c) 2011 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 __UNIFIED_STORAGE_ACCOUNTS_H__
+#define __UNIFIED_STORAGE_ACCOUNTS_H__
+
+#include <stdint.h>
+
+/**
+ * Plugin descriptor.
+ */
+typedef struct cloud_descriptor_t
+{
+ char* cloud_name;
+ char* cloud_icon_path;
+ char* cloud_account;
+} cloud_descriptor_s;
+
+/**
+ * Account ID descriptor.
+ */
+typedef struct id_descriptor_t
+{
+ cloud_descriptor_s cloud_info;
+ uint64_t account_id;
+ char* storage_uuid;
+} id_descriptor_s;
+
+/**
+ * Account descriptor with status.
+ */
+typedef struct account_descriptor_t
+{
+ id_descriptor_s id_descriptor;
+ uint64_t status;
+} account_descriptor_s;
+
+/**
+ * Account user info.
+ */
+typedef struct user_info_t
+{
+ char* user_name;
+ char* user_id;
+ char* email;
+} user_info_s;
+
+/**
+ * Account quota info.
+ */
+typedef struct quota_info_t
+{
+ uint64_t quota_total; /*< total size in B*/
+ uint64_t quota_occupied; /*< in B*/
+} quota_info_s;
+
+/**
+ * Account collective info.
+ */
+typedef struct account_info_t
+{
+ user_info_s user;
+ quota_info_s quota;
+ uint64_t update_interval_sec;
+ uint64_t allowed_connection_type;
+} account_info_s;
+
+/**
+ * Account collective info with descriptor ID.
+ */
+typedef struct account_details_t
+{
+ account_descriptor_s account_descriptor;
+ account_info_s account_info;
+} account_details_s;
+
+/**
+ * Account descriptor handle
+ */
+typedef struct account_details_t *account_details_h;
+
+#endif /* __UNIFIED_STORAGE_ACCOUNTS_H__ */
--- /dev/null
+/*
+* Copyright (c) 2011 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 __UNIFIED_STORAGE_ERROR_CODES_H__
+#define __UNIFIED_STORAGE_ERROR_CODES_H__
+
+#include <tizen.h>
+
+#define ERROR -1
+#define INVALID_PARAM -2
+#define NULL_ARGUMENT -3
+#define SUCCESS 0
+#define FAILURE 1
+
+/**
+ * Unified Storage service errors class
+ */
+#define UNIFIED_STORAGE_PLUGIN_ERROR_CLASS TIZEN_ERROR_CONTENT_CLASS
+
+typedef enum
+{
+ NO_ERROR = 0,
+
+ /* Generic errors */
+ NULL_POINTER_ARGUMENT = -1,
+ MEMORY_ALLOCATION_ERROR = -2,
+ WRONG_ARGUMENT = -3,
+ DBUS_ERROR = -4,
+ DBUS_PROXY_NOT_INITIALISED = -5,
+ DBUS_INVOCATION_FAILED = -6,
+ CLOUD_UNSUPPORTED = -7,
+ SUSPICIOUS_RETURN_DATA = -8,
+ RESPONSE_TIME_EXCEEDED = -9,
+ DBUS_INVOCATION_INVALID_RETURN_DATA = -10,
+ DBUS_CALL_FAILED = -11,
+ SETXATTR_ERROR = -12,
+ FOLDER_EXIST = -13,
+ MKDIR_ERROR = -14,
+ OPENFILE_ERROR = -15,
+ OPENDIR_ERROR = -16,
+ NO_SPACE = -17,
+
+ MEDIA_CONTENT_ERROR = -30,
+
+ /* Account errors */
+ ACCOUNT_MANAGER_ERROR = -100,
+ NO_SUCH_ACCOUNT = -101,
+ ACCOUNT_MANAGER_UNAVAILABLE = -102,
+
+ /* Plug-in errors */
+ PLUGIN_ERROR = -200,
+ GET_ACTIVE_ACCOUNTS_LIST_ERROR = -201,
+ PLUGIN_CREATE_FOLDER_ERROR = -202,
+ PLUGIN_DELETE_FILE_ERROR = -203,
+ PLUGIN_DELETE_FOLDER_ERROR = -204,
+ PLUGIN_DOWNLOAD_FILE_ERROR = -205,
+ PLUGIN_UPLOAD_FILE_ERROR = -206,
+ PLUGIN_GET_ACCOUNT_INFO_ERROR = -207,
+ PLUGIN_GET_FILE_INFO_ERROR = -208,
+ PLUGIN_GET_FILE_LIST_ERROR = -209,
+ PLUGIN_GET_FILE_THUMBNAIL_ERROR = -210,
+ PLUGIN_MOVE_FILE_ERROR = -211,
+ PLUGIN_MOVE_FOLDER_ERROR = -212,
+ PLUGIN_NETWORK_BANDWIDTH_ERROR = -213,
+ PLUGIN_RENAME_FILE_ERROR = -214,
+ PLUGIN_GET_ROOT_FOLDER_PATH_ERROR = -215,
+ PLUGIN_GET_NO_DATA = -216,
+
+ INVALID_HANDLE = -250, // handle given by application is Invalid
+ INVALID_PARAMS = -251, // Parameters given by application is Invalid
+ INVALID_URL = -252, // Invalid URL is requested.
+ INVALID_FILE = -253, // Invalid file
+ BAD_REQUEST = -254, // Bad request.
+ BAD_AUTHORIZATION = -255, // Bad authorization.
+ BAD_FORBIDDEN = -256, // Bad forbidden.
+ BAD_RESOURCE = -257, // Bad resource.
+ BAD_QUOTA = -258, // Bad quota.
+ BAD_NOT_ACCEPTABLE = -259, // Bad not acceptable.
+ BAD_SERVER = -260, // Bad server.
+ API_NOT_SUPPORTED = -261, // API Not supported.
+ NETWORK_FAILURE = -262, // Network connection failure
+ TIMEOUT_ERR = -263, // Timeout error
+ NOT_CHANGED = -264, // No change
+
+ /* Thread errors */
+ THREAD_ALREADY_RUNNING = -800, // Thread is already running.
+ CONDITIONAL_TIMEOUT_EXCEEDED = -801, // Timeout for conditional variable exceeded
+ THREAD_DATA_CORRUPTED = -802, // Thread seems to run, but its data is corrupted
+
+ UNKNOWN_ERROR = -999
+} unified_storage_error_codes_e;
+
+#endif /* __UNIFIED_STORAGE_ERROR_CODES_H__ */
--- /dev/null
+/*
+* Copyright (c) 2011 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 __UNIFIED_STORAGE_FORMAT_H__
+#define __UNIFIED_STORAGE_FORMAT_H__
+
+#include <sys/time.h>
+#include <stdint.h>
+#include <glib.h>
+#include <time.h>
+
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_IMPORT __declspec(dllimport)
+#define DLL_EXPORT __declspec(dllexport)
+#define DLL_LOCAL
+#else
+#if __GNUC__ >= 4
+#define DLL_IMPORT __attribute__ ((visibility ("default")))
+#define DLL_EXPORT __attribute__ ((visibility ("default")))
+#define DLL_LOCAL __attribute__ ((visibility ("hidden")))
+#else
+#define DLL_IMPORT
+#define DLL_EXPORT
+#define DLL_LOCAL
+#endif
+#endif
+
+#ifdef UNIFIED_STORAGE_FORMAT_DLL
+#ifdef UNIFIED_STORAGE_FORMAT_DLL_EXPORTS
+#define UNIFIED_STORAGE_FORMAT_PUBLIC_API DLL_EXPORT
+#else
+#define UNIFIED_STORAGE_FORMAT_PUBLIC_API DLL_IMPORT
+#endif
+#define UNIFIED_STORAGE_FORMAT_LOCAL_API DLL_LOCAL
+#else
+#define UNIFIED_STORAGE_FORMAT_PUBLIC_API
+#define UNIFIED_STORAGE_FORMAT_LOCAL_API
+#endif
+
+#define DEBUG_PRINT
+#define LOG_PRINT
+#define RELEASE
+
+#ifndef BOOL
+#define BOOL unsigned char // Represents bool variable
+#endif
+
+#define FILEBUFLEN 256
+#define CONTENTLEN 100
+
+#define IMAGE_TYPE_SIZE 10
+#define VIDEO_TYPE_SIZE 12
+#define MUSIC_TYPE_SIZE 14
+#define DOCUMENT_TYPE_SIZE 10
+
+/**
+ * Connection types
+ */
+#define USS_CONNECTION_TYPE_NONE 0x00000000
+#define USS_CONNECTION_TYPE_WIFI 0x00000001
+#define USS_CONNECTION_TYPE_ETHERNET 0x00000002
+#define USS_CONNECTION_TYPE_CELLULAR 0x00000004
+#define USS_CONNECTION_TYPE_BT 0x00000008 //Bluetooth
+#define USS_CONNECTION_TYPE_ALL 0xFFFFFFFF
+
+/**
+ * File state
+ */
+typedef enum
+{
+ LOCAL_FILE = 0, // LOCAL_GROUP
+ CLOUD_CREATE, // CLOUD_GROUP
+ CLOUD_SET_META,
+ CLOUD_THUMB_DOWNLOAD,
+ CLOUD_CACHE,
+ FILE_STATE_MAX
+} file_state_e;
+
+/**
+ * Folder type
+ */
+typedef enum
+{
+ ROOT = 0, // ROOT
+ LOCAL, // LOCAL
+ CLOUD, // CLOUD
+ CONTENT, // CONTENT
+ UNKNOWN, // UNKNOWN
+ FOLDER_TYPE_MAX
+} folder_type_e;
+
+/**
+ * File Type
+ */
+typedef enum
+{
+ FILE_TYPE_NONE = 0, // None / unknown type
+ FILE_TYPE_DIR, // Folder category
+ FILE_TYPE_IMAGE, // Image category
+ FILE_TYPE_VIDEO, // Video category
+ FILE_TYPE_AUDIO, // Audio category
+ FILE_TYPE_PDF, // Pdf category
+ FILE_TYPE_DOC, // Word category
+ FILE_TYPE_PPT, // Powerpoint category
+ FILE_TYPE_EXCEL, // Excel category
+ FILE_TYPE_TXT, // Txt category
+ FILE_TYPE_ETC, // Other files category
+ FILE_TYPE_MAX // enum guard
+} file_type_e;
+
+/**
+ * Attribute meta information
+ */
+typedef struct attribute_meta_t
+{
+ char title[CONTENTLEN]; // track title
+ char album[CONTENTLEN]; // album name
+ char artist[CONTENTLEN]; // artist name
+ char genre[CONTENTLEN]; // genre of track
+ char composer[CONTENTLEN]; // composer name
+ char year[CONTENTLEN]; // year
+ char recorded_date[CONTENTLEN]; // recorded date
+ char copyright[CONTENTLEN]; // copyright
+ char track_num[CONTENTLEN]; // track number
+ char description[CONTENTLEN]; // description
+ char datetaken[CONTENTLEN]; // datetaken
+ int bitrate; // bitrate
+ int samplerate; // samplerate
+ int channel; // channel
+ int duration; // duration
+ float longitude; // longitude
+ float latitude; // latitude
+ float altitude; // altitude
+ int width; // width
+ int height; // height
+ int orientation; // orientation
+ int rating; // user defined rating
+} attribute_meta_s;
+
+/**
+ * Attribute information
+ */
+typedef struct attribute_info_t
+{
+ char media_uuid[CONTENTLEN]; // Unique ID of item
+ char media_name[FILEBUFLEN]; // File name of media file
+ char media_path[FILEBUFLEN]; // Full path of media file
+ char media_thumb_path[FILEBUFLEN]; // Thumbnail image file path
+ char cloud_name[FILEBUFLEN]; //
+ char cloud_path[FILEBUFLEN]; //
+ char cloud_folder_name[FILEBUFLEN]; //
+ char cloud_folder_path[FILEBUFLEN]; //
+ attribute_meta_s media_meta; // meta data structure for audio files
+ unsigned long long media_size; // file size
+ time_t created_time; // added time, time_t
+ time_t modified_time; // modified time, time_t
+ int album_id; // Unique ID of album
+ int played_count; // played count
+ int last_played_time; // last played time
+ int last_played_position; // last played position
+ int favourite; // favourite. o or 1
+ int is_drm; // is_drm. o or 1
+ char mime_type[FILEBUFLEN]; // Type of media file
+ char storage_uuid[FILEBUFLEN]; // Storage uuid
+} attribute_info_s;
+
+/**
+ * Content meta information
+ */
+typedef struct content_meta_t
+{
+ char* title; // track title
+ char* album; // album name
+ char* artist; // artist name
+ char* genre; // genre of track
+ char* composer; // composer name
+ char* year; // year
+ char* recorded_date; // recorded date
+ char* copyright; // copyright
+ char* track_num; // track number
+ char* description; // description
+ int bitrate; // bitrate
+ int samplerate; // samplerate
+ int channel; // channel
+ int duration; // duration
+ float longitude; // longitude
+ float latitude; // latitude
+ float altitude; // altitude
+ int width; // width
+ int height; // height
+ char* datetaken; // date taken
+ int orientation; // orientation
+ int rating; // user defined rating
+} content_meta_s;
+
+/**
+ * Media data information
+ */
+typedef struct content_info_t
+{
+ char* media_uuid; // Unique ID of item
+ char* path; // Full path of media file
+ char* file_name; // File name of media file. Display name
+ int media_type; // Type of media file.
+ char* mime_type; // Full path and file name of media file
+ uint64_t size; // size
+ time_t added_time; // added time, time_t
+ time_t modified_time; // modified time, time_t
+ char* folder_uuid; // Unique ID of folder
+ int album_id; // Unique ID of album
+ char* thumbnail_path; // Thumbnail image file path
+ int played_count; // played count
+ int last_played_time; // last played time
+ int last_played_position; // last played position
+ int favourite; // favourite. 0 or 1
+ int is_drm; // is_drm. o or 1
+ char* storage_uuid; // Storage type
+ content_meta_s media_meta; // meta data structure for audio files
+ // for sugarsync
+ char* ref; //
+ char* file_data; //
+ char* cloud_path; //
+ char* cloud_name; //
+ char* cloud_folder_name; //
+ char* cloud_folder_path; //
+} content_info_s;
+
+/**
+ * structure that holds essential file information.
+ */
+typedef struct file_info_t
+{
+ char* name; // File name
+ char* path; // File path
+ char* cloud_path; // Full path of media file
+ int file_type; // file type
+ char* mime_type; // Full path and file name of media file
+ unsigned long long size; // size
+ time_t added_time; // added time
+ time_t modified_time; // modified time
+ char* title; // track title
+ char* album; // album name
+ char* artist; // artist name
+ char* genre; // genre of track
+ char* composer; // composer name
+ char* year; // year
+ char* recorded_date; // recorded date
+ char* copyright; // copyright
+ char* track_num; // track number
+ char* description; // description
+ int bitrate; // bitrate
+ int samplerate; // samplerate
+ int channel; // channel
+ int duration; // duration
+ float longitude; // longitude
+ float latitude; // latitude
+ float altitude; // altitude
+ int width; // width
+ int height; // height
+ char* datetaken; // date taken
+ int orientation; // orientation
+ int rating; // user defined rating
+ GList* child; //
+ char* ref; // for sugarsync
+ char* file_data; // for sugarsync
+ char* link_path; //
+} file_info_s;
+
+
+#endif /* __UNIFIED_STORAGE_FORMAT_H__ */
--- /dev/null
+/*
+* Copyright (c) 2011 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 __UNIFIED_STORAGE_LOG_H__
+#define __UNIFIED_STORAGE_LOG_H__
+
+#include <unistd.h>
+#include <linux/unistd.h>
+
+/**
+ * HOW TO USE IT:
+ * First you need to set platform logging on the device:
+ *
+ * # dlogctrl set platformlog 1
+ *
+ * After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:
+ *
+ * # dlogutil $LOG_TAG:D
+ *
+ * You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).
+ * Higher level messages are included by default e.g. dlogutil $LOG_TAG:W prints warnings but also errors and fatal messages.
+ */
+
+/* These defines must be located before #include <dlog.h> */
+// TODO: Investigate why this macro is defined somewhere else
+#ifndef TIZEN_ENGINEER_MODE
+#define TIZEN_ENGINEER_MODE
+#endif
+// TODO: Investigate why this macro is defined somewhere else
+#ifndef TIZEN_DEBUG_ENABLE
+#define TIZEN_DEBUG_ENABLE
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+// Literal to filter logs from dlogutil
+#define LOG_TAG "UNIFIED_STORAGE_FORMAT"
+
+#include <dlog.h>
+
+// Colors of font
+#define FONT_COLOR_RESET "\033[0m"
+#define FONT_COLOR_BLACK "\033[30m" // Black
+#define FONT_COLOR_RED "\033[31m" // Red
+#define FONT_COLOR_GREEN "\033[32m" // Green
+#define FONT_COLOR_YELLOW "\033[33m" // Yellow
+#define FONT_COLOR_BLUE "\033[34m" // Blue
+#define FONT_COLOR_PURPLE "\033[35m" // Purple
+#define FONT_COLOR_CYAN "\033[36m" // Cyan
+#define FONT_COLOR_WHITE "\033[37m" // White
+#define FONT_COLOR_BOLDBLACK "\033[1m\033[30m" // Bold Black
+#define FONT_COLOR_BOLDRED "\033[1m\033[31m" // Bold Red
+#define FONT_COLOR_BOLDGREEN "\033[1m\033[32m" // Bold Green
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m" // Bold Yellow
+#define FONT_COLOR_BOLDBLUE "\033[1m\033[34m" // Bold Blue
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m" // Bold Purple
+#define FONT_COLOR_BOLDCYAN "\033[1m\033[36m" // Bold Cyan
+#define FONT_COLOR_BOLDWHITE "\033[1m\033[37m" // Bold White
+
+/**
+ * Gets thread ID
+ */
+#define unified_storage_gettid() syscall(__NR_gettid)
+
+/**
+ * @brief Macro for returning value if expression is satisfied
+ * @param[in] expr Expression to be checked
+ * @param[out] val Value to be returned when expression is true
+ */
+#define unified_storage_retv_if(expr, val) do { \
+ if(expr) { \
+ LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, unified_storage_gettid()); \
+ return (val); \
+ } \
+} while (0)
+
+/**
+ * @brief Prints debug messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define unified_storage_debug(fmt, arg...) do { \
+ LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, unified_storage_gettid(), ##arg); \
+} while (0)
+
+/**
+ * @brief Prints info messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define unified_storage_info(fmt, arg...) do { \
+ LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, unified_storage_gettid() ,##arg); \
+} while (0)
+
+/**
+ * @brief Prints warning messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define unified_storage_warning(fmt, arg...) do { \
+ LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,unified_storage_gettid(), ##arg); \
+} while (0)
+
+/**
+ * @brief Prints error messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define unified_storage_error(fmt, arg...) do { \
+ LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,unified_storage_gettid(), ##arg); \
+} while (0)
+
+/**
+ * @brief Prints fatal messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define unified_storage_fatal(fmt, arg...) do { \
+ LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,unified_storage_gettid(), ##arg); \
+} while (0)
+
+/**
+ * @brief Prints debug message on entry to particular function
+ */
+#define unified_storage_debug_func(fmt, arg...) do { \
+ LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, unified_storage_gettid(), ##arg); \
+} while (0)
+
+/* forward declaration */
+struct timeval;
+
+#define PERFORMANCE_START(marker) struct timeval marker = MEASURE_START();
+#define PERFORMANCE_RESTART(marker) marker = MEASURE_START();
+
+/**
+ * @brief Prints performance messages
+ * @param[in] fmt Format of data to be displayed
+ * @param[in] args Arguments to be displayed
+ */
+#define PERFORMANCE_LOG(marker, fmt, arg...) do { \
+ LOGI(FONT_COLOR_BOLDYELLOW"[PERFORMANCE] [%d] - elapsed time: %llu msec for "fmt""FONT_COLOR_RESET, unified_storage_gettid(), MEASURE_TIME(marker), ##arg); \
+} while (0);
+
+#endif /* __UNIFIED_STORAGE_LOG_H__ */
--- /dev/null
+/*
+* Copyright (c) 2011 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 __UNIFIED_STORAGE_UTILS_H__
+#define __UNIFIED_STORAGE_UTILS_H__
+
+#include <glib.h>
+
+#include "unified_storage_error_codes.h"
+#include "unified_storage_format.h"
+#include "unified_storage_accounts.h"
+
+#define EMPTY_STRING ""
+#define THOUSAND 1000ULL
+#define MILLION 1000000ULL
+
+#define UNUSED(x) (void)(x)
+#define SAFE_FREE(src) {if(src) {free(src); src = NULL;}}
+#define SAFE_STRDUP(s) ((s == NULL) ? strdup(EMPTY_STRING) : strdup(s))
+#define IS_STRING_NONEMPTY(x) (((x)&&(*x!='\0'))?1:0)
+#define IS_STRING_EMPTY(x) (((x)&&(*x!='\0'))?0:1)
+#define STRCMP(str1, str2) ((strncmp(str1, str2, strlen(str1)) == 0) ? (1) : (0))
+
+#define UNIFIED_STORAGE_SYSTEM_UTILS_G_LIST_FOREACH(list, l, data) \
+ for (l = list, \
+ data = g_list_nth_data(l, 0); \
+ l; \
+ l = g_list_next(l), \
+ data = g_list_nth_data(l, 0))
+
+#define IS_LOCAL(type) ((type == LOCAL))
+#define IS_LOCAL_CONTENTS(type) ((type == LOCAL))
+#define IS_CLOUD(type) ((type == CLOUD))
+#define IS_CLOUD_CONTENTS(type) ((type == CLOUD))
+#define IS_TEMPFILE(str) (STRCMP(".swp", str) || STRCMP(".swx", str) || STRCMP(".sdca", str) || ('~' == *(str+(strlen(str)-1))))
+
+/**
+ * Wrapper for strerror() POSIX function
+ * @param err_number Error number
+ * @return pointer to string message of given error
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API const char* const strerror_w(int err_number);
+
+/**
+ * Secure version of sprintf()
+ * @param format Form of wanted string
+ * @return format string filled with arguments
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API char* sprintf_s(const char *format, ...);
+
+/**
+ * Converts attribute info structure into content info structure
+ * @param attribute_info Attribute info
+ * @param content_info Content info
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_convert_attribute_info_to_content_info(attribute_info_s *attribute_info, content_info_s *content_info);
+
+/**
+ * Converts content info structure into attribute info structure
+ * @param content_info Content info
+ * @param attribute_info Attribute info
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_convert_content_info_to_attribute_info(content_info_s *content_info, attribute_info_s *attribute_info);
+
+/**
+ * Releases memory for allocated for content_info structure
+ * @param content_info to be released
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_release_content_info(content_info_s *content_info);
+
+/**
+ * @brief Releases content list.
+ * @param content_list Content list.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_release_contents_list(GList* contents_list);
+
+/**
+ * @brief Releases memory occupated by file list element.
+ * @param data Pointer to file list element.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_release_file_info(file_info_s* list_element);
+
+/**
+ * @brief Releases file list.
+ * @param file_list File list.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_release_file_list(GList* file_list);
+
+/**
+ * @brief Releases accounts info.
+ * @param account_info Account info.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_release_accounts_info(account_info_s *account_info);
+
+/**
+ * @brief Releases accounts list.
+ * @param accounts_list Accounts list.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_release_accounts_list(GList *accounts_list);
+
+/**
+ * @brief Releases memory occupied by account descriptor.
+ * @param id_descriptor Account descriptor to be released.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_release_id_descriptor(id_descriptor_s *id_descriptor);
+
+/**
+ * @brief Releases memory occupated by accounts list element.
+ * @param data Pointer to accounts list element.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API void unified_storage_utils_release_accounts_list_element(gpointer data);
+
+/**
+ * Converts MIME to file_type enum.
+ * @param mime c-string with mime type description
+ * @return file_type value corresponding to given MIME string.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API file_type_e unified_storage_utils_get_file_type_by_mime_type(char* mime);
+
+/**
+ * Generates a timestamp.
+ * @return current timestamp.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API struct timeval MEASURE_START();
+
+/**
+ * Returns the amount of time that elapsed between the function call and
+ * time parameter.
+ * @param time the parameter to measure time difference
+ * @return number of milliseconds elapsed between time parameter and now.
+ */
+UNIFIED_STORAGE_FORMAT_PUBLIC_API unsigned long long int MEASURE_TIME(struct timeval time);
+
+#endif /* __UNIFIED_STORAGE_UTILS_H__ */
--- /dev/null
+Name: unifiedstorage-format
+Summary: unified storage format library
+Version: 0.1.5
+Release: 3
+Group: Libraries/Libraries
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+
+BuildRequires: cmake
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(capi-content-media-content)
+BuildRequires: pkgconfig(capi-media-thumbnail-util)
+BuildRequires: pkgconfig(capi-media-metadata-extractor)
+BuildRequires: pkgconfig(capi-media-image-util)
+BuildRequires: pkgconfig(dlog)
+
+%define _manifestdir /opt/share/packages
+
+%description
+unified storage format library
+
+%package -n %{name}-devel
+Summary: Development files for unified storage fs Format library
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description -n %{name}-devel
+This package contains the headers and pc files for unified storage FS Format library
+
+%prep
+%setup -q
+
+%build
+cmake \
+ -DCMAKE_INSTALL_PREFIX=/usr/ \
+ -DTARGET_PROFILE_NAME="%{?tizen_profile_name}" \
+ -DMANIFESTDIR=%{_manifestdir} \
+ .;make
+
+%install
+make install DESTDIR=$RPM_BUILD_ROOT/usr
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%clean
+make clean
+
+%files
+%defattr(-,root,root,-)
+%{_libdir}/libunifiedstorage-format.so
+%manifest unifiedstorage-format.manifest
+
+%files -n %{name}-devel
+%defattr(-,root,root,-)
+%{_libdir}/pkgconfig/*.pc
+%{_includedir}/unifiedstorage-format/*
--- /dev/null
+/*
+* Copyright (c) 2011 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 <stdlib.h>
+#include <stdio.h>
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+#include <media_content_internal.h>
+#endif
+#include <media_content_type.h>
+#include <media_content.h>
+#include <media_info.h>
+
+#include "unified_storage_utils.h"
+#include "unified_storage_log.h"
+#include "db_manager/db_manager.h"
+
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+/**
+ * @brief Converts unified_storage file type into media content file type.
+ *
+ * @param file_type unified_storage file type.
+ * @param media_content_type Media content file type.
+ */
+static void _convert_file_type_into_media_content_type(file_type_e file_type, media_content_type_e *media_content_type);
+
+/**
+ * @brief Fill media info from content info.
+ *
+ * @param content_info Content information.
+ * @param media_info Media information.
+ */
+static void _convert_content_info_to_media_info(const content_info_s *content_info, media_info_h *media_info);
+static void _cover_content_info_to_media_info(const content_info_s *content_info, media_info_h *media_info);
+
+/**
+ * @brief Gets string description of DB error.
+ *
+ * @param[in] error code
+ * @return error string description
+ */
+static const char *_get_string_db_error(int error);
+#endif
+
+int db_manager_insert_media_info(content_info_s *content_info, char **media_uuid)
+{
+ unified_storage_debug("db_manager_insert_media_info called, path = %s, storage_uuid = %s", content_info->path, content_info->storage_uuid);
+
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ int ret = NO_ERROR;
+ media_info_h in_media = NULL;
+ media_info_h out_media = NULL;
+
+ ret = media_info_create_handle(&in_media);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_info_create_handle failed, ret = [%d], [%s]", ret, _get_string_db_error(ret));
+ return MEDIA_CONTENT_ERROR;
+ }
+
+ _convert_content_info_to_media_info(content_info, &in_media);
+
+ ret = media_info_insert_to_db_with_data(in_media, &out_media);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_info_insert_to_db_with_data failed, ret = [%d], [%s]", ret, _get_string_db_error(ret));
+ media_info_destroy(in_media);
+
+ return MEDIA_CONTENT_ERROR;
+ }
+
+ ret = media_info_get_media_id(out_media, media_uuid);
+ if (MEDIA_CONTENT_ERROR_NONE != ret) {
+ unified_storage_error("media_info_get_media_id failed, ret = [%d], [%s]", ret, _get_string_db_error(ret));
+ media_info_destroy(in_media);
+ return MEDIA_CONTENT_ERROR;
+ }
+
+ media_info_destroy(in_media);
+ media_info_destroy(out_media);
+#endif
+
+ return NO_ERROR;
+}
+
+int db_manager_update_media_info(content_info_s *content_info, char **media_uuid)
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ int ret = NO_ERROR;
+ if (media_uuid == NULL) {
+ unified_storage_error("Null argument.");
+ return NULL_POINTER_ARGUMENT;
+ }
+
+ media_info_h info = NULL;
+ char *media_id = NULL;
+
+ ret = media_info_get_media_from_db(content_info->media_uuid, &info);
+
+ if (MEDIA_CONTENT_ERROR_NONE == ret) {
+ if (NULL != info) {
+ unified_storage_debug("File exist, to update %s", content_info->path);
+
+ ret = media_info_get_media_id(info, &media_id);
+ if (MEDIA_CONTENT_ERROR_NONE == ret) {
+ unified_storage_debug("success to get media id %s", media_id);
+
+ _cover_content_info_to_media_info(content_info, &info);
+ ret = media_info_update_to_db(info);
+ if (MEDIA_CONTENT_ERROR_NONE != ret) {
+ unified_storage_error("Failed update metadata [%s]", media_id);
+ }
+ }
+
+ SAFE_FREE(media_id);
+ } else {
+ unified_storage_debug("File don't exist, to insert %s", content_info->path);
+ ret = db_manager_insert_media_info(content_info, media_uuid);
+
+ if (MEDIA_CONTENT_ERROR_NONE != ret) {
+ unified_storage_error("Failed to insert media info for uuid = [%s], %s", content_info->media_uuid, _get_string_db_error(ret));
+ }
+ }
+ } else {
+ unified_storage_error("Failed to media info get for uuid = [%s], %s", content_info->media_uuid, _get_string_db_error(ret));
+ }
+
+ media_info_destroy(info);
+#endif
+ return NO_ERROR;
+}
+
+bool _storage_info_foreach_cb(media_storage_h storage, void *user_data)
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ char **storage_uuid = (char **)user_data;
+
+ char *uuid = NULL;
+
+ int ret = media_storage_get_id(storage, &uuid);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_storage_get_id failed : %d, %s", ret, _get_string_db_error(ret));
+ return false;
+ }
+
+ *storage_uuid = uuid;
+#endif
+ return true;
+}
+
+int db_manager_get_storage_uuid(const char *cloud_name, const char *cloud_account, char **storage_uuid)
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ int ret;
+ filter_h filter;
+ char condition[256] = { 0, };
+
+ media_filter_create(&filter);
+ snprintf(condition, 256, "storage_name='%s' and storage_account='%s'", cloud_name, cloud_account);
+
+ ret = media_filter_set_condition(filter, condition, MEDIA_CONTENT_ERROR_NONE);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_filter_set_condition failed : %d, %s", ret, _get_string_db_error(ret));
+ media_filter_destroy(filter);
+ return MEDIA_CONTENT_ERROR;
+ }
+
+ ret = media_storage_foreach_storage_from_db(filter, _storage_info_foreach_cb, (void *)storage_uuid);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_storage_foreach_storage_from_db failed : %d, %s", ret, _get_string_db_error(ret));
+ media_filter_destroy(filter);
+ return MEDIA_CONTENT_ERROR;
+ }
+
+ media_filter_destroy(filter);
+ unified_storage_debug("get_storage_uuid called cloud_name = %s, cloud_account = %s, storage_uuid = %s", cloud_name, cloud_account, *storage_uuid);
+#endif
+ return NO_ERROR;
+}
+
+int db_manager_delete_media_info(const char *media_uuid)
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ int ret = NO_ERROR;
+ if (media_uuid == NULL) {
+ unified_storage_error("Null argument.");
+ return NULL_POINTER_ARGUMENT;
+ }
+
+ ret = media_info_delete_from_db(media_uuid);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_info_delete_from_db failed, ret = [%d], [%s]", ret, _get_string_db_error(ret));
+ return MEDIA_CONTENT_ERROR;
+ }
+#endif
+ return NO_ERROR;
+}
+
+int db_manager_insert_storage_info(const char *storage_name, const char *default_path, const char *storage_account, char **storage_id)
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ int ret = NO_ERROR;
+ if (storage_name == NULL || default_path == NULL) {
+ unified_storage_error("Null argument.");
+ return NULL_POINTER_ARGUMENT;
+ }
+
+ media_storage_h storage = NULL;
+
+ ret = media_storage_insert_to_db(storage_name, default_path, storage_account, MEDIA_CONTENT_STORAGE_CLOUD, &storage);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_storage_insert failed, ret = [%d], [%s]", ret, _get_string_db_error(ret));
+ media_storage_destroy(storage);
+ return MEDIA_CONTENT_ERROR;
+ }
+
+ media_storage_get_id(storage, storage_id);
+ media_storage_destroy(storage);
+#endif
+ return NO_ERROR;
+}
+
+int db_manager_delete_storage_info(const char *storage_id)
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ int ret = NO_ERROR;
+
+ if (NULL == storage_id) {
+ unified_storage_error("Null argument.");
+ return NULL_POINTER_ARGUMENT;
+ }
+
+ ret = media_storage_delete_from_db(storage_id);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_storage_delete failed, ret = [%d], [%s]", ret, _get_string_db_error(ret));
+ return MEDIA_CONTENT_ERROR;
+ }
+#endif
+ return NO_ERROR;
+}
+
+int db_manager_init()
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ int ret = NO_ERROR;
+
+ ret = media_content_connect();
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_content_connect failed, ret = [%d], [%s]", ret, _get_string_db_error(ret));
+ return MEDIA_CONTENT_ERROR;
+ }
+#endif
+ return NO_ERROR;
+}
+
+int db_manager_deinit()
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ int ret = NO_ERROR;
+
+ ret = media_content_disconnect();
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ unified_storage_error("media_content_disconnect failed, ret = [%d], [%s]", ret, _get_string_db_error(ret));
+ return MEDIA_CONTENT_ERROR;
+ }
+#endif
+ return NO_ERROR;
+}
+
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+static const char *_get_string_db_error(int error)
+{
+ switch (error) {
+ case MEDIA_CONTENT_ERROR_NONE:
+ return "MEDIA_CONTENT_ERROR_NONE";
+ case MEDIA_CONTENT_ERROR_INVALID_PARAMETER:
+ return "MEDIA_CONTENT_ERROR_INVALID_PARAMETER";
+ case MEDIA_CONTENT_ERROR_OUT_OF_MEMORY:
+ return "MEDIA_CONTENT_ERROR_OUT_OF_MEMORY";
+ case MEDIA_CONTENT_ERROR_INVALID_OPERATION:
+ return "MEDIA_CONTENT_ERROR_INVALID_OPERATION";
+ case MEDIA_CONTENT_FILE_NO_SPACE_ON_DEVICE:
+ return "MEDIA_CONTENT_FILE_NO_SPACE_ON_DEVICE";
+ case MEDIA_CONTENT_ERROR_DB_FAILED:
+ return "MEDIA_CONTENT_ERROR_DB_FAILED";
+ case MEDIA_CONTENT_ERROR_DB_BUSY:
+ return "MEDIA_CONTENT_ERROR_DB_BUSY";
+ case MEDIA_CONTENT_ERROR_NETWORK:
+ return "MEDIA_CONTENT_ERROR_NETWORK";
+ case MEDIA_CONTENT_ERROR_UNSUPPORTED_CONTENT:
+ return "MEDIA_CONTENT_ERROR_UNSUPPORTED_CONTENT";
+ default:
+ return "UNKNOWN_ERROR";
+ }
+}
+#endif
+
+void _convert_file_type_into_media_content_type(file_type_e file_type, media_content_type_e *media_content_type)
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ switch (file_type) {
+ case FILE_TYPE_IMAGE:
+ *media_content_type = MEDIA_CONTENT_TYPE_IMAGE;
+ break;
+ case FILE_TYPE_VIDEO:
+ *media_content_type = MEDIA_CONTENT_TYPE_VIDEO;
+ break;
+ case FILE_TYPE_AUDIO:
+ *media_content_type = MEDIA_CONTENT_TYPE_MUSIC;
+ break;
+ default:
+ *media_content_type = MEDIA_CONTENT_TYPE_OTHERS;
+ break;
+ }
+#endif
+}
+
+void _convert_content_info_to_media_info(const content_info_s *content_info, media_info_h *media_info)
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ if ((NULL == content_info) || (NULL == media_info)) {
+ unified_storage_error("NULL pointer argument.");
+ return;
+ }
+
+ media_info_h media = (media_info_h) * media_info;
+
+ media_content_type_e media_content_type = MEDIA_CONTENT_TYPE_OTHERS;
+ _convert_file_type_into_media_content_type(content_info->media_type, &media_content_type);
+
+ media_info_set_media_type(media, media_content_type);
+
+ media_info_set_path(media, content_info->path);
+ media_info_set_mime_type(media, IS_STRING_NONEMPTY(content_info->mime_type) ? content_info->mime_type : "UNKNOWN");
+
+ if ((NULL == content_info->media_meta.title) || ((0 == g_ascii_strncasecmp("UNKNOWN", content_info->media_meta.title, strlen(content_info->media_meta.title))))) {
+ media_info_set_title(media, content_info->file_name);
+ } else {
+ media_info_set_title(media, content_info->media_meta.title);
+ }
+
+ if ((NULL == content_info->media_meta.artist) || (0 == g_ascii_strncasecmp("UNKNOWN", content_info->media_meta.artist, strlen(content_info->media_meta.artist)))) {
+ media_info_set_artist(media, content_info->cloud_name);
+ } else {
+ media_info_set_artist(media, content_info->media_meta.artist);
+ }
+
+ media_info_set_album(media, IS_STRING_NONEMPTY(content_info->media_meta.album) ? content_info->media_meta.album : "UNKNOWN");
+ media_info_set_genre(media, IS_STRING_NONEMPTY(content_info->media_meta.genre) ? content_info->media_meta.genre : "UNKNOWN");
+ media_info_set_recorded_date(media, IS_STRING_NONEMPTY(content_info->media_meta.datetaken) ? content_info->media_meta.datetaken : "UNKNOWN");
+
+ media_info_set_thumbnail_path(media, content_info->thumbnail_path);
+ media_info_set_size(media, content_info->size);
+ media_info_set_modified_time(media, content_info->modified_time);
+
+ media_info_set_duration(media, content_info->media_meta.duration);
+ media_info_set_width(media, content_info->media_meta.width);
+ media_info_set_height(media, content_info->media_meta.height);
+ media_info_set_storage_type(media, MEDIA_CONTENT_STORAGE_CLOUD);
+ media_info_set_storage_id(media, content_info->storage_uuid);
+#endif
+}
+
+void _cover_content_info_to_media_info(const content_info_s *content_info, media_info_h *media_info)
+{
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ if ((NULL == content_info) || (NULL == media_info)) {
+ unified_storage_error("NULL pointer argument.");
+ return;
+ }
+
+ media_info_h media = (media_info_h) * media_info;
+
+ if ((NULL == content_info->media_meta.title) || ((0 == g_ascii_strncasecmp("UNKNOWN", content_info->media_meta.title, strlen(content_info->media_meta.title))))) {
+ media_info_set_title(media, content_info->file_name);
+ } else {
+ media_info_set_title(media, content_info->media_meta.title);
+ }
+
+ if ((NULL == content_info->media_meta.artist) || (0 == g_ascii_strncasecmp("UNKNOWN", content_info->media_meta.artist, strlen(content_info->media_meta.artist)))) {
+ media_info_set_artist(media, content_info->cloud_name);
+ } else {
+ media_info_set_artist(media, content_info->media_meta.artist);
+ }
+
+ media_info_set_album(media, IS_STRING_NONEMPTY(content_info->media_meta.album) ? content_info->media_meta.album : "UNKNOWN");
+ media_info_set_genre(media, IS_STRING_NONEMPTY(content_info->media_meta.genre) ? content_info->media_meta.genre : "UNKNOWN");
+
+ media_info_set_duration(media, content_info->media_meta.duration);
+ media_info_set_width(media, content_info->media_meta.width);
+ media_info_set_height(media, content_info->media_meta.height);
+#endif
+}
--- /dev/null
+/*
+* Copyright (c) 2011 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 <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/xattr.h>
+#include <string.h>
+#include <fcntl.h>
+#include <metadata_extractor.h>
+
+#include "unified_storage_utils.h"
+#include "unified_storage_log.h"
+#include "metadata_manager/metadata_manager.h"
+
+/**
+ * Check if the file exists and is readable.
+ * The function will return 1 if NULL ptr is given as argument.
+ * @param filename path to the file
+ * @return 1 if yes, 0 otherwise
+ */
+static int file_exists(const char *filename);
+
+/**
+ * Convert file metadata to attribute_info_s structure.
+ * @param metadata metadata extractor handle
+ * @param file_info structure to be filled in by the function.
+ * @return true on success, false on failure
+ */
+static bool metadata_extract_from_handle(metadata_extractor_h metadata, attribute_info_s *file_info);
+
+int metadata_manager_extract_metadata(const char *file_path, attribute_info_s * file_info)
+{
+ int ret = METADATA_EXTRACTOR_ERROR_NONE;
+ metadata_extractor_h metadata;
+ if (!file_exists(file_path)) {
+ unified_storage_error("there is no file [%s]", file_path);
+ return -1;
+ }
+ ret = metadata_extractor_create(&metadata);
+ if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+ unified_storage_error("Fail metadata_extractor_create [%d]", ret);
+ return -2;
+ }
+
+ ret = metadata_extractor_set_path(metadata, file_path);
+ if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+ unified_storage_error("Fail metadata_extractor_set_path [%d]", ret);
+ metadata_extractor_destroy(metadata);
+ return -3;
+ }
+
+ metadata_extract_from_handle(metadata, file_info);
+ metadata_extractor_destroy(metadata);
+ return 0;
+}
+
+static int file_exists(const char *filename)
+{
+ int ret;
+
+ if (filename) {
+ const char *to_access = (strstr(filename, "file://") != NULL) ? filename + 7 : filename;
+ ret = access(to_access, R_OK);
+ if (ret != 0) {
+ unified_storage_info("file [%s] not found.", to_access);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void metadata_extract_create_thumbnail(metadata_extractor_h metadata, attribute_info_s *file_info)
+{
+ void *artwork = NULL;
+ char *artwork_mime = NULL;
+ int artwork_size = 0;
+ int size = 0;
+
+ if (NULL == metadata || NULL == file_info) {
+ unified_storage_error("Null pointer argument detected.");
+ return;
+ }
+
+ if (0 == strlen(file_info->media_thumb_path)) {
+ unified_storage_warning("There is no path to media thumb.");
+ return;
+ }
+
+ /*Get Artwork */
+ metadata_extractor_get_artwork(metadata, &artwork, &artwork_size, &artwork_mime);
+
+ if (artwork_size > 0) {
+ int ret = remove(file_info->media_thumb_path);
+ if (ERROR == ret) {
+ unified_storage_error("Thumbnail [%s] was not removed, error [%s]", file_info->media_thumb_path, strerror_w(errno));
+ }
+
+ int fh = 0;
+
+ fh = open(file_info->media_thumb_path, O_RDWR | O_TRUNC | O_CREAT, 0644);
+ if (fh == -1) {
+ unified_storage_debug("Cannot open thumbnail path = [%s]", file_info->media_thumb_path);
+ } else {
+ struct stat st;
+ stat(file_info->media_thumb_path, &st);
+ size = st.st_size;
+
+ if (size == 0) {
+ FILE *fp = fdopen(fh, "w");
+ if (fp != NULL) {
+ int n = fwrite((unsigned char *)artwork, 1, artwork_size, fp);
+ if (n != artwork_size) {
+ unified_storage_error("Cannot write to file [%s]", file_info->media_thumb_path);
+ fclose(fp);
+ } else {
+ unified_storage_debug("Created thumbnail = [%s]", file_info->media_thumb_path);
+ fflush(fp);
+ fclose(fp);
+ }
+ }
+ }
+ close(fh);
+ }
+ }
+
+ SAFE_FREE(artwork);
+ SAFE_FREE(artwork_mime);
+}
+
+static bool metadata_extract_from_handle(metadata_extractor_h metadata, attribute_info_s *file_info)
+{
+ char *duration = NULL;
+ char *audio_bitrate = NULL;
+ char *audio_channel = NULL;
+ char *audio_samplerate = NULL;
+ char *audio_track_cnt = NULL;
+ char *video_bitrate = NULL;
+ char *video_fps = NULL;
+ char *video_width = NULL;
+ char *video_height = NULL;
+ char *video_track_cnt = NULL;
+ void *video_thumbnail = NULL;
+ void *video_frame = NULL;
+
+ /*Tag info */
+ char *artist = NULL;
+ char *title = NULL;
+ char *album = NULL;
+ char *genre = NULL;
+ char *author = NULL;
+ char *copyright = NULL;
+ char *date = NULL;
+ char *description = NULL;
+ char *comment = NULL;
+ void *artwork = NULL;
+ char *artwork_mime = NULL;
+ char *track_num = NULL;
+ char *classification = NULL;
+ char *rating = NULL;
+ char *longitude = NULL;
+ char *latitude = NULL;
+ char *altitude = NULL;
+ char *conductor = NULL;
+ char *unsynclyrics = NULL;
+ char *synclyrics_num = NULL;
+ char *rec_date = NULL;
+ char *rotate = NULL;
+
+ if (metadata == NULL) {
+ unified_storage_error("Invalid handle.");
+ return false;
+ }
+
+ /*Get metadata */
+ metadata_extractor_get_metadata(metadata, METADATA_DURATION, &duration);
+ metadata_extractor_get_metadata(metadata, METADATA_AUDIO_BITRATE, &audio_bitrate);
+ metadata_extractor_get_metadata(metadata, METADATA_AUDIO_CHANNELS, &audio_channel);
+ metadata_extractor_get_metadata(metadata, METADATA_AUDIO_SAMPLERATE, &audio_samplerate);
+ metadata_extractor_get_metadata(metadata, METADATA_HAS_AUDIO, &audio_track_cnt);
+ metadata_extractor_get_metadata(metadata, METADATA_VIDEO_BITRATE, &video_bitrate);
+ metadata_extractor_get_metadata(metadata, METADATA_VIDEO_FPS, &video_fps);
+ metadata_extractor_get_metadata(metadata, METADATA_VIDEO_WIDTH, &video_width);
+ metadata_extractor_get_metadata(metadata, METADATA_VIDEO_HEIGHT, &video_height);
+ metadata_extractor_get_metadata(metadata, METADATA_HAS_VIDEO, &video_track_cnt);
+
+ metadata_extractor_get_metadata(metadata, METADATA_ARTIST, &artist);
+ metadata_extractor_get_metadata(metadata, METADATA_TITLE, &title);
+ metadata_extractor_get_metadata(metadata, METADATA_ALBUM, &album);
+ metadata_extractor_get_metadata(metadata, METADATA_GENRE, &genre);
+ metadata_extractor_get_metadata(metadata, METADATA_AUTHOR, &author);
+ metadata_extractor_get_metadata(metadata, METADATA_COPYRIGHT, ©right);
+ metadata_extractor_get_metadata(metadata, METADATA_DATE, &date);
+ metadata_extractor_get_metadata(metadata, METADATA_DESCRIPTION, &description);
+ metadata_extractor_get_metadata(metadata, METADATA_COMMENT, &comment);
+ metadata_extractor_get_metadata(metadata, METADATA_TRACK_NUM, &track_num);
+ metadata_extractor_get_metadata(metadata, METADATA_CLASSIFICATION, &classification);
+ metadata_extractor_get_metadata(metadata, METADATA_RATING, &rating);
+ metadata_extractor_get_metadata(metadata, METADATA_LONGITUDE, &longitude);
+ metadata_extractor_get_metadata(metadata, METADATA_LATITUDE, &latitude);
+ metadata_extractor_get_metadata(metadata, METADATA_ALTITUDE, &altitude);
+ metadata_extractor_get_metadata(metadata, METADATA_CONDUCTOR, &conductor);
+ metadata_extractor_get_metadata(metadata, METADATA_UNSYNCLYRICS, &unsynclyrics);
+ metadata_extractor_get_metadata(metadata, METADATA_RECDATE, &rec_date);
+ metadata_extractor_get_metadata(metadata, METADATA_ROTATE, &rotate);
+
+#ifdef VIDEO_THUMB
+ metadata_extractor_get_metadata(metadata, METADATA_SYNCLYRICS_NUM, &synclyrics_num);
+
+ int s_num = 0;
+ if (synclyrics_num != NULL)
+ s_num = atoi(synclyrics_num);
+ for (idx = 0; idx < s_num; idx++) {
+ metadata_extractor_get_synclyrics(metadata, idx, &time_info, &lyrics);
+ unified_storage_debug("[%2d][%6ld][%s]", idx, time_info, lyrics);
+ SAFE_FREE(lyrics);
+ }
+
+ /*Get Artwork */
+ metadata_extractor_get_artwork(metadata, &artwork, &artwork_size, &artwork_mime);
+ unified_storage_debug("artwork = [%p], artwork_size = [%d]", artwork, artwork_size);
+ unified_storage_debug("artwork_mime = [%s]", artwork_mime);
+
+ /*Get Thumbnail */
+ metadata_extractor_get_frame(metadata, &video_thumbnail, &video_thumbnail_len);
+ unified_storage_debug("video_thumbnail[%p], video_thumbnail_len = [%d]", video_thumbnail, video_thumbnail_len);
+
+ /*Get Video frame at time, extract frame of 22.5 sec and not key frame */
+ metadata_extractor_get_frame_at_time(metadata, 22500, false, &video_frame, &video_frame_len);
+ unified_storage_debug("video_frame[%p], video_frame_len = [%d]", video_frame, video_frame_len);
+#endif
+
+ /*Try get thumbnail from audio file, if exists create file in given path.*/
+ int video_track_num = 0;
+ if (video_track_cnt != NULL) {
+ video_track_num = atoi(video_track_cnt);
+ }
+ if (audio_track_cnt && g_strcmp0(audio_track_cnt, "0") && (0 == video_track_num)) {
+ metadata_extract_create_thumbnail(metadata, file_info);
+ }
+ /*content info */
+ if (title) {
+ snprintf(file_info->media_meta.title, CONTENTLEN, "%s", title);
+ }
+ if (album) {
+ snprintf(file_info->media_meta.album, CONTENTLEN, "%s", album);
+ }
+ if (artist) {
+ snprintf(file_info->media_meta.artist, CONTENTLEN, "%s", artist);
+ }
+ if (genre) {
+ snprintf(file_info->media_meta.genre, CONTENTLEN, "%s", genre);
+ }
+ if (date) {
+ snprintf(file_info->media_meta.datetaken, CONTENTLEN, "%s", date);
+ }
+ if (rec_date) {
+ snprintf(file_info->media_meta.recorded_date, CONTENTLEN, "%s", rec_date);
+ }
+ if (copyright) {
+ snprintf(file_info->media_meta.copyright, CONTENTLEN, "%s", copyright);
+ }
+ if (audio_track_cnt) {
+ snprintf(file_info->media_meta.track_num, CONTENTLEN, "%s", audio_track_cnt);
+ } else if (video_track_cnt) {
+ snprintf(file_info->media_meta.track_num, CONTENTLEN, "%s", video_track_cnt);
+ }
+ if (description) {
+ snprintf(file_info->media_meta.description, CONTENTLEN, "%s", description);
+ }
+ if (audio_bitrate) {
+ file_info->media_meta.bitrate = atoi(audio_bitrate);
+ } else if (video_bitrate) {
+ file_info->media_meta.bitrate = atoi(video_bitrate);
+ }
+ if (audio_samplerate) {
+ file_info->media_meta.samplerate = atoi(audio_samplerate);
+ }
+ if (audio_channel) {
+ file_info->media_meta.channel = atoi(audio_channel);
+ }
+ if (duration) {
+ file_info->media_meta.duration = atoi(duration);
+ }
+ if (longitude) {
+ file_info->media_meta.longitude = atof(longitude);
+ }
+ if (latitude) {
+ file_info->media_meta.latitude = atof(latitude);
+ }
+ if (altitude) {
+ file_info->media_meta.altitude = atof(altitude);
+ }
+ if (video_width) {
+ file_info->media_meta.width = atoi(video_width);
+ }
+ if (video_height) {
+ file_info->media_meta.height = atoi(video_height);
+ }
+
+ SAFE_FREE(duration);
+ SAFE_FREE(audio_bitrate);
+ SAFE_FREE(audio_channel);
+ SAFE_FREE(audio_samplerate);
+ SAFE_FREE(audio_track_cnt);
+ SAFE_FREE(video_bitrate);
+ SAFE_FREE(video_fps);
+ SAFE_FREE(video_width);
+ SAFE_FREE(video_height);
+ SAFE_FREE(video_track_cnt);
+ SAFE_FREE(video_thumbnail);
+ SAFE_FREE(video_frame);
+
+ SAFE_FREE(artist);
+ SAFE_FREE(title);
+ SAFE_FREE(album);
+ SAFE_FREE(genre);
+ SAFE_FREE(author);
+ SAFE_FREE(copyright);
+ SAFE_FREE(date);
+ SAFE_FREE(description);
+ SAFE_FREE(comment);
+ SAFE_FREE(artwork);
+ SAFE_FREE(artwork_mime);
+ SAFE_FREE(track_num);
+ SAFE_FREE(classification);
+ SAFE_FREE(rating);
+ SAFE_FREE(longitude);
+ SAFE_FREE(latitude);
+ SAFE_FREE(altitude);
+ SAFE_FREE(conductor);
+ SAFE_FREE(unsynclyrics);
+ SAFE_FREE(synclyrics_num);
+ SAFE_FREE(rec_date);
+ SAFE_FREE(rotate);
+
+ return true;
+}
--- /dev/null
+/*
+* Copyright (c) 2011 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 "thumbnail_manager/media-thumb-hash.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+
+static long long current_time_millis(void)
+{
+ struct timeval te;
+ gettimeofday(&te, NULL);
+ long long millis = te.tv_sec * 1000LL + te.tv_usec / 1000;
+ return millis;
+}
+
+int thumbnail_generate_hash_code(const char *origin_path, char *hash_code, int max_length)
+{
+ if (NULL == origin_path || 0 == strlen(origin_path))
+ return -1;
+
+ snprintf(hash_code, max_length, "%lld", current_time_millis());
+
+ return 0;
+}
--- /dev/null
+/*
+* Copyright (c) 2011 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 <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <alloca.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <glib.h>
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+#include <thumbnail_util.h>
+#include <image_util.h>
+#endif
+#include "unified_storage_utils.h"
+#include "unified_storage_log.h"
+#include "thumbnail_manager/thumbnail_manager.h"
+#include "thumbnail_manager/media-thumb-hash.h"
+
+#define THUMB_EXTRACT_TIMEOUT 5
+
+static thumbnail_size_s current_thumbnail_size = {
+ .height = 255,
+ .width = 255
+};
+
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+typedef struct sync_wrapper_context_s {
+ char *file_path;
+ char *thumb_path;
+ char *request_id;
+ GMainLoop *loop;
+ GMutex mutex;
+ GCond cond;
+ int error;
+} sync_wrapper_context_t;
+typedef sync_wrapper_context_t *sync_wrapper_context_h;
+
+static thumbnail_h thumb = NULL;
+#endif
+
+int thumbnail_manager_init(void)
+{
+ int ret = NO_ERROR;
+
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ if (NULL != thumb) {
+ thumbnail_util_destroy(thumb);
+ thumb = NULL;
+ }
+
+ ret = thumbnail_util_create(&thumb);
+
+ if (NO_ERROR != ret) {
+ unified_storage_error("thumbnail util create failed: %d", ret);
+ return ret;
+ }
+
+ ret = thumbnail_util_set_size(thumb, current_thumbnail_size.width, current_thumbnail_size.height);
+
+ if (NO_ERROR != ret) {
+ unified_storage_error("thumbnail util set size failed: %d", ret);
+ return ret;
+ }
+#endif
+
+ return ret;
+}
+
+int thumbnail_manager_deinit(void)
+{
+ int ret = NO_ERROR;
+
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ if (NULL == thumb) {
+ unified_storage_error("thumbnail util handle is NULL");
+ return INVALID_HANDLE;
+ }
+
+ ret = thumbnail_util_destroy(thumb);
+ thumb = NULL;
+#endif
+
+ return ret;
+}
+
+void thumbnail_manager_set_thumbnail_size(const thumbnail_size_s *thumbnail_size)
+{
+ current_thumbnail_size.height = thumbnail_size->height;
+ current_thumbnail_size.width = thumbnail_size->width;
+
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ if (NULL != thumb)
+ thumbnail_util_set_size(thumb, current_thumbnail_size.width, current_thumbnail_size.height);
+#endif
+}
+
+void thumbnail_manager_get_thumbnail_size(thumbnail_size_s *thumbnail_size)
+{
+ thumbnail_size->height = current_thumbnail_size.height;
+ thumbnail_size->width = current_thumbnail_size.width;
+}
+
+int thumbnail_manager_generate_hash(const char *origin_path, char *hash_code, int max_length)
+{
+ int ret = thumbnail_generate_hash_code(origin_path, hash_code, max_length);
+ return ret;
+}
+
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+int thumbnail_manager_save_to_jpeg(const char *thumb_path, int thumb_width, int thumb_height, unsigned char *thumb_data, int thumb_size)
+{
+ unsigned char *jpeg_buffer = NULL;
+ unsigned int jpeg_size = 0;
+
+ int ret = image_util_encode_jpeg_to_memory(thumb_data, thumb_width, thumb_height, IMAGE_UTIL_COLORSPACE_BGRA8888, 100, &jpeg_buffer, &jpeg_size);
+
+ if (NO_ERROR != ret) {
+ unified_storage_error("encode to jpeg failed: %s", ret);
+ free(jpeg_buffer);
+ return ret;
+ }
+
+ unified_storage_debug("jpeg_size: %u", jpeg_size);
+
+ /* Save to jpeg file */
+ int fd = -1;
+ if (0 > (fd = open(thumb_path, O_WRONLY|O_CREAT|O_EXCL, 0755))) {
+ unified_storage_error("Open file faied");
+ free(jpeg_buffer);
+ return OPENFILE_ERROR;
+ }
+
+ size_t total_size = (size_t) write(fd, jpeg_buffer, (size_t) jpeg_size);
+ if (total_size < (size_t) jpeg_size) {
+ unified_storage_error("Write file failed");
+ free(jpeg_buffer);
+ close(fd);
+ return UNKNOWN_ERROR;
+ }
+
+ free(jpeg_buffer);
+ close(fd);
+
+ return NO_ERROR;
+}
+
+void thumbnail_manager_extract_cb(thumbnail_util_error_e error, const char *request_id, int thumb_width, int thumb_height, unsigned char *thumb_data, int thumb_size, void *user_data)
+{
+ unified_storage_debug("thumbnail manager extract cb");
+
+ unified_storage_debug("error: %d", (int) error);
+ unified_storage_debug("request_id: %s", request_id);
+ unified_storage_debug("width: %d, height: %d", thumb_width, thumb_height);
+ unified_storage_debug("size: %d", thumb_size);
+
+ if (user_data == NULL) {
+ unified_storage_error("Cannot find thumbnail path");
+ return;
+ }
+
+ sync_wrapper_context_h context = (sync_wrapper_context_h) user_data;
+
+ if (THUMBNAIL_UTIL_ERROR_NONE != error) {
+ unified_storage_error("thumbnail extract failed: %d", (int) error);
+ context->error = error;
+ return;
+ }
+
+ /* Save thumbnail */
+ const char *thumb_path = (const char *) context->thumb_path;
+ unified_storage_debug("thumbnail path: %s", thumb_path);
+
+ int ret = thumbnail_manager_save_to_jpeg(thumb_path, thumb_width, thumb_height, thumb_data, thumb_size);
+ if (NO_ERROR != ret) {
+ unified_storage_error("thumbnail save failed: %d", ret);
+ context->error = ret;
+ }
+
+ g_cond_signal(&context->cond);
+}
+
+void *thumbnail_extract_async(void *data)
+{
+ sync_wrapper_context_h context = (sync_wrapper_context_h) data;
+
+ if (NULL == context) {
+ unified_storage_error("Empty context");
+ return NULL;
+ }
+
+ /* Lock */
+ g_mutex_lock(&context->mutex);
+
+ /* Extract */
+ int ret = thumbnail_util_extract(thumb, thumbnail_manager_extract_cb, (void *) context, &context->request_id);
+ if (NO_ERROR != ret) {
+ unified_storage_error("thumbnail util extract failed: %d", ret);
+ g_mutex_unlock(&context->mutex);
+ context->error = ret;
+ return NULL;
+ }
+
+ /* Wait callback */
+ gint64 end_time = g_get_monotonic_time() + THUMB_EXTRACT_TIMEOUT * G_TIME_SPAN_SECOND;
+ if (FALSE == g_cond_wait_until(&context->cond, &context->mutex, end_time)) {
+ /* Timeout */
+ unified_storage_error("thumbnail extraction timed out!!");
+ context->error = CONDITIONAL_TIMEOUT_EXCEEDED;
+ }
+
+ /* Unlock */
+ g_mutex_unlock(&context->mutex);
+ g_main_loop_quit(context->loop);
+
+ return NULL;
+}
+
+int thumbnail_request_save_to_file(const char *file_path, const char *thumb_path)
+{
+ unified_storage_debug("file_path: %s, thumb_path: %s", file_path, thumb_path);
+ unified_storage_debug("thumbnail request save to file");
+
+ int ret = NO_ERROR;
+
+ if (NULL == thumb) {
+ unified_storage_error("thumbnail util handle is NULL");
+ return INVALID_HANDLE;
+ }
+
+ /* Prepare sync-wrapper context */
+ sync_wrapper_context_h context = (sync_wrapper_context_h) calloc(1, sizeof(sync_wrapper_context_t));
+ if (NULL == context) {
+ unified_storage_error("Cannot allocate memory");
+ return MEMORY_ALLOCATION_ERROR;
+ }
+ context->file_path = strdup(file_path);
+ context->thumb_path = strdup(thumb_path);
+ g_mutex_init(&context->mutex);
+ g_cond_init(&context->cond);
+ context->loop = g_main_loop_new(NULL, FALSE);
+
+ /* Set Medial File Path */
+ ret = thumbnail_util_set_path(thumb, context->file_path);
+ if (NO_ERROR != ret) {
+ unified_storage_error("thumbnail util set path failed: %d", ret);
+ } else {
+ /* Extract thumbnail data */
+ GError *worker_error = NULL;
+ GThread *worker = g_thread_try_new("thumbnail_extractor", (GThreadFunc) thumbnail_extract_async, (void *) context, &worker_error);
+ if (NULL == worker) {
+ if (NULL == worker_error)
+ unified_storage_error("Cannot create thread");
+ else {
+ unified_storage_error("Cannot create thread: %s", worker_error->message);
+ g_clear_error(&worker_error);
+ }
+
+ ret = MEMORY_ALLOCATION_ERROR;
+ } else {
+ /* Wait */
+ g_main_loop_run(context->loop);
+
+ /* Result */
+ ret = context->error;
+ }
+ }
+
+ free(context->file_path);
+ free(context->thumb_path);
+ free(context->request_id);
+ g_main_loop_unref(context->loop);
+ g_mutex_clear(&context->mutex);
+ g_cond_clear(&context->cond);
+ free(context);
+
+ return ret;
+}
+#endif
+
+/* TODO check this function */
+/* int create_thumbnail_file_for_image_file(const char *file_path, media_thumb_type_e thumb_type, const char *thumb_path) */
+int create_thumbnail_file_for_image_file(const char *file_path, const char *thumb_path)
+{
+ int res = SUCCESS;
+#ifdef UNIFIED_FORMAT_MOBILE_FEATURE_ENABLE
+ res = thumbnail_request_save_to_file(file_path, thumb_path);
+/* res = thumbnail_request_save_to_file(file_path, (media_thumb_type)thumb_type, thumb_path); */
+#endif
+ if (res < 0)
+ unified_storage_error("Failed to save thumbnail for file [%s], thumbnail path = [%s], res = [%d]", file_path, thumb_path, res);
+
+ return res;
+}
--- /dev/null
+/*
+* Copyright (c) 2011 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 <stdlib.h>
+#include <glib.h>
+#include <stdio.h>
+#include <gio/gio.h>
+#include <sys/time.h>
+
+#include "unified_storage_error_codes.h"
+#include "unified_storage_log.h"
+#include "unified_storage_utils.h"
+
+struct _ftype_by_mime {
+ const char *mime;
+ file_type_e ftype;
+};
+
+static struct _ftype_by_mime mime_type[] = {
+ {"image/png", FILE_TYPE_IMAGE},
+ {"image/jpeg", FILE_TYPE_IMAGE},
+ {"image/gif", FILE_TYPE_IMAGE},
+ {"image/bmp", FILE_TYPE_IMAGE},
+ {"image/vnd.wap.wbmp", FILE_TYPE_IMAGE},
+ {"video/x-msvideo", FILE_TYPE_VIDEO},
+ {"video/mp4", FILE_TYPE_VIDEO},
+ {"video/3gpp", FILE_TYPE_VIDEO},
+ {"video/x-ms-asf", FILE_TYPE_VIDEO},
+ {"video/x-ms-wmv", FILE_TYPE_VIDEO},
+ {"video/x-matroska", FILE_TYPE_VIDEO},
+ {"audio/mpeg", FILE_TYPE_AUDIO},
+ {"audio/x-wav", FILE_TYPE_AUDIO},
+ {"application/x-smaf", FILE_TYPE_AUDIO},
+ {"audio/mxmf", FILE_TYPE_AUDIO},
+ {"audio/midi", FILE_TYPE_AUDIO},
+ {"audio/x-xmf", FILE_TYPE_AUDIO},
+ {"audio/x-ms-wma", FILE_TYPE_AUDIO},
+ {"audio/aac", FILE_TYPE_AUDIO},
+ {"audio/ac3", FILE_TYPE_AUDIO},
+ {"audio/ogg", FILE_TYPE_AUDIO},
+ {"audio/vorbis", FILE_TYPE_AUDIO},
+ {"audio/imelody", FILE_TYPE_AUDIO},
+ {"audio/iMelody", FILE_TYPE_AUDIO},
+ {"audio/x-rmf", FILE_TYPE_AUDIO},
+ {"application/vnd.smaf", FILE_TYPE_AUDIO},
+ {"audio/mobile-xmf", FILE_TYPE_AUDIO},
+ {"audio/mid", FILE_TYPE_AUDIO},
+ {"audio/vnd.ms-playready.media.pya", FILE_TYPE_AUDIO},
+ {"audio/imy", FILE_TYPE_AUDIO},
+ {"audio/m4a", FILE_TYPE_AUDIO},
+ {"audio/melody", FILE_TYPE_AUDIO},
+ {"audio/mmf", FILE_TYPE_AUDIO},
+ {"audio/mp3", FILE_TYPE_AUDIO},
+ {"audio/mp4", FILE_TYPE_AUDIO},
+ {"audio/MP4A-LATM", FILE_TYPE_AUDIO},
+ {"audio/mpeg3", FILE_TYPE_AUDIO},
+ {"audio/mpeg4", FILE_TYPE_AUDIO},
+ {"audio/mpg", FILE_TYPE_AUDIO},
+ {"audio/mpg3", FILE_TYPE_AUDIO},
+ {"audio/smaf", FILE_TYPE_AUDIO},
+ {"audio/sp-midi", FILE_TYPE_AUDIO},
+ {"audio/wav", FILE_TYPE_AUDIO},
+ {"audio/wave", FILE_TYPE_AUDIO},
+ {"audio/wma", FILE_TYPE_AUDIO},
+ {"audio/xmf", FILE_TYPE_AUDIO},
+ {"audio/x-mid", FILE_TYPE_AUDIO},
+ {"audio/x-midi", FILE_TYPE_AUDIO},
+ {"audio/x-mp3", FILE_TYPE_AUDIO},
+ {"audio/-mpeg", FILE_TYPE_AUDIO},
+ {"audio/x-mpeg", FILE_TYPE_AUDIO},
+ {"audio/x-mpegaudio", FILE_TYPE_AUDIO},
+ {"audio/x-mpg", FILE_TYPE_AUDIO},
+ {"audio/x-ms-asf", FILE_TYPE_AUDIO},
+ {"audio/x-wave", FILE_TYPE_AUDIO},
+ {"application/pdf", FILE_TYPE_PDF},
+ {"application/octet-stream", FILE_TYPE_ETC},
+ {"application/msword", FILE_TYPE_DOC},
+ {"application/vnd.openxmlformats-officedocument.wordprocessingml.document", FILE_TYPE_DOC},
+ {"application/vnd.ms-powerpoint", FILE_TYPE_PPT},
+ {"application/vnd.openxmlformats-officedocument.presentationml.presentation", FILE_TYPE_PPT},
+ {"application/vnd.ms-excel", FILE_TYPE_EXCEL},
+ {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", FILE_TYPE_EXCEL},
+ {"application/vnd.google-apps.audio", FILE_TYPE_AUDIO},
+ {"application/vnd.google-apps.document", FILE_TYPE_DOC},
+ {"application/vnd.google-apps.presentation", FILE_TYPE_PPT},
+ {"application/vnd.google-apps.spreadsheet", FILE_TYPE_EXCEL},
+ {"application/vnd.google-apps.video", FILE_TYPE_VIDEO},
+ {"application/vnd.google-apps.photo", FILE_TYPE_IMAGE},
+ {"application/vnd.google-apps.drawing", FILE_TYPE_IMAGE},
+ {"application/vnd.google-apps.folder", FILE_TYPE_DIR},
+ {"text/plain", FILE_TYPE_TXT},
+ {NULL, FILE_TYPE_NONE},
+};
+
+#define STRERROR_LEN 255
+char strerror_tab[STRERROR_LEN];
+
+const char* const strerror_w(int err_number)
+{
+ return strerror_r(err_number, strerror_tab, STRERROR_LEN);
+}
+
+char* sprintf_s(const char *format, ...)
+{
+ gchar *gbuf = NULL;
+ char *cbuf = NULL;
+ va_list args;
+
+ va_start(args, format);
+ gbuf = g_strdup_vprintf(format, args);
+ va_end(args);
+
+ if (NULL != gbuf) {
+ cbuf = SAFE_STRDUP((const char *)gbuf);
+ SAFE_FREE(gbuf);
+ }
+
+ return cbuf;
+}
+
+void unified_storage_utils_convert_attribute_info_to_content_info(attribute_info_s *attribute_info, content_info_s *content_info)
+{
+ content_info->media_uuid = SAFE_STRDUP(attribute_info->media_uuid);
+ content_info->file_name = SAFE_STRDUP(attribute_info->media_name);
+ content_info->path = SAFE_STRDUP(attribute_info->media_path);
+ content_info->thumbnail_path = SAFE_STRDUP(attribute_info->media_thumb_path);
+ content_info->cloud_name = SAFE_STRDUP(attribute_info->cloud_name);
+ content_info->cloud_path = SAFE_STRDUP(attribute_info->cloud_path);
+ content_info->cloud_folder_name = SAFE_STRDUP(attribute_info->cloud_folder_name);
+ content_info->cloud_folder_path = SAFE_STRDUP(attribute_info->cloud_folder_path);
+ content_info->storage_uuid = SAFE_STRDUP(attribute_info->storage_uuid);
+ content_info->media_meta.title = SAFE_STRDUP(attribute_info->media_meta.title);
+ content_info->media_meta.album = SAFE_STRDUP(attribute_info->media_meta.album);
+ content_info->media_meta.artist = SAFE_STRDUP(attribute_info->media_meta.artist);
+ content_info->media_meta.genre = SAFE_STRDUP(attribute_info->media_meta.genre);
+ content_info->media_meta.composer = SAFE_STRDUP(attribute_info->media_meta.composer);
+ content_info->media_meta.year = SAFE_STRDUP(attribute_info->media_meta.year);
+ content_info->media_meta.recorded_date = SAFE_STRDUP(attribute_info->media_meta.recorded_date);
+ content_info->media_meta.copyright = SAFE_STRDUP(attribute_info->media_meta.copyright);
+ content_info->media_meta.track_num = SAFE_STRDUP(attribute_info->media_meta.track_num);
+ content_info->media_meta.description = SAFE_STRDUP(attribute_info->media_meta.description);
+ content_info->media_meta.datetaken = SAFE_STRDUP(attribute_info->media_meta.datetaken);
+
+ content_info->media_meta.bitrate = attribute_info->media_meta.bitrate;
+ content_info->media_meta.samplerate = attribute_info->media_meta.samplerate;
+ content_info->media_meta.channel = attribute_info->media_meta.channel;
+ content_info->media_meta.duration = attribute_info->media_meta.duration;
+ content_info->media_meta.longitude = attribute_info->media_meta.longitude;
+ content_info->media_meta.latitude = attribute_info->media_meta.latitude;
+ content_info->media_meta.altitude = attribute_info->media_meta.altitude;
+ content_info->media_meta.width = attribute_info->media_meta.width;
+ content_info->media_meta.height = attribute_info->media_meta.height;
+ content_info->media_meta.orientation = attribute_info->media_meta.orientation;
+ content_info->media_meta.rating = attribute_info->media_meta.rating;
+ content_info->size = attribute_info->media_size;
+ content_info->added_time = attribute_info->created_time;
+ content_info->modified_time = attribute_info->modified_time;
+ content_info->album_id = attribute_info->album_id;
+ content_info->played_count = attribute_info->played_count;
+ content_info->last_played_time = attribute_info->last_played_time;
+ content_info->last_played_position = attribute_info->last_played_position;
+ content_info->favourite = attribute_info->favourite;
+ content_info->is_drm = attribute_info->is_drm;
+
+ if (strlen(attribute_info->mime_type) > 0) {
+ content_info->mime_type = SAFE_STRDUP(attribute_info->mime_type);
+ } else {
+ gboolean is_certain = FALSE;
+ char *content_type = g_content_type_guess(attribute_info->media_name, NULL, 0, &is_certain);
+
+ if (content_type != NULL) {
+ char *mime_type = g_content_type_get_mime_type(content_type);
+ unified_storage_debug("Guessing content type for file '%s': %s (certain: %s) MIME type for content type: %s", attribute_info->media_name, content_type, is_certain ? "yes" : "no", mime_type);
+ content_info->mime_type = SAFE_STRDUP(mime_type);
+ snprintf(attribute_info->mime_type, FILEBUFLEN, "%s", mime_type);
+ SAFE_FREE(mime_type);
+ }
+ SAFE_FREE(content_type);
+ }
+
+ content_info->media_type = unified_storage_utils_get_file_type_by_mime_type(content_info->mime_type);
+ content_info->folder_uuid = SAFE_STRDUP("");
+}
+
+void unified_storage_utils_convert_content_info_to_attribute_info(content_info_s *content_info, attribute_info_s *attribute_info)
+{
+ if (NULL == content_info || NULL == attribute_info) {
+ unified_storage_error("NULL argument(s): content_info [%p], attribute_info [%p]");
+ return;
+ }
+
+ if (NULL != content_info->media_uuid) {
+ snprintf(attribute_info->media_uuid, CONTENTLEN, "%s", content_info->media_uuid);
+ } else {
+ attribute_info->media_uuid[0] = 0;
+ }
+
+ if (NULL != content_info->file_name) {
+ snprintf(attribute_info->media_name, FILEBUFLEN, "%s", content_info->file_name);
+ }
+
+ if (NULL != content_info->path) {
+ snprintf(attribute_info->media_path, FILEBUFLEN, "%s", content_info->path);
+ }
+
+ if (NULL != content_info->storage_uuid) {
+ snprintf(attribute_info->storage_uuid, FILEBUFLEN, "%s", content_info->storage_uuid);
+ }
+
+ if (NULL != content_info->thumbnail_path) {
+ snprintf(attribute_info->media_thumb_path, CONTENTLEN, "%s", content_info->thumbnail_path);
+ }
+
+ if (NULL != content_info->cloud_name) {
+ snprintf(attribute_info->cloud_name, FILEBUFLEN, "%s", content_info->cloud_name);
+ }
+
+ if (NULL != content_info->cloud_path) {
+ snprintf(attribute_info->cloud_path, FILEBUFLEN, "%s", content_info->cloud_path);
+ }
+
+ if (NULL != content_info->cloud_folder_name) {
+ snprintf(attribute_info->cloud_folder_name, FILEBUFLEN, "%s", content_info->cloud_folder_name);
+ }
+
+ if (NULL != content_info->cloud_folder_path) {
+ snprintf(attribute_info->cloud_folder_path, FILEBUFLEN, "%s", content_info->cloud_folder_path);
+ }
+
+ if (NULL != content_info->media_meta.title) {
+ snprintf(attribute_info->media_meta.title, CONTENTLEN, "%s", content_info->media_meta.title);
+ }
+
+ if (NULL != content_info->media_meta.album) {
+ snprintf(attribute_info->media_meta.album, CONTENTLEN, "%s", content_info->media_meta.album);
+ }
+
+ if (NULL != content_info->media_meta.artist) {
+ snprintf(attribute_info->media_meta.artist, CONTENTLEN, "%s", content_info->media_meta.artist);
+ }
+
+ if (NULL != content_info->media_meta.genre) {
+ snprintf(attribute_info->media_meta.genre, CONTENTLEN, "%s", content_info->media_meta.genre);
+ }
+
+ if (NULL != content_info->media_meta.composer) {
+ snprintf(attribute_info->media_meta.composer, CONTENTLEN, "%s", content_info->media_meta.composer);
+ }
+
+ if (NULL != content_info->media_meta.year) {
+ snprintf(attribute_info->media_meta.year, CONTENTLEN, "%s", content_info->media_meta.year);
+ }
+
+ if (NULL != content_info->media_meta.recorded_date) {
+ snprintf(attribute_info->media_meta.recorded_date, CONTENTLEN, "%s", content_info->media_meta.recorded_date);
+ }
+
+ if (NULL != content_info->media_meta.copyright) {
+ snprintf(attribute_info->media_meta.copyright, CONTENTLEN, "%s", content_info->media_meta.copyright);
+ }
+
+ if (NULL != content_info->media_meta.track_num) {
+ snprintf(attribute_info->media_meta.track_num, CONTENTLEN, "%s", content_info->media_meta.track_num);
+ }
+
+ if (NULL != content_info->media_meta.description) {
+ snprintf(attribute_info->media_meta.description, CONTENTLEN, "%s", content_info->media_meta.description);
+ }
+
+ if (NULL != content_info->media_meta.datetaken) {
+ snprintf(attribute_info->media_meta.datetaken, CONTENTLEN, "%s", content_info->media_meta.datetaken);
+ }
+
+ attribute_info->media_meta.bitrate = content_info->media_meta.bitrate;
+ attribute_info->media_meta.samplerate = content_info->media_meta.samplerate;
+ attribute_info->media_meta.channel = content_info->media_meta.channel;
+ attribute_info->media_meta.duration = content_info->media_meta.duration;
+ attribute_info->media_meta.longitude = content_info->media_meta.longitude;
+ attribute_info->media_meta.latitude = content_info->media_meta.latitude;
+ attribute_info->media_meta.altitude = content_info->media_meta.altitude;
+ attribute_info->media_meta.width = content_info->media_meta.width;
+ attribute_info->media_meta.height = content_info->media_meta.height;
+ attribute_info->media_meta.orientation = content_info->media_meta.orientation;
+ attribute_info->media_meta.rating = content_info->media_meta.rating;
+ attribute_info->media_size = content_info->size;
+ attribute_info->created_time = content_info->added_time;
+ attribute_info->modified_time = content_info->modified_time;
+ attribute_info->album_id = content_info->album_id;
+ attribute_info->played_count = content_info->played_count;
+ attribute_info->last_played_time = content_info->last_played_time;
+ attribute_info->last_played_position = content_info->last_played_position;
+ attribute_info->favourite = content_info->favourite;
+ attribute_info->is_drm = content_info->is_drm;
+
+ if (content_info->mime_type && 0 < strlen(content_info->mime_type)) {
+ snprintf(attribute_info->mime_type, FILEBUFLEN, "%s", content_info->mime_type);
+ } else {
+ gboolean is_certain = FALSE;
+ char *content_type = g_content_type_guess(content_info->file_name, NULL, 0, &is_certain);
+
+ if (content_type != NULL) {
+ char *mime_type = g_content_type_get_mime_type(content_type);
+ unified_storage_debug("Guessing content type for file '%s': %s (certain: %s)\n MIME type for content type: %s", content_info->file_name, content_type, is_certain ? "yes" : "no", mime_type);
+ snprintf(attribute_info->mime_type, FILEBUFLEN, "%s", mime_type);
+ SAFE_FREE(mime_type);
+ }
+ SAFE_FREE(content_type);
+ }
+}
+
+void unified_storage_utils_release_content_info(content_info_s *content_info)
+{
+ if (content_info == NULL) {
+ return;
+ }
+
+ SAFE_FREE(content_info->media_uuid);
+ SAFE_FREE(content_info->path);
+ SAFE_FREE(content_info->file_name);
+ SAFE_FREE(content_info->mime_type);
+ SAFE_FREE(content_info->folder_uuid);
+ SAFE_FREE(content_info->thumbnail_path);
+ SAFE_FREE(content_info->ref);
+ SAFE_FREE(content_info->file_data);
+ SAFE_FREE(content_info->cloud_path);
+ SAFE_FREE(content_info->cloud_name);
+ SAFE_FREE(content_info->cloud_folder_name);
+ SAFE_FREE(content_info->cloud_folder_path);
+ SAFE_FREE(content_info->storage_uuid);
+
+ SAFE_FREE(content_info->media_meta.title);
+ SAFE_FREE(content_info->media_meta.album);
+ SAFE_FREE(content_info->media_meta.artist);
+ SAFE_FREE(content_info->media_meta.genre);
+ SAFE_FREE(content_info->media_meta.composer);
+ SAFE_FREE(content_info->media_meta.year);
+ SAFE_FREE(content_info->media_meta.recorded_date);
+ SAFE_FREE(content_info->media_meta.copyright);
+ SAFE_FREE(content_info->media_meta.track_num);
+ SAFE_FREE(content_info->media_meta.description);
+ SAFE_FREE(content_info->media_meta.datetaken);
+
+ SAFE_FREE(content_info);
+}
+
+void unified_storage_utils_release_contents_list(GList *contents_list)
+{
+ if (contents_list == NULL) {
+ return;
+ }
+
+ g_list_free_full(contents_list, (GDestroyNotify) unified_storage_utils_release_content_info);
+ contents_list = NULL;
+}
+
+void unified_storage_utils_release_file_info(file_info_s *list_element)
+{
+ if (list_element == NULL) {
+ return;
+ }
+
+ g_list_free_full(list_element->child, (GDestroyNotify) unified_storage_utils_release_file_info);
+ list_element->child = NULL;
+
+ SAFE_FREE(list_element->name);
+ SAFE_FREE(list_element->path);
+ SAFE_FREE(list_element->cloud_path);
+ SAFE_FREE(list_element->mime_type);
+ SAFE_FREE(list_element->title);
+ SAFE_FREE(list_element->album);
+ SAFE_FREE(list_element->artist);
+ SAFE_FREE(list_element->genre);
+ SAFE_FREE(list_element->composer);
+ SAFE_FREE(list_element->year);
+ SAFE_FREE(list_element->recorded_date);
+ SAFE_FREE(list_element->copyright);
+ SAFE_FREE(list_element->track_num);
+ SAFE_FREE(list_element->description);
+ SAFE_FREE(list_element->datetaken);
+ SAFE_FREE(list_element->ref);
+ SAFE_FREE(list_element->file_data);
+ SAFE_FREE(list_element->link_path);
+
+ SAFE_FREE(list_element);
+}
+
+void unified_storage_utils_release_file_list(GList *file_list)
+{
+ if (file_list == NULL) {
+ return;
+ }
+
+ g_list_free_full(file_list, (GDestroyNotify) unified_storage_utils_release_file_info);
+ file_list = NULL;
+}
+
+void unified_storage_utils_release_accounts_info(account_info_s *account_info)
+{
+ if (account_info == NULL) {
+ return;
+ }
+
+ SAFE_FREE(account_info->user.user_id);
+ SAFE_FREE(account_info->user.user_name);
+ SAFE_FREE(account_info->user.email);
+ SAFE_FREE(account_info);
+}
+
+void unified_storage_utils_release_accounts_list(GList *accounts_list)
+{
+ if (accounts_list == NULL) {
+ return;
+ }
+
+ g_list_free_full(accounts_list, (GDestroyNotify) unified_storage_utils_release_accounts_list_element);
+ accounts_list = NULL;
+}
+
+void unified_storage_utils_release_id_descriptor(id_descriptor_s *id_descriptor)
+{
+ if (id_descriptor == NULL) {
+ return;
+ }
+
+ SAFE_FREE(id_descriptor->cloud_info.cloud_name);
+ SAFE_FREE(id_descriptor->cloud_info.cloud_icon_path);
+ SAFE_FREE(id_descriptor->cloud_info.cloud_account);
+ SAFE_FREE(id_descriptor->storage_uuid);
+ SAFE_FREE(id_descriptor);
+}
+
+void unified_storage_utils_release_accounts_list_element(gpointer data)
+{
+ if (data == NULL) {
+ return;
+ }
+
+ unified_storage_utils_release_id_descriptor((id_descriptor_s *) data);
+ data = NULL;
+}
+
+file_type_e unified_storage_utils_get_file_type_by_mime_type(char *mime)
+{
+ int index = 0;
+ file_type_e file_type = FILE_TYPE_ETC;
+
+ if (NULL != mime) {
+ for (index = 0; mime_type[index].mime; index++) {
+ if (strncmp(mime, mime_type[index].mime, strlen(mime)) == 0) {
+ file_type = mime_type[index].ftype;
+ break;
+ }
+ }
+ }
+
+ return file_type;
+}
+
+struct timeval MEASURE_START()
+{
+ struct timeval time;
+ gettimeofday(&time, NULL);
+
+ return time;
+}
+
+unsigned long long int MEASURE_TIME(struct timeval time)
+{
+ struct timeval m_time;
+ gettimeofday(&m_time, NULL);
+
+ unsigned long long int elasped_time = ((m_time.tv_sec - time.tv_sec) * MILLION + (m_time.tv_usec - time.tv_usec)) / THOUSAND;
+
+ return elasped_time;
+}
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+ <assign>
+ <filesystem path="/usr/lib/libunifiedstorage-format.so" label="_" exec_label="_" />
+ </assign>
+</manifest>
--- /dev/null
+prefix=@PREFIX@
+libdir=@PREFIX@/lib
+includedir=@PREFIX@/include/unifiedstorage-format
+
+Name: unifiedstorage-format
+Description: unified storage format library
+
+Version: @VERSION@
+
+Libs: -L${libdir} -lunifiedstorage-format
+Cflags: -DUNIFIED_STORAGE_FORMAT_DLL -I${includedir}/