/*
  Copyright (c) 2019 Red Hat Inc.
  All rights reserved.

  This library is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation; either version 2.1 of
  the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.

  Authors: Jaroslav Kysela <perex@perex.cz>
*/

#include "tplg_local.h"

int tplg_decode_template(snd_tplg_t *tplg,
			 size_t pos,
			 struct snd_soc_tplg_hdr *hdr,
			 snd_tplg_obj_template_t *t)
{
	int type;

	type = tplg_get_type(hdr->type);
	tplg_log(tplg, 'D', pos, "template: asoc type %d library type %d",
		 hdr->type, type);
	if (type < 0)
		return type;

	memset(t, 0, sizeof(*t));
	t->type = type;
	t->index = hdr->index;
	t->version = hdr->version;
	t->vendor_type = hdr->vendor_type;
	tplg_log(tplg, 'D', pos, "template: index %d version %d vendor_type %d",
		 hdr->index, hdr->version, hdr->vendor_type);
	return 0;
}

int snd_tplg_decode(snd_tplg_t *tplg, void *bin, size_t size, int dflags)
{
	struct snd_soc_tplg_hdr *hdr;
	struct tplg_table *tptr;
	size_t pos;
	void *b = bin;
	unsigned int index;
	int err;

	if (dflags != 0)
		return -EINVAL;
	if (tplg == NULL || bin == NULL)
		return -EINVAL;
	while (1) {
		pos = b - bin;
		if (size == pos) {
			tplg_log(tplg, 'D', pos, "block: success (total %zd)", size);
			return 0;
		}
		if (size - pos < sizeof(*hdr)) {
			tplg_log(tplg, 'D', pos, "block: small size");
			SNDERR("incomplete header data to decode");
			return -EINVAL;
		}
		hdr = b;
		if (hdr->magic != SND_SOC_TPLG_MAGIC) {
			SNDERR("bad block magic %08x", hdr->magic);
			return -EINVAL;
		}

		tplg_log(tplg, 'D', pos, "block: abi %d size %d payload size %d",
			 hdr->abi, hdr->size, hdr->payload_size);
		if (hdr->abi != SND_SOC_TPLG_ABI_VERSION) {
			SNDERR("unsupported ABI version %d", hdr->abi);
			return -EINVAL;
		}
		if (hdr->size != sizeof(*hdr)) {
			SNDERR("header size mismatch");
			return -EINVAL;
		}

		if (size - pos < hdr->size + hdr->payload_size) {
			SNDERR("incomplete payload data to decode");
			return -EINVAL;
		}

		if (hdr->payload_size < 8) {
			SNDERR("wrong payload size %d", hdr->payload_size);
			return -EINVAL;
		}

		/* first block must be manifest */
		if (b == bin) {
			if (hdr->type != SND_SOC_TPLG_TYPE_MANIFEST) {
				SNDERR("first block must be manifest (value %d)", hdr->type);
				return -EINVAL;
			}
			err = snd_tplg_set_version(tplg, hdr->version);
			if (err < 0)
				return err;
		}

		pos += hdr->size;
		for (index = 0; index < tplg_table_items; index++) {
			tptr = &tplg_table[index];
			if (tptr->tsoc == (int)hdr->type)
				break;
		}
		if (index >= tplg_table_items || tptr->decod == NULL) {
			SNDERR("unknown block type %d", hdr->type);
			return -EINVAL;
		}
		tplg_log(tplg, 'D', pos, "block: type %d - %s", hdr->type, tptr->name);
		err = tptr->decod(tplg, pos, hdr, b + hdr->size, hdr->payload_size);
		if (err < 0)
			return err;
		b += hdr->size + hdr->payload_size;
	}
}
