⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slparhlr.c

📁 彩信MMS的全部代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -