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