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

📄 asmrule.c

📁 linux下流媒体下载程序代码
💻 C
字号:
/*********************************************************************** *    asmrule.c: interpretting ASMRuleBook in SDP header. *********************************************************************** * Copyright (C) 2007 metro <me_t_ro@yahoo.com> * * This file is part of msdl, media stream downloader * * based on syntax description in xine-lib program, asmrp.c *  * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * ***********************************************************************/ /* * Copyright notice of MPlayer project * which some part of msdl is based on. * (from MPlayer-1.0rc2/stream/realrtsp/asmrp.c) *//* * This file was ported to MPlayer from xine CVS asmrp.c,v 1.2 2002/12/17 16:49:48 *//* * Copyright (C) 2002 the xine project * * This file is part of xine, a free video player. *  * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA * * * a parser for real's asm rules * * grammar for these rules: *   rule_book  = { rule }   rule       = ( '#' condition { ',' assignment } | [ assignment {',' assignment} ]) ';'   assignment = id '=' const   const      = ( number | string )   condition  = comp_expr { ( '&&' | '||' ) comp_expr }   comp_expr  = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand }   operand    = ( '$' id | num | '(' condition ')' ) */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "msdllib.h"#include "display.h"#include "asmrule.h"static struct c_desc *new_c_desc(char *asmrule);static void free_c_desc(struct c_desc *cd);static struct node_t *new_node_t(int o,struct node_t *l,struct node_t *r);static void free_node_t(struct node_t *p);static int get_sym(struct c_desc *cd);static struct node_t *cond_expr(struct c_desc *cd);static struct node_t *comp_expr(struct c_desc *cd);static struct node_t *term_expr(struct c_desc *cd);static int eval_tree(struct node_t *p);/*  * this must be thread safe . no global, no static. *           return value  next symbol : success *                              S_NULL : end *                             S_ERROR : error *  forereading is not necessary , so do not do it. */static int get_sym(struct c_desc *cd){    char *p;    int len;    int val;      /* skip white space */    while(*cd->cur_p == ' ') cd->cur_p++;      if(*cd->cur_p == '$') { /* $Foobar */	p = cd->cur_p + 1;	while(isalpha(*p)) p++;	len = p - cd->cur_p - 1;    	if(cd->id_len < len + 1) {	    cd->id = xrealloc(cd->id,len + 1);	    cd->id_len = len + 1;	}	memcpy(cd->id,cd->cur_p + 1,len);	cd->id[len] = '\0';	cd->cur_p = p;	cd->op = S_ID;    }    else if(isdigit(*cd->cur_p)) {	val = 0;	while(isdigit(*cd->cur_p)) { /* always decimal */	    val *= 10;	    val += *cd->cur_p - '0';	    cd->cur_p++;	}	cd->op = S_NUM;	cd->val = val;    }    else if(*cd->cur_p == '<') {	cd->cur_p++;	if(*cd->cur_p == '=') {	    cd->cur_p++;	    cd->op = S_LESSEQ;	}	else {	    cd->op = S_LESS;	}    }    else if(*cd->cur_p == '>') {	cd->cur_p++;	if(*cd->cur_p == '=') {	    cd->cur_p++;	    cd->op = S_MOREEQ;	}	else {	    cd->op = S_MORE;	}    }    else if(*cd->cur_p == '&') {	cd->cur_p++;	if(*cd->cur_p == '&') {	    cd->cur_p++;	    cd->op = S_AND;	}	else {	    cd->op = S_ERROR;   /* & operator is not supported */	}    }    else if(*cd->cur_p == '|') {	cd->cur_p++;	if(*cd->cur_p == '|') {	    cd->cur_p++;	    cd->op = S_OR;	}	else {	    cd->op = S_ERROR;   /* | operator is not supported */	}    }    else if(*cd->cur_p == '=') {	cd->cur_p++;	if(*cd->cur_p == '=') {	    cd->cur_p++;	    cd->op = S_EQ;	}	else {	    cd->op = S_SUBSTI;	}    }    else if(*cd->cur_p == '(') {	cd->cur_p++;	cd->op = S_LPAREN;    }    else if(*cd->cur_p == ')') {	cd->cur_p++;	cd->op = S_RPAREN;    }    else if(*cd->cur_p == ',' || *cd->cur_p == ';') { /*end of condition ',' */	cd->op = S_NULL; /*END*/    }    else {	display(MSDL_ERR,"asmrule: syntax error\n");	cd->op = S_ERROR;    }      return cd->op;}static struct node_t *new_node_t(int o,struct node_t *l,struct node_t *r){    struct node_t *n = (struct node_t *)xmalloc(sizeof(struct node_t));    n->op = o;    n->left= l;    n->right = r;      return n;}static void free_node_t(struct node_t *p){    if(!p) return; /* just to make sure*/      if(p->op == O_ID || p->op == O_NUM) {	/* p->left is char *, or int * (malloced)*/	free(p->left);	p->left = NULL;    }    else {	if(p->left) free_node_t(p->left);	if(p->right) free_node_t(p->right);    }    free(p);}static struct c_desc *new_c_desc(char *asmrule){    struct c_desc *cd = (struct c_desc *)xmalloc(sizeof(struct c_desc));    cd->whole_line = asmrule;    cd->cur_p = cd->whole_line;    cd->op = S_NULL;    cd->val = 0;    cd->id = xmalloc(100);    cd->id_len = 100;    get_sym(cd);    return cd;}static void free_c_desc(struct c_desc *cd){    if(!cd) return;    if(cd->id) free(cd->id);    free(cd);}static struct node_t *term_expr(struct c_desc *cd){    struct node_t *p;    char *id;    int *i;      switch(cd->op) {    case S_NUM:	i = xmalloc(sizeof(int));	*i = cd->val;	p = new_node_t(O_NUM,(struct node_t *)i,NULL);	get_sym(cd);	break;        case S_ID:	id = strdup(cd->id);	p = new_node_t(O_ID,(struct node_t *)id,NULL);	get_sym(cd);	break;        case S_LPAREN:	get_sym(cd);	p = cond_expr(cd);	if(!p) { /* NULL */	    display(MSDL_ERR,"asmrule: parse error\n");	}	else if(cd->op != S_RPAREN) {	    display(MSDL_ERR,"asmrule: no closing ')'\n");	}	get_sym(cd);	break;    default:	display(MSDL_ERR,"asmrule: syntax error at %s\n",cd->cur_p);	p = NULL;    }      return p;}static struct node_t *comp_expr(struct c_desc *cd){    int tok,opr;    struct node_t *p,*q;      p = term_expr(cd);      /* don't do while, see syntax. */    if(S_LESS <= cd->op && cd->op <= S_MORE) {	tok = cd->op;	get_sym(cd);	q = term_expr(cd);	switch(tok) {	case S_LESS:   opr = O_LESS;   break;	case S_LESSEQ: opr = O_LESSEQ; break;	case S_EQ:     opr = O_EQ;     break;	case S_MOREEQ: opr = O_MOREEQ; break;	case S_MORE:   opr = O_MORE;   break;	default:       opr = O_ERR;    break; /* impossible */	}	p = new_node_t(opr,p,q);    }      return p;}static struct node_t *cond_expr(struct c_desc *cd){    int tok,opr;    struct node_t *p,*q;      p = comp_expr(cd);      /* don't do while, see syntax */    if(cd->op == S_AND || cd->op == S_OR) {	tok = cd->op;	get_sym(cd);	q = comp_expr(cd);    	if(tok == S_AND)     opr = O_AND;	else if(tok == S_OR) opr = O_OR;	else                 opr = O_ERR; /* impossible */    	p = new_node_t(opr,p,q);    }      return p;}/* * change id to val. change O_ID to O_NUM */static void insert_id_value(struct node_t *p,char *id,int val){    int *i;    if(!p) return;      if(p->op == O_ID) {	if(!strcmp((char *)p->left,id)) {	    free(p->left);	    p->left = NULL;	    i = (int *)xmalloc(sizeof(int));	    *i = val;	    p->left = (struct node_t *)i;	    p->op = O_NUM;	}    }    else if(p->op == O_NUM){	/* do nothing */	return;    }    else {	if(p->left)  insert_id_value(p->left,id,val);	if(p->right) insert_id_value(p->right,id,val);    }}#ifdef DEBUG/* debugging function */static void tree_debug(struct node_t *p){    if(p == NULL) {	printf("NULL!!!!\n");	return;    }      if(p->op == O_NUM) {	printf("number: %d\n",*(int *)p->left);    }    else if(p->op == O_ID) {	printf("id: %s\n",(char *)p->left);    }    else { /* tree node */	tree_debug(p->left);	printf("op : %d\n",p->op);	tree_debug(p->right);    }}#endif /* DEBUG *//* * eval by boolean. *           return value :    value : num *                                 1 : true (bool) *                                 0 : false (bool) of error  */static int eval_tree(struct node_t *p){    int lval,rval;    if(!p) return 0; /* this should not happen in this function */    switch (p->op) {    case O_NUM:	return *(int *)p->left;    case O_ID: /* not inserted id --> 0 */	return 0;        case O_AND:    case O_OR:    case O_LESS:    case O_LESSEQ:    case O_EQ:    case O_MOREEQ:    case O_MORE:	lval = eval_tree(p->left);	rval = eval_tree(p->right);	if(p->op == O_AND)    return (lval && rval);	if(p->op == O_OR)     return (lval || rval);	if(p->op == O_LESS)   return (lval < rval);	if(p->op == O_LESSEQ) return (lval <= rval);	if(p->op == O_EQ)     return (lval == rval);	if(p->op == O_MORE)   return (lval >= rval);	if(p->op == O_MOREEQ) return (lval > rval);    default:	return 0;    }}/* * judge if bw is OK in 'rulestr' *          return value:     0 ... no, it's not OK. *                        non 0 ... yes, it is. use this rule. */int asmrule_match(char *rulestr,int bw){    int ret = 0;    struct node_t *p;    struct c_desc *cd;      if(rulestr[0] != '#') { /* asmrule always start with #*/	return 1; /* if not, it's no description rule --> always match */    }      cd = new_c_desc(rulestr + 1);      p = cond_expr(cd);    /*tree_debug(p); debugging*/      insert_id_value(p,"OldPNMPlayer",0); /* we don't care about old player */    insert_id_value(p,"Bandwidth",bw);      ret = eval_tree(p);      free_node_t(p);    free_c_desc(cd);      return ret;}

⌨️ 快捷键说明

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