用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

same    -  云代码空间

——

使用PJSIP函数创建XML结构树,保存进文件和从文件加载到链表

2016-04-19|1557阅||

摘要:/** 1.使用PJSIP函数创建XML结构树,保存进文件和从文件加载到链表 2.需要PJ_SIP开发库 */ /* <RecordData> <Log> <record Name="aaa" Number="123" Account="0" S

/**
1.使用PJSIP函数创建XML结构树,保存进文件和从文件加载到链表
2.需要PJ_SIP开发库
*/

/*
<RecordData>
<Log>
    <record Name="aaa" Number="123" Account="0" StartTime="1234567890" EndTime="0" Type="1" ViewFlag="1"/>
    <record Name="bbb" Number="456" Account="0" StartTime="1234569890" EndTime="1234569999" Type="0" ViewFlag="0"/>
</Log>
</RecordData>
*/

//XML Record
static const pj_str_t STR_RECORDDATA  = {"RecordData", 10};
static const pj_str_t STR_LOG  = {"Log", 3};
static const pj_str_t STR_RECORD  = {"record", 6};
static const pj_str_t STR_NAME = { "Name", 4};
static const pj_str_t STR_NUMBER = { "Number", 6};
static const pj_str_t STR_STARTTIME = { "StartTime", 9};
static const pj_str_t STR_ENDTIME = { "EndTime", 7};
static const pj_str_t STR_ACCOUNT = { "Account", 7};
static const pj_str_t STR_TYPE = { "Type", 4};
static const pj_str_t STR_VIEWFLAG  = {"ViewFlag", 8};

typedef struct st_recorde_node
{
    //创建双向链表
    struct st_recorde_node *prev;
    struct st_recorde_node *next;

    char acName[MAX_DISP_NAME_LEN];
    char acNumber[MAX_NUMBER_LEN];
    unsigned short usAntNo;
    time_t stStartTime;
    time_t stEndTime;
    CALL_TYPE enType;
    unsigned short usViewFlag;
} ST_RECORD_NODE;

static ST_RECORD_NODE gastRecordData[MAX_CALLLOG_NUM + MAX_LINE_NUMBER];
ST_RECORD_NODE gstRecordsHead = {0};



void CL_Record2XML(pj_pool_t *pool, pj_xml_node *parent)
{
    ST_RECORD_NODE *p, stTemp;
    pj_xml_node *node;
    pj_xml_attr *attr;
    pj_str_t value;

    if (!pool || !parent)
    {
        LOG(LOG_LEVEL_ERROR, (THIS_FILE, "Invalid parent node"));
        return;
    }

    p = &gstRecordsHead;
    if (p == p->next)
        return;
    
    do   
    {
        p = p->next;        
        memset(&stTemp, 0, sizeof(ST_RECORD_NODE));
        memcpy(&stTemp, p, sizeof(ST_RECORD_NODE));
        node = pj_xml_node_new(pool, &STR_RECORD);

        /*Attr 属性*/
        value.ptr = stTemp.acName;
        value.slen = strlen(value.ptr);
        attr = pj_xml_attr_new(pool, &STR_NAME, &value);
        pj_xml_add_attr(node, attr);

        value.ptr = stTemp.acNumber;
        value.slen = strlen(value.ptr);
        attr = pj_xml_attr_new(pool, &STR_NUMBER, &value);
        pj_xml_add_attr(node, attr);
        
        if (MAX_ACCOUNT_NUMBER > stTemp.usAntNo)
        {
            sprintf(value.ptr, "%hu", stTemp.usAntNo + 1);
        }
        else
        {
            sprintf(value.ptr, "%hu", 0);
        }
        value.slen = strlen(value.ptr);
        attr = pj_xml_attr_new(pool, &STR_ACCOUNT, &value);
        pj_xml_add_attr(node, attr);

        sprintf(value.ptr, "%ld", stTemp.stStartTime);
        value.slen = strlen(value.ptr);
        attr = pj_xml_attr_new(pool, &STR_STARTTIME, &value);
        pj_xml_add_attr(node, attr);

        sprintf(value.ptr, "%ld", stTemp.stEndTime);
        value.slen = strlen(value.ptr);
        attr = pj_xml_attr_new(pool, &STR_ENDTIME, &value);
        pj_xml_add_attr(node, attr);

        sprintf(value.ptr, "%d", stTemp.enType);
        value.slen = strlen(value.ptr);
        attr = pj_xml_attr_new(pool, &STR_TYPE, &value);
        pj_xml_add_attr(node, attr);

        sprintf(value.ptr, "%d", stTemp.usViewFlag);
        value.slen = strlen(value.ptr);
        attr = pj_xml_attr_new(pool, &STR_VIEWFLAG, &value);
        pj_xml_add_attr(node, attr);

        pj_xml_add_node(parent, node);
    }while (p->next != &gstRecordsHead);
}

int CL_SaveToXML()
{
    pj_status_t status;
    pj_oshandle_t xml_file = NULL;
    pj_xml_node  *recorddata, *Log;
    pj_pool_t *pool = NULL;

    char buff[BUFLEN_1M] = {0};

    //创建内存池
    pool = pjsua_pool_create("XMLHISTORY", BUFLEN_1M, BUFLEN_1M);

    //打开文件
    status = pj_file_open(pool, CL_RECORD_FILE, PJ_O_WRONLY, &xml_file);
    if (status != PJ_SUCCESS)
    {
        LOG(LOG_LEVEL_ERROR, (THIS_FILE, "Error creating "LOCAL_XML_DIRECTORY" file"));
        return FALSE;
    }

    /* 建立主结点 */
    recorddata = pj_xml_node_new(pool, &STR_RECORDDATA);

    //添加1个子节点
    Log = pj_xml_node_new(pool, &STR_LOG);
    pj_xml_add_node(recorddata, Log);

    /* 添加呼叫记录到Log节点树下*/
    CL_Record2XML(pool, Log);

    pj_xml_print(recorddata, buff, BUFLEN_1M, PJ_FALSE);
    pj_ssize_t size = strlen(buff);
    if (BUFLEN_1M > size)
    {
        pj_file_write(xml_file, buff, &size);
    }
    else
    {
        LOG(LOG_LEVEL_ERROR, (THIS_FILE, "File "LOCAL_XML_DIRECTORY" is too large!"));
    }

    pj_file_close(xml_file);
    pj_pool_release(pool);

    return TRUE;
}

void CL_XML2Record(pj_xml_node *parent)
{
    int  strlen;
    pj_xml_attr *attr;
    char acStr[12] = {0};
    ST_RECORD_NODE *pstHead, *p, *pstNew, stTempNode;
    pj_xml_node *node;

    if (!parent)
    {
        LOG(LOG_LEVEL_ERROR, (THIS_FILE, "Invalid parent node"));
        return;
    }

    node = pj_xml_find_node(parent, &STR_RECORD);

    while (NULL != node)
    {
        memset(&stTempNode, 0, sizeof(ST_RECORD_NODE));
        attr = pj_xml_find_attr(node, &STR_NAME, NULL);
        if (attr)
        {
            strlen = (attr->value.slen > BUFLEN_32) ? BUFLEN_32 - 1 : attr->value.slen;
            memcpy(stTempNode.acName, attr->value.ptr, strlen);
        }

        attr = pj_xml_find_attr(node, &STR_NUMBER, NULL);
        if (attr)
        {
            strlen = (attr->value.slen > BUFLEN_32) ? BUFLEN_32 - 1 : attr->value.slen;
            memcpy(stTempNode.acNumber, attr->value.ptr, strlen);
        }

        attr = pj_xml_find_attr(node, &STR_ACCOUNT, NULL);
        if (attr)
        {
            strlen = (attr->value.slen > 8) ? 7 : attr->value.slen;
            memset(acStr, 0, sizeof(acStr));
            memcpy(acStr, attr->value.ptr, strlen);
            stTempNode.usAntNo = (unsigned short)(atoi(acStr) - 1);
        }

        attr = pj_xml_find_attr(node, &STR_STARTTIME, NULL);
        if (attr)
        {
            strlen = (attr->value.slen > 12) ? 10 : attr->value.slen;
            memset(acStr, 0, sizeof(acStr));
            memcpy(acStr, attr->value.ptr, strlen);
            stTempNode.stStartTime = atol(acStr);
        }

        attr = pj_xml_find_attr(node, &STR_ENDTIME, NULL);
        if (attr)
        {
            strlen = (attr->value.slen > 12) ? 10 : attr->value.slen;
            memset(acStr, 0, sizeof(acStr));
            memcpy(acStr, attr->value.ptr, strlen);
            stTempNode.stEndTime = atol(acStr);
        }

        attr = pj_xml_find_attr(node, &STR_TYPE, NULL);
        if (attr)
        {
            strlen = (attr->value.slen > 8) ? 7 : attr->value.slen;
            memset(acStr, 0, sizeof(acStr));
            memcpy(acStr, attr->value.ptr, strlen);
            stTempNode.enType = atoi(acStr);
        }

        attr = pj_xml_find_attr(node, &STR_VIEWFLAG, NULL);
        if (attr)
        {
            strlen = (attr->value.slen > 8) ? 7 : attr->value.slen;
            memset(acStr, 0, sizeof(acStr));
            memcpy(acStr, attr->value.ptr, strlen);
            stTempNode.usViewFlag = atoi(acStr);
        }

        //按类型判断添加进链表
        pstNew = CL_RecordMalloc();
        if (NULL == pstNew)
        {
            LOG(LOG_LEVEL_WARNING, (THIS_FILE, "List Is Full!"));
            return;
        }
        
        pstHead = &gstRecordsHead;  
        p = pstHead;
        while (p->next != pstHead)
        {
            p = p->next;
        }

        memcpy(pstNew, &stTempNode, sizeof(ST_RECORD_NODE));

        //如果该类型达到最大数量就跳过不添加进去
        if (CALLLOG_NUM > CL_CountFromType(pstNew->enType))
        {        
            p->next = pstNew;
            pstNew->prev = p;
            pstNew->next = pstHead;
            pstHead->prev = pstNew;
        }
            
        node = pj_xml_find_next_node(parent, node, &STR_RECORD);
    }
}

int CL_StringToList(char *msg, size_t len)
{
    pj_xml_node *recorddata, *node;
    pj_pool_t *pool = NULL;

    if (!msg || !len)
    {
        return FALSE;
    }

    pool = pjsua_pool_create("StrToList", BUFLEN_2K, BUFLEN_2K);
    if (!pool)
    {
        return FALSE;
    }

    /* Parse XML */
    recorddata = pj_xml_parse(pool, msg, len);
    if (!recorddata)
    {
        LOG(LOG_LEVEL_ERROR, (THIS_FILE, "recorddata ERROR!\n"));
        return FALSE;
    }

    /* Root document must be "ContactData" */
    if (pj_stricmp(&recorddata->name, &STR_RECORDDATA) != 0)
    {
        LOG(LOG_LEVEL_ERROR, (THIS_FILE, "recorddata Name ERROR!\n"));
        return FALSE;
    }

    /*Log结点*/
    node = pj_xml_find_node(recorddata, &STR_LOG);
    if (node)
    {
        CL_XML2Record(node);
    }

    pj_pool_release(pool);

    return TRUE;
    //return PB_SaveToXML();
}

int CL_LoadXMLFile2List(char *file)
{
    pj_status_t status;
    pj_oshandle_t xml_file = NULL;
    pj_off_t xml_file_len;
    pj_pool_t *pool = NULL;

    if (!file)
    {
        LOG(LOG_LEVEL_ERROR, (THIS_FILE, "Invalid File"));
        return FALSE;
    }

    pool = pjsua_pool_create("XMLHISTORY", BUFLEN_2K, BUFLEN_2K);

    status = pj_file_open(pool, file, PJ_O_RDONLY, &xml_file);
    if (status != PJ_SUCCESS)
    {
        LOG(LOG_LEVEL_ERROR, (THIS_FILE, "Error Open PhoneBook XML file", status));
        return FALSE;
    }

    pj_file_setpos(xml_file, 0, PJ_SEEK_END);
    pj_file_getpos(xml_file, &xml_file_len);
    pj_file_setpos(xml_file, 0, PJ_SEEK_SET);

    pj_str_t msg;
    msg.ptr = (char *)pj_pool_alloc(pool, xml_file_len);
    msg.slen = xml_file_len;

    status = pj_file_read(xml_file, msg.ptr, &msg.slen);
    if (status != PJ_SUCCESS)
    {
        return FALSE;
    }
    pj_file_close(xml_file);
    status = CL_StringToList(msg.ptr, msg.slen);
    pj_pool_release(pool);
    return status;
}

顶 0踩 0收藏
文章评论
    发表评论

    个人资料

    • 昵称: same
    • 等级: 初级程序员
    • 积分: 32
    • 代码: 1 个
    • 文章: 2 篇
    • 随想: 0 条
    • 访问: 0 次
    • 关注

    标签

    最新提问

      站长推荐