/*
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "hf/memiter.h"

#include "hf/std.h"

/**
 * Initialises the given memory iterator.
 */
void memiter_init(struct memiter *it, const void *data, size_t size)
{
	it->next = data;
	it->limit = it->next + size;
}

/**
 * Determines if the next character is a whitespace.
 */
static bool memiter_isspace(struct memiter *it)
{
	switch (*it->next) {
	case ' ':
	case '\t':
	case '\n':
	case '\r':
		return true;
	default:
		return false;
	}
}

/**
 * Moves iterator to the next non-whitespace character.
 */
static void memiter_skip_space(struct memiter *it)
{
	while (it->next < it->limit && memiter_isspace(it)) {
		it->next++;
	}
}

/**
 * Compares the iterator to a null-terminated string.
 */
bool memiter_iseq(const struct memiter *it, const char *str)
{
	size_t len = strlen(str);

	if (len != it->limit - it->next) {
		return false;
	}

	return memcmp(it->next, str, len) == 0;
}

/**
 * Retrieves the next string that is delimited by whitespaces. The result is
 * stored in "str".
 */
bool memiter_parse_str(struct memiter *it, struct memiter *str)
{
	/* Skip all white space and fail if we reach the end of the buffer. */
	memiter_skip_space(it);
	if (it->next >= it->limit) {
		return false;
	}

	str->next = it->next;

	/* Find the end of the string. */
	while (it->next < it->limit && !memiter_isspace(it)) {
		it->next++;
	}

	str->limit = it->next;

	return true;
}

/**
 * Parses the next string that represents a 64-bit number.
 */
bool memiter_parse_uint(struct memiter *it, uint64_t *value)
{
	uint64_t v = 0;

	/* Skip all white space and fail if we reach the end of the buffer. */
	memiter_skip_space(it);
	if (it->next >= it->limit) {
		return false;
	}

	/* Fail if it's not a number. */
	if (*it->next < '0' || *it->next > '9') {
		return false;
	}

	/* Parse the number. */
	do {
		v = v * 10 + *it->next - '0';
		it->next++;
	} while (it->next < it->limit && *it->next >= '0' && *it->next <= '9');

	*value = v;

	return true;
}

/**
 * Advances the iterator by the given number of bytes. Returns true if the
 * iterator was advanced without going over its limit; returns false and leaves
 * the iterator unmodified otherwise.
 */
bool memiter_advance(struct memiter *it, size_t v)
{
	const char *p = it->next + v;

	if (p < it->next || p > it->limit) {
		return false;
	}

	it->next = p;

	return true;
}
