#include <u.h>
#include <libc.h>
#include <thread.h>
#include <sunrpc.h>

SunStatus
suncallpack(SunProg *prog, uchar *a, uchar *ea, uchar **pa, SunCall *c)
{
	uchar *x;
	int (*pack)(uchar*, uchar*, uchar**, SunCall*);

	if(pa == nil)
		pa = &x;
	if(c->type < 0 || c->type >= prog->nproc || (pack=prog->proc[c->type].pack) == nil)
		return SunProcUnavail;
	if((*pack)(a, ea, pa, c) < 0)
		return SunGarbageArgs;
	return SunSuccess;
}

SunStatus
suncallunpack(SunProg *prog, uchar *a, uchar *ea, uchar **pa, SunCall *c)
{
	uchar *x;
	int (*unpack)(uchar*, uchar*, uchar**, SunCall*);

	if(pa == nil)
		pa = &x;
	if(c->type < 0 || c->type >= prog->nproc || (unpack=prog->proc[c->type].unpack) == nil)
		return SunProcUnavail;
	if((*unpack)(a, ea, pa, c) < 0){
		fprint(2, "%lud %d: '%.*H' unpack failed\n", prog->prog, c->type, (int)(ea-a), a);
		return SunGarbageArgs;
	}
	return SunSuccess;
}

SunStatus
suncallunpackalloc(SunProg *prog, SunCallType type, uchar *a, uchar *ea, uchar **pa, SunCall **pc)
{
	uchar *x;
	uint size;
	int (*unpack)(uchar*, uchar*, uchar**, SunCall*);
	SunCall *c;

	if(pa == nil)
		pa = &x;
	if(type < 0 || type >= prog->nproc || (unpack=prog->proc[type].unpack) == nil)
		return SunProcUnavail;
	size = prog->proc[type].sizeoftype;
	if(size == 0)
		return SunProcUnavail;
	c = mallocz(size, 1);
	if(c == nil)
		return SunSystemErr;
	c->type = type;
	if((*unpack)(a, ea, pa, c) < 0){
		fprint(2, "in: %.*H unpack failed\n", (int)(ea-a), a);
		free(c);
		return SunGarbageArgs;
	}
	*pc = c;
	return SunSuccess;
}

uint
suncallsize(SunProg *prog, SunCall *c)
{
	uint (*size)(SunCall*);

	if(c->type < 0 || c->type >= prog->nproc || (size=prog->proc[c->type].size) == nil)
		return ~0;
	return (*size)(c);
}
