/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you 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
 *
 * http://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 <errno.h>
#include <stdlib.h>
#include <string.h>

#include "avro/allocation.h"
#include "avro/data.h"
#include "avro/errors.h"
#include "avro_private.h"


void avro_raw_array_init(avro_raw_array_t *array, size_t element_size)
{
	memset(array, 0, sizeof(avro_raw_array_t));
	array->element_size = element_size;
}


void avro_raw_array_done(avro_raw_array_t *array)
{
	if (array->data) {
		avro_free(array->data, array->allocated_size);
	}
	memset(array, 0, sizeof(avro_raw_array_t));
}


void avro_raw_array_clear(avro_raw_array_t *array)
{
	array->element_count = 0;
}


int
avro_raw_array_ensure_size(avro_raw_array_t *array, size_t desired_count)
{
	size_t  required_size = array->element_size * desired_count;
	if (array->allocated_size >= required_size) {
		return 0;
	}

	/*
	 * Double the old size when reallocating.
	 */

	size_t  new_size;
	if (array->allocated_size == 0) {
		/*
		 * Start with an arbitrary 10 items.
		 */

		new_size = 10 * array->element_size;
	} else {
		new_size = array->allocated_size * 2;
	}

	if (required_size > new_size) {
		new_size = required_size;
	}

	array->data = avro_realloc(array->data, array->allocated_size, new_size);
	if (array->data == NULL) {
		avro_set_error("Cannot allocate space in array for %" PRIsz " elements",
			       desired_count);
		return ENOMEM;
	}
	array->allocated_size = new_size;

	return 0;
}


int
avro_raw_array_ensure_size0(avro_raw_array_t *array, size_t desired_count)
{
	int  rval;
	size_t  old_allocated_size = array->allocated_size;
	check(rval, avro_raw_array_ensure_size(array, desired_count));

	if (array->allocated_size > old_allocated_size) {
		size_t  extra_space = array->allocated_size - old_allocated_size;
		void  *buf = array->data;
		memset((char *)buf + old_allocated_size, 0, extra_space);
	}

	return 0;
}


void *avro_raw_array_append(avro_raw_array_t *array)
{
	int  rval;

	rval = avro_raw_array_ensure_size(array, array->element_count + 1);
	if (rval) {
		return NULL;
	}

	size_t  offset = array->element_size * array->element_count;
	array->element_count++;
	return (char *)array->data + offset;
}
