Esempio 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;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}