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

📄 dom_smjs.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
			/*append value*/			else {				char *new_val = malloc(sizeof(char) * (strlen(ctx->headers[nb_hdr+1])+strlen(val)+3));				sprintf(new_val, "%s, %s", ctx->headers[nb_hdr+1], val);				free(ctx->headers[nb_hdr+1]);				ctx->headers[nb_hdr+1] = new_val;				return;			}			nb_hdr+=2;		}	}	nb_hdr = 0;	if (ctx->headers) {		while (ctx->headers[nb_hdr]) nb_hdr+=2;	}	ctx->headers = realloc(ctx->headers, sizeof(char*)*(nb_hdr+3));	ctx->headers[nb_hdr] = strdup(hdr);	ctx->headers[nb_hdr+1] = strdup(val ? val : "");	ctx->headers[nb_hdr+2] = NULL;}static void xml_http_reset_recv_hdr(XMLHTTPContext *ctx){	u32 nb_hdr = 0;	if (ctx->recv_headers) {		while (ctx->recv_headers[nb_hdr]) {			free(ctx->recv_headers[nb_hdr]);			free(ctx->recv_headers[nb_hdr+1]);			nb_hdr+=2;		}		free(ctx->recv_headers);		ctx->recv_headers = NULL;	}}static void xml_http_append_recv_header(XMLHTTPContext *ctx, char *hdr, char *val){	u32 nb_hdr = 0;	if (ctx->recv_headers) {		while (ctx->recv_headers[nb_hdr]) nb_hdr+=2;	}	ctx->recv_headers = realloc(ctx->recv_headers, sizeof(char*)*(nb_hdr+3));	ctx->recv_headers[nb_hdr] = strdup(hdr);	ctx->recv_headers[nb_hdr+1] = strdup(val ? val : "");	ctx->recv_headers[nb_hdr+2] = NULL;}static void xml_http_reset(XMLHTTPContext *ctx){	u32 nb_hdr = 0;	if (ctx->method) { free(ctx->method); ctx->method = NULL; }	if (ctx->url) { free(ctx->url); ctx->url = NULL; }	xml_http_reset_recv_hdr(ctx);	if (ctx->headers) {		while (ctx->headers[nb_hdr]) {			free(ctx->headers[nb_hdr]);			free(ctx->headers[nb_hdr+1]);			nb_hdr+=2;		}		free(ctx->headers);		ctx->headers = NULL;	}	if (ctx->sess) {		gf_dm_sess_del(ctx->sess);		ctx->sess = NULL;	}	if (ctx->data) {		free(ctx->data);		ctx->data = NULL;	}	if (ctx->statusText) {		free(ctx->statusText);		ctx->statusText = NULL;	}	if (ctx->url) {		free(ctx->url);		ctx->url = NULL;	}	if (ctx->sax) {		gf_xml_sax_del(ctx->sax);		ctx->sax = NULL;	}	if (ctx->node_stack) {		gf_list_del(ctx->node_stack);		ctx->node_stack = NULL;	}	if (ctx->document) {		gf_node_unregister(ctx->document->RootNode, NULL);		/*we're sure the graph is a "nomade" one since we initially put the refcount to 1 ourselves*/		ctx->document->reference_count--;		if (!ctx->document->reference_count) {			gf_sg_del(ctx->document);		}	}	ctx->document = NULL;	ctx->size = 0;	ctx->async = 0;	ctx->readyState = 0;	ctx->cur_header = 0;	ctx->ret_code = 0;	ctx->html_status = 0;}static void xml_http_finalize(JSContext *c, JSObject *obj){	XMLHTTPContext *ctx;	if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return;	ctx = (XMLHTTPContext *)JS_GetPrivate(c, obj);	if (ctx) {		xml_http_reset(ctx);		free(ctx);	}}static JSBool xml_http_constructor(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	XMLHTTPContext *p;	if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_FALSE;	GF_SAFEALLOC(p, XMLHTTPContext);	p->c = c;	p->_this = obj;	JS_SetPrivate(c, obj, p);	*rval = OBJECT_TO_JSVAL(obj);	return JS_TRUE;}static void xml_http_state_change(XMLHTTPContext *ctx){	jsval rval;	//GF_SceneGraph *scene = (GF_SceneGraph *) xml_get_scenegraph(ctx->c);	if (ctx->onreadystatechange)		JS_CallFunction(ctx->c, ctx->_this, ctx->onreadystatechange, 0, NULL, &rval);	/*todo - fire event*/}static JSBool xml_http_open(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	char *val;	GF_JSAPIParam par;	XMLHTTPContext *ctx;	GF_SceneGraph *scene;	if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_FALSE;	ctx = (XMLHTTPContext *)JS_GetPrivate(c, obj);	if (!ctx) return JS_FALSE;	/*reset*/	if (ctx->readyState) xml_http_reset(ctx);	if (argc<2) return JS_FALSE;	/*method is a string*/	if (!JSVAL_IS_STRING(argv[0])) return JS_FALSE;	/*url is a string*/	if (!JSVAL_IS_STRING(argv[1])) return JS_FALSE;	xml_http_reset(ctx);	val = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));	if (strcmp(val, "GET") && strcmp(val, "POST") && strcmp(val, "HEAD")	&& strcmp(val, "PUT") && strcmp(val, "DELETE") && strcmp(val, "OPTIONS") )		return JS_FALSE;	ctx->method = strdup(val);	val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1]));	/*concatenate URL*/	scene = xml_get_scenegraph(c);	ScriptAction(scene, GF_JSAPI_OP_GET_SCENE_URI, scene->RootNode, &par);	if (par.uri.url) ctx->url = gf_url_concatenate(par.uri.url, val);	if (!ctx->url) ctx->url = strdup(val);	/*async defaults to true*/	ctx->async = 1;	if (argc>2) {		ctx->async = (JSVAL_TO_BOOLEAN(argv[2])==JS_TRUE) ? 1 : 0;		if (argc>3) {			if (!JSVAL_IS_STRING(argv[3])) return JS_FALSE;			val = JS_GetStringBytes(JSVAL_TO_STRING(argv[3]));			/*TODO*/			if (argc>4) {				if (!JSVAL_IS_STRING(argv[3])) return JS_FALSE;				val = JS_GetStringBytes(JSVAL_TO_STRING(argv[3]));				/*TODO*/			}		}	}	/*OPEN success*/	ctx->readyState = 1;	xml_http_state_change(ctx);	return JS_TRUE;}static JSBool xml_http_set_header(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	char *hdr, *val;	XMLHTTPContext *ctx;	if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_FALSE;	ctx = (XMLHTTPContext *)JS_GetPrivate(c, obj);	if (!ctx) return JS_FALSE;	if (ctx->readyState!=1) return JS_FALSE;	if (argc!=2) return JS_FALSE;	if (!JSVAL_IS_STRING(argv[0])) return JS_FALSE;	if (!JSVAL_IS_STRING(argv[1])) return JS_FALSE;	hdr = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));	val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1]));	xml_http_append_send_header(ctx, hdr, val);	return JS_TRUE;}static void xml_http_sax_start(void *sax_cbck, const char *node_name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes){	u32 i;	GF_DOMFullAttribute *prev = NULL;	GF_DOMFullNode *par;	XMLHTTPContext *ctx = (XMLHTTPContext *)sax_cbck;	GF_DOMFullNode *node = (GF_DOMFullNode *) gf_node_new(ctx->document, TAG_DOMFullNode);	node->name = strdup(node_name);	for (i=0; i<nb_attributes; i++) {		GF_DOMFullAttribute *att;		GF_SAFEALLOC(att, GF_DOMFullAttribute);		att->tag = TAG_DOM_ATTRIBUTE_FULL;		att->name = strdup(attributes[i].name);		att->data = strdup(attributes[i].value);		if (prev) prev->next = (GF_DOMAttribute*)att;		else node->attributes = (GF_DOMAttribute*)att;		prev = att;	}	par = gf_list_last(ctx->node_stack);	gf_node_register((GF_Node*)node, (GF_Node*)par);	if (par) {		gf_node_list_add_child(&par->children, (GF_Node*)node);	} else {		assert(!ctx->document->RootNode);		ctx->document->RootNode = (GF_Node*)node;	}	gf_list_add(ctx->node_stack, node);}static void xml_http_sax_end(void *sax_cbck, const char *node_name, const char *name_space){	XMLHTTPContext *ctx = (XMLHTTPContext *)sax_cbck;	GF_DOMFullNode *par = gf_list_last(ctx->node_stack);	if (par) {		/*depth mismatch*/		if (strcmp(par->name, node_name)) return;		gf_list_rem_last(ctx->node_stack);	}}static void xml_http_sax_text(void *sax_cbck, const char *content, Bool is_cdata){	XMLHTTPContext *ctx = (XMLHTTPContext *)sax_cbck;	GF_DOMFullNode *par = gf_list_last(ctx->node_stack);	if (par) {		u32 i, len;		GF_DOMText *txt;		/*basic check, remove all empty text nodes*/		len = strlen(content);		for (i=0; i<len; i++) {			if (!strchr(" \n\r\t", content[i])) break;		}		if (i==len) return;		txt = gf_dom_add_text_node((GF_Node *)par, strdup(content) );		txt->is_cdata = is_cdata;	}}static void xml_http_on_data(void *usr_cbk, GF_NETIO_Parameter *parameter){	XMLHTTPContext *ctx = (XMLHTTPContext *)usr_cbk;	/*if session not set, we've had an abort*/	if (!ctx->sess) return;	switch (parameter->msg_type) {	case GF_NETIO_SETUP:		/*nothing to do*/		return;	case GF_NETIO_CONNECTED:		/*nothing to do*/		return;	case GF_NETIO_WAIT_FOR_REPLY:		/*reset send() state (data, current header) and prepare recv headers*/		if (ctx->data) free(ctx->data);		ctx->data = NULL;		ctx->size = 0;		ctx->cur_header = 0;		ctx->html_status = 0;		if (ctx->statusText) {			free(ctx->statusText);			ctx->statusText = NULL;		}		xml_http_reset_recv_hdr(ctx);		ctx->readyState = 2;		xml_http_state_change(ctx);		return;	/*this is signaled sent AFTER headers*/	case GF_NETIO_PARSE_REPLY:		ctx->html_status = parameter->reply;		if (parameter->value) {			ctx->statusText = strdup(parameter->value);		}		ctx->readyState = 3;		xml_http_state_change(ctx);		return;	case GF_NETIO_GET_METHOD:		parameter->name = ctx->method;		return;	case GF_NETIO_GET_HEADER:		if (ctx->headers && ctx->headers[2*ctx->cur_header]) {			parameter->name = ctx->headers[2*ctx->cur_header];			parameter->value = ctx->headers[2*ctx->cur_header+1];			ctx->cur_header++;		}		return;	case GF_NETIO_GET_CONTENT:		if (ctx->data) {			parameter->data = ctx->data;			parameter->size = strlen(ctx->data);		}		return;	case GF_NETIO_PARSE_HEADER:		xml_http_append_recv_header(ctx, parameter->name, parameter->value);		/*prepare DOM*/		if (strcmp(parameter->name, "Content-Type")) return;		if (!strcmp(parameter->value, "application/xml")			|| !strcmp(parameter->value, "text/xml")			|| strstr(parameter->value, "+xml")		) {			assert(!ctx->sax);			ctx->sax = gf_xml_sax_new(xml_http_sax_start, xml_http_sax_end, xml_http_sax_text, ctx);			ctx->node_stack = gf_list_new();			ctx->document = gf_sg_new();			/*mark this doc as "nomade", and let it leave until all references to it are destroyed*/			ctx->document->reference_count = 1;		}		return;	case GF_NETIO_DATA_EXCHANGE:		if (parameter->data && parameter->size) {			if (ctx->sax) {				GF_Err e;				if (!ctx->size) e = gf_xml_sax_init(ctx->sax, parameter->data);				else e = gf_xml_sax_parse(ctx->sax, parameter->data);				if (e) {					gf_xml_sax_del(ctx->sax);					ctx->sax = NULL;				}			}			ctx->data = realloc(ctx->data, sizeof(char)*(ctx->size+parameter->size+1));			memcpy(ctx->data + ctx->size, parameter->data, sizeof(char)*parameter->size);			ctx->size += parameter->size;			ctx->data[ctx->size] = 0;		}		return;	case GF_NETIO_DATA_TRANSFERED:		break;	case GF_NETIO_DISCONNECTED:		return;	case GF_NETIO_STATE_ERROR:		ctx->ret_code = parameter->error;		break;	}	/*if we get here, destroy downloader - FIXME we'll need a mutex here for sync case...*/	if (ctx->sess) {		gf_dm_sess_del(ctx->sess);		ctx->sess = NULL;	}		/*error, complete reset*/	if (parameter->error) {		xml_http_reset(ctx);	}	/*but stay in loaded mode*/	ctx->readyState = 4;	xml_http_state_change(ctx);}static JSBool xml_http_send(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	GF_JSAPIParam par;	GF_SceneGraph *scene;	char *data = NULL;	XMLHTTPContext *ctx;	GF_Err e;	if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_FALSE;	ctx = (XMLHTTPContext *)JS_GetPrivate(c, obj);	if (!ctx) return JS_FALSE;	if (ctx->readyState!=1) return JS_FALSE;	if (ctx->sess) return JS_FALSE;	if (argc) {		if (JSVAL_IS_OBJECT(argv[0])) {//			if (!JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &documentClass, NULL) ) return JS_FALSE;						/*NOT SUPPORTED YET, we must serialize the sg*/			return JS_FALSE;		} else {			if (!JSVAL_IS_STRING(argv[0])) return JS_FALSE;			data = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));		}	}	scene = xml_get_scenegraph(c);	par.dnld_man = NULL;	ScriptAction(scene, GF_JSAPI_OP_GET_DOWNLOAD_MANAGER, NULL, &par);	if (!par.dnld_man) return JS_FALSE;	/*reset previous text*/	if (ctx->data) free(ctx->data);	ctx->data = data ? strdup(data) : NULL;	ctx->sess = gf_dm_sess_new(par.dnld_man, ctx->url, GF_NETIO_SESSION_NOT_CACHED, xml_http_on_data, ctx, &e);	if (!ctx->sess) return JS_FALSE;	/*just wait for destruction*/	if (!ctx->async) {		while (ctx->sess) {			gf_sleep(20);		}	}	return JS_TRUE;}static JSBool xml_http_abort(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	GF_DownloadSession *sess;	XMLHTTPContext *ctx;	if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return JS_FALSE;	ctx = (XMLHTTPContext *)JS_GetP

⌨️ 快捷键说明

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