as_val *
geojson_to_asval(const as_particle *p)
{
	geojson_mem *p_geojson_mem = (geojson_mem *)p;

	size_t jsonsz;
	char const *jsonptr = geojson_mem_jsonstr(p_geojson_mem, &jsonsz);
	char *buf = cf_malloc(jsonsz + 1);

	if (! buf) {
		return NULL;
	}

	memcpy(buf, jsonptr, jsonsz);
	buf[jsonsz] = '\0';

	return (as_val *)as_geojson_new_wlen(buf, jsonsz, true);
}
Beispiel #2
0
static void
as_command_parse_value(uint8_t* p, uint8_t type, uint32_t value_size, as_val** value)
{
	// Allocate values on heap.
	switch (type) {
		case AS_BYTES_UNDEF: {
			*value = (as_val*)&as_nil;
			break;
		}
		case AS_BYTES_INTEGER: {
			int64_t v = 0;
			as_command_bytes_to_int(p, value_size, &v);
			*value = (as_val*)as_integer_new(v);
			break;
		}
		case AS_BYTES_DOUBLE: {
			double v = cf_swap_from_big_float64(*(double*)p);
			*value = (as_val*)as_double_new(v);
			break;
		}
		case AS_BYTES_STRING: {
			char* v = cf_malloc(value_size + 1);
			memcpy(v, p, value_size);
			v[value_size] = 0;
			*value = (as_val*)as_string_new_wlen(v, value_size, true);
			break;
		}
		case AS_BYTES_GEOJSON: {
			uint8_t * ptr = p;

			// skip flags
			ptr++;

			// ncells
			uint16_t ncells = cf_swap_from_be16(* (uint16_t *) ptr);
			ptr += sizeof(uint16_t);

			// skip any cells
			ptr += sizeof(uint64_t) * ncells;

			// Use the json bytes.
			size_t jsonsz = value_size - 1 - 2 - (ncells * sizeof(uint64_t));
			char* v = cf_malloc(jsonsz + 1);
			memcpy(v, ptr, jsonsz);
			v[jsonsz] = 0;
			*value = (as_val*) as_geojson_new_wlen(v, jsonsz, true);
			break;
		}
		case AS_BYTES_LIST:
		case AS_BYTES_MAP: {
			as_buffer buffer;
			buffer.data = p;
			buffer.size = value_size;
			
			as_serializer ser;
			as_msgpack_init(&ser);
			as_serializer_deserialize(&ser, &buffer, value);
			as_serializer_destroy(&ser);
			break;
		}
		default: {
			void* v = cf_malloc(value_size);
			memcpy(v, p, value_size);
			*value = (as_val*)as_bytes_new_wrap(v, value_size, true);
			break;
		}
	}
}
static bool
unpack_blob(serial_context *ser_cont, uint32_t size, as_val **value)
{
	int32_t type = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes);

	if (type == EOF) {
		err("Error while reading BLOB type");
		return false;
	}

	--size;

	if (VERBOSE) {
		ver("%sBLOB, %u byte(s), type 0x%02x", indent(ser_cont), size, type);
	}

	// Waste one byte...
	void *buffer = safe_malloc(size + 1);

	// ... so that we can NUL-terminate all strings for as_string_val_hashcode().
	char *chars = buffer;
	chars[size] = 0;

	if (!READ_BLOCK(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes,
			buffer, size)) {
		err("Error while reading BLOB data");
		cf_free(buffer);
		return false;
	}

	if (type == AS_BYTES_STRING) {
		if (VERBOSE) {
			ver("%s  -> string BLOB: \"%s\"", indent(ser_cont), chars);
		}

		as_string *string = as_string_new_wlen(buffer, size, true);

		if (string == NULL) {
			err("Error while allocating string");
			cf_free(buffer);
			return false;
		}

		*value = (as_val *)string;
		return true;
	}

	if (type == AS_BYTES_GEOJSON) {
		if (VERBOSE) {
			ver("%s  -> geo BLOB: \"%s\"", indent(ser_cont), chars);
		}

		as_geojson *geo = as_geojson_new_wlen(buffer, size, true);

		if (geo == NULL) {
			err("Error while allocating geo value");
			cf_free(buffer);
			return false;
		}

		*value = (as_val *)geo;
		return true;
	}

	as_bytes *blob = as_bytes_new_wrap(buffer, size, true);

	if (blob == NULL) {
		err("Error while allocating BLOB");
		return false;
	}

	blob->type = (as_bytes_type)type;
	*value = (as_val *)blob;
	return true;
}