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