Exemplo n.º 1
0
/**
	set_conv_funs : 'connection -> function:1 -> function:1 -> function:1 -> void
	<doc>Set three wrapper methods to be be called when creating a string, a date, and binary data in results</doc>
**/
static value set_conv_funs( value o, value fstring, value fdate, value fbytes ) {
	val_check_kind(o,k_connection);
	val_check_function(fstring,1);
	val_check_function(fdate,1);
	val_check_function(fbytes,1);
	CNX(o)->conv_string = fstring;
	CNX(o)->conv_date = fdate;
	CNX(o)->conv_bytes = fbytes;
	return val_null;
}
Exemplo n.º 2
0
/**
	$varargs : f:function:1 -> function
	<doc>
	Return a variable argument function that, when called, will callback
	[f] with the array of arguments.
	</doc>
**/
static value builtin_varargs( value f ) {
	value fvar;
	val_check_function(f,1);
	fvar = alloc_function(varargs_callback,VAR_ARGS,"varargs");
	((vfunction*)fvar)->env = f;
	return fvar;
}
Exemplo n.º 3
0
/**
	result_set_conv_date : 'result -> function:1 -> void
	<doc>Set the function that will convert a Date or DateTime string
	to the corresponding value.</doc>
**/
static value result_set_conv_date( value o, value c ) {
	val_check_function(c,1);
	if( val_is_int(o) )
		return val_true;
	val_check_kind(o,k_result);
	RESULT(o)->conv_date = c;
	return val_true;
}
Exemplo n.º 4
0
/**
	cgi_set_main : function:0? -> void
	<doc>Set or disable the main entry point function</doc>
**/
static value cgi_set_main( value f ) {
	if( val_is_null(f) ) {
		CONTEXT()->main = NULL;
		return val_true;
	}
	val_check_function(f,0);
	CONTEXT()->main = f;
	return val_true;
}
Exemplo n.º 5
0
/**
	$setresolver : function:2? -> void
	<doc>Set a function to callback with object and field id when an object field is not found.</doc>
**/
static value builtin_setresolver( value f ) {
	neko_vm *vm = NEKO_VM();
	if( val_is_null(f) )
		vm->resolver = NULL;
	else {
		val_check_function(f,2);
		vm->resolver = f;
	}
	return val_null;
}
Exemplo n.º 6
0
static value print_redirect( value f ) {
	neko_vm *vm = neko_vm_current();
	if( val_is_null(f) ) {
		neko_vm_redirect(vm,NULL,NULL);
		return val_null;
	}
	val_check_function(f,1);
	neko_vm_redirect(vm,print_callback,f);
	return val_null;
}
Exemplo n.º 7
0
/**
	thread_create : f:function:1 -> p:any -> 'thread
	<doc>Creates a thread that will be running the function [f(p)]</doc>
**/
static value thread_create( value f, value param ) {
	tparams *p;
	val_check_function(f,1);
	p = (tparams*)alloc(sizeof(tparams));
	p->callb = f;
	p->callparam = param;
	p->jit = neko_vm_jit(neko_vm_current(),-1);	
	if( !neko_thread_create(thread_init,thread_loop,p,&p->handle) )
		neko_error();
	return p->t->v;
}
Exemplo n.º 8
0
static value os_winlog_new( value title, value f ) {
	window *w;	
	val_check(title,string);
	val_check_function(f,0);
	w = (window*)alloc(sizeof(window));
	w->click = f;
	w->p = sys_winlog_new(val_string(title),wnd_callback,w);
	if( w->p == NULL )		
		neko_error();	
	return alloc_abstract(k_winlog,w);
}
Exemplo n.º 9
0
/**
	module_read : fread:(buf:string -> pos:int -> len:int -> int) -> loader:object -> 'module
	<doc>
	Read a module using the specified read function and the specified loader.
	</doc>
**/
static value module_read( value fread, value loader ) {
	value p;
	neko_module *m;
	val_check_function(fread,3);
	val_check(loader,object);
	p = alloc_array(2);
	val_array_ptr(p)[0] = fread;
	val_array_ptr(p)[1] = alloc_empty_string(READ_BUFSIZE);
	m = neko_read_module(read_proxy,p,loader);
	if( m == NULL )
		neko_error();
	m->name = alloc_string("");
	return alloc_abstract(neko_kind_module,m);
}
Exemplo n.º 10
0
static value inputandroid_initialize(value onTouchBatchStartCallback, value onTouchCallback, value setCachedVariables)
{
	val_check_function(onTouchBatchStartCallback, 1); // Is Func ?

	if (__onTouchBatchStartCallback == NULL)
	{
		__onTouchBatchStartCallback = alloc_root();
	}
	*__onTouchBatchStartCallback = onTouchBatchStartCallback;

	val_check_function(onTouchCallback, 1); // Is Func ?

	if (__onTouchCallback == NULL)
	{
		__onTouchCallback = alloc_root();
	}
	*__onTouchCallback = onTouchCallback;

    __touchValue = alloc_abstract(0, &__touch);
    __touchCountValue = alloc_abstract(0, &__touchCount);

	val_call2(setCachedVariables, __touchValue, __touchCountValue);
	return alloc_null();
}
Exemplo n.º 11
0
/**
	$hiter : 'hash -> f:function:2 -> void
	<doc>Call the function [f] with every key and value in the hashtable</doc>
**/
static value builtin_hiter( value vh, value f ) {
	int i;
	hcell *c;
	vhash *h;
	val_check_function(f,2);
	val_check_kind(vh,k_hash);
	h = val_hdata(vh);
	for(i=0;i<h->ncells;i++) {
		c = h->cells[i];
		while( c != NULL ) {
			val_call2(f,c->key,c->val);
			c = c->next;
		}
	}
	return val_null;
}
Exemplo n.º 12
0
value hxfcgi_cache_module(value func) {
	val_check_function(func,1);
	hxfcgi::Request *req;
	while (true) {
		try {
			if(FCGX_IsCGI()) break;
			req = new hxfcgi::Request();
			val_call1(func,alloc_abstract(hxRequest,req));
			delete req;
		}
		catch (string error) {
			hx_failure(error.c_str());
			break;
		}
	}
	return val_null;
	
}
Exemplo n.º 13
0
/**
	regexp_replace_fun : 'regexp -> from:string -> f:('regexp -> any) -> string
	<doc>Perform a replacement of all matched substrings by calling [f] for every match</doc>
**/
static value regexp_replace_fun( value o, value s, value f ) {
	val_check_kind(o,k_regexp);
	val_check(s,string);
	val_check_function(f,1);
	{
		pcredata *d = PCRE(o);
		buffer b = alloc_buffer(NULL);
		int pos = 0;
		int len = val_strlen(s);
		const char *str = val_string(s);
		d->str = s;
		while( pcre_exec(d->r,NULL,str,len,pos,0,d->matchs,d->nmatchs * 3) >= 0 ) {
			buffer_append_sub(b,str+pos,d->matchs[0] - pos);
			val_buffer(b,val_call1(f,o));
			pos = d->matchs[1];
		}
		d->str = alloc_null();
		buffer_append_sub(b,str+pos,len-pos);
		return buffer_to_string(b);
	}
}
Exemplo n.º 14
0
/**
	$hset : 'hash -> k:any -> v:any -> cmp:function:2? -> bool
	<doc>
	Set the value bound to key [k] to [v] or add it to the hashtable if not found.
	Return true if the value was added to the hashtable.
	</doc>
**/
static value builtin_hset( value vh, value key, value val, value cmp ) {
	vhash *h;
	hcell *c;
	int hkey;
	if( !val_is_null(cmp) )
		val_check_function(cmp,2);
	val_check_kind(vh,k_hash);
	h = val_hdata(vh);
	hkey = val_hash(key);
	c = h->cells[hkey % h->ncells];
	if( val_is_null(cmp) ) {
		while( c != NULL ) {
			if( val_compare(key,c->key) == 0 ) {
				c->val = val;
				return val_false;
			}
			c = c->next;
		}
	} else {
		while( c != NULL ) {
			if( val_call2(cmp,key,c->key) == alloc_int(0) ) {
				c->val = val;
				return val_false;
			}
			c = c->next;
		}
	}
	if( h->nitems >= (h->ncells << 1) )
		builtin_hresize(vh,alloc_int(h->ncells << 1));
	c = (hcell*)alloc(sizeof(hcell));
	c->hkey = hkey;
	c->key = key;
	c->val = val;
	hkey %= h->ncells;
	c->next = h->cells[hkey];
	h->cells[hkey] = c;
	h->nitems++;
	return val_true;
}
Exemplo n.º 15
0
/**
	$hremove : 'hash -> k:any -> cmp:function:2? -> bool
	<doc>
		Look for the value bound to the key [k] in the hashtable.
		Use the comparison function [cmp] or [$compare] if [null].
		Return true if such value exists and remove it from the hash, false either.
	</doc>
**/
static value builtin_hremove( value vh, value key, value cmp ) {
	vhash *h;
	hcell *c, *prev = NULL;
	int hkey;
	if( !val_is_null(cmp) )
		val_check_function(cmp,2);
	val_check_kind(vh,k_hash);
	h = val_hdata(vh);
	hkey = val_hash(key) % h->ncells;
	c = h->cells[hkey];
	if( val_is_null(cmp) ) {
		while( c != NULL ) {
			if( val_compare(key,c->key) == 0 ) {
				if( prev == NULL )
					h->cells[hkey] = c->next;
				else
					prev->next = c->next;
				h->nitems--;
				return val_true;
			}
			prev = c;
			c = c->next;
		}
	} else {
		while( c != NULL ) {
			if( val_call2(cmp,key,c->key) == alloc_int(0) ) {
				if( prev == NULL )
					h->cells[hkey] = c->next;
				else
					prev->next = c->next;
				h->nitems--;
				return val_true;
			}
			prev = c;
			c = c->next;
		}
	}
	return val_false;
}
Exemplo n.º 16
0
/**
	$hmem : 'hash -> k:any -> cmp:function:2? -> bool
	<doc>
		Look for the value bound to the key [k] in the hashtable.
		Use the comparison function [cmp] or [$compare] if [null].
		Return true if such value exists, false either.
	</doc>
**/
static value builtin_hmem( value vh, value key, value cmp ) {
	vhash *h;
	hcell *c;
	if( !val_is_null(cmp) )
		val_check_function(cmp,2);
	val_check_kind(vh,k_hash);
	h = val_hdata(vh);
	c = h->cells[val_hash(key) % h->ncells];
	if( val_is_null(cmp) ) {
		while( c != NULL ) {
			if( val_compare(key,c->key) == 0 )
				return val_true;
			c = c->next;
		}
	} else {
		while( c != NULL ) {
			if( val_call2(cmp,key,c->key) == alloc_int(0) )
				return val_true;
			c = c->next;
		}
	}
	return val_false;
}
Exemplo n.º 17
0
/**
	ui_sync : callb:(void -> void) -> void
	<doc>
	Queue a method call [callb] to be executed by the main thread while running the UI event
	loop. This can be used to perform UI updates in the UI thread using results processed by
	another thread.
	</doc>
**/
static value ui_sync( value f ) {
	value *r;
	val_check_function(f,0);
	r = alloc_root(1);
	*r = f;
#	if defined(NEKO_WINDOWS)
	while( !PostMessage(data.wnd,WM_SYNC_CALL,0,(LPARAM)r) )
		Sleep(100);
#	elif defined(NEKO_MAC)
	EventRef e;
	CreateEvent(NULL,UIEvent,eCall,GetCurrentEventTime(),kEventAttributeUserEvent,&e);
	SetEventParameter(e,pFunc,typeVoidPtr,sizeof(void*),&r);
	PostEventToQueue(GetMainEventQueue(),e,kEventPriorityStandard);
	ReleaseEvent(e);
#	elif defined(NEKO_LINUX)
	// the lock should not be needed because GTK is MT-safe
	// however the GTK lock mechanism is a LOT slower than
	// using a pthread_mutex
	pthread_mutex_lock(&data.lock);
	gtk_timeout_add( 0, onSyncCall, (gpointer)r );
	pthread_mutex_unlock(&data.lock);
#	endif
	return val_null;
}
Exemplo n.º 18
0
static value conf_set_servername_callback( value config, value cb ){
	val_check_kind(config,k_ssl_conf);
	val_check_function(cb,1);
	mbedtls_ssl_conf_sni( val_conf(config), sni_callback, (void *)cb );
	return val_true;
}
Exemplo n.º 19
0
value hxfcgi_parse_multipart_neko(value hreq, value onpart, value ondata ) {
	val_check_kind(hreq,hxRequest);
	val_check_function(onpart,2);
	val_check_function(ondata,3);
	hxfcgi::Request *req = get_request(hreq);
	char *buf;
	int len = 0;
	char *boundstr;
	hxfcgi::BasicData b;
	string ctype = b.getHeader("CONTENT_TYPE");
	if(ctype.find("multipart/form-data") != 0)
		return val_null;
	// extract boundary value
	{
		const char *boundary, *bend;
		if( (boundary = strstr(ctype.c_str(),"boundary=")) == NULL )
			neko_error();
		boundary += 9;
		PARSE_HEADER(boundary,bend);
		len = (int)(bend - boundary);
		boundstr = (char *) malloc(sizeof(char) * (len+3));
		if( strlen(boundstr) > BUFSIZE / 2 )
			neko_error();
		
		boundstr[0] = '-';
		boundstr[1] = '-';
		memcpy(boundstr+2,boundary,len);
		boundstr[len+2] = 0;
	}
	
	len = 0;
	buf = (char *) malloc(sizeof(char) * (BUFSIZE));
	while( true ) {
		char *name, *end_name, *filename, *end_file_name, *data;
		int pos;
		// refill buffer
		// we assume here that the the whole multipart header can fit in the buffer
		req->bufferFill(buf,&len);
		// is boundary at the beginning of buffer ?
		if( len < (int) strlen(boundstr) || memcmp(buf,boundstr,strlen(boundstr)) != 0 ) {
			free(boundstr);
			free(buf);
			return val_null;
		}		
		name = memfind(buf,len,"Content-Disposition:");
		if( name == NULL )
			break;
		name = memfind(name,len - (int)(name - buf),"name=");
		if( name == NULL ) {
			free(boundstr);
			free(buf);
			return val_null;
		}
		name += 5;
		PARSE_HEADER(name,end_name);
		data = memfind(end_name,len - (int)(end_name - buf),"\r\n\r\n");
		if( data == NULL ) {
			free(boundstr);
			free(buf);
			return val_null;
		}
		filename = memfind(name,(int)(data - name),"filename=");
		if( filename != NULL ) {
			filename += 9;
			PARSE_HEADER(filename,end_file_name);
		}
		data += 4;
		pos = (int)(data - buf);
		// send part name
		val_call2(onpart,copy_string(name,(int)(end_name - name)),filename?copy_string(filename,(int)(end_file_name - filename)):val_null);
		
		
		// read data
		while( true ) {
			const char *boundary;
			// recall buffer
			memcpy(buf,buf+pos,len - pos);
			len -= pos;
			pos = 0;
			req->bufferFill(buf,&len);
			// lookup bounds
			boundary = memfind(buf,len,boundstr);
			if( boundary == NULL ) {
				if( len == 0 ) {
					free(boundstr);
					free(buf);
					return val_null;
				}
				// send as much buffer as possible to client
				if( len < BUFSIZE )
					pos = len;
				else
					pos = len - strlen(boundstr) + 1;
				val_call3(ondata,copy_string(buf,pos),alloc_int(0),alloc_int(pos));
			} else {
				// send remaining data
				pos = (int)(boundary - buf);
				val_call3(ondata,copy_string(buf,pos-2),alloc_int(0),alloc_int(pos-2));
				// recall
				memcpy(buf,buf+pos,len - pos);
				len -= pos;
				break;
			}
		}
	}	
	free(boundstr);
	free(buf);
	return val_null;
}
Exemplo n.º 20
0
/**
	parse_multipart_data : onpart:function:2 -> ondata:function:3 -> void
	<doc>
	Incrementally parse the multipart data. call [onpart(name,filename)] for each part
	found and [ondata(buf,pos,len)] when some data is available
	</doc>
**/
static value parse_multipart_data( value onpart, value ondata ) {
	value buf;
	int len = 0;
	mcontext *c = CONTEXT();
	const char *ctype = ap_table_get(c->r->headers_in,"Content-Type");
	value boundstr;
	val_check_function(onpart,2);
	val_check_function(ondata,3);
	buf = alloc_empty_string(BUFSIZE);
	if( !ctype || strstr(ctype,"multipart/form-data") == NULL )
		return val_null;
	// extract boundary value
	{
		const char *boundary, *bend;
		if( (boundary = strstr(ctype,"boundary=")) == NULL )
			neko_error();
		boundary += 9;
		PARSE_HEADER(boundary,bend);
		len = (int)(bend - boundary);
		boundstr = alloc_empty_string(len+2);
		if( val_strlen(boundstr) > BUFSIZE / 2 )
			neko_error();
		val_string(boundstr)[0] = '-';
		val_string(boundstr)[1] = '-';
		memcpy(val_string(boundstr)+2,boundary,len);
	}
	len = 0;
    if( !ap_should_client_block(c->r) )
		neko_error();
	while( true ) {
		char *name, *end_name, *filename, *end_file_name, *data;
		int pos;
		// refill buffer
		// we assume here that the the whole multipart header can fit in the buffer
		fill_buffer(c,buf,&len);
		// is boundary at the beginning of buffer ?
		if( len < val_strlen(boundstr) || memcmp(val_string(buf),val_string(boundstr),val_strlen(boundstr)) != 0 )
			return discard_body(c);
		name = memfind(val_string(buf),len,"Content-Disposition:");
		if( name == NULL )
			break;
		name = memfind(name,len - (int)(name - val_string(buf)),"name=");
		if( name == NULL )
			return discard_body(c);
		name += 5;
		PARSE_HEADER(name,end_name);
		data = memfind(end_name,len - (int)(end_name - val_string(buf)),"\r\n\r\n");
		if( data == NULL )
			return discard_body(c);
		filename = memfind(name,(int)(data - name),"filename=");
		if( filename != NULL ) {
			filename += 9;
			PARSE_HEADER(filename,end_file_name);
		}
		data += 4;
		pos = (int)(data - val_string(buf));
		// send part name
		val_call2(onpart,copy_string(name,(int)(end_name - name)),filename?copy_string(filename,(int)(end_file_name - filename)):val_null);
		// read data
		while( true ) {
			const char *boundary;
			// recall buffer
			memmove(val_string(buf),val_string(buf)+pos,len - pos);
			len -= pos;
			pos = 0;
			fill_buffer(c,buf,&len);
			// lookup bounds
			boundary = memfind(val_string(buf),len,val_string(boundstr));
			if( boundary == NULL ) {
				if( len == 0 )
					return discard_body(c);
				// send as much buffer as possible to client
				if( len < BUFSIZE )
					pos = len;
				else
					pos = len - val_strlen(boundstr) + 1;
				val_call3(ondata,buf,alloc_int(0),alloc_int(pos));
			} else {
				// send remaining data
				pos = (int)(boundary - val_string(buf));
				val_call3(ondata,buf,alloc_int(0),alloc_int(pos-2));
				// recall
				memmove(val_string(buf),val_string(buf)+pos,len - pos);
				len -= pos;
				break;
			}
		}
	}
	return val_null;
}