Exemplo n.º 1
0
String::String(rune code) {
	rune r[2] = { code, 0 };

	s_len = s_cap = 0;
	s_data = nullptr;
	grow(utf8_encoded_len(r) + 1);
	utf8_encode(r, s_data, s_cap);
	s_len = utf8_len(s_data);
}
Exemplo n.º 2
0
String::String(const rune *r) {
	if (r == nullptr) {
		s_len = 0;
		s_cap = kSmallestString;
		s_data = new char[s_cap];
		*s_data = 0;
	} else {
		s_len = s_cap = 0;
		s_data = nullptr;
		grow(utf8_encoded_len(r) + 1);
		utf8_encode(r, s_data, s_cap);
		s_len = utf8_len(s_data);
	}
}
Exemplo n.º 3
0
static uint32
parse_numeric_entity(const struct array entity)
{
	size_t i = 0;

	if (i < entity.size && '#' == entity.data[i]) {
		unsigned base;
		uint32 v;

		i++;
		switch (entity.data[i]) {
		case 'x':
		case 'X':
			base = 16;
			i++;
			break;
		default:
			base = 10;
		}
		v = 0;
		while (i < entity.size) {
			unsigned d;

			d = hex2int_inline(entity.data[i++]);
			if (d >= base)
				goto error;

			v = v * base + d;
			if (v >= 0x10ffffU)
				goto error;
		}
		if (0 == utf8_encoded_len(v))
			goto error;
		return v;
	}

error:
	return -1;
}
Exemplo n.º 4
0
static int
html_parse(struct html_output *output, const struct array array)
{
	size_t i, line_num;
	const char *msg;
	uint32 c;
	unsigned c_len;
	struct array tag, text;
	struct html_node *nodes, *root;

	line_num = 1;

	root = html_node_alloc();
	nodes = root;

	tag = zero_array;
	text = array_init(array.data, 0);

	for (i = 0; i < array.size; i += c_len) {
		const char *next_ptr;

		c = utf8_decode(&array.data[i], i - array.size);
		if ((uint32)-1 == c) {
			msg = "Invalid UTF-8 encoding";
			goto error;
		}
		c_len = utf8_encoded_len(c);
		next_ptr = &array.data[i + c_len];

		switch (c) {
		case '<':
			if (tag.data) {
				tag.size += c_len;
			} else {
				if (text.data && text.size > 0) {
					struct html_node *node;

					node = html_node_alloc();
					node->type = HTML_NODE_TEXT;
					node->array = text;
					node->next = NULL;
					nodes->next = node;
					nodes = node;
					text = zero_array;
				}
				tag.data = deconstify_gchar(next_ptr);
				tag.size = 0;
			}
			break;

		case '>':
			if (!tag.data) {
				g_warning("'>' but no open tag");
				if (text.data)
					text.size += c_len;
			} else if (
				HTML_TAG_COMMENT == parse_tag(tag) &&
				0 != memcmp(&tag.data[tag.size - 2], "--", 2)
			) {
				tag.size += c_len;
			} else {
				struct html_node *node;

				node = html_node_alloc();
				node->type = HTML_NODE_TAG;
				node->array = tag;
				node->next = NULL;
				nodes->next = node;
				nodes = node;
				tag = zero_array;
				text = array_init(next_ptr, 0);
			}
			break;

		case '\n':
			line_num++;
			/* FALL THROUGH */
		default:
			if (tag.data) {
				tag.size += c_len;
			} else if (text.data) {
				text.size += c_len;
			}
		}
	}

	{
		struct render_context ctx;

		ctx = zero_render_context;
		ctx.output = output;
		ctx.root = root;
		html_render(&ctx);
	}

	html_free(root);
	return 0;

error:
	g_warning("line %zu: error: %s", line_num, msg);
	html_free(root);
	return -1;
}