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

📄 mmp.c

📁 Sun公司Dream项目
💻 C
字号:
/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the "License").  You may not use this file except
 * in compliance with the License.
 *
 * You can obtain a copy of the license at
 * http://www.opensource.org/licenses/cddl1.php
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL
 * HEADER in each file and include the License file at
 * http://www.opensource.org/licenses/cddl1.php.  If 
 * applicable, add the following below this CDDL HEADER, 
 * with the fields enclosed by brackets "[]" replaced 
 * with your own identifying information: 
 * Portions Copyright [yyyy]
 * [name of copyright owner]
 */ 

/*
 * $(@)Mmp.c $Revision: 1.2 $ $Date: 2006/07/15 00:02:38 $
 * 
 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
 */
/*
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 */

/*
 * Mmp.c
 * 
 * Mmp is the multi-media parser framework.
 */

#pragma ident "@(#)Mmp.c 1.1	96/09/18 SMI"

/***********************************************************************
 * Includes
 ***********************************************************************/
#include <stdlib.h>

#include "cobjs/Macros.h"
#include "cobjs/RetCode.h"
#include "cobjs/Types.h"

#include "mmp/Pipe.h"

#include "mmp/Mmp.h"

#define	MMP_MAX_CHUNK		1

/***********************************************************************
 * OBJECT Mmp Instance Type
 ***********************************************************************/

struct _Mmp {
    MmpParserObject   **pops;
    Pipe                pipe;
    PipePosition        maxScanDistance;
    MmpCallBack         callBack;
    void               *callBackToken;
    PipePosition	putPosition;
};

/***********************************************************************
 * OBJECT Mmp Private Prototypes
 ***********************************************************************/

static size_t       mmpMaxChunk(Mmp mmp);
static RetCode      mmpRecognize(Mmp mmp, Pipe pipe, int *popxp);
static RetCode      mmpParse(void *instp, MmpContextObject *cop, Pipe pipe);
static void	    mmpCleanup(Mmp mmp);

/***********************************************************************
 * OBJECT Mmp Private Data
 ***********************************************************************/

static RetCodeTable mmpErrorTable[] = {
    {MMP_ERROR_UNREC_STREAM, NULL, "unrecognized stream"},
    {MMP_ERROR_NO_PARSER, NULL, "no parser"},
    {0, NULL, NULL}
};

static RetCodeId    retCodeId;

/***********************************************************************
 * OBJECT Mmp Class Interface
 ***********************************************************************/

Mmp
mmpNew(void)
{
    Mmp                 mmp = NEW_ZEROED(struct _Mmp, 1);

    if (retCodeId == 0) {
	retCodeId = retCodeRegisterWithTable(MMP_CLASSNAME,
					     mmpErrorTable);
    }
    mmp->putPosition = 0LL;

    return mmp;
}

/***********************************************************************
 * OBJECT Mmp Instance Interface
 ***********************************************************************/

void
mmpSetParsers(Mmp mmp, MmpParserObject *pops[])
{
    int                 nParsers = 0;
    MmpParserObject   **popp;
    size_t		maxChunk;

    if (mmp->pops != NULL) {
	for (popp = mmp->pops; *popp != NULL; popp++) {
	    MMP_PARSER_RECOVER(*popp);
	}
	free(mmp->pops);
    }
    if (mmp->pipe != NULL) {
	(void) pipeFree(mmp->pipe);
	mmp->pipe = NULL;
    }

    for (popp = pops; *popp != NULL; popp++) {
	nParsers++;
    }
    mmp->pops = (MmpParserObject**)MEMDUP(pops, (nParsers + 1) * sizeof(MmpParserObject *));

    if (nParsers > 0) {
        maxChunk = mmpMaxChunk(mmp);
        mmp->pipe = pipeNew(maxChunk, (PipeParser) mmpParse,
		(PipeCleanup) mmpCleanup, mmp, NULL);
    }
}

void
mmpSetPosition(Mmp mmp, PipePosition putPosition)
{
    mmp->putPosition = putPosition;
}

void
mmpSetCallBack(Mmp mmp, MmpCallBack callBack, void *callBackToken)
{
    mmp->callBack = callBack;
    mmp->callBackToken = callBackToken;
}

void
mmpSetMaxScanDistance(Mmp mmp, PipePosition maxScanDistance)
{
    mmp->maxScanDistance = maxScanDistance;
}

RetCode
mmpPut(Mmp mmp, u8 *buf, size_t len)
{
    RetCode retCode;

    if (mmp->pipe == NULL) {
	return RetCode(RETCODE_CONS(retCodeId, MMP_ERROR_NO_PARSER));
    }
    retCode = pipePut(mmp->pipe, buf, len, FALSE, mmp->putPosition);
    mmp->putPosition += len;
    return retCode;
}

RetCode
mmpEof(Mmp mmp)
{
    if (mmp->pipe == NULL) {
	return RetCode(RETCODE_CONS(retCodeId, MMP_ERROR_NO_PARSER));
    }
    return pipeEof(mmp->pipe);
}

PipePosition
mmpParsedBytes(Mmp mmp)
{
    return mmp->pipe == NULL ? 0 : pipeRelativePosition(mmp->pipe);
}

void
mmpRecover(Mmp mmp)
{
    if (mmp->pipe != NULL) {
	mmpCleanup(mmp);
	pipeRecover(mmp->pipe);
    }
}

void
mmpFree(Mmp mmp)
{
    if (mmp->pipe != NULL) {
        MmpParserObject   **popp;

	for (popp = mmp->pops; *popp != NULL; popp++) {
	    MMP_PARSER_RECOVER(*popp);
	}
	(void) pipeFree(mmp->pipe);
    }
    free(mmp->pops);
    free(mmp);
}

/***********************************************************************
 * OBJECT Mmp Private Methods
 ***********************************************************************/

static size_t
mmpMaxChunk(Mmp mmp)
{
    MmpParserObject   **popp;
    size_t              maxChunk = MMP_MAX_CHUNK;

    for (popp = mmp->pops; *popp != NULL; popp++) {
	size_t              chunk = MMP_PARSER_MAXCHUNK(*popp);

	if (chunk > maxChunk) {
	    maxChunk = chunk;
	}
    }
    return maxChunk;
}

static RetCode
mmpRecognize(Mmp mmp, Pipe pipe, int *popxp)
{
    MmpParserObject   **popp;
    RetCode             retCode;

    for (popp = mmp->pops; *popp != NULL; popp++) {
	retCode = MMP_PARSER_RECOGNIZE(*popp, pipe);
	if (retCode == RETCODE_SUCCESS) {
	    goto done;
	}
    }
    retCode = RETCODE_CONS(retCodeId, MMP_ERROR_UNREC_STREAM);
done:
    if (popxp != NULL) {
	*popxp = popp - mmp->pops;
    }
    return retCode;
}

static RetCode
mmpParse(void *instp, MmpContextObject *cop, Pipe pipe)
{
    Mmp                 mmp = (Mmp) instp;
    RetCode             retCode;
    MmpInfo             info;
    MmpInfo            *infop = &info;
    PipePosition        scanDistance = 0;
    int                 popx;

    do {
	retCode = mmpRecognize(mmp, pipe, &popx);
	if (retCode == RETCODE_SUCCESS) {
	    break;
	}
	pipeSkip(mmp->pipe, 1);
    } while (++scanDistance < mmp->maxScanDistance);

    if (retCode == RETCODE_SUCCESS) {
	if (mmp->callBack != NULL) {
	    infop->parserIndex = popx;
	    infop->scanDistance = scanDistance;
	    infop->position = pipePosition(pipe);
	    retCode = (*mmp->callBack) (mmp->callBackToken, infop, retCode);
	    if (retCode != RETCODE_SUCCESS) {
		return retCode;
	    }
	}
	retCode = MMP_PARSER_PARSE(mmp->pops[popx], cop, pipe);
    }
    return retCode;
}

static void
mmpCleanup(Mmp mmp)
{
    if (mmp->pipe != NULL) {
        MmpParserObject   **popp;

	for (popp = mmp->pops; *popp != NULL; popp++) {
	    MMP_PARSER_RECOVER(*popp);
	}
    }
}

⌨️ 快捷键说明

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