Increase memory limit
[platform/core/messaging/msg-service.git] / utils / MsgSmil.cpp
1 /*
2  * Copyright (c) 2014 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 #include <ctype.h>
18 #include <libxml/parser.h>
19 #include <libxml/tree.h>
20
21 #include "MsgMmsMessage.h"
22 #include "MsgInternalTypes.h"
23 #include "MsgSmil.h"
24 #include "MsgUtilFunction.h"
25 #include "MsgDebug.h"
26
27 #define INVALID_HOBJ    -1
28 #define MSG_SMIL_MAX_DOC        1
29 #define MSG_SMIL_COLOR_SIZE     10
30 #define MSG_STDSTR_SHORT        0x7F
31
32 typedef int HMsgSmil; /* SmilDoc Handle */
33
34 typedef enum _SMIL_ELEMENT_T {
35         ELEMENT_SMIL,
36         ELEMENT_HEAD,
37         ELEMENT_LAYOUT,
38         ELEMENT_ROOTLAYOUT,
39         ELEMENT_REGION,
40         ELEMENT_TRANSITION,
41         ELEMENT_META,
42         ELEMENT_BODY,
43         ELEMENT_PAR,
44         ELEMENT_PARAM,
45         ELEMENT_TEXT,
46         ELEMENT_IMG,
47         ELEMENT_AUDIO,
48         ELEMENT_VIDEO,
49         ELEMENT_REF,
50         ELEMENT_ANIMATE,
51         ELEMENT_MAX,
52 } SMIL_ELEMENT_T;
53
54 typedef enum _SMIL_ATTRIBUTE_T {
55         ATTRIBUTE_UNKNOWN = -1,
56         ATTRIBUTE_ID,
57         ATTRIBUTE_TOP,
58         ATTRIBUTE_LEFT,
59         ATTRIBUTE_WIDTH,
60         ATTRIBUTE_HEIGHT,
61         ATTRIBUTE_FIT,
62         ATTRIBUTE_BGCOLOR,
63         ATTRIBUTE_DUR,
64         ATTRIBUTE_SRC,
65         ATTRIBUTE_COLOR,
66         ATTRIBUTE_BOLD,
67         ATTRIBUTE_UNDERLINE,
68         ATTRIBUTE_ITALIC,
69         ATTRIBUTE_REVERSE,
70         ATTRIBUTE_DIRECTION,
71         ATTRIBUTE_SIZE,
72         ATTRIBUTE_FONT,
73         ATTRIBUTE_REGION,
74         ATTRIBUTE_NAME,
75         ATTRIBUTE_VALUE,
76         ATTRIBUTE_ALT,
77         ATTRIBUTE_TYPE,
78         ATTRIBUTE_SUBTYPE,
79         ATTRIBUTE_CONTENT,
80         ATTRIBUTE_FGCOLOR,
81         ATTRIBUTE_TEXTFORMAT,
82         ATTRIBUTE_TRANSIN,
83         ATTRIBUTE_TRANSOUT,
84         ATTRIBUTE_BEGIN,
85         ATTRIBUTE_END,
86         ATTRIBUTE_REPEAT_COUNT,
87 } SMIL_ATTRIBUTE_T;
88
89 typedef struct _MsgSmilDoc {
90         xmlDocPtr pSmilDoc;
91         xmlNodePtr pstRootNode;
92 } MsgSmilDoc;
93
94 /* static variables */
95 static char gszEmptyRawDoc[] = "<smil><head><layout></layout></head><body></body></smil>";
96
97 __thread MsgSmilDoc *__gpaMsgSmilDoc[MSG_SMIL_MAX_DOC]={NULL, };
98 __thread char gszColor[MSG_SMIL_COLOR_SIZE + 1] = {0, };
99
100 __thread bool gCmd[ELEMENT_MAX] = {false, };
101 __thread MMS_SMIL_ROOTLAYOUT gRootlayout = {};
102 __thread MMS_SMIL_REGION *gRegion = NULL;
103 __thread MMS_PAGE_S *gPage = NULL;
104 __thread MMS_MEDIA_S *gMedia = NULL;
105 __thread MMS_SMIL_TRANSITION *gTransition = NULL;
106 __thread MMS_SMIL_META *gMeta = NULL;
107
108 /* For Parse Smil */
109 static int MsgSmilGetColorValue(xmlChar *content);
110 static int MsgSmilGetTime(char *pValue);
111 static int MsgSmilAtoIHexa(char *pInput);
112 static int MsgSmilGetElementID(char *pString);
113 static int MsgSmilGetAttrID(char *pString);
114 static int MsgSmilGetFontSizeValue(char *pString);
115 static bool MsgSmilGetFontAttrib(char *pString);
116 static MmsTextDirection MsgSmilGetFontDirection(char *pString);
117 static MmsSmilFontType MsgSmilGetFontTypeValue(char *pString);
118
119 static xmlNodePtr MsgSmilGetNodeByElementName(xmlNodePtr pstNode, char *pszName);
120
121 /* For Generate Smil */
122 static HMsgSmil MsgSmilCreateEmptySmilDoc(void);
123 static HMsgSmil MsgSmilCreateSmilDoc(char *pszRawData);
124 static bool MsgSmilDestroyDoc(HMsgSmil hSmilDoc);
125 static bool IsValidSmilDocNo(int nSmilDocNo);
126 static char *MsgSmilGetRawData(HMsgSmil hSmilDoc);
127
128 static const char *MsgSmilColorValueToString(int nValue);
129
130 static bool MsgSmilAddPage(HMsgSmil hSmilDoc, MMS_PAGE_S *pstSmilPage);
131 static bool MsgSmilAddRootLayout(HMsgSmil hSmilDoc, MMS_SMIL_ROOTLAYOUT *pstSmilRootLayout);
132 static bool MsgSmilAddRegion(HMsgSmil hSmilDoc, MMS_SMIL_REGION *pstSmilRegion);
133 static bool MsgSmilAddMedia(HMsgSmil hSmilDoc, int nPageNo, int nMediaIdx, MMS_MEDIA_S *pstSmilMedia, char *pszContentID);
134 static xmlNode *MsgSmilCreateTextNode(MMS_MEDIA_S *pstSmilMedia, char *pszContentID);
135 static xmlNode *MsgSmilCreateMMNode(MMS_MEDIA_S *pstSmilMedia, char *pszContentID);
136 static bool MsgSmilInsertFirstChild(xmlNode *pParent, xmlNode *pNode);
137 static bool MsgSmilInsertNode(xmlNode *pParent, xmlNode *pLeftSibling, xmlNode *pNode);
138 static void MsgSmilSetAttribute(xmlNode *pNode, char *szField, char *szValue);
139
140
141 int MsgSmilGetColorValue(xmlChar *content)
142 {
143         int color;
144         char color_inp[9] = {0, };
145
146         if (content[0] == '#') {        /* RGB value */
147                 snprintf(color_inp, sizeof(color_inp), "FF%s", (char *)&content[1]);
148                 color = MsgSmilAtoIHexa(color_inp);
149         } else if (content[0] == '0' && (content[1] == 'x' || content[1] == 'X')) {
150                 snprintf(color_inp, sizeof(color_inp), "%s", (char *)&content[2]);
151                 color = MsgSmilAtoIHexa(color_inp);
152         } else {
153                 MSG_DEBUG("Invalid Color Value");
154                 color = 0x00000000;
155         }
156
157         return color;
158 }
159
160
161 const char *MsgSmilColorValueToString(int nValue)
162 {
163         unsigned char alpha = (nValue & 0xFF000000) >> 24;
164         unsigned char red = (nValue & 0xFF0000) >> 16;
165         unsigned char green = (nValue & 0x00FF00) >> 8;
166         unsigned char blue = nValue & 0x0000FF;
167
168         if (alpha == 0xFF) {
169                 snprintf(gszColor, sizeof(gszColor), "#%02x%02x%02x", red, green, blue);
170         } else {
171                 snprintf(gszColor, sizeof(gszColor), "0x%02x%02x%02x%02x", alpha, red, green, blue);
172         }
173
174         MSG_DEBUG("color value : [%s]", gszColor);
175
176         return gszColor;
177 }
178
179
180 int MsgSmilAtoIHexa(char *pInput)
181 {
182         int res = 0;
183         int len = 0;
184         int temp = 1;
185         int i  = 0;
186         int j = 0;
187         char *pOutput = NULL;
188
189         len = strlen(pInput);
190         pOutput = (char *)malloc(len + 1);
191
192         if (pOutput == NULL) {
193                 MSG_DEBUG("Memory full");
194                 goto __CATCH;
195         }
196
197         memset(pOutput, 0, len + 1);
198
199         for (i = len - 1; i >= 0; i--) {
200                 for (j = 0; j < (len - 1 - i); j++) {
201                         temp *= 16;
202                 }
203
204                 switch (pInput[i]) {
205                 case '0':
206                         pOutput[i] = 0;
207                         break;
208
209                 case '1':
210                         pOutput[i] = 1;
211                         break;
212
213                 case '2':
214                         pOutput[i] = 2;
215                         break;
216
217                 case '3':
218                         pOutput[i] = 3;
219                         break;
220
221                 case '4':
222                         pOutput[i] = 4;
223                         break;
224
225                 case '5':
226                         pOutput[i] = 5;
227                         break;
228
229                 case '6':
230                         pOutput[i] = 6;
231                         break;
232
233                 case '7':
234                         pOutput[i] = 7;
235                         break;
236
237                 case '8':
238                         pOutput[i] = 8;
239                         break;
240
241                 case '9':
242                         pOutput[i] = 9;
243                         break;
244
245                 case 'a':
246                 case 'A':
247                         pOutput[i] = 10;
248                         break;
249
250                 case 'b':
251                 case 'B':
252                         pOutput[i] = 11;
253                         break;
254
255                 case 'c':
256                 case 'C':
257                         pOutput[i] = 12;
258                         break;
259
260                 case 'd':
261                 case 'D':
262                         pOutput[i] = 13;
263                         break;
264
265                 case 'e':
266                 case 'E':
267                         pOutput[i] = 14;
268                         break;
269
270                 case 'f':
271                 case 'F':
272                         pOutput[i] = 15;
273                         break;
274                 }
275
276                 res += (pOutput[i] * temp);
277                 temp = 1;
278         }
279
280 __CATCH:
281
282         if (pOutput) {
283                 free(pOutput);
284                 pOutput = NULL;
285         }
286
287         return res;
288 }
289
290 int MsgSmilGetTime(char *pValue)
291 {
292         char *pTemp = NULL;
293         bool bMSec = false;
294         int retVal = 0;
295         int i = 0;
296
297         if (pValue == NULL || pValue[0] == '\0')
298                 return 0;
299
300         /* Default time unit -> millisecond */
301         if (strstr(pValue, "msec"))
302                 bMSec = true;
303
304         if (strstr(pValue, "ms"))
305                 bMSec = true;
306
307         pTemp = (char *)calloc(1, strlen(pValue) + 1);
308
309         if (NULL == pTemp) {
310                 MSG_DEBUG("calloc for <time> attribute is failed");
311                 return 0;
312         }
313
314         while (isdigit(pValue[i])) {
315                 pTemp[i] = pValue[i];
316                 i++;
317         }
318         pTemp[i] = '\0';
319
320         /* Detect 's' and 'ms' here */
321         retVal = atoi(pTemp);
322
323         if (bMSec == false)
324                 retVal *= 1000;
325
326         if (pTemp) {
327                 free(pTemp);
328                 pTemp = NULL;
329         }
330
331         return retVal;
332 }
333
334 int MsgSmilGetElementID(char *pString)
335 {
336         if (!strcmp(pString, "smil"))
337                 return ELEMENT_SMIL;
338         else if (!strcmp(pString, "head"))
339                 return ELEMENT_HEAD;
340         else if (!strcmp(pString, "layout"))
341                 return ELEMENT_LAYOUT;
342         else if (!strcmp(pString, "root-layout"))
343                 return ELEMENT_ROOTLAYOUT;
344         else if (!strcmp(pString, "region"))
345                 return ELEMENT_REGION;
346         else if (!strcmp(pString, "body"))
347                 return ELEMENT_BODY;
348         else if (!strcmp(pString, "par"))
349                 return ELEMENT_PAR;
350         else if (!strcmp(pString, "param"))
351                 return ELEMENT_PARAM;
352         else if (!strcmp(pString, "text"))
353                 return ELEMENT_TEXT;
354         else if (!strcmp(pString, "img"))
355                 return ELEMENT_IMG;
356         else if (!strcmp(pString, "audio"))
357                 return ELEMENT_AUDIO;
358         else if (!strcmp(pString, "video"))
359                 return ELEMENT_VIDEO;
360         else if (!strcmp(pString, "ref"))
361                 return ELEMENT_REF;
362         else if (!strcmp(pString, "animate"))
363                 return ELEMENT_ANIMATE;
364         else if (!strcmp(pString, "transition"))
365                 return ELEMENT_TRANSITION;
366         else if (!strcmp(pString, "meta"))
367                 return ELEMENT_META;
368         else
369                 return -1;
370 }
371
372 int MsgSmilGetAttrID(char *pString)
373 {
374         if (!strcmp(pString, "id"))
375                 return ATTRIBUTE_ID;
376         else if (!strcmp(pString, "top"))
377                 return ATTRIBUTE_TOP;
378         else if (!strcmp(pString, "left"))
379                 return ATTRIBUTE_LEFT;
380         else if (!strcmp(pString, "width"))
381                 return ATTRIBUTE_WIDTH;
382         else if (!strcmp(pString, "height"))
383                 return ATTRIBUTE_HEIGHT;
384         else if (!strcmp(pString, "fit"))
385                 return ATTRIBUTE_FIT;
386         else if (!strcmp(pString, "backgroundColor") || !strcmp(pString, "background-color"))
387                 return ATTRIBUTE_BGCOLOR;
388         else if (!strcmp(pString, "dur"))
389                 return ATTRIBUTE_DUR;
390         else if (!strcmp(pString, "src"))
391                 return ATTRIBUTE_SRC;
392         else if (!strcmp(pString, "color"))
393                 return ATTRIBUTE_COLOR;
394         else if (!strcmp(pString, "bold"))
395                 return ATTRIBUTE_BOLD;
396         else if (!strcmp(pString, "underline"))
397                 return ATTRIBUTE_UNDERLINE;
398         else if (!strcmp(pString, "italic"))
399                 return ATTRIBUTE_ITALIC;
400         else if (!strcmp(pString, "reverse"))
401                 return ATTRIBUTE_REVERSE;
402         else if (!strcmp(pString, "direction"))
403                 return ATTRIBUTE_DIRECTION;
404         else if (!strcmp(pString, "size"))
405                 return ATTRIBUTE_SIZE;
406         else if (!strcmp(pString, "font"))
407                 return ATTRIBUTE_FONT;
408         else if (!strcmp(pString, "region"))
409                 return ATTRIBUTE_REGION;
410         else if (!strcmp(pString, "name"))
411                 return ATTRIBUTE_NAME;
412         else if (!strcmp(pString, "value"))
413                 return ATTRIBUTE_VALUE;
414         else if (!strcmp(pString, "alt"))
415                 return ATTRIBUTE_ALT;
416         else if (!strcmp(pString, "type"))
417                 return ATTRIBUTE_TYPE;
418         else if (!strcmp(pString, "subtype"))
419                 return ATTRIBUTE_SUBTYPE;
420         else if (!strcmp(pString, "content"))
421                 return ATTRIBUTE_CONTENT;
422         else if (!strcmp(pString, "transIn"))
423                 return ATTRIBUTE_TRANSIN;
424         else if (!strcmp(pString, "transOut"))
425                 return ATTRIBUTE_TRANSOUT;
426         else if (!strcmp(pString, "begin"))
427                 return ATTRIBUTE_BEGIN;
428         else if (!strcmp(pString, "end"))
429                 return ATTRIBUTE_END;
430         else if (!strcmp(pString, "repeatCount"))
431                 return ATTRIBUTE_REPEAT_COUNT;
432
433         return -1;
434 }
435
436 bool MsgSmilGetFontAttrib(char *pString)
437 {
438         if (!strcmp(pString, "true"))
439                 return true;
440         else
441                 return false;
442 }
443
444 MmsTextDirection MsgSmilGetFontDirection(char *pString)
445 {
446         MmsTextDirection direction = MMS_TEXT_DIRECTION_INVALID;
447
448         if (!strcmp(pString, "right"))
449                 direction = MMS_TEXT_DIRECTION_RIGHT;
450         else if (!strcmp(pString, "down"))
451                 direction = MMS_TEXT_DIRECTION_DOWN;
452
453         return direction;
454 }
455
456 int MsgSmilGetFontSizeValue(char *pString)
457 {
458         if (!strcmp(pString, "small"))
459                 return MMS_SMIL_FONT_SIZE_SMALL;
460         else if (!strcmp(pString, "normal"))
461                 return MMS_SMIL_FONT_SIZE_NORMAL;
462         else if (!strcmp(pString, "large"))
463                 return MMS_SMIL_FONT_SIZE_LARGE;
464         else
465                 return atoi(pString);
466 }
467
468 MmsSmilFontType MsgSmilGetFontTypeValue(char *pString)
469 {
470         if (!strcmp(pString, "normal"))
471                 return MMS_SMIL_FONT_TYPE_NORMAL;
472         else if (!strcmp(pString, "italic"))
473                 return MMS_SMIL_FONT_TYPE_ITALIC;
474         else if (!strcmp(pString, "bold"))
475                 return MMS_SMIL_FONT_TYPE_BOLD;
476         else if (!strcmp(pString, "underline"))
477                 return MMS_SMIL_FONT_TYPE_UNDERLINE;
478         else
479                 return MMS_SMIL_FONT_TYPE_NORMAL;
480 }
481
482 HMsgSmil MsgSmilCreateEmptySmilDoc(void)
483 {
484         HMsgSmil hMmsSmil;
485
486         MSG_BEGIN();
487
488         hMmsSmil = MsgSmilCreateSmilDoc(gszEmptyRawDoc);
489
490         MSG_DEBUG("Create an empty smilDoc.(Handle = %d)", hMmsSmil);
491
492         MSG_END();
493
494         return hMmsSmil;
495 }
496
497 HMsgSmil MsgSmilCreateSmilDoc(char *pszRawData)
498 {
499         int nSmilDocNo = 0;
500         xmlNodePtr stRootNode;
501
502         MSG_BEGIN();
503
504         /* Destroy smil doc if present */
505         if (NULL != __gpaMsgSmilDoc[nSmilDocNo]) {
506                 if (false == MsgSmilDestroyDoc(nSmilDocNo)) {
507                         MSG_DEBUG("MsgSmilDestroyDoc: Failed!");
508                 }
509         }
510
511         for (nSmilDocNo = 0; nSmilDocNo < MSG_SMIL_MAX_DOC; nSmilDocNo++) {
512                 if (NULL == __gpaMsgSmilDoc[nSmilDocNo])
513                         break;
514         }
515
516         if (MSG_SMIL_MAX_DOC == nSmilDocNo) {
517                 MSG_DEBUG("SmilDoc table is full. Can't create.");
518                 return INVALID_HOBJ;
519         }
520         __gpaMsgSmilDoc[nSmilDocNo] = (MsgSmilDoc*)malloc(sizeof(MsgSmilDoc));
521         if (NULL ==  __gpaMsgSmilDoc[nSmilDocNo]) {
522                 MSG_DEBUG("Memory Allocation Failed.");
523                 return INVALID_HOBJ;
524         }
525         memset(__gpaMsgSmilDoc[nSmilDocNo], 0, sizeof(MsgSmilDoc));
526
527         __gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc = xmlParseMemory(pszRawData, strlen(pszRawData));
528         if (NULL == __gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc) {
529                 if (false == MsgSmilDestroyDoc(nSmilDocNo)) {
530                         MSG_DEBUG("MsgSmilDestroyDoc: Failed!");
531                 }
532                 return INVALID_HOBJ;
533         }
534
535         stRootNode = xmlDocGetRootElement(__gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc);
536         if (NULL == stRootNode) {
537                 MSG_DEBUG("Empty document");
538                 if (false == MsgSmilDestroyDoc(nSmilDocNo)) {
539                         MSG_DEBUG("MsgSmilDestroyDoc: Failed!");
540                 }
541                 return INVALID_HOBJ;
542         }
543
544         if (xmlStrcmp(stRootNode->name, (const xmlChar *) "smil")) {
545                 MSG_DEBUG("Document of the wrong type, root node != smil");
546                 if (false == MsgSmilDestroyDoc(nSmilDocNo)) {
547                         MSG_DEBUG("MsgSmilDestroyDoc: Failed!");
548                 }
549                 return INVALID_HOBJ;
550         }
551
552         __gpaMsgSmilDoc[nSmilDocNo]->pstRootNode = stRootNode;
553
554         MSG_END();
555         return ((HMsgSmil)nSmilDocNo);
556 }
557
558 bool MsgSmilDestroyDoc(HMsgSmil hSmilDoc)
559 {
560         int nSmilDocNo = (int)hSmilDoc;
561         bool bFlag = true;
562         MSG_BEGIN();
563
564         if (0 <= nSmilDocNo &&
565                 nSmilDocNo < MSG_SMIL_MAX_DOC &&
566                 __gpaMsgSmilDoc[nSmilDocNo]) {
567                 if (__gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc) {
568                         xmlFreeDoc(__gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc);
569                 }
570
571                 if (__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode) {
572                         /* Need to Check */
573                 }
574                 free(__gpaMsgSmilDoc[nSmilDocNo]);
575                 __gpaMsgSmilDoc[nSmilDocNo] = NULL;
576         } else {
577                 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
578                 bFlag =  false;
579         }
580
581         MSG_END();
582         return bFlag;
583 }
584
585 bool IsValidSmilDocNo(int nSmilDocNo)
586 {
587         bool bIsValidSmil = false;
588
589         MSG_BEGIN();
590
591         if (0 <= nSmilDocNo &&
592                 nSmilDocNo < MSG_SMIL_MAX_DOC &&
593                 __gpaMsgSmilDoc[nSmilDocNo] &&
594                 __gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc) {
595                 bIsValidSmil = true;
596         }
597
598         MSG_END();
599         return bIsValidSmil;
600 }
601
602 char *MsgSmilGetRawData(HMsgSmil hSmilDoc)
603 {
604         int nSmilDocNo = (int)hSmilDoc;
605         char *pszRawData = NULL;
606
607         MSG_BEGIN();
608
609         if (IsValidSmilDocNo(nSmilDocNo)) {
610                 /* xmlSaveFormatFileEnc("-", __gpaMmsSmilDoc[nSmilDocNo]->pSmilDoc, "UTF-8", 1); */
611                 xmlDocDumpMemory(__gpaMsgSmilDoc[nSmilDocNo]->pSmilDoc, (xmlChar **)(&pszRawData) , NULL);
612                 if (NULL == pszRawData) {
613                         MSG_DEBUG("Invalid pSmilDoc (now wellformed document)");
614                 }
615                 MSG_END();
616         } else {
617                 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
618         }
619         return pszRawData;
620 }
621
622 bool MsgSmilAddPage(HMsgSmil hSmilDoc, MMS_PAGE_S *pstSmilPage)
623 {
624         int nSmilDocNo = hSmilDoc;
625
626         MSG_BEGIN();
627
628         bool ret = true;
629
630         if (IsValidSmilDocNo(nSmilDocNo)) {
631                 xmlNodePtr pstParElement;
632                 xmlNodePtr pstBodyElement;
633                 xmlNodePtr pstParList;
634                 char szBuf[MSG_STDSTR_SHORT] = {0, };
635
636                 pstBodyElement = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"body");
637
638                 if (NULL == pstBodyElement) {
639                         MSG_DEBUG("There is no <body> node. Can't create <par> node.");
640                         return false;
641                 }
642
643                 /* Create "par"  node and insert it */
644                 pstParElement = xmlNewNode(NULL, (xmlChar *)"par");
645
646                 if (NULL == pstParElement) {
647                         MSG_DEBUG("Can't create <par> node. (from XmlParser)");
648                         return false;
649                 }
650
651                 MSG_SEC_DEBUG("Par Element Name = %s", (char *)pstParElement->name);
652
653                 /* Add attributes to "par" */
654                 if (pstSmilPage->nDur > 0) {
655                         snprintf(szBuf, MSG_STDSTR_SHORT, "%dms", pstSmilPage->nDur);
656                         xmlSetProp(pstParElement, (const xmlChar *)"dur", (const xmlChar *)szBuf);
657                         MSG_DEBUG("[Set Attribute] : dur : [%s]", szBuf);
658                 }
659
660                 /* Find the insertion point : right sibling of the last <par> node or first child of <body> */
661                 pstParList = xmlGetLastChild(pstBodyElement);
662
663                 if (pstParList) {
664                         ret = MsgSmilInsertNode(pstBodyElement, pstParList, pstParElement);
665                         if (ret == false)
666                                 xmlFreeNode(pstParElement);
667                 } else {
668                         ret = MsgSmilInsertFirstChild(pstBodyElement, pstParElement);
669                         if (ret == false)
670                                 xmlFreeNode(pstParElement);
671                 }
672         } else {
673                 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
674                 return false;
675         }
676
677         return ret;
678 }
679
680 bool MsgSmilAddRootLayout(HMsgSmil hSmilDoc, MMS_SMIL_ROOTLAYOUT *pstSmilRootLayout)
681 {
682         int nSmilDocNo = hSmilDoc;
683         xmlNodePtr pstRootLayout = NULL;
684         xmlNodePtr pstLayoutList = NULL;
685         xmlNodePtr pstRootLayoutList = NULL;
686         char szBuf[MSG_STDSTR_SHORT] = {0, };
687
688         MSG_BEGIN();
689
690         if (IsValidSmilDocNo(nSmilDocNo)) {
691                 pstLayoutList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"layout");
692
693                 if (NULL == pstLayoutList) {
694                         MSG_DEBUG("There is no <layout> node. Can't create <root-layout> node.");
695                         return false;
696                 }
697                 MSG_SEC_DEBUG("Layout Element Name = %s ", (char *)pstLayoutList->name);
698
699                 pstRootLayoutList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"root-layout");
700
701                 if (NULL != pstRootLayoutList) {
702                         MSG_DEBUG("There is <root-layout> node already");
703                         MSG_SEC_DEBUG("Root Layout Element Name = %s", (char *)pstRootLayoutList->name);
704                         return false;
705                 }
706                 /* Create "root-layout" node and insert it */
707                 pstRootLayout = xmlNewNode(NULL, (xmlChar *)"root-layout");
708                 if (NULL == pstRootLayout) {
709                         MSG_DEBUG("Can't create <root-layout> node. (from XmlParser)");
710                         return false;
711                 }
712                 MSG_SEC_DEBUG("Root Layout Element Name = %s", (char *)pstRootLayout->name);
713
714                 if (pstSmilRootLayout->bBgColor == true) {      /* Replace value later */
715                         if (((pstSmilRootLayout->bgColor & 0xFF000000) >> 24) > 0) { /* check alpha value */
716                                 xmlSetProp(pstRootLayout, (const xmlChar *)"backgroundColor", (const xmlChar *)MsgSmilColorValueToString(pstSmilRootLayout->bgColor));
717                         }
718                 }
719
720                 /* width */
721                 if (true == pstSmilRootLayout->width.bUnitPercent) {
722                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRootLayout->width.value);
723                         xmlSetProp(pstRootLayout, (const xmlChar *)"width", (const xmlChar *)szBuf);
724                 } else {
725                         if (pstSmilRootLayout->width.value > 0) {
726                                 snprintf(szBuf, MSG_STDSTR_SHORT, "%d", pstSmilRootLayout->width.value);
727                                 xmlSetProp(pstRootLayout, (const xmlChar *)"width", (const xmlChar *)szBuf);
728                         } else {
729                                 MSG_DEBUG("Set Width : default value [100%%]");
730                                 xmlSetProp(pstRootLayout, (const xmlChar *)"width", (const xmlChar *)"100%");
731                         }
732                 }
733
734                 /* Height */
735                 if (true == pstSmilRootLayout->height.bUnitPercent) {
736                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRootLayout->height.value);
737                         xmlSetProp(pstRootLayout, (const xmlChar *)"height", (const xmlChar *)szBuf);
738                 } else {
739                         if (pstSmilRootLayout->height.value > 0) {
740                                 snprintf(szBuf, MSG_STDSTR_SHORT, "%d", pstSmilRootLayout->height.value);
741                                 xmlSetProp(pstRootLayout, (const xmlChar *)"height", (const xmlChar *)szBuf);
742                         } else {
743                                 xmlSetProp(pstRootLayout, (const xmlChar *)"height", (const xmlChar *)"100%");
744                         }
745                 }
746
747                 xmlAddChild(pstLayoutList, pstRootLayout);
748
749                 return true;
750         } else {
751                 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
752                 return false;
753         }
754 }
755
756 bool MsgSmilAddRegion(HMsgSmil hSmilDoc, MMS_SMIL_REGION *pstSmilRegion)
757 {
758         int nSmilDocNo = hSmilDoc;
759
760         MSG_BEGIN();
761
762         if (IsValidSmilDocNo(nSmilDocNo)) {
763                 int nRootWidth = 0;
764                 int nRootHeight = 0;
765                 xmlNodePtr pstRegion;
766                 xmlNodePtr pstLayoutList;
767                 xmlNodePtr pstRootLayoutList;
768                 xmlAttrPtr pAttribute;
769                 char szBuf[MSG_STDSTR_SHORT] = {0, };
770
771                 pstLayoutList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"layout");
772                 if (NULL == pstLayoutList) {
773                         MSG_DEBUG(" There is no <layout> node. Can't create <region> node");
774                         return false;
775                 }
776
777                 /* Find the insertion point : right sibling of the last root-layout node or first child of pLayout */
778                 pstRootLayoutList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"root-layout");
779
780                 if (NULL == pstRootLayoutList) {
781                         MSG_DEBUG("There is no <root-layout> node. Can't create <root-layout> node.");
782                         return false;
783                 } else {
784                         pAttribute =  pstRootLayoutList->properties;
785                 }
786
787                 if (NULL == pAttribute) {
788                         MSG_DEBUG("There is no Attribute in <root-layout> node.");
789                         return false;
790                 }
791
792                 xmlAttrPtr pstAttr = pAttribute;
793                 for ( ; pstAttr; pstAttr = pstAttr->next) {
794                         int     attrType;
795                         MSG_SEC_DEBUG("AttributeType: (%s, %s) ", pstAttr->name, pstAttr->children->content);
796                         switch (attrType = MsgSmilGetAttrID((char *)pstAttr->name)) {
797                         case ATTRIBUTE_WIDTH: {
798 #if 0
799                                 int bUnitPercent;
800
801                                 if (strchr((char *)pstAttr->children->content, '%'))
802                                         bUnitPercent = true;
803                                 else
804                                         bUnitPercent = false;
805 #endif
806                                         nRootWidth = atoi((char *)pstAttr->children->content);
807                                 }
808                                 break;
809
810                         case ATTRIBUTE_HEIGHT: {
811 #if 0
812                                 int bUnitPercent;
813
814                                 if (strchr((char *)pstAttr->children->content, '%'))
815                                         bUnitPercent = true;
816                                 else
817                                         bUnitPercent = false;
818 #endif
819                                         nRootHeight = atoi((char *)pstAttr->children->content);
820                                 }
821                                 break;
822                         }
823                 }
824
825
826                 /* Add attributes */
827                 if (pstSmilRegion) {
828                         /* Create "region" node and insert it */
829                         pstRegion = xmlNewNode(NULL, (xmlChar *)"region");
830                         if (NULL == pstRegion) {
831                                 MSG_DEBUG("Can't create <region> node. (from XmlParser)");
832                                 return false;
833                         }
834
835                         MSG_SEC_DEBUG("Region Element Name = %s", (char *)pstRegion->name);
836
837                         if (strlen(pstSmilRegion->szID) > 0) {
838                                 xmlSetProp(pstRegion, (const xmlChar *)"id", (const xmlChar *)pstSmilRegion->szID);
839                                 MSG_DEBUG("[Set Attribute] : Region Id : [%s]", pstSmilRegion->szID);
840                         }
841
842                         if (pstSmilRegion->bBgColor == true) {
843                                 MSG_DEBUG(" [Set Attribute] : BkGrd Color");
844                                 if (((pstSmilRegion->bgColor & 0xFF000000) >> 24) > 0) {
845                                         xmlSetProp(pstRegion, (const xmlChar *)"backgroundColor", (const xmlChar *)MsgSmilColorValueToString(pstSmilRegion->bgColor));
846                                         MSG_DEBUG("[Set Attribute] : backgroundColor [%s]", MsgSmilColorValueToString(pstSmilRegion->bgColor));
847                                 }
848                         }
849
850
851                         if (true == pstSmilRegion->width.bUnitPercent) {
852                                 if (pstSmilRegion->width.value > 0) {
853                                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRegion->width.value);
854                                         xmlSetProp(pstRegion, (const xmlChar *)"width", (const xmlChar *)szBuf);
855                                         MSG_DEBUG("[Set Attribute] : Width : [%s]", szBuf);
856                                 }
857                         } else {
858                                 /* Note: nRootWidth should be in terms of value(pixel) not unitpercent(%) */
859                                 /* Validation should be done before this. */
860                                 if (pstSmilRegion->width.value >= 0 &&
861                                         pstSmilRegion->width.value <= nRootWidth &&
862                                         nRootWidth != 0) {
863                                         int iWidth = (pstSmilRegion->width.value * 100) / nRootWidth;
864
865                                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", iWidth);
866                                         xmlSetProp(pstRegion, (const xmlChar *)"width", (const xmlChar *)szBuf);
867                                         MSG_DEBUG("[Set Attribute] : Width : [%s]", szBuf);
868                                 }
869                         }
870
871                         if (true == pstSmilRegion->height.bUnitPercent) {
872                                 if (pstSmilRegion->height.value > 0) {
873                                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRegion->height.value);
874                                         xmlSetProp(pstRegion, (const xmlChar *)"height", (const xmlChar *)szBuf);
875                                         MSG_DEBUG("[Set Attribute] : Height : [%s]", szBuf);
876                                 }
877                         } else {
878                                 /* Note: nRootHeight should be in terms of value(pixel) not unitpercent(%) */
879                                 /* Validation should be done before this. */
880                                 if (pstSmilRegion->height.value >= 0 &&
881                                         pstSmilRegion->height.value <= nRootHeight &&
882                                         nRootHeight != 0) {
883                                         int iHeight = (pstSmilRegion->height.value * 100) / nRootHeight;
884
885                                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", iHeight);
886                                         xmlSetProp(pstRegion, (const xmlChar *)"height", (const xmlChar *)szBuf);
887
888                                         MSG_DEBUG("[Set Attribute] : Height : [%s]", szBuf);
889                                 }
890                         }
891
892                         if (true == pstSmilRegion->nLeft.bUnitPercent) {
893                                 if (pstSmilRegion->nLeft.value > 0) {
894                                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRegion->nLeft.value);
895                                         xmlSetProp(pstRegion, (const xmlChar *)"left", (const xmlChar *)szBuf);
896
897                                         MSG_DEBUG("[Set Attribute] : Left : [%s]", szBuf);
898                                 }
899                         } else {
900                                 /* Note: nRootWidth should be in terms of value(pixel) not unitpercent(%) */
901                                 /* Validation should be done before this. */
902                                 if (pstSmilRegion->nLeft.value >= 0 && nRootWidth != 0) {
903                                         int iLeft = (pstSmilRegion->nLeft.value * 100) / nRootWidth;
904
905                                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", iLeft);
906                                         xmlSetProp(pstRegion, (const xmlChar *)"left", (const xmlChar *)szBuf);
907                                         MSG_DEBUG("[Set Attribute] : Left : [%s]", szBuf);
908                                 }
909                         }
910
911                         if (true == pstSmilRegion->nTop.bUnitPercent) {
912                                 if (pstSmilRegion->nTop.value > 0 &&
913                                                 nRootHeight != 0) {
914                                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", pstSmilRegion->nTop.value);
915                                         xmlSetProp(pstRegion, (const xmlChar *)"top", (const xmlChar *)szBuf);
916                                         MSG_DEBUG("[Set Attribute] : Top : [%s]", szBuf);
917                                 }
918                         } else {
919                                 /* Note: nRootHeight should be in terms of value(pixel) not unitpercent(%) */
920                                 /* Validation should be done before this. */
921                                 if (pstSmilRegion->nTop.value >= 0 && nRootHeight != 0) {
922                                         int iTop = (pstSmilRegion->nTop.value * 100) / nRootHeight;
923
924                                         snprintf(szBuf, MSG_STDSTR_SHORT, "%d%%", iTop);
925                                         xmlSetProp(pstRegion, (const xmlChar *)"top", (const xmlChar *)szBuf);
926                                         MSG_DEBUG("[Set Attribute] : Top : [%s]", szBuf);
927                                 }
928                         }
929
930                         /* Fit Attribute */
931                         if (MMSUI_IMAGE_REGION_FIT_MEET == pstSmilRegion->fit) {
932                                 xmlSetProp(pstRegion, (const xmlChar *)"fit", (const xmlChar *)"meet");
933                                 MSG_DEBUG("[Set Attribute] : fit : [meet]");
934                         } else if (MMSUI_IMAGE_REGION_FIT_HIDDEN == pstSmilRegion->fit) {
935                                 xmlSetProp(pstRegion, (const xmlChar *)"fit", (const xmlChar *)"hidden");
936                                 MSG_DEBUG("[Set Attribute] : fit : [hidden]");
937                         }
938
939                         MsgSmilInsertNode(pstLayoutList, pstRootLayoutList, pstRegion);
940                 } else {
941                         MSG_DEBUG("There is no attribute in <region> node");
942                 }
943
944                 MSG_END();
945                 return true;
946         } else {
947                 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
948                 return false;
949         }
950 }
951
952 bool MsgSmilAddMedia(HMsgSmil hSmilDoc, int nPageNo, int nMediaIdx, MMS_MEDIA_S *pstSmilMedia, char *pszContentID)
953 {
954         int nSmilDocNo = hSmilDoc;
955
956         MSG_BEGIN();
957
958         if (NULL == pszContentID) {
959                 MSG_DEBUG(" Content Id is NULL");
960                 return false;
961         }
962         memset(pszContentID, 0, sizeof(pstSmilMedia->szContentID));
963         if (IsValidSmilDocNo(nSmilDocNo)) {
964                 int nIndex = 0;
965                 xmlNode *pstMedia;
966                 xmlNode *pstLastChild;
967                 xmlNodePtr pstParList;
968                 char *pszExt ;
969
970                 pstParList = MsgSmilGetNodeByElementName(__gpaMsgSmilDoc[nSmilDocNo]->pstRootNode, (char *)"par");
971
972                 if (NULL == pstParList) {
973                         MSG_DEBUG("There is no <par> node. Can't create <media> node.");
974                         return false;
975                 }
976
977                 for (nIndex = 0; (pstParList &&  nIndex < nPageNo); nIndex++) {
978                         pstParList = pstParList->next;
979                 }
980
981                 if (NULL == pstParList) {
982                         MSG_DEBUG("There is no such page node. Can't insert <media> node.");
983                         return false;
984                 }
985
986                 /* Find insertion point and make a contentID */
987                 pstLastChild = xmlGetLastChild(pstParList);
988
989                 pszExt = strrchr(pstSmilMedia->szFileName, '.');
990                 if (pszExt && !strrchr(pszExt, '/'))
991                         snprintf(pszContentID, MSG_MSG_ID_LEN+1, "%lu_%lu%s", (unsigned long)nPageNo, (unsigned long)nMediaIdx, pszExt);
992                 else
993                         snprintf(pszContentID, MSG_MSG_ID_LEN+1, "%lu_%lu", (unsigned long)nPageNo, (unsigned long)nMediaIdx);
994
995                 /* remove space character in content location */
996                 msg_replace_space_char(pstSmilMedia->szFileName);
997
998                 memset(pstSmilMedia->szContentLocation, 0, sizeof(pstSmilMedia->szContentLocation));
999                 gchar *tmpContentLoc = msg_replace_non_ascii_char(pstSmilMedia->szFileName, '_');
1000                 if (tmpContentLoc) {
1001                         MSG_SEC_DEBUG("tmpContentLoc = [%s]", tmpContentLoc);
1002                         snprintf(pstSmilMedia->szContentLocation, sizeof(pstSmilMedia->szContentLocation), "%s", tmpContentLoc);
1003                         g_free(tmpContentLoc);
1004                         tmpContentLoc = NULL;
1005                 } else {
1006                         MSG_WARN("tmpContentLoc is NULL.");
1007                         snprintf(pstSmilMedia->szContentLocation, sizeof(pstSmilMedia->szContentLocation), "%s", pstSmilMedia->szFileName);
1008                 }
1009
1010                 /* Create <media> node and insert set attribute */
1011                 switch (pstSmilMedia->mediatype) {
1012                 case MMS_SMIL_MEDIA_TEXT:
1013                         pstMedia = MsgSmilCreateTextNode(pstSmilMedia, pszContentID);
1014                         break;
1015                 case MMS_SMIL_MEDIA_AUDIO:
1016                 case MMS_SMIL_MEDIA_VIDEO:
1017                 case MMS_SMIL_MEDIA_IMG:
1018                         pstMedia = MsgSmilCreateMMNode(pstSmilMedia, pszContentID);
1019                         break;
1020                 default:
1021                         MSG_DEBUG("Invalid media type. Can't insert such-<media> node.");
1022                         return false;
1023                 }
1024
1025                 if (NULL == pstMedia) {
1026                         MSG_DEBUG("Can't create <media> node. (from XmlParser) (media-type:%d)", pstSmilMedia->mediatype);
1027                         return false;
1028                 }
1029
1030                 /* Find the insertion point : the last child of <par> node */
1031                 if (pstLastChild)
1032                         MsgSmilInsertNode(pstParList, pstLastChild, pstMedia);
1033                 else
1034                         MsgSmilInsertFirstChild(pstParList, pstMedia);
1035
1036                 MSG_END();
1037                 return true;
1038         } else {
1039                 MSG_DEBUG("Invalid SmilDoc(hSmilDoc:%d)", nSmilDocNo);
1040                 return false;
1041         }
1042 }
1043
1044 xmlNode *MsgSmilCreateTextNode(MMS_MEDIA_S *pstSmilMedia, char *pszContentID)
1045 {
1046         xmlNode *pstMedia = NULL;
1047         xmlNode *pstParam = NULL;
1048         char szBuf[MSG_STDSTR_SHORT] = {0, };
1049         char szSizeBuf[MSG_STDSTR_SHORT] = {0, };
1050
1051         MSG_BEGIN();
1052
1053         pstMedia = xmlNewNode(NULL, (xmlChar *)"text");
1054         if (NULL == pstMedia) {
1055                 MSG_DEBUG("Can't create <Text> node.");
1056                 return NULL;
1057         }
1058
1059         /* Add attributes */
1060         if (pstSmilMedia) {
1061                 if (strlen(pstSmilMedia->regionId) > 0) {
1062                         xmlSetProp(pstMedia, (const xmlChar *)"region", (const xmlChar *)pstSmilMedia->regionId);
1063                         MSG_DEBUG("[Set Attribute] Region Id : [%s]", pstSmilMedia->regionId);
1064                 }
1065
1066                 if (pstSmilMedia->sMedia.sText.nBegin > 0) {
1067                         snprintf (szBuf, sizeof(szBuf), "%dms", pstSmilMedia->sMedia.sText.nBegin);
1068                         xmlSetProp(pstMedia, (const xmlChar *)"begin", (const xmlChar *) szBuf);
1069                         MSG_DEBUG("[Set Attribute] Begin : [%s]", szBuf);
1070                 }
1071
1072                 if (pstSmilMedia->sMedia.sText.nDurTime > 0) {
1073                         snprintf (szBuf, sizeof(szBuf), "%dms", pstSmilMedia->sMedia.sText.nDurTime);
1074                         xmlSetProp(pstMedia, (const xmlChar *)"dur", (const xmlChar *)szBuf);
1075                         MSG_DEBUG("[Set Attribute] Duration : [%s]", szBuf);
1076                 }
1077
1078                 if (strlen(pstSmilMedia->szAlt) > 0) {
1079                         int wrn = snprintf (szBuf, sizeof(szBuf), "%s", pstSmilMedia->szAlt);
1080                         if(wrn<0)
1081                                 MSG_DEBUG("snprintf was  failed\n");
1082                         xmlSetProp(pstMedia, (const xmlChar *)"alt", (const xmlChar *)szBuf);
1083                         MSG_DEBUG("[Set Attribute] Alternate : [%s]", szBuf);
1084                 }
1085
1086 #if 0
1087                 char szFilePathWithCid[MSG_MSG_ID_LEN + 5];     /* for "cid:" */
1088
1089                 snprintf (szFilePathWithCid, sizeof(szFilePathWithCid), "cid:%s", pszContentID);
1090                 MsgSmilSetAttribute(pstMedia, (char *)"src", szFilePathWithCid);
1091 #endif
1092                 if (strlen(pstSmilMedia->szContentLocation) > 0) {
1093                         MsgSmilSetAttribute(pstMedia, (char *)"src", pstSmilMedia->szContentLocation); /* using content Location in Smil */
1094                         MSG_DEBUG("[Set Attribute] Src : [%s]", pstSmilMedia->szContentLocation);
1095                 }
1096
1097                 if (((pstSmilMedia->sMedia.sText.nColor & 0xFF000000) >> 24) > 0) {
1098                         pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1099
1100                         if (NULL == pstParam) {
1101                                 MSG_DEBUG("Cannot create <param> node");
1102                                 return NULL;
1103                         }
1104
1105                         xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"foreground-color");
1106                         xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)MsgSmilColorValueToString(pstSmilMedia->sMedia.sText.nColor));
1107
1108                         MSG_DEBUG("[Set param] Font Foreground Color : [0x%08x]", pstSmilMedia->sMedia.sText.nColor);
1109
1110                         MsgSmilInsertFirstChild(pstMedia, pstParam);
1111                 }
1112
1113                 if (((pstSmilMedia->sMedia.sText.nBgColor & 0xFF000000) >> 24) > 0) {
1114                         pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1115
1116                         if (NULL == pstParam) {
1117                                 MSG_DEBUG("Cannot create <param> node");
1118                                 return NULL;
1119                         }
1120
1121                         xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"background-color");
1122                         xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)MsgSmilColorValueToString(pstSmilMedia->sMedia.sText.nBgColor));
1123
1124                         MSG_DEBUG("[Set param] Font Background Color : [0x%08x]", pstSmilMedia->sMedia.sText.nBgColor);
1125
1126                         MsgSmilInsertFirstChild(pstMedia, pstParam);
1127                 }
1128
1129                 if (pstSmilMedia->sMedia.sText.nSize > 0) {
1130                         pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1131                         if (NULL == pstParam) {
1132                                 MSG_DEBUG(" __MmsCreateTextNode: cannot create <param> node");
1133                                 return NULL;
1134                         }
1135
1136                         if (pstSmilMedia->sMedia.sText.nSize  <= MMS_SMIL_FONT_SIZE_SMALL) {
1137                                 snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "small");
1138                         } else if ((pstSmilMedia->sMedia.sText.nSize  > MMS_SMIL_FONT_SIZE_SMALL) && (pstSmilMedia->sMedia.sText.nSize  < MMS_SMIL_FONT_SIZE_LARGE)) {
1139                                 snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "normal");
1140                         } else {
1141                                 snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "large");
1142                         }
1143
1144                         xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"textsize");
1145                         xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)szSizeBuf);
1146
1147                         MSG_DEBUG("[Set param] textsize : [%s]", szSizeBuf);
1148
1149                         MsgSmilInsertFirstChild(pstMedia, pstParam);
1150                 }
1151
1152                 if (pstSmilMedia->sMedia.sText.bBold == true) {
1153                         pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1154                         if (NULL == pstParam) {
1155                                 MSG_DEBUG(" __MmsCreateTextNode: cannot create <param> node");
1156                                 return NULL;
1157                         }
1158
1159                         snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "bold");
1160
1161                         xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"textattribute");
1162                         xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)szSizeBuf);
1163
1164                         MSG_DEBUG("[Set param] textattribute : [%s]", szSizeBuf);
1165
1166                         MsgSmilInsertFirstChild(pstMedia, pstParam);
1167                 }
1168
1169                 if (pstSmilMedia->sMedia.sText.bItalic == true) {
1170                         pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1171                         if (NULL == pstParam) {
1172                                 MSG_DEBUG(" __MmsCreateTextNode: cannot create <param> node");
1173                                 return NULL;
1174                         }
1175
1176                         snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "italic");
1177
1178                         xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"textattribute");
1179                         xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)szSizeBuf);
1180
1181                         MSG_DEBUG("[Set param] textattribute : [%s]", szSizeBuf);
1182
1183                         MsgSmilInsertFirstChild(pstMedia, pstParam);
1184                 }
1185
1186                 if (pstSmilMedia->sMedia.sText.bUnderLine == true) {
1187                         pstParam = xmlNewNode(NULL, (xmlChar *)"param");
1188                         if (NULL == pstParam) {
1189                                 MSG_DEBUG(" __MmsCreateTextNode: cannot create <param> node");
1190                                 return NULL;
1191                         }
1192
1193                         snprintf(szSizeBuf, sizeof(szSizeBuf), "%s", "underline");
1194
1195                         xmlSetProp(pstParam, (const xmlChar *)"name", (const xmlChar *)"textattribute");
1196                         xmlSetProp(pstParam, (const xmlChar *)"value", (const xmlChar *)szSizeBuf);
1197
1198                         MSG_DEBUG("[Set param] textattribute : [%s]", szSizeBuf);
1199
1200                         MsgSmilInsertFirstChild(pstMedia, pstParam);
1201                 }
1202         }
1203
1204         MSG_END();
1205         return pstMedia;
1206 }
1207
1208 xmlNode *MsgSmilCreateMMNode(MMS_MEDIA_S *pstSmilMedia, char *pszContentID)
1209 {
1210         xmlNode *pstMedia = NULL;
1211         char szBuf[MSG_STDSTR_SHORT] = {0, };
1212
1213         MSG_BEGIN();
1214
1215         if (!pstSmilMedia)
1216                 return NULL;
1217
1218         switch (pstSmilMedia->mediatype) {
1219         case MMS_SMIL_MEDIA_AUDIO:
1220                 pstMedia = xmlNewNode(NULL, (xmlChar *)"audio");
1221                 break;
1222
1223         case MMS_SMIL_MEDIA_VIDEO:
1224                 pstMedia = xmlNewNode(NULL, (xmlChar *)"video");
1225                 break;
1226
1227         case MMS_SMIL_MEDIA_IMG:
1228                 pstMedia = xmlNewNode(NULL, (xmlChar *)"img");
1229                 break;
1230         default:
1231                 MSG_DEBUG("Invalid media type. Can't insert such-<media> node.");
1232                 return NULL;
1233         }
1234
1235         if (pstMedia) {
1236                 if (strlen(pstSmilMedia->regionId) > 0) {
1237                         xmlSetProp(pstMedia, (const xmlChar *)"region", (const xmlChar *)pstSmilMedia->regionId);
1238                         MSG_DEBUG("[Set Attribute] Region Id : [%s]", pstSmilMedia->regionId);
1239                 }
1240
1241 #if 0 /* set src attribute cid */
1242                 char szFilePathWithCid[MSG_MSG_ID_LEN + 5];             /* for "cid:" */
1243                 snprintf (szFilePathWithCid, sizeof(szFilePathWithCid), "cid:%s", pszContentID);
1244                 MsgSmilSetAttribute(pstMedia, (char *)"src", szFilePathWithCid);
1245 #endif
1246                 if (strlen(pstSmilMedia->szContentLocation) > 0) {
1247                         MsgSmilSetAttribute(pstMedia, (char *)"src", pstSmilMedia->szContentLocation); /* using content Location in Smil */
1248                         MSG_SEC_DEBUG("[Set Attribute] src : [%s]", pstSmilMedia->szContentLocation);
1249                 }
1250
1251                 if (pstSmilMedia->sMedia.sAVI.nBegin > 0) {
1252                         snprintf (szBuf, sizeof(szBuf), "%dms", pstSmilMedia->sMedia.sAVI.nBegin);
1253                         xmlSetProp(pstMedia, (const xmlChar *)"begin", (const xmlChar *)szBuf);
1254                         MSG_DEBUG("[Set Attribute] begin : [%s]", szBuf);
1255                 }
1256
1257                 if (pstSmilMedia->sMedia.sAVI.nDurTime > 0) {
1258                         snprintf (szBuf, sizeof(szBuf), "%dms", pstSmilMedia->sMedia.sAVI.nDurTime);
1259                         xmlSetProp(pstMedia, (const xmlChar *)"dur", (const xmlChar *)szBuf);
1260                         MSG_DEBUG("[Set Attribute] dur : [%s]", szBuf);
1261                 }
1262
1263                 if (strlen(pstSmilMedia->szAlt) > 0) {
1264                         int wrn = snprintf (szBuf, sizeof(szBuf), "%s", pstSmilMedia->szAlt);
1265                         if(wrn<0)
1266                                 MSG_DEBUG("snprintf was  failed\n");
1267                         xmlSetProp(pstMedia, (const xmlChar *)"alt", (const xmlChar *)szBuf);
1268                         MSG_DEBUG("[Set Attribute] alt : [%s]", szBuf);
1269                 }
1270         } else {
1271                 MSG_DEBUG("There is no attribute in such-<media> node");
1272         }
1273
1274         MSG_END();
1275         return pstMedia;
1276 }
1277
1278 bool MsgSmilInsertFirstChild(xmlNode *pstParent, xmlNode *pstCurr)
1279 {
1280         bool bFlag = true;
1281
1282         MSG_BEGIN();
1283
1284          if (NULL == xmlAddChild(pstParent, pstCurr)) {
1285                 MSG_SEC_DEBUG("%s Node not added", pstCurr->name);
1286                 bFlag = false;
1287          }
1288
1289          MSG_END();
1290          return bFlag;
1291 }
1292
1293 bool MsgSmilInsertNode(xmlNode *pstParent, xmlNode *pstLeftSibling, xmlNode *pstCurr)
1294 {
1295         MSG_BEGIN();
1296         bool bFlag = true;
1297
1298         if (pstLeftSibling) {
1299                 /* Parent Node is Unused */
1300                 while (pstLeftSibling->next != NULL)
1301                         pstLeftSibling = pstLeftSibling->next;
1302
1303                  if (NULL == xmlAddNextSibling(pstLeftSibling, pstCurr)) {
1304                         MSG_SEC_DEBUG("%s Node not added", pstCurr->name);
1305                         bFlag = false;
1306                  }
1307         } else {
1308                  if (NULL == xmlAddChild(pstParent, pstCurr)) {
1309                         MSG_SEC_DEBUG("%s Node not added", pstCurr->name);
1310                         bFlag = false;
1311                  }
1312         }
1313         MSG_END();
1314         return bFlag;
1315 }
1316
1317 void MsgSmilSetAttribute(xmlNode *pNode, char *szField, char *szValue)
1318 {
1319         MSG_BEGIN();
1320
1321         if (pNode && szField && strlen(szField)) {
1322                 if (szValue && strlen(szValue)) {
1323                         xmlSetProp(pNode, (const xmlChar *)szField, (const xmlChar *)szValue);
1324                 } else {
1325                         xmlSetProp(pNode, (const xmlChar *)szField, (const xmlChar *)"");
1326                 }
1327         }
1328
1329         MSG_END();
1330 }
1331
1332 xmlNodePtr MsgSmilGetNodeByElementName(xmlNodePtr pstNode, char *pszName)
1333 {
1334         if ((NULL != pstNode) && (NULL != pszName)) {
1335                 xmlNodePtr pstTempNode;
1336                 xmlNodePtr pstReturnNode;
1337
1338                 pstTempNode = pstNode;
1339
1340                 for ( ; pstTempNode; pstTempNode = pstTempNode->next) {
1341                         if (0 == strcasecmp((char *)pstTempNode->name, pszName)) {
1342                                 MSG_SEC_DEBUG("Find Node : name [%s][%p]", (char *)pstTempNode->name, pstTempNode);
1343                                 return pstTempNode;
1344                         }
1345
1346                         if (pstTempNode->children) {
1347                                 pstReturnNode = MsgSmilGetNodeByElementName(pstTempNode->children, pszName);
1348                                 if (NULL != pstReturnNode) {
1349                                         return pstReturnNode;
1350                                 }
1351                         }
1352                 }
1353         }
1354         return NULL;
1355 }
1356
1357 void MsgSmilParseNode(MMS_MESSAGE_DATA_S *pMmsMsg, xmlNode *a_node, int depth)
1358 {
1359         MSG_BEGIN();
1360
1361         int elementType;
1362         int attrType;
1363
1364         xmlNode *cur_node = NULL;
1365
1366         if (depth == 0) { /* init */
1367                 memset(gCmd, 0x00, ELEMENT_MAX);
1368                 memset(&gRootlayout, 0x00, sizeof(MMS_SMIL_ROOTLAYOUT));
1369                 gRegion = NULL;
1370                 gPage = NULL;
1371                 gMedia = NULL;
1372                 gTransition = NULL;
1373                 gMeta = NULL;
1374         }
1375
1376         for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
1377                 MSG_SEC_DEBUG("## [%d] node type : [Element], name: [%s] ##", depth, cur_node->name);
1378
1379                 if (cur_node->type == XML_ELEMENT_NODE) {
1380                         /* Get Smil Element */
1381                         switch (elementType = MsgSmilGetElementID((char *)cur_node->name)) {
1382                         case ELEMENT_ROOTLAYOUT:
1383                                 gCmd[ELEMENT_ROOTLAYOUT] = true;
1384                                 break;
1385
1386                         case ELEMENT_REGION:
1387                                 if (gRegion) {
1388                                         MSG_DEBUG("region exist");
1389                                         return;
1390                                 }
1391
1392                                 gRegion = (MMS_SMIL_REGION *)calloc(1, sizeof(MMS_SMIL_REGION));
1393                                 gCmd[ELEMENT_REGION] = true;
1394                                 break;
1395
1396                         case ELEMENT_TRANSITION:
1397                                 if (gTransition) {
1398                                         MSG_DEBUG("Transition exist");
1399                                         return;
1400                                 }
1401
1402                                 gTransition = (MMS_SMIL_TRANSITION *)calloc(1, sizeof(MMS_SMIL_TRANSITION));
1403                                 gCmd[ELEMENT_TRANSITION] = true;
1404                                 break;
1405
1406                         case ELEMENT_META:
1407                                 if (gMeta) {
1408                                         MSG_DEBUG("Meta exist");
1409                                         return;
1410                                 }
1411
1412                                 gMeta = (MMS_SMIL_META *)calloc(1, sizeof(MMS_SMIL_META));
1413                                 gCmd[ELEMENT_META] = true;
1414                                 break;
1415
1416                         case ELEMENT_PAR:
1417                                 if (gPage) {
1418                                         MSG_DEBUG("Page exist");
1419                                         return;
1420                                 }
1421
1422                                 gPage = (MMS_PAGE_S *)calloc(1, sizeof(MMS_PAGE_S));
1423                                 gCmd[ELEMENT_PAR] = true;
1424                                 break;
1425
1426                         case ELEMENT_PARAM: /* Need to check the original element type */
1427                                 gCmd[ELEMENT_PARAM] = true;
1428                                 break;
1429
1430                         case ELEMENT_TEXT:
1431                                 if (gMedia) {
1432                                         MSG_DEBUG("Media exist");
1433                                         return;
1434                                 }
1435
1436                                 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1437                                 if (!gMedia) {
1438                                         MSG_DEBUG("calloc for gMedia is failed");
1439                                         return;
1440                                 }
1441                                 gMedia->mediatype = MMS_SMIL_MEDIA_TEXT;
1442                                 gCmd[ELEMENT_TEXT] = true;
1443                                 break;
1444
1445                         case ELEMENT_IMG:
1446                                 if (gMedia) {
1447                                         MSG_DEBUG("Media exist");
1448                                         return;
1449                                 }
1450
1451                                 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1452                                 if (!gMedia) {
1453                                         MSG_DEBUG("calloc for gMedia is failed");
1454                                         return;
1455                                 }
1456                                 gMedia->mediatype = MMS_SMIL_MEDIA_IMG;
1457                                 gCmd[ELEMENT_IMG] = true;
1458                                 break;
1459
1460                         case ELEMENT_AUDIO:
1461                                 if (gMedia) {
1462                                         MSG_DEBUG("Media exist");
1463                                         return;
1464                                 }
1465
1466                                 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1467                                 if (!gMedia) {
1468                                         MSG_DEBUG("calloc for gMedia is failed");
1469                                         return;
1470                                 }
1471                                 gMedia->mediatype = MMS_SMIL_MEDIA_AUDIO;
1472                                 gCmd[ELEMENT_AUDIO] = true;
1473                                 break;
1474
1475                         case ELEMENT_VIDEO:
1476                                 if (gMedia) {
1477                                         MSG_DEBUG("Media exist");
1478                                         return;
1479                                 }
1480
1481                                 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1482                                 if (!gMedia) {
1483                                         MSG_DEBUG("calloc for gMedia is failed");
1484                                         return;
1485                                 }
1486                                 gMedia->mediatype = MMS_SMIL_MEDIA_VIDEO;
1487                                 gCmd[ELEMENT_VIDEO] = true;
1488                                 break;
1489
1490                         case ELEMENT_REF:
1491                                 if (gMedia) {
1492                                         MSG_DEBUG("Media exist");
1493                                         return;
1494                                 }
1495
1496                                 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1497                                 if (!gMedia) {
1498                                         MSG_DEBUG("calloc for gMedia is failed");
1499                                         return;
1500                                 }
1501                                 gMedia->mediatype = MMS_SMIL_MEDIA_IMG_OR_VIDEO;
1502                                 gCmd[ELEMENT_REF] = true;
1503                                 break;
1504
1505                         case ELEMENT_ANIMATE:
1506                                 if (gMedia) {
1507                                         MSG_DEBUG("Media exist");
1508                                         return;
1509                                 }
1510
1511                                 gMedia = (MMS_MEDIA_S *)calloc(1, sizeof(MMS_MEDIA_S));
1512                                 if (!gMedia) {
1513                                         MSG_DEBUG("calloc for gMedia is failed");
1514                                         return;
1515                                 }
1516                                 gMedia->mediatype = MMS_SMIL_MEDIA_ANIMATE;
1517                                 gCmd[ELEMENT_ANIMATE] = true;
1518                                 break;
1519
1520                         default:
1521                                 MSG_DEBUG("Unsupported element type [%d]", elementType);
1522                                 break;
1523                         }
1524
1525                         /* Get Smil Attribute */
1526                         xmlAttr *pAttr = cur_node->properties;
1527
1528                         SMIL_ATTRIBUTE_T paramType = ATTRIBUTE_UNKNOWN;
1529
1530                         for ( ; pAttr; pAttr = pAttr->next) {
1531                                 MSG_SEC_DEBUG("## attribute type : name [%s] value [%s] ##", pAttr->name, pAttr->children->content);
1532
1533                                 switch (attrType = MsgSmilGetAttrID((char *)pAttr->name)) {
1534                                 case ATTRIBUTE_ID: {
1535                                                 if (gCmd[ELEMENT_REGION] && gRegion) {
1536                                                         strncpy(gRegion->szID, (char *)pAttr->children->content, MAX_SMIL_REGION_ID - 1);
1537                                                 } else if (gCmd[ELEMENT_TRANSITION] && gTransition) {
1538                                                         strncpy(gTransition->szID, (char *)pAttr->children->content, MAX_SMIL_TRANSITION_ID - 1);
1539                                                 } else if (gCmd[ELEMENT_META] && gMeta) {
1540                                                         strncpy(gMeta->szID, (char *)pAttr->children->content, MAX_SMIL_META_ID - 1);
1541                                                 }
1542                                         }
1543                                         break;
1544
1545                                 case ATTRIBUTE_TOP: {
1546                                                 int bUnitPercent;
1547                                                 int value;
1548
1549                                                 if (strchr((char *)pAttr->children->content, '%'))
1550                                                         bUnitPercent = true;
1551                                                 else
1552                                                         bUnitPercent = false;
1553
1554                                                 value = atoi((char *)pAttr->children->content);
1555
1556                                                 if (gCmd[ELEMENT_REGION] && gRegion) {
1557                                                         gRegion->nTop.bUnitPercent = bUnitPercent;
1558                                                         gRegion->nTop.value = value;
1559                                                 }
1560                                         }
1561                                         break;
1562
1563                                 case ATTRIBUTE_LEFT: {
1564                                                 int bUnitPercent;
1565                                                 int value;
1566
1567                                                 if (strchr((char *)pAttr->children->content, '%'))
1568                                                         bUnitPercent = true;
1569                                                 else
1570                                                         bUnitPercent = false;
1571
1572                                                 value = atoi((char *)pAttr->children->content);
1573
1574                                                 if (gCmd[ELEMENT_REGION] && gRegion) {
1575                                                         gRegion->nLeft.bUnitPercent = bUnitPercent;
1576                                                         gRegion->nLeft.value = value;
1577                                                 }
1578                                         }
1579                                         break;
1580
1581
1582                                 case ATTRIBUTE_WIDTH: {
1583                                                 int bUnitPercent;
1584                                                 int value;
1585
1586                                                 if (strchr((char *)pAttr->children->content, '%'))
1587                                                         bUnitPercent = true;
1588                                                 else
1589                                                         bUnitPercent = false;
1590
1591                                                 value = atoi((char *)pAttr->children->content);
1592
1593                                                 if (gCmd[ELEMENT_ROOTLAYOUT]) {
1594                                                         gRootlayout.width.bUnitPercent = bUnitPercent;
1595                                                         gRootlayout.width.value = value;
1596                                                 } else if (gCmd[ELEMENT_REGION] && gRegion) {
1597                                                         gRegion->width.bUnitPercent = bUnitPercent;
1598                                                         gRegion->width.value = value;
1599                                                 }
1600                                         }
1601                                         break;
1602
1603                                 case ATTRIBUTE_HEIGHT: {
1604                                                 int bUnitPercent;
1605                                                 int value;
1606
1607                                                 if (strchr((char *)pAttr->children->content, '%'))
1608                                                         bUnitPercent = true;
1609                                                 else
1610                                                         bUnitPercent = false;
1611
1612                                                 value = atoi((char *)pAttr->children->content);
1613
1614                                                 if (gCmd[ELEMENT_ROOTLAYOUT]) {
1615                                                         gRootlayout.height.bUnitPercent = bUnitPercent;
1616                                                         gRootlayout.height.value = value;
1617                                                 } else if (gCmd[ELEMENT_REGION] && gRegion) {
1618                                                         gRegion->height.bUnitPercent = bUnitPercent;
1619                                                         gRegion->height.value = value;
1620                                                 }
1621                                         }
1622                                         break;
1623
1624                                 case ATTRIBUTE_FIT:
1625                                         if (gCmd[ELEMENT_REGION] && gRegion) {
1626                                                 if (!strcmp((char *)pAttr->children->content, "meet")) {
1627                                                         gRegion->fit = MMSUI_IMAGE_REGION_FIT_MEET;
1628                                                 } else {
1629                                                         gRegion->fit = MMSUI_IMAGE_REGION_FIT_HIDDEN;
1630                                                 }
1631                                         }
1632                                         break;
1633
1634                                 case ATTRIBUTE_BGCOLOR:
1635                                         if (gCmd[ELEMENT_ROOTLAYOUT]) {
1636                                                 gRootlayout.bBgColor = true;
1637                                                 gRootlayout.bgColor = MsgSmilGetColorValue(pAttr->children->content);
1638                                         } else if (gCmd[ELEMENT_REGION] && gRegion) {
1639                                                 gRegion->bBgColor = true;
1640                                                 gRegion->bgColor = MsgSmilGetColorValue(pAttr->children->content);
1641                                         } else if (gCmd[ELEMENT_TEXT] && gMedia) {
1642                                                 gMedia->sMedia.sText.nBgColor = MsgSmilGetColorValue(pAttr->children->content);
1643                                         } else if (gMedia) {
1644                                                 gMedia->sMedia.sAVI.nBgColor = MsgSmilGetColorValue(pAttr->children->content);
1645                                         }
1646
1647                                         break;
1648
1649                                 case ATTRIBUTE_DUR:
1650                                         if (gCmd[ELEMENT_PAR] && gPage) {
1651                                                 if (elementType == ELEMENT_PAR)
1652                                                         gPage->nDur =  MsgSmilGetTime((char *)pAttr->children->content);
1653                                         } else if (gCmd[ELEMENT_TRANSITION] && gTransition) {
1654                                                 gTransition->nDur =  MsgSmilGetTime((char *)pAttr->children->content);
1655                                         } else if (gCmd[ELEMENT_TEXT] && gMedia) {
1656                                                 gMedia->sMedia.sText.nDurTime =  MsgSmilGetTime((char *)pAttr->children->content);
1657                                         } else if (gMedia) {
1658                                                 gMedia->sMedia.sAVI.nDurTime =  MsgSmilGetTime((char *)pAttr->children->content);
1659                                         }
1660                                         break;
1661
1662                                 case ATTRIBUTE_SRC: {
1663                                         if (gMedia) {
1664                                                 char szContentID[MSG_MSG_ID_LEN + 1] = {0, };
1665                                                 int cLen;
1666
1667                                                 snprintf(szContentID, sizeof(szContentID), "%s", (char *)pAttr->children->content);
1668
1669                                                 cLen = strlen(szContentID);
1670                                                 if (!strncasecmp(szContentID, "cid:", 4)) {
1671                                                         strncpy(gMedia->szContentID, szContentID + 4, cLen - 4);
1672                                                         gMedia->szContentID[cLen - 4] = '\0';
1673                                                 } else {
1674                                                         strncpy(gMedia->szContentID, szContentID, cLen);
1675                                                         gMedia->szContentID[cLen] = '\0';
1676                                                 }
1677                                         }
1678                                         break;
1679                                 }
1680                                 case ATTRIBUTE_COLOR:
1681                                         if (gCmd[ELEMENT_TEXT] && gMedia)
1682                                                 gMedia->sMedia.sText.nColor = MsgSmilGetColorValue(pAttr->children->content);
1683                                         break;
1684
1685                                 case ATTRIBUTE_SIZE:
1686                                         if (gCmd[ELEMENT_TEXT] && gMedia)
1687                                                 gMedia->sMedia.sText.nSize = atoi((char *)pAttr->children->content);
1688                                         break;
1689
1690                                 case ATTRIBUTE_BOLD:
1691                                         if (gCmd[ELEMENT_TEXT] && gMedia) {
1692                                                 gMedia->sMedia.sText.bBold = MsgSmilGetFontAttrib((char *)pAttr->children->content);
1693                                         }
1694                                         break;
1695
1696                                 case ATTRIBUTE_UNDERLINE:
1697                                         if (gCmd[ELEMENT_TEXT] && gMedia)
1698                                                 gMedia->sMedia.sText.bUnderLine = MsgSmilGetFontAttrib((char *)pAttr->children->content);
1699                                         break;
1700
1701                                 case ATTRIBUTE_ITALIC:
1702                                         if (gCmd[ELEMENT_TEXT] && gMedia)
1703                                                 gMedia->sMedia.sText.bItalic = MsgSmilGetFontAttrib((char *)pAttr->children->content);
1704                                         break;
1705
1706                                 case ATTRIBUTE_REVERSE:
1707                                         if (gCmd[ELEMENT_TEXT] && gMedia)
1708                                                 gMedia->sMedia.sText.bReverse = MsgSmilGetFontAttrib((char *)pAttr->children->content);
1709                                         break;
1710
1711                                 case ATTRIBUTE_DIRECTION:
1712                                         if (gCmd[ELEMENT_TEXT] && gMedia)
1713                                                 gMedia->sMedia.sText.nDirection = MsgSmilGetFontDirection((char *)pAttr->children->content);
1714                                         break;
1715                                 case ATTRIBUTE_REGION:
1716                                         if (gMedia) {
1717                                                 strncpy(gMedia->regionId, (char *)pAttr->children->content, MAX_SMIL_REGION_ID - 1);
1718                                         }
1719                                         break;
1720
1721                                 case ATTRIBUTE_TRANSIN:
1722                                         if (gMedia) {
1723                                                 if (gCmd[ELEMENT_TEXT] )
1724                                                         strncpy(gMedia->sMedia.sText.szTransInId, (char *)pAttr->children->content, MAX_SMIL_TRANSIN_ID - 1);
1725                                                 else
1726                                                         strncpy(gMedia->sMedia.sAVI.szTransInId, (char *)pAttr->children->content, MAX_SMIL_TRANSIN_ID - 1);
1727                                         }
1728                                         break;
1729
1730                                 case ATTRIBUTE_TRANSOUT:
1731                                         if (gMedia) {
1732                                                 if (gCmd[ELEMENT_TEXT])
1733                                                         strncpy(gMedia->sMedia.sText.szTransOutId, (char *)pAttr->children->content, MAX_SMIL_TRANSOUT_ID - 1);
1734                                                 else
1735                                                         strncpy(gMedia->sMedia.sAVI.szTransOutId, (char *)pAttr->children->content, MAX_SMIL_TRANSOUT_ID - 1);
1736                                         }
1737                                         break;
1738
1739                                 case ATTRIBUTE_BEGIN:
1740                                         if (gMedia) {
1741                                                 if (gCmd[ELEMENT_TEXT])
1742                                                         gMedia->sMedia.sText.nBegin = MsgSmilGetTime((char *)pAttr->children->content);
1743                                                 else
1744                                                         gMedia->sMedia.sAVI.nBegin = MsgSmilGetTime((char *)pAttr->children->content);
1745                                         }
1746                                         break;
1747
1748                                 case ATTRIBUTE_END:
1749                                         if (gMedia) {
1750                                                 if (gCmd[ELEMENT_TEXT])
1751                                                         gMedia->sMedia.sText.nEnd = MsgSmilGetTime((char *)pAttr->children->content);
1752                                                 else
1753                                                         gMedia->sMedia.sAVI.nEnd = MsgSmilGetTime((char *)pAttr->children->content);
1754                                         }
1755                                         break;
1756
1757                                 case ATTRIBUTE_REPEAT_COUNT:
1758                                         if (gMedia) {
1759                                                 if (gCmd[ELEMENT_TEXT])
1760                                                         gMedia->sMedia.sText.nRepeat = atoi((char *)pAttr->children->content);
1761                                                 else
1762                                                         gMedia->sMedia.sAVI.nRepeat = atoi((char *)pAttr->children->content);
1763                                         }
1764                                         break;
1765
1766                                 case ATTRIBUTE_NAME:
1767                                         if (gCmd[ELEMENT_PARAM]) {
1768                                                 if (!strcmp((char *)pAttr->children->content, "foreground-color") || !strcmp((char *)pAttr->children->content, "foregroundcolor"))
1769                                                         paramType = ATTRIBUTE_FGCOLOR;
1770                                                 else if (!strcmp((char *)pAttr->children->content, "background-color") || !strcmp((char *)pAttr->children->content, "backgroundcolor"))
1771                                                         paramType = ATTRIBUTE_BGCOLOR;
1772                                                 else if (!strcmp((char *)pAttr->children->content, "textsize"))
1773                                                         paramType = ATTRIBUTE_SIZE;
1774                                                 else if (!strcmp((char *)pAttr->children->content, "textattribute"))
1775                                                         paramType = ATTRIBUTE_TEXTFORMAT;
1776
1777                                         } else if (gCmd[ELEMENT_META] && gMeta) {
1778                                                 strncpy(gMeta->szName, (char *)pAttr->children->content, MAX_SMIL_META_NAME - 1);
1779                                         }
1780                                         break;
1781
1782                                 case ATTRIBUTE_VALUE:
1783
1784                                         if (paramType == ATTRIBUTE_SIZE && gCmd[ELEMENT_TEXT] && gMedia) {
1785                                                 gMedia->sMedia.sText.nSize = MsgSmilGetFontSizeValue((char *)pAttr->children->content);
1786                                         } else if (paramType == ATTRIBUTE_FGCOLOR && gCmd[ELEMENT_TEXT] && gMedia) {
1787                                                 gMedia->sMedia.sText.nColor =  MsgSmilGetColorValue(pAttr->children->content);
1788                                         } else if (paramType == ATTRIBUTE_BGCOLOR && gCmd[ELEMENT_TEXT] && gMedia) {
1789                                                 gMedia->sMedia.sText.nBgColor =  MsgSmilGetColorValue(pAttr->children->content);
1790                                         } else if (paramType == ATTRIBUTE_TEXTFORMAT && gCmd[ELEMENT_TEXT] && gMedia) {
1791                                                 MmsSmilFontType fontType;
1792
1793                                                 fontType = MsgSmilGetFontTypeValue((char *)pAttr->children->content);
1794
1795                                                 if (fontType == MMS_SMIL_FONT_TYPE_BOLD)
1796                                                         gMedia->sMedia.sText.bBold = true;
1797                                                 else
1798                                                         gMedia->sMedia.sText.bBold = false;
1799
1800                                                 if (fontType == MMS_SMIL_FONT_TYPE_ITALIC)
1801                                                         gMedia->sMedia.sText.bItalic = true;
1802                                                 else
1803                                                         gMedia->sMedia.sText.bItalic = false;
1804
1805                                                 if (fontType == MMS_SMIL_FONT_TYPE_UNDERLINE)
1806                                                         gMedia->sMedia.sText.bUnderLine = true;
1807                                                 else
1808                                                         gMedia->sMedia.sText.bUnderLine = false;
1809                                         }
1810                                         paramType = ATTRIBUTE_UNKNOWN;
1811                                         break;
1812
1813                                 case ATTRIBUTE_ALT:
1814                                         if (gMedia) {
1815                                                 strncpy(gMedia->szAlt, (char *)pAttr->children->content, MAX_SMIL_ALT_LEN - 1);
1816                                         }
1817                                         break;
1818
1819                                 case ATTRIBUTE_TYPE:
1820                                         if (gTransition) {
1821                                                 gTransition->nType = (MmsSmilTransType)atoi((char *)pAttr->children->content);
1822
1823                                                 switch (gTransition->nType) {
1824                                                 case MMS_SMIL_TRANS_SLIDEWIPE:
1825                                                         gTransition->nSubType = MMS_SMIL_TRANS_SUB_FROM_LEFT;
1826                                                         break;
1827                                                 case MMS_SMIL_TRANS_BARWIPE:
1828                                                         gTransition->nSubType = MMS_SMIL_TRANS_SUB_TOP_TO_BOTTOM;
1829                                                         break;
1830                                                 case MMS_SMIL_TRANS_BARNDOORWIPE:
1831                                                         gTransition->nSubType = MMS_SMIL_TRANS_SUB_HORIZONTAL;
1832                                                         break;
1833                                                 default:
1834                                                         gTransition->nSubType = MMS_SMIL_TRANS_SUB_NONE;
1835                                                         break;
1836                                                 }
1837                                         }
1838                                         break;
1839
1840                                 case ATTRIBUTE_SUBTYPE:
1841                                         if (gTransition)
1842                                                 gTransition->nSubType = (MmsSmilTransSubType)atoi((char *)pAttr->children->content);
1843                                         break;
1844
1845                                 case ATTRIBUTE_CONTENT:
1846                                         if (gMeta)
1847                                                 strncpy(gMeta->szContent, (char *)pAttr->children->content, MAX_SMIL_META_CONTENT - 1);
1848                                         break;
1849
1850                                 default:
1851                                         MSG_DEBUG("Undefined Attribute was found!!!!!");
1852                                         break;
1853                                 }
1854                         }
1855
1856                         if (cur_node->children) { /* child first */
1857                                 MsgSmilParseNode(pMmsMsg, cur_node->children, depth + 1);
1858                         }
1859
1860                         if (elementType == ELEMENT_REGION && gRegion) {
1861                                 _MsgMmsAddRegion(pMmsMsg, gRegion);
1862                                 gRegion = NULL;
1863                         } else if (elementType ==  ELEMENT_PAR && gPage) {
1864                                 _MsgMmsAddPage(pMmsMsg, gPage);
1865                                 gPage = NULL;
1866                         } else if ((elementType == ELEMENT_TEXT || elementType == ELEMENT_IMG || elementType == ELEMENT_AUDIO || elementType == ELEMENT_VIDEO || elementType == ELEMENT_ANIMATE || elementType == ELEMENT_REF)
1867                                         && gCmd[ELEMENT_PAR] && gPage && gMedia) {
1868                                 _MsgMmsAddMedia(gPage, gMedia);
1869                                 gMedia = NULL;
1870                         } else if (elementType == ELEMENT_ROOTLAYOUT) {
1871                                 _MsgMmsSetRootLayout(pMmsMsg, &gRootlayout);
1872                         } else if (elementType == ELEMENT_TRANSITION  && gTransition) {
1873                                 _MsgMmsAddTransition(pMmsMsg, gTransition);
1874                                 gTransition = NULL;
1875                         } else if (elementType == ELEMENT_META && gMeta) {
1876                                 _MsgMmsAddMeta(pMmsMsg, gMeta);
1877                                 gMeta = NULL;
1878                         }
1879
1880                         if (elementType >= ELEMENT_SMIL)
1881                                 gCmd[elementType] = false;
1882
1883                         paramType = ATTRIBUTE_UNKNOWN;
1884                 }
1885         }
1886
1887         MSG_END();
1888 }
1889
1890 bool MsgSmilParseSmilDoc(MMS_MESSAGE_DATA_S *pstMsgMmsBody, const char *pSmilDoc)
1891 {
1892         MSG_BEGIN();
1893
1894         xmlDocPtr doc;
1895         xmlNodePtr cur;
1896
1897         if (pSmilDoc == NULL || strlen(pSmilDoc) == 0) {
1898                 MSG_DEBUG("Invalid Parameter : pSmilDoc [%p]", pSmilDoc);
1899                 return false;
1900         }
1901
1902         MSG_SEC_INFO("Parse Smil : [%s]", pSmilDoc);
1903
1904         doc = xmlParseMemory(pSmilDoc, strlen(pSmilDoc));
1905         if (doc == NULL) {
1906                 MSG_DEBUG("Failed xmlParseMemory");
1907                 return false;
1908         }
1909
1910         cur = xmlDocGetRootElement(doc);
1911         if (cur == NULL) {
1912                 MSG_DEBUG("Failed xmlDocGetRootElement");
1913                 xmlFreeDoc(doc);
1914                 return false;
1915         }
1916
1917         if (xmlStrcmp(cur->name, (const xmlChar *) "smil")) {
1918                 MSG_DEBUG("document of the wrong type, root node != smil");
1919                 xmlFreeDoc(doc);
1920                 return false;
1921         }
1922
1923         MsgSmilParseNode(pstMsgMmsBody, cur, 0);
1924
1925         xmlFreeDoc(doc);
1926         MSG_END();
1927         return true;
1928 }
1929
1930 bool MsgSmilGenerateSmilDoc(MMS_MESSAGE_DATA_S *pstMsgMmsBody, char **ppSmilDoc)
1931 {
1932         MSG_BEGIN();
1933
1934         HMsgSmil hSmilDoc = INVALID_HOBJ;
1935         int nIndex;
1936         int nMediaIndex;
1937         int nTotalPageNum;
1938         int nTotalMediaNum;
1939         int nRegionCount;
1940         MMS_PAGE_S *pstPage;
1941         MMS_MEDIA_S *pstMedia;
1942         MMS_SMIL_REGION *pstRegion;
1943         char *pszRawData;
1944
1945         hSmilDoc = MsgSmilCreateEmptySmilDoc();
1946         if (INVALID_HOBJ == hSmilDoc) {
1947                 MSG_DEBUG("Invalid SmilDoc[%d]", hSmilDoc);
1948                 return false;
1949         }
1950         /* Add Root Layout to Smil Document */
1951         if (false == MsgSmilAddRootLayout(hSmilDoc, &(pstMsgMmsBody->rootlayout))) {
1952                 MSG_DEBUG("MsgSmilAddRootLayout Failed");
1953                 MsgSmilDestroyDoc(hSmilDoc);
1954         }
1955         /* Add Region list to Smil Document */
1956         nRegionCount = pstMsgMmsBody->regionCnt;
1957         MSG_DEBUG("Region Count = [%d]", nRegionCount);
1958         for (nIndex = 0; nIndex < nRegionCount; nIndex++) {
1959                 pstRegion = _MsgMmsGetSmilRegion(pstMsgMmsBody, nIndex);
1960                 if (NULL == pstRegion) {
1961                         MSG_DEBUG("pstRegion is NULL");
1962                         MsgSmilDestroyDoc(hSmilDoc);
1963                         return false;
1964                 }
1965
1966                 if (false == MsgSmilAddRegion(hSmilDoc, pstRegion)) {
1967                         MSG_DEBUG("Adding Region to smil doc failed");
1968                         MsgSmilDestroyDoc(hSmilDoc);
1969                         return false;
1970                 }
1971         }
1972
1973         /* Add page list to Smil Document */
1974         nTotalPageNum = pstMsgMmsBody->pageCnt ;
1975         MSG_DEBUG("Page Count = [%d]", nTotalPageNum);
1976         for (nIndex = 0; nIndex < nTotalPageNum; nIndex++) {
1977                 pstPage = _MsgMmsGetPage(pstMsgMmsBody, nIndex);
1978                 if (NULL == pstPage) {
1979                         MSG_DEBUG("pstPage is NULL");
1980                         MsgSmilDestroyDoc(hSmilDoc);
1981                         return false;
1982                 }
1983
1984                 /* Add page to smil doc */
1985                 if (false == MsgSmilAddPage(hSmilDoc, pstPage)) {
1986                         MSG_DEBUG("Adding page to smil doc failed");
1987                         MsgSmilDestroyDoc(hSmilDoc);
1988                         return false;
1989                 }
1990
1991                 nTotalMediaNum = pstPage->mediaCnt;
1992                 MSG_DEBUG("Media Count = [%d]", nTotalMediaNum);
1993                 for (nMediaIndex = 0; nMediaIndex < nTotalMediaNum; nMediaIndex++) {
1994                         pstMedia = _MsgMmsGetMedia(pstPage, nMediaIndex);
1995                         if (NULL == pstMedia) {
1996                                 MSG_DEBUG("pMedia is NULL");
1997                                 MsgSmilDestroyDoc(hSmilDoc);
1998                                 return false;
1999                         }
2000
2001                         if (false == MsgSmilAddMedia(hSmilDoc, nIndex, nMediaIndex, pstMedia, pstMedia->szContentID)) {
2002                                 MSG_DEBUG("MsgSmilAddMedia failed");
2003                                 MsgSmilDestroyDoc(hSmilDoc);
2004                                 return false;
2005                         }
2006                 }
2007         }
2008
2009         pszRawData = MsgSmilGetRawData(hSmilDoc);
2010         if (NULL == pszRawData) {
2011                 MSG_DEBUG("MsgSmilGetRawData failed");
2012                 MsgSmilDestroyDoc(hSmilDoc);
2013                 return false;
2014         }
2015
2016         if (ppSmilDoc) {
2017                 *ppSmilDoc = pszRawData;
2018                 MSG_SEC_INFO("Generated Smil : [%s]", pszRawData);
2019         }
2020
2021         MsgSmilDestroyDoc(hSmilDoc);
2022         MSG_END();
2023         return true;
2024 }