#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#if defined(lint) && defined(HAVE_NOTE_H)
#include <note.h>
#endif /* lint && HAVE_NOTE_H */

#include <iiimp-data.h>

#include "iiimp-dataP.h"
#include "print-misc.h"


IIIMP_feedback_attr_list *
iiimp_feedback_attr_list_new(
    IIIMP_data_s *		data_s,
    int				count,
    const IIIMP_feedback_attr *	ptr)
{
    IIIMP_feedback_attr_list *	data;
    size_t			nbyte;
    int				i;

    data = (IIIMP_feedback_attr_list *)
	malloc(sizeof (IIIMP_feedback_attr_list));
    if (NULL == data) {
	data_s->status = IIIMP_DATA_MALLOC_ERROR;
	return NULL;
    }

    nbyte = ((4 + 4) * count);

    data->nbyte = nbyte;
    data->count = count;

    nbyte = ((sizeof (IIIMP_feedback_attr)) * data->count);

    if (0 == data) {
	data->ptr = NULL;
    } else {
	data->ptr = (IIIMP_feedback_attr *)malloc(nbyte);
	if (NULL == data->ptr) {
	    iiimp_feedback_attr_list_delete(data_s, data);
	    data_s->status = IIIMP_DATA_MALLOC_ERROR;
	    return NULL;
	}
    }

    if (NULL != ptr) {
	for (i = 0; i < count; i++) {
	    (data->ptr + i)->nbyte = 8;
	    (data->ptr + i)->id = (ptr + i)->id;
	    (data->ptr + i)->feedback = (ptr + i)->feedback;
	}
    }

    return data;
}


void
iiimp_feedback_attr_list_delete(
    IIIMP_data_s *		data_s,
    IIIMP_feedback_attr_list *	data)
{
#if defined(lint) && defined(HAVE_NOTE_H)
    NOTE(ARGUNUSED(data_s))
#endif /* lint && HAVE_NOTE_H */
    if (NULL == data) return;
    free(data->ptr);
    free(data);
    return;
}


void
iiimp_feedback_attr_list_pack(
    IIIMP_data_s *		data_s,
    IIIMP_feedback_attr_list *	m,
    size_t *			nbyte,
    uchar_t **			ptr)
{
    size_t	rest;
    uchar_t *	p;
    int		i;

    rest = *nbyte;
    p = *ptr;

    for (i = 0; i < m->count; i++) {
	PUTU32((m->ptr + i)->id, rest, p, data_s->byte_swap);
	PUTU32((m->ptr + i)->feedback, rest, p, data_s->byte_swap);
    }

    *nbyte = rest;
    *ptr = p;

    return;
}


IIIMP_feedback_attr_list *
iiimp_feedback_attr_list_unpack(
    IIIMP_data_s *	data_s,
    size_t *		nbyte,
    const uchar_t **	ptr,
    size_t		nbyte_max)
{
    IIIMP_feedback_attr_list *	data;
    const uchar_t *		p;
    size_t			rest;
    int				data_count;
    int				i;

    rest = nbyte_max;
    p = *ptr;

    if ((*nbyte < rest) || (0 != (nbyte_max & 0x07))) {
	data_s->status = IIIMP_DATA_INVALID;
	return NULL;
    }

    data_count = (nbyte_max / (4 + 4));

    data = (IIIMP_feedback_attr_list *)
	malloc(sizeof (IIIMP_feedback_attr_list));
    if (NULL == data) {
	data_s->status = IIIMP_DATA_MALLOC_ERROR;
	return NULL;
    }

    data->count = data_count;

    data->ptr = (IIIMP_feedback_attr *)
	malloc((sizeof (IIIMP_feedback_attr)) * data_count);
    if (NULL == data->ptr) {
	iiimp_feedback_attr_list_delete(data_s, data);
	data_s->status = IIIMP_DATA_MALLOC_ERROR;
	return NULL;
    }

    for (i = 0; i < data_count; i++) {
	GETU32((data->ptr + i)->id, rest, p, data_s->byte_swap);
	GETU32((data->ptr + i)->feedback, rest, p, data_s->byte_swap);
    }

    *nbyte -= (nbyte_max - rest);
    *ptr += nbyte_max;

    return data;
}


void
iiimp_feedback_attr_print(
    IIIMP_data_s *		data_s,
    IIIMP_feedback_attr *	m)
{
    if (NULL == m) return;
    if (0 == m->id) {
	(void)fprintf(data_s->print_fp, "%s", feedback_string_get(m->feedback));
    } else {
	(void)fprintf(data_s->print_fp, "\n\tFeedback ID=%d Feedback=%d\n",
		      m->id, m->feedback);
    }
}


void
iiimp_feedback_attr_list_print(
    IIIMP_data_s *		data_s,
    IIIMP_feedback_attr_list *	m)
{
    int	i;

    if (NULL == m) return;

    for (i = 0; i < m->count; i++) {
	(void)fputc(' ', data_s->print_fp);
	iiimp_feedback_attr_print(data_s, m->ptr + i);
    }
}


/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
