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

📄 loader_bt.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / Scene Management sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC 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 Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/scene_manager.h>#include <gpac/utf.h>#include <gpac/constants.h>#include <gpac/internal/bifs_dev.h>#include <gpac/internal/scenegraph_dev.h>#include <gpac/nodes_x3d.h>/*for key codes...*/#include <gpac/user.h>/*since 0.2.2, we use zlib for bt reading to handle wrl.gz files*/#include <zlib.h>void gf_sm_load_done_BT(GF_SceneLoader *load);#define BT_LINE_SIZE	4000typedef struct{	char *name;	char *value;} BTDefSymbol;typedef struct{	GF_SceneLoader *load;	gzFile gz_in;	u32 file_size, file_pos;	/*create from string only*/	GF_List *top_nodes;	GF_Err last_error;	u32 line;	Bool done;	u32 is_wrl;	/*0: no unicode, 1: UTF-16BE, 2: UTF-16LE*/	u32 unicode_type;	GF_List *def_symbols;	/*routes are not created in the graph when parsing, so we need to track insert and delete/replace*/	GF_List *unresolved_routes, *inserted_routes, *peeked_nodes;	GF_List *undef_nodes, *def_nodes;	char *line_buffer;	char cur_buffer[500];	s32 line_size, line_pos, line_start_pos;	/*set when parsing proto*/	GF_Proto *parsing_proto;	Bool is_extern_proto_field;	/*current stream ID, AU time and RAP flag*/	u32 stream_id;	u32 au_time;	Bool au_is_rap;	/*current BIFS stream & AU*/	GF_StreamContext *bifs_es;	GF_AUContext *bifs_au;	u32 base_bifs_id;	GF_Command *cur_com;	/*current OD stream & AU*/	GF_StreamContext *od_es;	GF_AUContext *od_au;	u32 base_od_id;	GF_List *scripts;} GF_BTParser;GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdList);GF_Route *gf_bt_parse_route(GF_BTParser *parser, Bool skip_def, Bool is_insert, GF_Command *com);void gf_bt_resolve_routes(GF_BTParser *parser, Bool clean);static GF_Err gf_bt_report(GF_BTParser *parser, GF_Err e, char *format, ...){#ifndef GPAC_DISABLE_LOG	if (gf_log_get_level() && (gf_log_get_tools() & GF_LOG_PARSER)) {		char szMsg[2048];		va_list args;		va_start(args, format);		vsprintf(szMsg, format, args);		va_end(args);		GF_LOG((u32) (e ? GF_LOG_ERROR : GF_LOG_WARNING), GF_LOG_PARSER, ("[BT/WRL Parsing] %s (line %d)\n", szMsg, parser->line));	}#endif	if (e) parser->last_error = e;	return e;}GF_Node *gf_bt_new_node(GF_BTParser *parser, u32 tag) {	GF_Node *n = gf_node_new(parser->load->scene_graph, tag);	return n;}void gf_bt_check_line(GF_BTParser *parser){	while (1) {		switch (parser->line_buffer[parser->line_pos]) {		case ' ':		case '\t':		case '\n':		case '\r':			parser->line_pos++;			continue;		default:			break;		}		break;	}	if (parser->line_buffer[parser->line_pos]=='#') {		parser->line_size = parser->line_pos;	}	else if ((parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/') ) parser->line_size = parser->line_pos;	if (parser->line_size == parser->line_pos) {		/*string based input - done*/		if (!parser->gz_in) {			parser->done = 1;			return;		}next_line:		parser->line_start_pos = gztell(parser->gz_in);		parser->line_buffer[0] = 0;		if (parser->unicode_type) {			u8 c1, c2;			unsigned short wchar;			unsigned short l[BT_LINE_SIZE];			unsigned short *dst = l;			Bool is_ret = 0;			u32 last_space_pos, last_space_pos_stream;			u32 go = BT_LINE_SIZE - 1;			last_space_pos = last_space_pos_stream = 0;			while (go && !gzeof(parser->gz_in) ) {				c1 = gzgetc(parser->gz_in);				c2 = gzgetc(parser->gz_in);				/*Little-endian order*/				if (parser->unicode_type==2) {					if (c2) { wchar = c2; wchar <<=8; wchar |= c1; }					else wchar = c1;				} else {					wchar = c1;					if (c2) { wchar <<= 8; wchar |= c2;}				}				*dst = wchar;				if (wchar=='\r') is_ret = 1;				else if (wchar=='\n') {					dst++;					break;				}				else if (is_ret && wchar!='\n') {					u32 fpos = gztell(parser->gz_in);					gzseek(parser->gz_in, fpos-2, SEEK_SET);					is_ret = 1;					break;				}				if (wchar==' ') {					last_space_pos_stream = gztell(parser->gz_in);					last_space_pos = dst - l;				}				dst++;				go--;			}			*dst = 0;			/*long line, rewind stream to last space*/			if (!go) {				u32 rew_pos = gztell(parser->gz_in) - 2*(dst - &l[last_space_pos]);				gzseek(parser->gz_in, rew_pos, SEEK_SET);				l[last_space_pos+1] = 0;			}			/*check eof*/			if (l[0]==0xFFFF) {				parser->done = 1;				return;			}			/*convert to mbc string*/			dst = l;			gf_utf8_wcstombs(parser->line_buffer, BT_LINE_SIZE, (const unsigned short **) &dst);			if (!strlen(parser->line_buffer) && gzeof(parser->gz_in)) {				parser->done = 1;				return;			}		} else {			if ((gzgets(parser->gz_in, parser->line_buffer, BT_LINE_SIZE) == NULL) 				|| (!strlen(parser->line_buffer) && gzeof(parser->gz_in))) {				parser->done = 1;				return;			}			/*watchout for long lines*/			if (1 + strlen(parser->line_buffer) == BT_LINE_SIZE) {				u32 rew, pos, go;				rew = 0;				go = 1;				while (go) {					switch (parser->line_buffer[strlen(parser->line_buffer)-1]) {					case ' ':					case ',':					case '[':					case ']':						go = 0;						break;					default:						parser->line_buffer[strlen(parser->line_buffer)-1] = 0;						rew++;						break;					}				}				pos = gztell(parser->gz_in);				gzseek(parser->gz_in, pos-rew, SEEK_SET);			}		}		while (1) {			char c;			u32 len = strlen(parser->line_buffer);			if (!len) break;			c = parser->line_buffer[len-1];			if (!strchr("\n\r\t", c)) break;			parser->line_buffer[len-1] = 0;		}				parser->line_size = strlen(parser->line_buffer);		parser->line_pos = 0;		parser->line++;		{			u32 pos = gztell(parser->gz_in);			if (pos>=parser->file_pos) {				parser->file_pos = pos;				if (parser->line>1) gf_set_progress("BT Parsing", pos, parser->file_size);			}		}		while ((parser->line_buffer[parser->line_pos]==' ') || (parser->line_buffer[parser->line_pos]=='\t'))			parser->line_pos++;		if ( (parser->line_buffer[parser->line_pos]=='#') 			|| ( (parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/')) ) {			if (parser->line==1) {				if (strstr(parser->line_buffer, "VRML")) {					if (strstr(parser->line_buffer, "VRML V2.0")) parser->is_wrl = 1;					/*although not std, many files use this*/					else if (strstr(parser->line_buffer, "VRML2.0")) parser->is_wrl = 1;					else {						gf_bt_report(parser, GF_NOT_SUPPORTED, "%s: VRML Version Not Supported", parser->line_buffer);						return;					}				}				else if (strstr(parser->line_buffer, "X3D")) {					if (strstr(parser->line_buffer, "X3D V3.0")) parser->is_wrl = 2;					else {						gf_bt_report(parser, GF_NOT_SUPPORTED, "%s: X3D Version Not Supported", parser->line_buffer);						return;					}				}			}			if (!strnicmp(parser->line_buffer+parser->line_pos, "#define ", 8)) {				char *buf, *sep;				parser->line_pos+=8;				buf = parser->line_buffer+parser->line_pos;				sep = strchr(buf, ' ');				if (sep && (sep[1]!='\n') ) {					BTDefSymbol *def;					GF_SAFEALLOC(def, BTDefSymbol);					sep[0] = 0;					def->name = strdup(buf);					sep[0] = ' ';					buf = sep+1;					while (strchr(" \t", buf[0])) buf++;					def->value = strdup(buf);					gf_list_add(parser->def_symbols, def);				}			}			goto next_line;		}		/*brute-force replacement of defined symbols (!!FIXME - no mem checking done !!)*/		if (parser->line_pos < parser->line_size) {			u32 i, count;			count = gf_list_count(parser->def_symbols);			while (1) {				Bool found = 0;				for (i=0; i<count; i++) {					u32 symb_len, val_len, copy_len;					BTDefSymbol *def = (BTDefSymbol *)gf_list_get(parser->def_symbols, i);					char *start = strstr(parser->line_buffer, def->name);					if (!start) continue;					symb_len = strlen(def->name);					if (!strchr(" \n\r\t,[]{}\'\"", start[symb_len])) continue;					val_len = strlen(def->value);					copy_len = strlen(start + symb_len) + 1;					memmove(start + val_len, start + symb_len, sizeof(char)*copy_len);					memcpy(start, def->value, sizeof(char)*val_len);					parser->line_size = strlen(parser->line_buffer);					found = 1;				}				if (!found) break;			}		}	}	if (!parser->line_size) {		if (!gzeof(parser->gz_in)) gf_bt_check_line(parser);		else parser->done = 1;	}	else if (!parser->done && (parser->line_size == parser->line_pos)) gf_bt_check_line(parser);}void gf_bt_force_line(GF_BTParser *parser){	parser->line_pos = parser->line_size;}Bool gf_bt_check_code(GF_BTParser *parser, char code){	gf_bt_check_line(parser);	if (parser->line_buffer[parser->line_pos]==code) {		parser->line_pos++;		return 1;	}	return 0;}char *gf_bt_get_next(GF_BTParser *parser, Bool point_break){	u32 has_quote;	Bool go = 1;	s32 i;	gf_bt_check_line(parser);	i=0;	has_quote = 0;	while (go) {		if (parser->line_buffer[parser->line_pos + i] == '\"') {			if (!has_quote) has_quote = 1;			else has_quote = 0;			parser->line_pos += 1;			if (parser->line_pos+i==parser->line_size) break;			continue;		}		if (!has_quote) {			switch (parser->line_buffer[parser->line_pos + i]) {			case 0:			case ' ':			case '\t':			case '{':			case '}':			case ']':			case '[':			case ',':				go = 0;				break;			case '.':				if (point_break) go = 0;				break;			}			if (!go) break;		}				parser->cur_buffer[i] = parser->line_buffer[parser->line_pos + i];		i++;		if (parser->line_pos+i==parser->line_size) break;	}	parser->cur_buffer[i] = 0;	parser->line_pos += i;	return parser->cur_buffer;}char *gf_bt_get_string(GF_BTParser *parser){	char *res;	s32 i, size;#define	BT_STR_CHECK_ALLOC	\		if (i==size) {		\			res = (char*)realloc(res, sizeof(char) * (size+500));	\			size += 500;	\		}	\	res = (char*)malloc(sizeof(char) * 500);	size = 500;	while (parser->line_buffer[parser->line_pos]==' ') parser->line_pos++;		if (parser->line_pos==parser->line_size) {		if (gzeof(parser->gz_in)) return NULL;		gf_bt_check_line(parser);	}	i=0;	while (1) {		if (parser->line_buffer[parser->line_pos] == '\"') 			if (parser->line_buffer[parser->line_pos-1] != '\\') break;		BT_STR_CHECK_ALLOC		if ((parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/') && (parser->line_buffer[parser->line_pos-1]!=':') ) {			/*this looks like a comment*/			if (!strstr(&parser->line_buffer[parser->line_pos], "\"")) {				gf_bt_check_line(parser);				continue;			}

⌨️ 快捷键说明

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