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

📄 pssuaprofparser.c

📁 移动流媒体同步服务器模块
💻 C
字号:
/********************************************************************
Copyright(C), 2006, Wuhan Hongxu Information Technologies Co., Ltd.
Filename   : pssUaprofParser.c
Description: uaprof parser program.
Author     : YangJun
Version    : Initial version
Date       : 2006年12月
History    :
<author>     <time>     <version >     <desc>
********************************************************************/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <expat.h>
#include "StreamDBMsgDefs.h"
#include "pssUaprofParser.h"

/*终端能力信息文件命名空间*/
#define XMLNS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define XMLNS_PRF "http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#"
#define XMLNS_PSS5 "http://www.3gpp.org/profiles/PSS/ccppschema-PSS5"
#define XMLNS_PSS6 "http://www.3gpp.org/profiles/PSS/ccppschema-PSS6"

/*流媒体终端能力组件*/
#define PSS5_COMPONENT_STREAMING     "Streaming"
#define PSS6_COMPONENT_COMMON        "PssCommon"
#define PSS6_COMPONENT_STREAMING     "Streaming"
#define PSS6_COMPONENT_3GP_FILE      "ThreeGPFileFormat"

/*流媒体终端能力属性*/
#define PSS_PROPERTY_PSSVERSION         "PssVersion"
#define PSS_PROPERTY_SCREENSIZE         "RenderingScreenSize"
#define PSS5_PROPERTY_PSSACCEPT         "PssAccept"
#define PSS6_PROPERTY_STREAMING_ACCEPT  "StreamingAccept"
#define PSS6_PROPERTY_3GP_ACCEPT        "ThreeGPAccept"
#define PSS6_PROPERTY_BRANDS            "Brands"

/*终端能力硬件属性*/
#define UAPROF_MODEL        "Model"

/*其他终端能力信息文件通用属性*/
#define UAPROF_RDF_BAG      "Bag"
#define UAPROF_RDF_LI       "li"

/*流媒体终端能力信息文件版本*/
#define PSS_VERSION_5       5
#define PSS_VERSION_6       6
#define PSS_VERSION_UNKNOWN 7

#define THREEGP_R5        "3GPP-R5"
#define THREEGP_R6        "3GPP-R6"

#define MAX_XMLNS_LEN        16
typedef struct _pss_uaprof_parser_context_t
{
    pss_uaprof_t        *pPssUaProf;
    XML_Parser          parser;
    char                xmlnsRdf[MAX_XMLNS_LEN];
    char                xmlnsPrf[MAX_XMLNS_LEN];
    char                xmlnsPss5[MAX_XMLNS_LEN];
    char                xmlnsPss6[MAX_XMLNS_LEN];
    unsigned int        parserStatus;
    XML_Bool            isPss5PssAcept;
    XML_Bool            isPss6StreamingAccept;
    XML_Bool            isPss6Brands;
    XML_Bool            isPss63GPAccept;
    XML_Bool            isRootElement;
    XML_Bool            isBagLi;
    XML_Bool            isPssVersion;
    XML_Bool            isScreenSize;
    XML_Bool            isModel;
    char                pssVersion;/*PSS_VERSION_5,PSS_VERSION_6*/
}pss_uaprof_parser_context_t;

static void XMLCALL
startUaprofElement(void *userData, const char *name, const char **atts)
{
    pss_uaprof_parser_context_t *pCtx=(pss_uaprof_parser_context_t*)userData;
    int i;
    char temp[128];

    /*在根元素中确定各相关命名空间的值*/
    if (XML_TRUE==pCtx->isRootElement)
    {
        for (i=0;atts[i];i=i+2)
        {
            if (strlen(atts[i])>MAX_XMLNS_LEN+5)/*去掉"xmlns:"后长度不能超过MAX_XMLNS_LEN-1*/
            {
                pCtx->parserStatus=UAPROF_PARSER_OVERFLOW;
                XML_StopParser(pCtx->parser,XML_FALSE);
                return;
            }
            if (0==strcmp(atts[i+1],XMLNS_RDF))
            {
                strcpy(pCtx->xmlnsRdf,atts[i]+strlen("xmlns:"));
                continue;
            }
            if (0==strcmp(atts[i+1],XMLNS_PRF))
            {
                strcpy(pCtx->xmlnsPrf,atts[i]+strlen("xmlns:"));
                continue;
            }
            if (0==strcmp(atts[i+1],XMLNS_PSS5))
            {
                strcpy(pCtx->xmlnsPss5,atts[i]+strlen("xmlns:"));
                continue;
            }
            if (0==strcmp(atts[i+1],XMLNS_PSS6))
            {
                strcpy(pCtx->xmlnsPss5,atts[i]+strlen("xmlns:"));
                continue;
            }
        }
        pCtx->isRootElement=XML_FALSE;
        return;
    }

    /*记录当前分析到哪个元素*/
    sprintf(temp,"%s:%s",pCtx->xmlnsPrf,UAPROF_MODEL);
    if (0==strcmp(name,temp))/*prf:Model*/
    {
        pCtx->isModel=XML_TRUE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsPss5,PSS5_PROPERTY_PSSACCEPT);
    if (0==strcmp(name,temp))/*pss5:PssAccept*/
    {
        pCtx->isPss5PssAcept=XML_TRUE;
        return;
    }
    if (NULL!=strstr(name,PSS_PROPERTY_SCREENSIZE))/*pss5:RenderingScreenSize或者pss6:RenderingScreenSize*/
    {
        pCtx->isScreenSize=XML_TRUE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsPss6,PSS6_PROPERTY_STREAMING_ACCEPT);
    if (0==strcmp(name,temp))/*pss6:StreamingAccept*/
    {
        pCtx->isPss6StreamingAccept=XML_TRUE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsPss6,PSS6_PROPERTY_BRANDS);
    if (0==strcmp(name,temp))/*pss6:Brands*/
    {
        pCtx->isPss6Brands=XML_TRUE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsPss6,PSS6_PROPERTY_3GP_ACCEPT);
    if (0==strcmp(name,temp))/*pss6:ThreeGPAccept*/
    {
        pCtx->isPss63GPAccept=XML_TRUE;
        return;
    }
    if (NULL!=strstr(name,PSS_PROPERTY_PSSVERSION))/*pss5:PssVersion 或者 pss6:PssVersion*/
    {
        pCtx->isPssVersion=XML_TRUE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsRdf,"li");
    if (0==strcmp(name,temp))/*rdf:li*/
    {
        pCtx->isBagLi=XML_TRUE;
        return;
    }
}

static void XMLCALL
endUaprofElement(void *userData,const XML_Char *name)
{
    pss_uaprof_parser_context_t *pCtx=(pss_uaprof_parser_context_t*)userData;
    char temp[128];

    /*退出当前元素的处理,与进入时的赋值正好相反*/
    sprintf(temp,"%s:%s",pCtx->xmlnsPrf,UAPROF_MODEL);
    if (0==strcmp(name,temp))/*prf:Model*/
    {
        pCtx->isModel=XML_FALSE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsPss5,PSS5_PROPERTY_PSSACCEPT);
    if (0==strcmp(name,temp))/*pss5:PssAccept*/
    {
        pCtx->isPss5PssAcept=XML_FALSE;
        return;
    }
    if (NULL!=strstr(name,PSS_PROPERTY_SCREENSIZE))/*pss5:RenderingScreenSize或者pss6:RenderingScreenSize*/
    {
        pCtx->isScreenSize=XML_FALSE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsPss6,PSS6_PROPERTY_STREAMING_ACCEPT);
    if (0==strcmp(name,temp))/*pss6:StreamingAccept*/
    {
        pCtx->isPss6StreamingAccept=XML_FALSE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsPss6,PSS6_PROPERTY_BRANDS);
    if (0==strcmp(name,temp))/*pss6:Brands*/
    {
        pCtx->isPss6Brands=XML_FALSE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsPss6,PSS6_PROPERTY_3GP_ACCEPT);
    if (0==strcmp(name,temp))/*pss6:ThreeGPAccept*/
    {
        pCtx->isPss63GPAccept=XML_FALSE;
        return;
    }
    if (NULL!=strstr(name,PSS_PROPERTY_PSSVERSION))/*pss5:PssVersion 或者 pss6:PssVersion*/
    {
        pCtx->isPssVersion=XML_FALSE;
        return;
    }
    sprintf(temp,"%s:%s",pCtx->xmlnsRdf,"li");
    if (0==strcmp(name,temp))/*rdf:li*/
    {
        pCtx->isBagLi=XML_FALSE;
        return;
    }
}

#define MAX_CHAR_DATA_LEN        255

/*
处理UaProf文件中元素的文本内容
*/
static void XMLCALL
UaprofCharDataHandler(void *userData, const char *name, int len)
{
    pss_uaprof_parser_context_t *pCtx=(pss_uaprof_parser_context_t*)userData;
    char charData[MAX_CHAR_DATA_LEN];        /*保存文本内容*/
    char width[8];                           /*屏幕宽度字符串*/
    char hight[8];                           /*屏幕高度字符串*/
    char *p;
    int nPos;

    if (len>MAX_CHAR_DATA_LEN)
    {
        /*当数据长度过大时,溢出*/
        pCtx->parserStatus=UAPROF_PARSER_OVERFLOW;
        XML_StopParser(pCtx->parser,XML_FALSE);
        return;
    }
    memset(charData,'\0',MAX_CHAR_DATA_LEN);
    memcpy(charData,name,len);

    /*不同的元素进行不同的处理*/
    if (XML_TRUE==pCtx->isBagLi)
    {
        /*rdf:li元素处理*/
        if (XML_TRUE==pCtx->isPss5PssAcept || XML_TRUE==pCtx->isPss6StreamingAccept)
        {
            /*当前元素是pss5:PssAccept或者pss6:StreamingAccept元素的子元素*/
            if (strlen(pCtx->pPssUaProf->pssStreaming.streamingAccept)+len+1>MAX_PSS_STREAMING_ACCEPT_LEN-1)
            {
                pCtx->parserStatus=UAPROF_PARSER_OVERFLOW;
                XML_StopParser(pCtx->parser,XML_FALSE);
                return;
            }
            if (strlen(pCtx->pPssUaProf->pssStreaming.streamingAccept)>0)
            {
                strcat(pCtx->pPssUaProf->pssStreaming.streamingAccept,",");
            }
            strcat(pCtx->pPssUaProf->pssStreaming.streamingAccept,charData);
            return;
        }
        if (XML_TRUE==pCtx->isPss63GPAccept)
        {
            /*当前元素是pss6:3GPAccept的子元素*/
            if (strlen(pCtx->pPssUaProf->pssThreeGPFileFormat.threeGPAccept)+len+1>MAX_PSS_STREAMING_ACCEPT_LEN-1)
            {
                pCtx->parserStatus=UAPROF_PARSER_OVERFLOW;
                XML_StopParser(pCtx->parser,XML_FALSE);
                return;
            }
            if (strlen(pCtx->pPssUaProf->pssThreeGPFileFormat.threeGPAccept)>0)
            {
                strcat(pCtx->pPssUaProf->pssThreeGPFileFormat.threeGPAccept,",");
            }
            strcat(pCtx->pPssUaProf->pssThreeGPFileFormat.threeGPAccept,charData);
            return;
        }
        if (XML_TRUE==pCtx->isPss6Brands)
        {
            /*当前元素是pss6:Brands的子元素*/
            if (strlen(pCtx->pPssUaProf->pssThreeGPFileFormat.brands)+len+1>MAX_PSS_BRANDS_LEN-1)
            {
                pCtx->parserStatus=UAPROF_PARSER_OVERFLOW;
                XML_StopParser(pCtx->parser,XML_FALSE);
                return;
            }
            if (strlen(pCtx->pPssUaProf->pssThreeGPFileFormat.brands)>0)
            {
                strcat(pCtx->pPssUaProf->pssThreeGPFileFormat.brands,",");
            }
            strcat(pCtx->pPssUaProf->pssThreeGPFileFormat.brands,charData);
            return;
        }
        return;
    }
    if (XML_TRUE==pCtx->isModel)
    {
        /*当前元素是prf:Model*/
        if (len>MAX_MT_MODEL_LEN-1)
        {
            pCtx->parserStatus=UAPROF_PARSER_OVERFLOW;
            XML_StopParser(pCtx->parser,XML_FALSE);
            return;
        }

        strcpy(pCtx->pPssUaProf->model,charData);

        return;
    }
    if (XML_TRUE==pCtx->isPssVersion)
    {
        if (0==strcmp(charData,THREEGP_R5))
        {
            pCtx->pssVersion=PSS_VERSION_5;
            return;
        }
        if (0==strcmp(charData,THREEGP_R6))
        {
            pCtx->pssVersion=PSS_VERSION_6;
            return;
        }
        pCtx->pssVersion=PSS_VERSION_UNKNOWN;
        return;
    }

    if (XML_TRUE==pCtx->isScreenSize)
    {
        /*当前元素为pss5:RenderingScreenSize或者pss6:RenderingScreenSize*/
        memset(width,'\0',8);
        memset(hight,'\0',8);

        p=strchr(charData,'x');
        nPos=p-charData+1;
        memcpy(width,charData,nPos-1);
        pCtx->pPssUaProf->pssCommon.RenderingScreenSize.width=atoi(width);

        strcpy(hight,charData+nPos);
        pCtx->pPssUaProf->pssCommon.RenderingScreenSize.height=atoi(hight);

        return;
    }
}

#define BUFFER_SIZE 1024

unsigned int parsePssUaProf(pss_uaprof_t *pPssUaProf,FILE *pFileUaProf)
{
    XML_Parser parser;
    int dataLen;
    int isFinal;
    unsigned int parserStatus;
    char buffer[BUFFER_SIZE];
    pss_uaprof_parser_context_t userData;

    parser=XML_ParserCreate(NULL);

    if (NULL==parser)
    {
        return UAPROF_PARSER_INIT_FAILED;
    }
    memset(pPssUaProf,0,sizeof(pss_uaprof_t));
    userData.pPssUaProf=pPssUaProf;
    strcpy(userData.xmlnsPrf,"prf");
    strcpy(userData.xmlnsPss5,"pss5");
    strcpy(userData.xmlnsPss6,"pss6");
    strcpy(userData.xmlnsRdf,"rdf");
    userData.parserStatus=UAPROF_PARSER_OK;
    userData.isBagLi=XML_FALSE;
    userData.isPss5PssAcept=XML_FALSE;
    userData.isPss63GPAccept=XML_FALSE;
    userData.isModel=XML_FALSE;
    userData.isPss6Brands=XML_FALSE;
    userData.isPss6StreamingAccept=XML_FALSE;
    userData.isPssVersion=XML_FALSE;
    userData.isScreenSize=XML_FALSE;
    userData.isRootElement=XML_TRUE;
    userData.parser=parser;

    XML_SetUserData(parser,(void*)&userData);
    XML_SetElementHandler(parser,startUaprofElement,endUaprofElement);
    XML_SetCharacterDataHandler(parser,UaprofCharDataHandler);

    dataLen=0;
    isFinal=0;

    while (0==isFinal)
    {
        dataLen=fread(buffer,1,BUFFER_SIZE,pFileUaProf);

        if (ferror(pFileUaProf))
        {
            userData.parserStatus=UAPROF_PARSER_FERROR;
            break;
        }

        isFinal=feof(pFileUaProf);
        if (XML_STATUS_ERROR==XML_Parse(parser,buffer,dataLen,isFinal))
        {
            userData.parserStatus=UAPROF_PARSER_BADFORM;
            break;
        }

    }
    parserStatus=userData.parserStatus;
    XML_ParserFree(parser);
    return parserStatus;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -