Exemplo n.º 1
0
/*
	lightuserdata pattern
	string format "ixrsmb"
	integer size
 */
static int
_pattern_pack(lua_State *L) {
	struct pbc_pattern * pat = lua_touserdata(L,1);
	size_t format_sz = 0;
	const char * format = lua_tolstring(L,2,&format_sz);
	int size = lua_tointeger(L,3);

	char data[size];

	memset(data, 0 ,size);

	char * ptr = data;

	int i;

	for (i=0;i<format_sz;i++) {
		if (format[i] >= 'a' && format[i] <='z') {
			ptr = _get_value(L, 4+i, ptr, format[i]);
		} else {
			if (!lua_istable(L,4+i)) {
				luaL_error(L,"need table for array type");
			}
			int j;
			int n = lua_rawlen(L,4+i);
			for (j=0;j<n;j++) {
				lua_rawgeti(L,4+i,j);
				_get_array_value(L,(void *)ptr,format[i]);
				lua_pop(L,1);
			}
			ptr += sizeof(pbc_array);
		}
	}

	luaL_Buffer b;
	luaL_buffinit(L, &b);

	int cap = 128;
	do {
		char * temp = luaL_prepbuffsize(&b , cap);

		struct pbc_slice slice;
		slice.buffer = temp;
		slice.len = cap;

		int ret = pbc_pattern_pack(pat, data, &slice);

		if (ret < 0) {
			cap = cap * 2;
			_Free(temp);
			continue;
		}

		luaL_addsize(&b , slice.len);
	} while (0);
	luaL_pushresult(&b);

	pbc_pattern_close_arrays(pat, data);

	return 1;
}
Exemplo n.º 2
0
static void
test_pattern_unpack(struct pbc_env *env, struct pbc_slice * slice) {
	struct person p;
	int r = pbc_pattern_unpack(pat, slice, &p);
	if (r>=0) {
		printf("name = %s\n",(const char *)p.name.buffer);
		printf("id = %d\n",p.id);
		printf("email = %s\n",(const char *)p.email.buffer);
		int n = pbc_array_size(p.phone);
		int i;
		for (i=0;i<n;i++) {
			struct pbc_slice * bytes = pbc_array_slice(p.phone, i);
			struct person_phone pp;
			pbc_pattern_unpack(pat_phone , bytes , &pp);
			printf("\tnumber = %s\n" , (const char*)pp.number.buffer);
			printf("\ttype = %d\n" , pp.type);
		}

		n = pbc_array_size(p.test);
		for (i=0;i<n;i++) {
			printf("test[%d] = %d\n",i, pbc_array_integer(p.test, i , NULL));
		}

		pbc_pattern_close_arrays(pat,&p);
	}
}
Exemplo n.º 3
0
int 
pbc_pattern_unpack(struct pbc_pattern *pat, struct pbc_slice *s, void * output) {
	pbc_ctx _ctx;
	int r = _pbcC_open(_ctx, s->buffer, s->len);
	if (r <= 0) {
		_pbcC_close(_ctx);
		return r+1;
	}
	set_default(pat, output);

	struct context * ctx = (struct context *)_ctx;

	int i;

	for (i=0;i<ctx->number;i++) {
		struct _pattern_field * f = bsearch_pattern(pat, ctx->a[i].id);
		if (f) {
			char * out = (char *)output + f->offset;
			if (unpack_field(f->ctype , f->ptype , ctx->buffer , &ctx->a[i], out) != 0) {
				pbc_pattern_close_arrays(pat, output);
				_pbcC_close(_ctx);
				return -i-1;
			}
		}
	}
	_pbcC_close(_ctx);
	return 0;
}
Exemplo n.º 4
0
/*
	lightuserdata pattern
	string format "ixrsmb"
	integer size
	lightuserdata buffer
	integer buffer_len
 */
static int
_pattern_unpack(lua_State *L) {
	struct pbc_pattern * pat = (struct pbc_pattern *)checkuserdata(L, 1);
	if (pat == NULL) {
		return luaL_error(L, "unpack pattern is NULL");
	}
	size_t format_sz = 0;
	const char * format = lua_tolstring(L,2,&format_sz);
	int size = lua_tointeger(L,3);
	struct pbc_slice slice;
	if (lua_isstring(L,4)) {
		size_t buffer_len = 0;
		const char *buffer = luaL_checklstring(L,4,&buffer_len);
		slice.buffer = (void *)buffer;
		slice.len = buffer_len;
	} else {
		if (!lua_isuserdata(L,4)) {
			return luaL_error(L, "Need a userdata");
		}
		slice.buffer = lua_touserdata(L,4);
		slice.len = luaL_checkinteger(L,5);
	}
	
	char * temp = (char *)alloca(size);
	int ret = pbc_pattern_unpack(pat, &slice, temp);
	if (ret < 0) {
		return 0;
	}
	lua_checkstack(L, format_sz + 3);
	int i;
	char * ptr = temp;
	bool array = false;
	for (i=0;i<format_sz;i++) {
		char type = format[i];
		if (type >= 'a' && type <='z') {
			ptr = (char *)_push_value(L,ptr,type);
		} else {
			array = true;
			int n = pbc_array_size((struct _pbc_array *)ptr);
			lua_createtable(L,n,0);
			int j;
			for (j=0;j<n;j++) {
				_push_array(L,(struct _pbc_array *)ptr, type, j);
			}
			ptr += sizeof(pbc_array);
		}
	}
	if (array) {
		pbc_pattern_close_arrays(pat, temp);
	}
	return format_sz;
}
Exemplo n.º 5
0
static int
register_internal(struct pbc_env * p, void *buffer, int size) {
	struct pbc_pattern * FIELD_T =  _pbcP_new(8);
	F(0,name,string);
	F(1,id,int32);
	F(2,label,int32);
	F(3,type,int32);
	F(4,type_name,string);
	F(5,default_integer,int32);
	F(6,default_string,string);
	F(7,default_real,double);

	struct pbc_pattern * FILE_T =  _pbcP_new(10);

	D(0,name,string);
	D(1,dependency,string_array);
	D(2,message_name,string_array);
	D(3,message_size,int32_array);
	D(4,message_field,message_array);
	D(5,enum_name,string_array);
	D(6,enum_size,int32_array);
	D(7,enum_string,string_array);
	D(8,enum_id,int32_array);

	int ret = 0;

	struct file_t file;
	int r = pbc_pattern_unpack(FILE_T, buffer, size, &file);
	if (r != 0) {
		ret = 1;
		goto _return;
	}

	_pbcM_sp_insert(p->files , file.name->s.str, NULL);

	pbc_array queue;
	_pbcA_open(queue);

	set_enums(p, &file);
	set_msgs(FIELD_T, p, &file, queue);
	_pbcB_register_fields(p, queue);

	_pbcA_close(queue);
	pbc_pattern_close_arrays(FILE_T, &file);

_return:
	free(FIELD_T);
	free(FILE_T);
	return ret;
}
Exemplo n.º 6
0
/*
	lightuserdata pattern
	string format "ixrsmb"
	integer size
	lightuserdata buffer
	integer buffer_len
 */
static int
_pattern_unpack(lua_State *L) {
	struct pbc_pattern * pat = lua_touserdata(L, 1);
	size_t format_sz = 0;
	const char * format = lua_tolstring(L,2,&format_sz);
	int size = lua_tointeger(L,3);
	struct pbc_slice slice;
	if (lua_isstring(L,4)) {
		size_t buffer_len = 0;
		const char *buffer = lua_tolstring(L,4,&buffer_len);
		slice.buffer = (void *)buffer;
		slice.len = buffer_len;
	} else {
		slice.buffer = lua_touserdata(L,4);
		slice.len = lua_tointeger(L,5);
	}
	
	char temp[size];
	int ret = pbc_pattern_unpack(pat, &slice, temp);
	if (ret < 0) 
		return 0;
	lua_checkstack(L, format_sz + 3);
	int i;
	char * ptr = temp;
	bool array = false;
	for (i=0;i<format_sz;i++) {
		char type = format[i];
		if (type >= 'a' && type <='z') {
			ptr = _push_value(L,ptr,type);
		} else {
			array = true;
			int n = pbc_array_size((void *)ptr);
			lua_createtable(L,n,0);
			int j;
			for (j=0;j<n;j++) {
				_push_array(L,(void *)ptr, type, j);
			}
		}
	}
	if (array) {
		pbc_pattern_close_arrays(pat, temp);
	}
	return format_sz;
}
Exemplo n.º 7
0
/*
	lightuserdata pattern
	string format "ixrsmbp"
	integer size
 */
static int
_pattern_pack(lua_State *L) {
	struct pbc_pattern * pat = (struct pbc_pattern *)checkuserdata(L,1);
	if (pat == NULL) {
		return luaL_error(L, "pack pattern is NULL");
	}
	size_t format_sz = 0;
	const char * format = lua_tolstring(L,2,&format_sz);
	int size = lua_tointeger(L,3);

	char * data = (char *)alloca(size);
//	A trick , we don't need default value. zero buffer for array and message field.
//	pbc_pattern_set_default(pat, data);
	memset(data, 0 , size);

	char * ptr = data;

	int i;

	for (i=0;i<format_sz;i++) {
		if (format[i] >= 'a' && format[i] <='z') {
			ptr = _get_value(L, 4+i, ptr, format[i]);
		} else {
			if (!lua_istable(L,4+i)) {
				luaL_error(L,"need table for array type");
			}
			int j;
			int n = lua_rawlen(L,4+i);
			for (j=0;j<n;j++) {
				lua_rawgeti(L,4+i,j+1);
				_get_array_value(L,(struct _pbc_array *)ptr,format[i]);
				lua_pop(L,1);
			}
			ptr += sizeof(pbc_array);
		}
	}

	luaL_Buffer b;
	luaL_buffinit(L, &b);

	int cap = 128;
	for (;;) {
		char * temp = (char *)luaL_prepbuffsize(&b , cap);

		struct pbc_slice slice;
		slice.buffer = temp;
		slice.len = cap;

		int ret = pbc_pattern_pack(pat, data, &slice);

		if (ret < 0) {
			cap = cap * 2;
			continue;
		}

		luaL_addsize(&b , slice.len);
		break;
	}
	luaL_pushresult(&b);

	pbc_pattern_close_arrays(pat, data);
	return 1;
}
Exemplo n.º 8
0
static int
test_pattern_pack(struct pbc_env *env , struct pbc_slice *slice) {
	struct person p;
	/*
	  If you don't care about default values (you will set all values by yourself) ,
      you can also use memset(&p, 0 , sizeof(p)) instead of pbc_pattern_set_default.
	*/
	pbc_pattern_set_default(pat, &p);

	p.name.buffer = (void*)"Alice";
	p.name.len = -1;	// encode '\0'
	p.id = 1234;
	p.email.buffer = (void*)"alice@unknown";
	p.email.len = -1;

	struct person_phone phone;
	phone.number.buffer = (void *)"1234567";
	phone.number.len = -1;
	phone.type = 1;

	char temp[128];		
	struct pbc_slice phone_slice = { temp, sizeof(temp) };

	int unused = pbc_pattern_pack(pat_phone, &phone , &phone_slice);
	
	if (unused < 0) {
		slice->len = 0;
		return slice->len;
	}

	pbc_array_push_slice(p.phone, &phone_slice);

	pbc_pattern_set_default(pat_phone, &phone);

	phone.number.buffer = (void *)"87654321";
	phone.number.len = -1;

	char temp2[128];		
	struct pbc_slice phone_slice2 = { temp2, sizeof(temp2) };

	unused = pbc_pattern_pack(pat_phone, &phone , &phone_slice2);
	
	if (unused < 0) {
		slice->len = 0;
		return slice->len;
	}

	pbc_array_push_slice(p.phone, &phone_slice2);

	int i;
	for (i=0;i<3;i++) {
		pbc_array_push_integer(p.test, -i*4,0);
	}

	int r = pbc_pattern_pack(pat, &p, slice);
	
	pbc_pattern_close_arrays(pat,&p);
	printf("pack into %d bytes\n", slice->len);

	return r;
}