Ejemplo n.º 1
0
V strslice(utf8 source, utf8index from, utf8index to)
{
	size_t len = to >= from ? to - from : 0;
	return str_to_string(len, source + from);
}
Ejemplo n.º 2
0
Archivo: literals.c Proyecto: gvx/deja
bool read_literals(char *oldpos, size_t size, Header* h)
{
	int i, j;
	int n = 0;
	char type;
	uint32_t str_length;
	uint32_t ref;
	char *startpos = oldpos + h->size * 4;
	char *curpos = startpos;
	while (!eofreached)
	{
		type = *curpos++;
		if (eofreached)
		{
			break;
		}
		n++;
		switch (type)
		{
			case TYPE_NUM:
				curpos += 8;
				break;
			case TYPE_NUM | TYPE_SHORT:
				curpos += 3;
				break;
			case TYPE_STR:
			case TYPE_IDENT:
				memcpy(&str_length, curpos, 4);
				curpos += 4 + ntohl(str_length);
				break;
			case TYPE_STR | TYPE_SHORT:
			case TYPE_IDENT | TYPE_SHORT:
				str_length = (unsigned char)*curpos++;
				curpos += str_length;
				break;
			case TYPE_PAIR:
				curpos += 6;
				break;
			case TYPE_FRAC:
				curpos += 16;
				break;
			case TYPE_FRAC | TYPE_SHORT:
				curpos += 2;
				break;
			case TYPE_LIST:
				memcpy(&str_length, curpos, 4);
				curpos += 4 + 3 * ntohl(str_length);
				break;
			case TYPE_DICT:
				memcpy(&str_length, curpos, 4);
				curpos += 4 + 6 * ntohl(str_length);
				break;
		}
	}
	V* arr = calloc(n, sizeof(V));
	V t;
	curpos = startpos;
	for (i = 0; i < n; i++)
	{
		type = *curpos++;
		if (type == TYPE_NUM)
		{
			union double_or_uint64_t d;
			memcpy(&d, curpos, 8);
			curpos += 8;
			d.i = ntohll(d.i);
			t = double_to_value(d.d);
		}
		else if (type == (TYPE_NUM | TYPE_SHORT))
		{
			ref = 0;
			memcpy(((char*)&ref) + 1, curpos, 3);
			ref = ntohl(ref);
			curpos += 3;
			t = int_to_value(ref);
		}
		else if (type == TYPE_STR)
		{
			memcpy(&str_length, curpos, 4);
			curpos += 4;
			str_length = ntohl(str_length);
			if (!valid_utf8(str_length, curpos))
			{
				set_error_msg("wrong encoding for string literal, should be UTF-8");
				return false;
			}
			t = str_to_string(str_length, curpos);
			curpos += str_length;
		}
		else if (type == TYPE_IDENT)
		{
			memcpy(&str_length, curpos, 4);
			curpos += 4;
			str_length = ntohl(str_length);
			char data[str_length + 1];
			memcpy(&data, curpos, str_length);
			data[str_length] = '\0';
			t = lookup_ident(str_length, data);
			curpos += str_length;
		}
		else if (type == (TYPE_STR | TYPE_SHORT))
		{
			str_length = (unsigned char)*curpos++;
			if (!valid_utf8(str_length, curpos))
			{
				set_error_msg("wrong encoding for string literal, should be UTF-8");
				return false;
			}
			t = str_to_string(str_length, curpos);
			curpos += str_length;
		}
		else if (type == (TYPE_IDENT | TYPE_SHORT))
		{
			str_length = *curpos++;
			char data[str_length + 1];
			memcpy(&data, curpos, str_length);
			data[str_length] = '\0';
			t = lookup_ident(str_length, data);
			curpos += str_length;
		}
		else if (type == TYPE_PAIR)
		{
			ref = 0;
			memcpy(((char*)&ref) + 1, curpos, 3);
			ref = ntohl(ref);
			if (ref >= i)
			{
				set_error_msg("illegal pair detected");
				return false;
			}
			V v1 = arr[ref];

			ref = 0;
			memcpy(((char*)&ref) + 1, curpos + 3, 3);
			ref = ntohl(ref);
			if (ref >= i)
			{
				set_error_msg("illegal pair detected");
				return false;
			}
			V v2 = arr[ref];

			t = new_pair(v1, v2);
			curpos += 6;
		}
		else if (type == TYPE_FRAC)
		{
			int64_t numer;
			int64_t denom;
			memcpy(&numer, curpos, 8);
			numer = ntohll(numer);
			memcpy(&denom, curpos + 8, 8);
			denom = ntohll(denom);
			t = new_frac(numer, denom);
			curpos += 16;
		}
		else if (type == (TYPE_FRAC | TYPE_SHORT))
		{
			int8_t numer;
			uint8_t denom;
			numer = *curpos++;
			denom = *curpos++;
			t = new_frac(numer, denom);
		}
		else if (type == TYPE_LIST)
		{
			memcpy(&str_length, curpos, 4);
			str_length = ntohl(str_length);
			t = new_list();
			curpos += 4;
			if (str_length > 0)
			{
				uint32_t size = 64;
				while (size < str_length) size <<= 1;
				toStack(t)->size = size;
				toStack(t)->used = str_length;
				toStack(t)->nodes = calloc(size, sizeof(V));
				for (j = 0; j < str_length; j++)
				{
					ref = 0;
					memcpy(((char*)&ref) + 1, curpos, 3);
					ref = ntohl(ref);
					toStack(t)->nodes[j] = intToV((uint64_t)ref);
					curpos += 3;
				}
			}
		}
		else if (type == TYPE_DICT)
		{
			memcpy(&str_length, curpos, 4);
			curpos += 4;
			str_length = ntohl(str_length);
			t = new_dict();
			if (str_length > 0)
			{
				uint32_t size = 16;
				while (size < str_length) size <<= 1;
				toHashMap(t)->size = size;
				toHashMap(t)->used = str_length;
				toHashMap(t)->map = (Bucket**)curpos;
			}
			curpos += 6 * str_length;
		}
		else
		{
			set_error_msg("Unknown literal type.");
			return false;
		}
		arr[i] = t;
	}

	for (i = 0; i < n; i++)
	{
		t = arr[i];
		switch(getType(t))
		{
			case TYPE_LIST:
				for (j = 0; j < toStack(t)->used; j++)
				{
					toStack(t)->nodes[j] = arr[toInt(toStack(t)->nodes[j])];
				}
				break;
			case TYPE_DICT:
				if (toHashMap(t)->map)
				{
					curpos = ((char*)toHashMap(t)->map);

					toHashMap(t)->map = NULL;
					str_length = toHashMap(t)->used; //worst abuse of variable name ever Y/Y?
					toHashMap(t)->used = 0;
					for (j = 0; j < str_length; j++)
					{
						ref = 0;
						memcpy(((char*)&ref) + 1, curpos, 3);
						ref = ntohl(ref);
						V key = arr[ref];

						ref = 0;
						memcpy(((char*)&ref) + 1, curpos + 3, 3);
						ref = ntohl(ref);
						V value = arr[ref];

						set_hashmap(toHashMap(t), key, value);

						curpos += 6;
					}
				}
				break;
		}
	}

	h->n_literals = n;
	h->literals = arr;
	return true;
}