Fix filter condition collate bug
[platform/core/api/media-content.git] / src / media_filter.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 #include <media_info_private.h>
19 #include <media_util_private.h>
20 #include <vconf.h>
21
22 static const char *media_token[] = {
23         " ",
24         "\"",
25         "'",
26         "(",
27         ")",
28         "=",
29         "<=",
30         "<",
31         ">=",
32         ">",
33         "!=",
34 };
35
36
37 typedef struct _token_t {
38         int type;
39         char *str;
40 } token_t;
41
42
43 #define MAX_LEFT_VALUE 512
44 #define SPACE_LEN 1
45 #define SPACE " "
46 #define UNKNOWN_TYPE 1000
47 #define STRING_TYPE 100
48
49 static char *__get_order_str(media_content_order_e order_enum);
50 static char *__get_collate_str(media_content_collation_e collate_type);
51 static void __filter_attribute_free_value(gpointer key, gpointer value, gpointer user_data);
52 static char *__media_filter_replace_attr(attribute_h attr, char *name);
53 static int __tokenize_operator(token_t *token, const char *str, int op_type);
54 static int __tokenize(GList **token_list, const char *str);
55
56 static bool __is_pinyin_needed(void)
57 {
58         char *lang = NULL;
59         const char *china = "zh_CN";
60         const char *hongkong = "zh_HK";
61         int ret = FALSE;
62
63         /*Check CSC first*/
64         bool pinyin_support = FALSE;
65         media_svc_check_pinyin_support(&pinyin_support);
66         if (pinyin_support) {
67                 /*Check Language Setting*/
68                 lang = vconf_get_str(VCONFKEY_LANGSET);
69                 media_content_retvm_if(lang == NULL, ret, "Fail to get string of language set");
70
71                 if ((strncmp(china, lang, strlen(china)) == 0) ||
72                         (strncmp(hongkong, lang, strlen(hongkong)) == 0)) {
73                         ret = TRUE;
74                 }
75
76                 SAFE_FREE(lang);
77         }
78
79         return ret;
80 }
81
82 static char *__get_order_str(media_content_order_e order_enum)
83 {
84         switch (order_enum) {
85         case MEDIA_CONTENT_ORDER_ASC:
86                 return (char *)"ASC";
87         case MEDIA_CONTENT_ORDER_DESC:
88                 return (char *)"DESC";
89         default:
90                 return (char *)" ";
91         }
92 }
93
94 static char *__get_collate_str(media_content_collation_e collate_type)
95 {
96         switch (collate_type) {
97         case MEDIA_CONTENT_COLLATE_NOCASE:
98                 return (char *)"NOCASE";
99         case MEDIA_CONTENT_COLLATE_RTRIM:
100                 return (char *)"RTRIM";
101         case MEDIA_CONTENT_COLLATE_LOCALIZED:
102                 if (__is_pinyin_needed())
103                         return (char *)"NOCASE";
104                 else
105                         return (char *)"localized";
106         default: return (char *)" ";
107         }
108 }
109
110 static void __filter_attribute_free_value(gpointer key, gpointer value, gpointer user_data)
111 {
112         SAFE_G_FREE(key);
113         SAFE_G_FREE(value);
114 }
115
116 static char *__media_filter_replace_attr(attribute_h attr, char *name)
117 {
118         char *key_temp = NULL;
119         char *generated_value = NULL;
120         attribute_s *_attr = (attribute_s *)attr;
121
122         if (!g_hash_table_lookup_extended(_attr->attr_map, name, (gpointer)&key_temp, (gpointer)&generated_value)) {
123                 /* can't find the value */
124                 /* media_content_error("NOT_FOUND_VALUE(%s)", name); */
125                 return NULL;
126         }
127
128         if (STRING_VALID(generated_value))
129                 return strdup(generated_value);
130
131         media_content_error("__media_filter_replace_attr fail");
132
133         return NULL;
134 }
135
136 static int __tokenize_operator(token_t *token, const char *str, int op_type)
137 {
138         int ret = 0;
139         const char *tmp = str;
140
141         if (token != NULL && STRING_VALID(tmp)) {
142                 token->type = op_type;
143                 int token_size = strlen(media_token[op_type]);
144                 media_content_retvm_if(token_size == 0, -1, "Invalid token_size. op_type[%d]", op_type);
145
146                 token->str = (char*)calloc(token_size+1, sizeof(char));
147                 media_content_retvm_if(token->str == NULL, -1, "OUT_OF_MEMORY");
148
149                 strncpy(token->str, tmp, token_size);
150                 /*media_content_debug("type : [%d] str : [%s]", token->type, token->str);*/
151                 ret = token_size;
152         } else {
153                 ret = -1;
154         }
155
156         return ret;
157 }
158
159 static int __tokenize_string(token_t *token, const char *str, int size)
160 {
161         int ret = size;
162         const char *tmp = str;
163
164         if (token != NULL && STRING_VALID(tmp) && size > 0) {
165                 token->str = (char*)calloc(size+1, sizeof(char));
166                 media_content_retvm_if(token->str == NULL, -1, "OUT_OF_MEMORY");
167
168                 token->type = UNKNOWN_TYPE;
169                 strncpy(token->str, tmp, size);
170                 /*media_content_debug("type : [%d] str : [%s]", token->type, token->str);*/
171         } else {
172                 ret = -1;
173         }
174
175         return ret;
176 }
177
178 static int __tokenize_attribute(GList **token_list, const char *str)
179 {
180         int ret = 0;
181         int idx = 0;
182
183         media_content_retvm_if(!STRING_VALID(str), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Parameter string is invalid");
184
185         const char *tmp = str;
186         const char *dst_ptr = str + strlen(str);
187
188         for (idx = 0; (*(tmp+idx)) && (tmp < dst_ptr); idx++) {
189                 /*media_content_debug("[%d] '%c'", idx, tmp[idx]);*/
190                 if (tmp[idx] == ' ') {          /* " " */
191                         if (idx == 0) {         /* ignore the space. */
192                                 tmp++;
193                                 idx = -1;
194                                 continue;
195                         }
196                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
197                         media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
198
199                         token->type = UNKNOWN_TYPE;
200                         token->str = (char*)calloc(idx+1, sizeof(char));
201                         if (token->str == NULL) {
202                                 SAFE_FREE(token);
203                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
204                                 return -1;
205                         }
206                         strncpy(token->str, tmp, idx);
207                         /*media_content_debug("type : [%d] str : [%s]", token->type, token->str);*/
208                         *token_list = g_list_append(*token_list, token);
209                         tmp = tmp +idx + strlen(media_token[0]);
210                         idx = -1;
211                 } else if (tmp[idx] == ',') {   /* " , " */
212                         if (idx != 0) {
213                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
214                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
215
216                                 ret = __tokenize_string(token, tmp, idx);
217                                 if (ret < 0) {
218                                         SAFE_FREE(token);
219                                         media_content_error("tokenize error occured");
220                                         return -1;
221                                 } else {
222                                         *token_list = g_list_append(*token_list, token);
223                                         tmp = tmp + idx;
224                                 }
225                         }
226
227                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
228                         int size = __tokenize_operator(token, tmp, 3);
229
230                         if (token != NULL && STRING_VALID(token->str)) {
231                                 *token_list = g_list_append(*token_list, token);
232                                 tmp += size;
233                                 idx = -1;
234                         } else {
235                                 SAFE_FREE(token);
236                                 media_content_error("tokenize error occured");
237                                 return -1;
238                         }
239                 }
240         }
241
242         if (*tmp) {                     /* remained string */
243                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
244                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
245
246                 ret = __tokenize_string(token, tmp, idx);
247                 if (ret < 0) {
248                         SAFE_FREE(token);
249                         media_content_error("tokenize error occured");
250                         return -1;
251                 }
252
253                 if (token != NULL && STRING_VALID(token->str)) {
254                         *token_list = g_list_append(*token_list, token);
255                 } else {
256                         SAFE_FREE(token);
257                         media_content_error("tokenize error occured");
258                         return -1;
259                 }
260         }
261
262         return MEDIA_CONTENT_ERROR_NONE;
263 }
264
265 static int __tokenize(GList **token_list, const char *str)
266 {
267         int ret = 0;
268         int idx = 0;
269
270         media_content_retvm_if(!STRING_VALID(str), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Parameter string is invalid");
271
272         const char *tmp = str;
273         const char *dst_ptr = str + strlen(str);
274
275         for (idx = 0; (*(tmp+idx)) && (tmp < dst_ptr); idx++) {
276                 /* media_content_debug("[%d] '%c'", idx, tmp[idx]); */
277                 if (tmp[idx] == media_token[0][0]) {            /* " " */
278                         if (idx == 0) {         /* ignore the space. */
279                                 tmp++;
280                                 idx = -1;
281                                 continue;
282                         }
283
284                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
285                         media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
286
287                         token->type = UNKNOWN_TYPE;
288                         token->str = (char *)calloc(idx+1, sizeof(char));
289                         if (token->str == NULL) {
290                                 SAFE_FREE(token);
291                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
292                                 return -1;
293                         }
294                         strncpy(token->str, tmp, idx);
295                         /* media_content_debug("type : [%d] str : [%s]", token->type, token->str); */
296                         *token_list = g_list_append(*token_list, token);
297                         tmp = tmp +idx + strlen(media_token[0]);
298                         idx = -1;
299                 } else if (tmp[idx] == media_token[1][0]) {     /* " \" " */
300                         int j;
301                         bool flag = false;
302                         for (j = idx+1; tmp[j]; j++) {  /* find next quotation */
303                                 if (tmp[j] == media_token[1][0] && tmp[j+1] == media_token[1][0]) {
304                                         j += 1;
305                                         continue;
306                                 }
307                                 if (tmp[j] == media_token[1][0]) {
308                                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
309                                         media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
310
311                                         token->str = (char*) calloc(j+1+1, sizeof(char));
312                                         if (token->str == NULL) {
313                                                 SAFE_FREE(token);
314                                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
315                                                 return -1;
316                                         }
317                                         token->type = STRING_TYPE;
318                                         strncpy(token->str, tmp, j+1);
319                                         /* media_content_debug("type : [%d] str : [%s], j : %d", token->type, token->str, j); */
320                                         *token_list = g_list_append(*token_list, token);
321                                         tmp = tmp + strlen(token->str);
322                                         idx = -1;
323                                         flag = true;
324                                         break;
325                                 }
326                         }
327
328                         if (!flag && *tmp != '\0' && tmp[j] == '\0') {
329                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
330                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
331
332                                 token->str = (char *) calloc(j+1, sizeof(char));
333                                 if (token->str == NULL) {
334                                         SAFE_FREE(token);
335                                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
336                                         return -1;
337                                 }
338                                 token->type = UNKNOWN_TYPE;
339                                 strncpy(token->str, tmp, j);
340                                 /* media_content_debug("type : [%d] str : [%s]", token->type, token->str);*/
341                                 *token_list = g_list_append(*token_list, token);
342                                 tmp = tmp +strlen(token->str);
343                                 idx = -1;
344                         }
345                 } else if (tmp[idx] == media_token[2][0]) {     /* " \' "*/
346                         int j;
347                         bool flag = false;
348                         for (j = idx+1; tmp[j]; j++) {
349                                 if (tmp[j] == media_token[2][0] && tmp[j+1] == media_token[2][0]) {
350                                         j += 1;
351                                         continue;
352                                 }
353                                 if (tmp[j] == media_token[2][0]) {
354                                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
355                                         media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
356
357                                         token->str = (char *) calloc(j+1+1, sizeof(char));
358                                         if (token->str == NULL) {
359                                                 SAFE_FREE(token);
360                                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
361                                                 return -1;
362                                         }
363                                         token->type = STRING_TYPE;
364                                         strncpy(token->str, tmp, j+1);
365                                         /* media_content_debug("type : [%d] str : [%s]", token->type, token->str); */
366                                         *token_list = g_list_append(*token_list, token);
367                                         tmp = tmp + strlen(token->str);
368                                         idx = -1;
369                                         flag = true;
370                                         break;
371                                 }
372                         }
373
374                         if (!flag && *tmp != '\0' && tmp[j] == '\0') {
375                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
376                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
377
378                                 token->str = (char*) calloc(j+1, sizeof(char));
379                                 if (token->str == NULL) {
380                                         SAFE_FREE(token);
381                                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
382                                         return -1;
383                                 }
384                                 token->type = UNKNOWN_TYPE;
385                                 strncpy(token->str, tmp, j);
386                                 /* media_content_debug("type : [%d] str : [%s]", token->type, token->str); */
387                                 *token_list = g_list_append(*token_list, token);
388                                 tmp = tmp + strlen(token->str);
389                                 idx = -1;
390                         }
391                 } else if (tmp[idx] == media_token[3][0]) {     /* "(" */
392                         if (idx != 0) {
393                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
394                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
395
396                                 ret = __tokenize_string(token, tmp, idx);
397                                 if (ret < 0) {
398                                         SAFE_FREE(token);
399                                         media_content_error("tokenize error occured");
400                                         return -1;
401                                 } else {
402                                         *token_list = g_list_append(*token_list, token);
403                                         tmp = tmp + idx;
404                                 }
405                         }
406                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
407                         int size = __tokenize_operator(token, tmp, 3);
408
409                         if (token != NULL && STRING_VALID(token->str)) {
410                                 *token_list = g_list_append(*token_list, token);
411                                 tmp += size;
412                                 idx = -1;
413                         } else {
414                                 SAFE_FREE(token);
415                                 media_content_error("tokenize error occured");
416                                 return -1;
417                         }
418
419                 } else if (tmp[idx] == media_token[4][0]) {     /* ")" */
420                         if (idx != 0) {
421                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
422                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
423
424                                 ret = __tokenize_string(token, tmp, idx);
425                                 if (ret < 0) {
426                                         SAFE_FREE(token);
427                                         media_content_error("tokenize error occured");
428                                         return -1;
429                                 } else {
430                                         *token_list = g_list_append(*token_list, token);
431                                         tmp = tmp + idx;
432                                 }
433                         }
434                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
435                         int size = __tokenize_operator(token, tmp, 4);
436
437                         if (token != NULL && STRING_VALID(token->str)) {
438                                 *token_list = g_list_append(*token_list, token);
439                                 tmp += size;
440                                 idx = -1;
441                         } else {
442                                 SAFE_FREE(token);
443                                 media_content_error("tokenize error occured");
444                                 return -1;
445                         }
446
447                 } else if (tmp[idx] == media_token[5][0]) {     /* "=" */
448                         if (idx != 0) {
449                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
450                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
451
452                                 ret = __tokenize_string(token, tmp, idx);
453                                 if (ret < 0) {
454                                         SAFE_FREE(token);
455                                         media_content_error("tokenize error occured");
456                                         return -1;
457                                 } else {
458                                         *token_list = g_list_append(*token_list, token);
459                                         tmp = tmp + idx;
460                                 }
461                         }
462                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
463                         int size = __tokenize_operator(token, tmp, 5);
464
465                         if (token != NULL && STRING_VALID(token->str)) {
466                                 *token_list = g_list_append(*token_list, token);
467                                 tmp += size;
468                                 idx = -1;
469                         } else {
470                                 SAFE_FREE(token);
471                                 media_content_error("tokenize error occured");
472                                 return -1;
473                         }
474
475                 } else if (tmp[idx] == media_token[6][0] && tmp[idx+1] == media_token[6][1]) {  /* "<=", */
476                         if (idx != 0) {
477                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
478                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
479
480                                 ret = __tokenize_string(token, tmp, idx);
481                                 if (ret < 0) {
482                                         SAFE_FREE(token);
483                                         media_content_error("tokenize error occured");
484                                         return -1;
485                                 } else {
486                                         *token_list = g_list_append(*token_list, token);
487                                         tmp = tmp + idx;
488                                 }
489                         }
490                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
491                         int size = __tokenize_operator(token, tmp, 6);
492
493                         if (token != NULL && STRING_VALID(token->str)) {
494                                 *token_list = g_list_append(*token_list, token);
495                                 tmp += size;
496                                 idx = -1;
497                         } else {
498                                 SAFE_FREE(token);
499                                 media_content_error("tokenize error occured");
500                                 return -1;
501                         }
502
503                 } else if (tmp[idx] == media_token[7][0]) {     /* "<", */
504                         if (idx != 0) {
505                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
506                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
507
508                                 ret = __tokenize_string(token, tmp, idx);
509                                 if (ret < 0) {
510                                         SAFE_FREE(token);
511                                         media_content_error("tokenize error occured");
512                                         return -1;
513                                 } else {
514                                         *token_list = g_list_append(*token_list, token);
515                                         tmp = tmp + idx;
516                                 }
517                         }
518                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
519                         int size = __tokenize_operator(token, tmp, 7);
520
521                         if (token != NULL && STRING_VALID(token->str)) {
522                                 *token_list = g_list_append(*token_list, token);
523                                 tmp += size;
524                                 idx = -1;
525                         } else {
526                                 SAFE_FREE(token);
527                                 media_content_error("tokenize error occured");
528                                 return -1;
529                         }
530
531                 } else if (tmp[idx] == media_token[8][0] && tmp[idx+1] == media_token[8][1]) {  /* ">=", */
532                         if (idx != 0) {
533                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
534                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
535
536                                 ret = __tokenize_string(token, tmp, idx);
537                                 if (ret < 0) {
538                                         SAFE_FREE(token);
539                                         media_content_error("tokenize error occured");
540                                         return -1;
541                                 } else {
542                                         *token_list = g_list_append(*token_list, token);
543                                         tmp = tmp + idx;
544                                 }
545                         }
546                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
547                         int size = __tokenize_operator(token, tmp, 8);
548
549                         if (token != NULL && STRING_VALID(token->str)) {
550                                 *token_list = g_list_append(*token_list, token);
551                                 tmp += size;
552                                 idx = -1;
553                         } else {
554                                 SAFE_FREE(token);
555                                 media_content_error("tokenize error occured");
556                                 return -1;
557                         }
558
559                 } else if (tmp[idx] == media_token[9][0]) {     /* ">", */
560                         if (idx != 0) {
561                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
562                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
563
564                                 ret = __tokenize_string(token, tmp, idx);
565                                 if (ret < 0) {
566                                         SAFE_FREE(token);
567                                         media_content_error("tokenize error occured");
568                                         return -1;
569                                 } else {
570                                         *token_list = g_list_append(*token_list, token);
571                                         tmp = tmp + idx;
572                                 }
573                         }
574                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
575                         int size = __tokenize_operator(token, tmp, 9);
576
577                         if (token != NULL && STRING_VALID(token->str)) {
578                                 *token_list = g_list_append(*token_list, token);
579                                 tmp += size;
580                                 idx = -1;
581                         } else {
582                                 SAFE_FREE(token);
583                                 media_content_error("tokenize error occured");
584                                 return -1;
585                         }
586                 } else if (tmp[idx] == media_token[10][0] && tmp[idx+1] == media_token[10][1]) {        /* "!=", */
587                         if (idx != 0) {
588                                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
589                                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
590
591                                 ret = __tokenize_string(token, tmp, idx);
592                                 if (ret < 0) {
593                                         SAFE_FREE(token);
594                                         media_content_error("tokenize error occured");
595                                         return -1;
596                                 } else {
597                                         *token_list = g_list_append(*token_list, token);
598                                         tmp = tmp + idx;
599                                 }
600                         }
601                         token_t *token = (token_t*)calloc(1, sizeof(token_t));
602                         int size = __tokenize_operator(token, tmp, 10);
603
604                         if (token != NULL && STRING_VALID(token->str)) {
605                                 *token_list = g_list_append(*token_list, token);
606                                 tmp += size;
607                                 idx = -1;
608                         } else {
609                                 SAFE_FREE(token);
610                                 media_content_error("tokenize error occured");
611                                 return -1;
612                         }
613                 }
614         }
615
616         if (*tmp) {                     /* remained string */
617                 token_t *token = (token_t*)calloc(1, sizeof(token_t));
618                 media_content_retvm_if(token == NULL, -1, "OUT_OF_MEMORY");
619
620                 ret = __tokenize_string(token, tmp, idx);
621                 if (ret < 0) {
622                         SAFE_FREE(token);
623                         media_content_error("tokenize error occured");
624                         return -1;
625                 }
626
627                 if (token != NULL && STRING_VALID(token->str)) {
628                         *token_list = g_list_append(*token_list, token);
629                 } else {
630                         SAFE_FREE(token);
631                         media_content_error("tokenize error occured");
632                         return -1;
633                 }
634         }
635
636         return MEDIA_CONTENT_ERROR_NONE;
637 }
638
639 int _media_filter_attribute_create(attribute_h *attr)
640 {
641         int ret = MEDIA_CONTENT_ERROR_NONE;
642
643         media_content_retvm_if(attr == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid attr");
644
645         attribute_s *_attr = (attribute_s*)calloc(1, sizeof(attribute_s));
646         media_content_retvm_if(_attr == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
647
648         _attr->attr_map = g_hash_table_new(g_str_hash, g_str_equal);
649         *attr = (attribute_h)_attr;
650
651         return ret;
652 }
653
654 int _media_filter_attribute_add(attribute_h attr, const char *user_attr, const char *platform_attr)
655 {
656         int ret = MEDIA_CONTENT_ERROR_NONE;
657         char *_user = NULL;
658         char *_platform = NULL;
659         attribute_s *_attr = (attribute_s*)attr;
660
661         media_content_retvm_if(_attr == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid attr");
662
663         if (STRING_VALID(user_attr) && STRING_VALID(platform_attr)) {
664                 _user = g_strdup(user_attr);
665                 media_content_retvm_if(_user == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
666
667                 _platform = g_strdup(platform_attr);
668                 if (_platform == NULL) {
669                         SAFE_G_FREE(_user);
670                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
671                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
672                 }
673
674                 g_hash_table_insert(_attr->attr_map, _user, _platform);
675         } else {
676                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
677                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
678         }
679
680         return ret;
681 }
682
683 int _media_filter_attribute_destory(attribute_h attr)
684 {
685         int ret = MEDIA_CONTENT_ERROR_NONE;
686         attribute_s *_attr = (attribute_s*)attr;
687
688         media_content_retvm_if(_attr == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid attr");
689
690         if (_attr->attr_map != NULL) {
691                 g_hash_table_foreach(_attr->attr_map, __filter_attribute_free_value, NULL);
692                 g_hash_table_destroy(_attr->attr_map);
693         }
694
695         SAFE_FREE(_attr);
696
697         return ret;
698 }
699
700 int _media_filter_attribute_generate(attribute_h attr, char *condition, media_content_collation_e collate_type, char **generated_condition)
701 {
702         unsigned int idx = 0;
703         GList *token_list = NULL;
704         int size = 0;
705         int ret = MEDIA_CONTENT_ERROR_NONE;
706         int total_str_size = 0;
707         token_t *token;
708
709         media_content_retvm_if(condition == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid condition");
710         media_content_retvm_if(generated_condition == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid generated_condition");
711         media_content_retvm_if(attr == NULL, MEDIA_CONTENT_ERROR_DB_FAILED, "DB field mapping table doesn't exist. Check db connection");
712
713         if (__tokenize(&token_list, condition) < 0) {
714                 media_content_error("INVALID_PARAMETER(0x%08x):Invalid the condition", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
715                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
716         }
717
718         for (idx = 0; idx < g_list_length(token_list); idx++) {
719                 token = (token_t*)g_list_nth_data(token_list, idx);
720
721                 if (token->type == UNKNOWN_TYPE) {
722                         char *replace_str = __media_filter_replace_attr(attr, token->str);
723                         if (STRING_VALID(replace_str)) {
724                                 SAFE_FREE(token->str);
725                                 token->str = replace_str;
726                         }
727                 }
728
729                 total_str_size += strlen(token->str)+1;
730                 /* media_content_debug("[%d][type:%d]:%s", idx, token->type, token->str); */
731         }
732
733         /* make the statment */
734         size = total_str_size + COLLATE_STR_SIZE + 1;
735         *generated_condition = (char*)calloc(size, sizeof(char));
736
737         for (idx = 0; idx < g_list_length(token_list); idx++) {
738                 token = (token_t*)g_list_nth_data(token_list, idx);
739
740                 if ((token != NULL) && STRING_VALID(token->str)) {
741                         SAFE_STRLCAT(*generated_condition, token->str, size);
742                         SAFE_STRLCAT(*generated_condition, SPACE, size);
743
744                         SAFE_FREE(token->str);
745                         SAFE_FREE(token);
746                 }
747         }
748
749         if (collate_type == MEDIA_CONTENT_COLLATE_NOCASE || collate_type == MEDIA_CONTENT_COLLATE_RTRIM || collate_type == MEDIA_CONTENT_COLLATE_LOCALIZED) {
750                 SAFE_STRLCAT(*generated_condition, "COLLATE ", size);
751                 SAFE_STRLCAT(*generated_condition, __get_collate_str(collate_type), size);
752                 SAFE_STRLCAT(*generated_condition, SPACE, size);
753         }
754
755         /* Always close in here (condition collate option issue)*/
756         SAFE_STRLCAT(*generated_condition, QUERY_KEYWORD_BRACKET, size);
757
758         /* media_content_debug("statement : %s(%d) (total:%d)", *generated_condition, strlen(*generated_condition), total_str_size); */
759         media_content_sec_debug("Condition : %s", *generated_condition);
760
761         /* if(*generated_condition != NULL)
762                 res = 1; */
763
764         if (token_list != NULL)
765                 g_list_free(token_list);
766
767         return ret;
768 }
769
770 int _media_filter_attribute_option_generate(attribute_h attr, filter_h filter, char **generated_option)
771 {
772         int ret = MEDIA_CONTENT_ERROR_NONE;
773         filter_s *_filter = NULL;
774         char option_query[DEFAULT_QUERY_SIZE] = {0, };
775         char condition[DEFAULT_QUERY_SIZE] = {0, };
776         int size = 0;
777
778         media_content_retvm_if(attr == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid attr");
779         media_content_retvm_if(filter == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid filter");
780
781         _filter = (filter_s*)filter;
782
783         memset(option_query, 0x00, sizeof(option_query));
784
785         /* Order by*/
786         if (STRING_VALID(_filter->order_keyword)) {
787                 if ((_filter->order_type == MEDIA_CONTENT_ORDER_ASC) || (_filter->order_type == MEDIA_CONTENT_ORDER_DESC)) {
788                         unsigned int idx = 0;
789                         int total_str_size = 0;
790                         GList *token_list = NULL;
791                         token_t *token;
792                         char *attr_str;
793
794                         if (__tokenize_attribute(&token_list, _filter->order_keyword) < 0) {
795                                 media_content_error("INVALID_PARAMETER(0x%08x):Invalid the condition", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
796                                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
797                         }
798
799                         for (idx = 0; idx < g_list_length(token_list); idx++) {
800                                 token = (token_t*)g_list_nth_data(token_list, idx);
801
802                                 if (token->type == UNKNOWN_TYPE) {
803                                         char *replace_str = __media_filter_replace_attr(attr, token->str);
804                                         if (STRING_VALID(replace_str)) {
805                                                 attr_str = (char*)calloc(strlen(replace_str) + COLLATE_STR_SIZE + 1, sizeof(char));
806                                                 if (attr_str == NULL) {
807                                                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
808                                                         SAFE_FREE(replace_str);
809                                                         continue;
810                                                 }
811
812                                                 if (_filter->order_collate_type == MEDIA_CONTENT_COLLATE_NOCASE || _filter->order_collate_type == MEDIA_CONTENT_COLLATE_RTRIM || _filter->order_collate_type == MEDIA_CONTENT_COLLATE_LOCALIZED)
813                                                         snprintf(attr_str, strlen(replace_str) + COLLATE_STR_SIZE + 1, "%s COLLATE %s %s", replace_str, __get_collate_str(_filter->order_collate_type), __get_order_str(_filter->order_type));
814                                                 else
815                                                         snprintf(attr_str, strlen(replace_str) + COLLATE_STR_SIZE + 1, "%s %s", replace_str, __get_order_str(_filter->order_type));
816
817                                                 SAFE_FREE(token->str);
818                                                 token->str = attr_str;
819                                                 SAFE_FREE(replace_str);
820                                         } else {
821                                                 media_content_error("There is no matched db field for %s", token->str);
822                                         }
823                                 }
824
825                                 total_str_size += strlen(token->str) + 1;
826                                 /* media_content_debug("[%d][type:%d]:%s", idx, token->type, token->str); */
827                         }
828
829                         /* make the statment */
830                         char *generated_condition = NULL;
831                         size = total_str_size + COLLATE_STR_SIZE + 1;
832                         generated_condition = (char*)calloc(size, sizeof(char));
833
834                         for (idx = 0; idx < g_list_length(token_list); idx++) {
835                                 token = (token_t*)g_list_nth_data(token_list, idx);
836
837                                 if ((token != NULL) && STRING_VALID(token->str)) {
838                                         /* media_content_debug("[%d] %s", idx, token->str); */
839                                         SAFE_STRLCAT(generated_condition, token->str, size);
840                                         SAFE_STRLCAT(generated_condition, SPACE, size);
841
842                                         SAFE_FREE(token->str);
843                                         SAFE_FREE(token);
844                                 }
845                         }
846
847                         snprintf(condition, sizeof(condition), "ORDER BY %s", generated_condition);
848                         SAFE_STRLCAT(option_query, condition, sizeof(option_query));
849
850                         if (token_list != NULL)
851                                 g_list_free(token_list);
852
853                         SAFE_FREE(generated_condition);
854                 } else {
855                         SAFE_STRLCAT(option_query, _filter->order_keyword, sizeof(option_query));
856                         media_content_error("option_query [%s]", option_query);
857                 }
858         }
859
860         /* offset */
861         SAFE_STRLCAT(option_query, SPACE, sizeof(option_query));
862         snprintf(condition, sizeof(condition), "LIMIT %d, %d", _filter->offset, _filter->count);
863         SAFE_STRLCAT(option_query, condition, sizeof(option_query));
864
865         if (STRING_VALID(option_query))
866                 *generated_option = strdup(option_query);
867         else
868                 *generated_option = NULL;
869
870         return ret;
871 }
872
873 int media_filter_create(filter_h *filter)
874 {
875         int ret = MEDIA_CONTENT_ERROR_NONE;
876
877         media_content_retvm_if(filter == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid filter");
878
879         filter_s *_filter = (filter_s*)calloc(1, sizeof(filter_s));
880         media_content_retvm_if(_filter == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
881
882         _filter->storage_id = NULL;
883         _filter->condition = NULL;
884         _filter->order_keyword = NULL;
885         _filter->order_type = -1;
886         _filter->condition_collate_type = MEDIA_CONTENT_COLLATE_DEFAULT;
887         _filter->order_collate_type = MEDIA_CONTENT_COLLATE_DEFAULT;
888         _filter->offset = -1;
889         _filter->count = -1;
890
891         *filter = (filter_h)_filter;
892
893         return ret;
894 }
895
896 int media_filter_destroy(filter_h filter)
897 {
898         int ret = MEDIA_CONTENT_ERROR_NONE;
899         filter_s *_filter = (filter_s*)filter;
900
901         if (_filter) {
902                 SAFE_FREE(_filter->storage_id);
903                 SAFE_FREE(_filter->condition);
904                 SAFE_FREE(_filter->order_keyword);
905                 SAFE_FREE(_filter);
906
907                 ret = MEDIA_CONTENT_ERROR_NONE;
908         } else {
909                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
910                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
911         }
912
913         return ret;
914 }
915
916 int media_filter_set_offset(filter_h filter, int offset, int count)
917 {
918         int ret = MEDIA_CONTENT_ERROR_NONE;
919         filter_s *_filter = (filter_s*)filter;
920
921         if (_filter != NULL) {
922                 _filter->offset = offset;
923                 _filter->count = count;
924         } else {
925                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
926                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
927         }
928
929         return ret;
930 }
931
932 int media_filter_set_condition(filter_h filter, const char *condition, media_content_collation_e collate_type)
933 {
934         int ret = MEDIA_CONTENT_ERROR_NONE;
935         filter_s *_filter = (filter_s*)filter;
936
937         if ((_filter != NULL) && STRING_VALID(condition)
938                 && ((collate_type >= MEDIA_CONTENT_COLLATE_DEFAULT) && (collate_type <= MEDIA_CONTENT_COLLATE_LOCALIZED))) {
939                 if (STRING_VALID(_filter->condition))
940                         SAFE_FREE(_filter->condition);
941
942                 char new_condition[MAX_QUERY_SIZE] = {0, };
943                 memset(new_condition, 0, sizeof(new_condition));
944                 ret = _media_content_replace_path_in_condition(condition, new_condition, TRUE);
945                 media_content_retvm_if(!STRING_VALID(new_condition), MEDIA_CONTENT_ERROR_INVALID_OPERATION, "path replacement failed");
946
947                 _filter->condition = strdup(new_condition);
948                 media_content_retvm_if(_filter->condition == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
949
950                 media_content_sec_debug("Condition string : %s", _filter->condition);
951
952                 _filter->condition_collate_type = collate_type;
953         } else {
954                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
955                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
956         }
957
958         return ret;
959 }
960
961 int media_filter_set_order(filter_h filter, media_content_order_e order_type, const char *order_keyword, media_content_collation_e collate_type)
962 {
963         int ret = MEDIA_CONTENT_ERROR_NONE;
964         filter_s *_filter = (filter_s*)filter;
965
966         if ((_filter != NULL) && STRING_VALID(order_keyword)
967                 && ((order_type == MEDIA_CONTENT_ORDER_ASC) || (order_type == MEDIA_CONTENT_ORDER_DESC))
968                 && ((collate_type >= MEDIA_CONTENT_COLLATE_DEFAULT) && (collate_type <= MEDIA_CONTENT_COLLATE_LOCALIZED))) {
969                 SAFE_FREE(_filter->order_keyword);
970
971                 if (STRING_VALID(order_keyword)) {
972                         _filter->order_keyword = strdup(order_keyword);
973                         media_content_retvm_if(_filter->order_keyword == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
974
975                         _filter->order_type = order_type;
976                         _filter->order_collate_type = collate_type;
977                 } else {
978                         media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
979                         ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
980                 }
981         } else {
982                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
983                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
984         }
985
986         return ret;
987 }
988
989 int media_filter_set_storage(filter_h filter, const char *storage_id)
990 {
991         int ret = MEDIA_CONTENT_ERROR_NONE;
992         filter_s *_filter = (filter_s*)filter;
993
994         if ((_filter != NULL) && STRING_VALID(storage_id)) {
995                 if (STRING_VALID(_filter->storage_id))
996                         SAFE_FREE(_filter->storage_id);
997
998                 _filter->storage_id = strdup(storage_id);
999                 media_content_retvm_if(_filter->storage_id == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
1000
1001                 media_content_sec_debug("storage_id : %s", _filter->storage_id);
1002         } else {
1003                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
1004                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1005         }
1006
1007         return ret;
1008 }
1009
1010 int media_filter_get_offset(filter_h filter, int *offset, int *count)
1011 {
1012         int ret = MEDIA_CONTENT_ERROR_NONE;
1013         filter_s *_filter = (filter_s*)filter;
1014
1015         if (_filter) {
1016                 *offset = _filter->offset;
1017                 *count = _filter->count;
1018         } else {
1019                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
1020                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1021         }
1022
1023         return ret;
1024 }
1025
1026 int media_filter_get_condition(filter_h filter, char **condition, media_content_collation_e *collate_type)
1027 {
1028         int ret = MEDIA_CONTENT_ERROR_NONE;
1029         filter_s *_filter = (filter_s*)filter;
1030
1031         if (_filter) {
1032                 if (STRING_VALID(_filter->condition)) {
1033                         char new_condition[MAX_QUERY_SIZE] = {0, };
1034                         memset(new_condition, 0, sizeof(new_condition));
1035                         ret = _media_content_replace_path_in_condition(_filter->condition, new_condition, FALSE);
1036                         media_content_retvm_if(!STRING_VALID(new_condition), MEDIA_CONTENT_ERROR_INVALID_OPERATION, "path replacement failed");
1037
1038                         *condition = strdup(new_condition);
1039                         media_content_retvm_if(*condition == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
1040                 } else {
1041                         *condition = NULL;
1042                 }
1043
1044                 *collate_type = _filter->condition_collate_type;
1045         } else {
1046                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
1047                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1048         }
1049
1050         return ret;
1051 }
1052
1053 int media_filter_get_order(filter_h filter, media_content_order_e* order_type, char **order_keyword, media_content_collation_e *collate_type)
1054 {
1055         int ret = MEDIA_CONTENT_ERROR_NONE;
1056         filter_s *_filter = (filter_s*)filter;
1057
1058         if (_filter) {
1059                 if (STRING_VALID(_filter->order_keyword)) {
1060                         *order_keyword = strdup(_filter->order_keyword);
1061                         media_content_retvm_if(*order_keyword == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
1062                 } else {
1063                         *order_keyword = NULL;
1064                 }
1065
1066                 *order_type = _filter->order_type;
1067                 *collate_type = _filter->order_collate_type;
1068         } else {
1069                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
1070                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1071         }
1072
1073         return ret;
1074 }
1075
1076 int media_filter_get_storage(filter_h filter, char **storage_id)
1077 {
1078         int ret = MEDIA_CONTENT_ERROR_NONE;
1079         filter_s *_filter = (filter_s*)filter;
1080
1081         if (_filter) {
1082                 if (STRING_VALID(_filter->storage_id)) {
1083                         *storage_id = strdup(_filter->storage_id);
1084                         media_content_retvm_if(*storage_id == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
1085                 } else {
1086                         *storage_id = NULL;
1087                 }
1088         } else {
1089                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
1090                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1091         }
1092
1093         return ret;
1094 }