Modify external storage scan
[platform/core/multimedia/libmedia-service.git] / src / common / media-svc-localize-utils.c
1 /*
2  * Media Service
3  *
4  * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include <unicode/uchar.h>
24 #include <unicode/ustring.h>
25 #include <unicode/ucol.h>
26
27 #include <vconf.h>
28
29 #include "media-util-err.h"
30 #include "media-svc-debug.h"
31 #include "media-svc-localize-utils.h"
32
33 #define SAFE_STRLEN(src) ((src) ? strlen(src) : 0)
34
35 int _media_svc_check_utf8(char c)
36 {
37         if ((c & 0xff) < (128 & 0xff))
38                 return 1;
39         else if ((c & (char)0xe0) == (char)0xc0)
40                 return 2;
41         else if ((c & (char)0xf0) == (char)0xe0)
42                 return 3;
43         else if ((c & (char)0xf8) == (char)0xf0)
44                 return 4;
45         else if ((c & (char)0xfc) == (char)0xf8)
46                 return 5;
47         else if ((c & (char)0xfe) == (char)0xfc)
48                 return 6;
49         else
50                 return MS_MEDIA_ERR_INVALID_PARAMETER;
51 }
52
53 int SAFE_SNPRINTF(char **buf, int *buf_size, int len, const char *src)
54 {
55         int remain = 0;
56         int temp_len = 0;
57
58         if (len < 0)
59                 return -1;
60
61         remain = *buf_size - len;
62         if (remain > (int)strlen(src) + 1) {
63                 temp_len = snprintf((*buf) + len, remain, "%s", src);
64                 return temp_len;
65         } else {
66                 char *temp;
67                 while (1) {
68                         temp = realloc(*buf, *buf_size * 2);
69                         if (NULL == temp)
70                                 return -1;
71                         *buf = temp;
72                         *buf_size = *buf_size * 2;
73                         remain = *buf_size - len;
74                         if (remain > (int)strlen(src) + 1)
75                                 break;
76                 }
77                 temp_len = snprintf((*buf) + len, remain, "%s", src);
78                 return temp_len;
79         }
80 }
81
82 static int __media_svc_remove_special_char(const char *src, char *dest, int dest_size)
83 {
84         int s_pos = 0, d_pos = 0, char_type, src_size;
85
86         if (NULL == src) {
87                 media_svc_error("The parameter(src) is NULL");
88                 dest[d_pos] = '\0';
89                 return 0;
90         }
91         src_size = strlen(src);
92
93         while (src[s_pos] != 0) {
94                 char_type = _media_svc_check_utf8(src[s_pos]);
95
96                 if (0 < char_type && char_type < dest_size - d_pos && char_type <= src_size - s_pos) {
97                         memcpy(dest + d_pos, src + s_pos, char_type);
98                         d_pos += char_type;
99                         s_pos += char_type;
100                 } else {
101                         media_svc_error("The parameter(src:%s) has invalid character set", src);
102                         dest[d_pos] = '\0';
103                         return MS_MEDIA_ERR_INVALID_PARAMETER;
104                 }
105         }
106
107         dest[d_pos] = '\0';
108         return d_pos;
109 }
110
111 static inline int __media_svc_collation_str(const char *src, char **dest)
112 {
113         int32_t size = 0;
114         UErrorCode status = U_ZERO_ERROR;
115         UChar *tmp_result = NULL;
116         UCollator *collator;
117         char region[50] = {0};
118         char *lang = NULL;
119         const char *en_us = "en_US.UTF-8";
120
121         /*lang = vconf_get_str(VCONFKEY_LANGSET); */
122         if (lang != NULL) {
123                 if (strlen(lang) < 50) {
124                         strncpy(region, lang, strlen(lang));
125                         free(lang);
126                 } else {
127                         media_svc_error("Lang size error(%s)", lang);
128                         free(lang);
129                 }
130         } else {
131                 strncpy(region, en_us, strlen(en_us));
132         }
133
134         char *dot = strchr(region, '.');
135         if (dot)
136                 *dot = '\0';
137
138         collator = ucol_open(region, &status);
139
140         media_svc_retvm_if(U_FAILURE(status), MS_MEDIA_ERR_INTERNAL,
141                            "ucol_open() Failed(%s)", u_errorName(status));
142
143         u_strFromUTF8(NULL, 0, &size, src, strlen(src), &status);
144         if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) {
145                 media_svc_error("u_strFromUTF8 to get the dest length Failed(%s)", u_errorName(status));
146                 ucol_close(collator);
147                 return MS_MEDIA_ERR_INTERNAL;
148         }
149         status = U_ZERO_ERROR;
150         tmp_result = calloc(1, sizeof(UChar) * (size + 1));
151         u_strFromUTF8(tmp_result, size + 1, NULL, src, -1, &status);
152         if (U_FAILURE(status)) {
153                 media_svc_error("u_strFromUTF8 Failed(%s)", u_errorName(status));
154                 free(tmp_result);
155                 ucol_close(collator);
156                 return MS_MEDIA_ERR_INTERNAL;
157         }
158
159         size = ucol_getSortKey(collator, tmp_result, -1, NULL, 0);
160         *dest = calloc(1, sizeof(uint8_t) * (size + 1));
161         size = ucol_getSortKey(collator, tmp_result, -1, (uint8_t *) * dest, size + 1);
162
163         ucol_close(collator);
164         free(tmp_result);
165         return MS_MEDIA_ERR_NONE;
166 }
167
168 int _media_svc_collation_str(const char *src, char **dest)
169 {
170         int ret;
171         char temp[SAFE_STRLEN(src) + 1];
172
173         ret = __media_svc_remove_special_char(src, temp, sizeof(temp));
174         media_svc_retvm_if(ret < MS_MEDIA_ERR_NONE, ret, "__ctsvc_remove_special_char() Failed(%d)", ret);
175
176         return __media_svc_collation_str(temp, dest);
177 }
178