📄 slparhlr.c
字号:
/*
* Copyright (C) Obigo AB, 2002-2005.
* All rights reserved.
*
* This software is covered by the license agreement between
* the end user and Obigo AB, and may be
* used and copied only in accordance with the terms of the
* said agreement.
*
* Obigo AB assumes no responsibility or
* liability for any errors or inaccuracies in this software,
* or any consequential, incidental or indirect damage arising
* out of the use of the software.
*
*/
#include "cansilib.h"
#include "cmnconf.h"
#include "aapifile.h"
#include "aapicmn.h"
#include "gmem.h"
#include "cutils.h"
#include "ccoder.h"
#include "mmem.h"
#include "mmsconf.h"
#include "mmstypes.h"
#include "msig.h"
#include "aapimms.h"
#include "mtimer.h"
#include "slutil.h"
#include "slparhlr.h"
typedef enum
{
SLPH_STATE_IDLE = 0,
SLPH_STATE_PARSING_HEAD,
SLPH_STATE_WAIT_FOR_HEAD_RESPONSE,
SLPH_STATE_WAIT_FOR_FIRST_PAR,
SLPH_STATE_PARSING_PAR,
SLPH_STATE_MAX
} SlphParserHandlerState;
static const char SLPH_FIT_STR_FILL[] = "fill";
static const char SLPH_FIT_STR_HIDDEN[] = "hidden";
static const char SLPH_FIT_STR_MEET[] = "meet";
static const char SLPH_FIT_STR_SCROLL[] = "scroll";
static const char SLPH_FIT_STR_SLICE[] = "slice";
#define SLPH_FILE_READ_FAILED -1
#define SLPH_FILE_OPEN_FAILED -1
#define SLPH_NO_FILE 0
#define SLPH_FIRST_FILE_POS 0
#define SLPH_BIT_PARSER_FINISHED 0x01
typedef struct SlphParListSt
{
SmilPar *par;
CMN_BOOL finished;
struct SlphParListSt *next;
} SlphParList;
typedef struct
{
SmilMetaInfo *metaInfo;
SmilRegion *region;
SmilRootLayout *rootLayout;
SlphParList *parList;
} SlphParserData;
typedef struct
{
SmilMsg src;
int filePos;
SlphParserData data;
SlphParserHandlerState state;
int stack[SMIL_SPH_MAX_NESTING_DEPTH];
short stackTopElem;
unsigned char flag;
} SlphInstance;
typedef void SlphStateFunctionHandler(const MmsSignal *sig);
static SlphStateFunctionHandler *slphSignalHandlers[SLPH_STATE_MAX];
static SlphInstance *slphInst = NULL;
static CMN_BOOL slphFsmBusy = FALSE;
#define SLPH_STACK_EMPTY -1
typedef struct
{
const char *colorName;
const UINT32 colorValue;
}SlphColor;
const SlphColor slphColorSet[] = SMIL_COLOR_SET;
static SmilResult beginParsing(void);
static void changeState(SlphParserHandlerState toState);
static UINT32 colorSTOI(const char *colorStrVal);
static void copyRegionFitString(SmilRegion *reg, int fit);
static void copyStrAttribute(char **pDest, const SlphAttribute *pSrcAttr);
static CMN_BOOL dataExistToDeliver(void);
static void deleteInstance(void);
static void endElement(void);
static void freeStartElement(SlphStartElem *pData);
static void freeSignalParam(MmsSignal *sig);
static char *getStrAttr(const SlphStartElem *pData, int type);
static void idleStateHandler(const MmsSignal *sig);
static void initInstance(void);
static void manageParser(const MmsSignal *sig);
static void mediaObjectStartElem(const SlphStartElem *pData);
static void metaInfoStartElem(const SlphStartElem *pData);
static void parserAck(void);
static void parserFoundStartElem(const MmsSignal *sig);
static void headResponseStateHandler(const MmsSignal *sig);
static void headStateHandler(const MmsSignal *sig);
static void parStateHandler(const MmsSignal *sig);
static void parStartElem(const SlphStartElem *pData);
static void paramStartElem(const SlphStartElem *pData);
static void regionStartElem(const SlphStartElem *pData);
static void receivedCancel(void);
static void rootlayoutStartElem(const SlphStartElem *pData);
static SmilResult sendDataToParser(void);
static void sendPar(void);
static void slphMain(MmsSignal *sig);
static CMN_BOOL stackIsEmpty(void);
static void stackPop(void);
static SmilResult stackPush(int val);
static int stackTop(void);
static CMN_BOOL stackSearch(int element);
static void waitForFirstParStateHandler(const MmsSignal *sig);
static SmilResult beginParsing(void)
{
if (SMIL_MSG_STORED_IN_BUFFER == slphInst->src.storageType)
{
SMILa_parserData(slphInst->src.data.buffer,
(int)slphInst->src.dataSize, FALSE);
return SMIL_RESULT_OK;
}
else
{
if (SLPH_NO_FILE == slphInst->src.data.file.id)
{
return SMIL_RESULT_OPEN_FILE_FAILED;
}
else if (SLPH_FILE_OPEN_FAILED ==
FILEa_open(slphInst->src.data.file.category,
slphInst->src.data.file.id, FILE_OPTION_READ))
{
MMS_LOG_I(("SMIL SLPH: failed to open source file.\n"));
return SMIL_RESULT_OPEN_FILE_FAILED;
}
else
{
return sendDataToParser();
}
}
}
static void changeState(SlphParserHandlerState toState)
{
MMS_LOG_I(("SMIL SLPH: changing state from: %d to: %d\n",
slphInst->state, toState));
slphInst->state = toState;
}
static void copyRegionFitString(SmilRegion *reg, int fit)
{
const char *pStr = NULL;
unsigned int strLen;
if (reg->fit)
{
return;
}
switch(fit)
{
case SLPH_ATTRVAL_FILL:
pStr = SLPH_FIT_STR_FILL;
break;
case SLPH_ATTRVAL_HIDDEN:
pStr = SLPH_FIT_STR_HIDDEN;
break;
case SLPH_ATTRVAL_MEET:
pStr = SLPH_FIT_STR_MEET;
break;
case SLPH_ATTRVAL_SCROLL:
pStr = SLPH_FIT_STR_SCROLL;
break;
case SLPH_ATTRVAL_SLICE:
pStr = SLPH_FIT_STR_SLICE;
break;
default:
MMS_LOG_I(("SMIL SLPH: copyRegionFitString unknown fit, %d\n", fit));
break;
}
if (pStr)
{
strLen = strlen(pStr) + 1;
reg->fit = (char *)M_ALLOC(strLen);
strcpy(reg->fit, pStr);
}
}
static void copyStrAttribute(char **pDest, const SlphAttribute *pSrcAttr)
{
unsigned int strLen;
if (NULL == *pDest)
{
if (! pSrcAttr->value.data)
{
*pDest = NULL;
}
else
{
strLen = strlen(pSrcAttr->value.data) + 1;
*pDest = (char *)M_ALLOC(strLen);
strcpy(*pDest, pSrcAttr->value.data);
}
}
}
static CMN_BOOL dataExistToDeliver(void)
{
return slphInst->data.parList != NULL && slphInst->data.parList->finished;
}
static void deleteInstance()
{
SlphParList *pList;
SlphParList *pList2;
M_TIMER_RESET(M_FSM_SMIL_PARSE_HANDLER);
if (slphInst)
{
if ((SLPH_STATE_IDLE != slphInst->state) &&
( !(SLPH_BIT_PARSER_FINISHED & slphInst->flag)))
{
SMILa_parserStop();
}
if (SMIL_MSG_STORED_AS_FILE == slphInst->src.storageType &&
SLPH_NO_FILE != slphInst->src.data.file.id)
{
FILEa_close(slphInst->src.data.file.category,
slphInst->src.data.file.id);
}
else if (SMIL_MSG_STORED_IN_BUFFER == slphInst->src.storageType)
{
M_FREE(slphInst->src.data.buffer);
}
if (slphInst->data.metaInfo)
{
sluFreeMeta(slphInst->data.metaInfo);
}
if (slphInst->data.region)
{
sluFreeRegion(slphInst->data.region);
}
if (slphInst->data.rootLayout)
{
sluFreeRootLayout(slphInst->data.rootLayout);
}
if (slphInst->data.parList)
{
pList = slphInst->data.parList;
while (pList)
{
sluFreeNoneNestedPar(pList->par);
pList2 = pList;
pList = pList->next;
M_FREE(pList2);
}
}
M_FREE(slphInst);
slphInst = NULL;
}
if (slphFsmBusy)
{
slphFsmBusy = FALSE;
}
}
static void endElement(void)
{
SlphParList *pList;
if (SLPH_ELEMENT_PAR == stackTop())
{
pList = slphInst->data.parList;
while (pList)
{
if (! pList->finished)
{
pList->finished = TRUE;
break;
}
pList = pList->next;
}
}
stackPop();
}
static void freeStartElement(SlphStartElem *pData)
{
int i;
SlphAttribute *pAttr;
if (pData)
{
if (pData->attrs && pData->numAttrs > 0)
{
pAttr = pData->attrs;
for (i = 0; i < pData->numAttrs; ++i)
{
if (pAttr[i].valueType == SLPH_STRING)
{
M_FREE(pAttr[i].value.data);
}
}
M_FREE(pData->attrs);
}
M_FREE(pData);
}
}
static void freeSignalParam(MmsSignal *sig)
{
SmilMsg *msg;
switch (sig->type)
{
case SLPH_SIG_START_PARSER_HANDLER:
if (sig->p_param)
{
msg = (SmilMsg *)(sig->p_param);
if (SMIL_MSG_STORED_IN_BUFFER == msg->storageType)
{
M_FREE(msg->data.buffer);
}
M_FREE(sig->p_param);
sig->p_param = NULL;
}
break;
case SLPH_SIG_PARSER_START_ELEMENT:
if (sig->p_param)
{
freeStartElement((SlphStartElem *)sig->p_param);
sig->p_param = NULL;
}
break;
case SLPH_SIG_PARSER_CHAR_DATA:
if (sig->p_param)
{
SlphCharacterData *pData;
pData = (SlphCharacterData *)sig->p_param;
if (pData->charData)
{
M_FREE(pData->charData);
}
M_FREE(sig->p_param);
sig->p_param = NULL;
}
break;
}
}
static void idleStateHandler(const MmsSignal *sig)
{
SmilMsg *msg;
SmilResult res;
switch (sig->type)
{
case SLPH_SIG_START_PARSER_HANDLER:
msg = (SmilMsg *)(sig->p_param);
if (! msg)
{
MMS_LOG_I(("SMIL SLPH: no SMIL message included with the start signal.\n"));
SMILa_parserHandlerResponse(SMIL_RESULT_MISSING_DATA);
deleteInstance();
return;
}
else if (SMIL_MSG_STORED_IN_BUFFER != msg->storageType &&
SMIL_MSG_STORED_AS_FILE != msg->storageType)
{
MMS_LOG_I(("SMIL SLPH: unknown source storage type.\n"));
SMILa_parserHandlerResponse(SMIL_RESULT_UNKNOWN_STORAGE_TYPE);
deleteInstance();
return;
}
else if (SMIL_MSG_STORED_IN_BUFFER == msg->storageType)
{
if (msg->dataSize == 0)
{
MMS_LOG_I(("SMIL SLPH: source buffer size (%d)>= 0.\n",
msg->dataSize));
SMILa_parserHandlerResponse(SMIL_RESULT_BUFFER_SIZE_ZERO);
deleteInstance();
return;
}
slphInst->src.data.buffer = (unsigned char *)M_ALLOC(msg->dataSize);
memcpy(slphInst->src.data.buffer, msg->data.buffer, msg->dataSize);
slphInst->src.dataSize = msg->dataSize;
slphInst->src.storageType = msg->storageType;
}
else if (SMIL_MSG_STORED_AS_FILE == msg->storageType)
{
slphInst->src.data.file.category = msg->data.file.category;
slphInst->src.data.file.id = msg->data.file.id;
slphInst->src.dataSize = msg->dataSize;
slphInst->src.storageType = msg->storageType;
}
if (SMIL_RESULT_OK != (res = beginParsing()))
{
MMS_LOG_I(("%s(%d): Failed to begin parsing.\n", __FILE__, __LINE__));
SMILa_parserHandlerResponse(res);
deleteInstance();
}
else
{
M_TIMER_SET(M_FSM_SMIL_PARSE_HANDLER, SMIL_PARSE_HANDLER_TIMEOUT);
changeState(SLPH_STATE_PARSING_HEAD);
}
break;
case SLPH_SIG_CANCEL:
SMILa_parserHandlerResponse(SMIL_RESULT_CANCELLED_BY_USER);
deleteInstance();
break;
default:
MMS_LOG_I(("%s(%d): with unknown element!\n", __FILE__, __LINE__));
break;
}
}
static void initInstance(void)
{
slphInst = (SlphInstance *)M_CALLOC(sizeof(SlphInstance));
slphInst->filePos = SLPH_FIRST_FILE_POS;
slphInst->stackTopElem = SLPH_STACK_EMPTY;
slphInst->state = SLPH_STATE_IDLE;
}
static void mediaObjectStartElem(const SlphStartElem *pData)
{
SmilMediaObject *pNew;
SmilMediaObject *pTmp;
SlphParList *pParList;
SlphAttribute *pAttr;
int i;
if (! pData)
{
return;
}
if (! slphInst->data.parList || !slphInst->data.parList->par)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -