/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 */

#ifndef __VBUSDEVICEINFO_H__
#define __VBUSDEVICEINFO_H__

#include "commontypes.h"

#pragma pack(push, 1)		/* both GCC and VC now allow this pragma */

/* An array of this struct is present in the channel area for each vbus.
 * (See vbuschannel.h.)
 * It is filled in by the client side to provide info about the device
 * and driver from the client's perspective.
 */
typedef struct _ULTRA_VBUS_DEVICEINFO {
	u8 devType[16];		/* short string identifying the device type */
	u8 drvName[16];		/* driver .sys file name */
	u8 infoStrings[96];	/* sequence of tab-delimited id strings: */
	/* <DRIVER_REV> <DRIVER_VERTAG> <DRIVER_COMPILETIME> */
	u8 reserved[128];	/* pad size to 256 bytes */
} ULTRA_VBUS_DEVICEINFO;

#pragma pack(pop)

/* Reads chars from the buffer at <src> for <srcmax> bytes, and writes to
 * the buffer at <p>, which is <remain> bytes long, ensuring never to
 * overflow the buffer at <p>, using the following rules:
 * - printable characters are simply copied from the buffer at <src> to the
 *   buffer at <p>
 * - intervening streaks of non-printable characters in the buffer at <src>
 *   are replaced with a single space in the buffer at <p>
 * Note that we pay no attention to '\0'-termination.
 * Returns the number of bytes written to <p>.
 *
 * Pass <p> == NULL and <remain> == 0 for this special behavior.  In this
 * case, we simply return the number of bytes that WOULD HAVE been written
 * to a buffer at <p>, had it been infinitely big.
 */
static inline int
vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax)
{
	int chars = 0;
	int nonprintable_streak = 0;
	while (srcmax > 0) {
		if ((*src >= ' ') && (*src < 0x7f)) {
			if (nonprintable_streak) {
				if (remain > 0) {
					*p = ' ';
					p++;
					remain--;
					chars++;
				} else if (p == NULL)
					chars++;
				nonprintable_streak = 0;
			}
			if (remain > 0) {
				*p = *src;
				p++;
				remain--;
				chars++;
			} else if (p == NULL)
				chars++;
		} else
			nonprintable_streak = 1;
		src++;
		srcmax--;
	}
	return chars;
}

#define VBUSCHANNEL_ADDACHAR(ch, p, remain, chars) \
	do {					   \
		if (remain <= 0)		   \
			break;			   \
		*p = ch;			   \
		p++;  chars++;  remain--;	   \
	} while (0)

/* Converts the non-negative value at <num> to an ascii decimal string
 * at <p>, writing at most <remain> bytes.  Note there is NO '\0' termination
 * written to <p>.
 *
 * Returns the number of bytes written to <p>.
 *
 * Note that we create this function because we need to do this operation in
 * an environment-independent way (since we are in a common header file).
 */
static inline int
vbuschannel_itoa(char *p, int remain, int num)
{
	int digits = 0;
	char s[32];
	int i;

	if (num == 0) {
		/* '0' is a special case */
		if (remain <= 0)
			return 0;
		*p = '0';
		return 1;
	}
	/* form a backwards decimal ascii string in <s> */
	while (num > 0) {
		if (digits >= (int) sizeof(s))
			return 0;
		s[digits++] = (num % 10) + '0';
		num = num / 10;
	}
	if (remain < digits) {
		/* not enough room left at <p> to hold number, so fill with
		 * '?' */
		for (i = 0; i < remain; i++, p++)
			*p = '?';
		return remain;
	}
	/* plug in the decimal ascii string representing the number, by */
	/* reversing the string we just built in <s> */
	i = digits;
	while (i > 0) {
		i--;
		*p = s[i];
		p++;
	}
	return digits;
}

/* Reads <devInfo>, and converts its contents to a printable string at <p>,
 * writing at most <remain> bytes.  Note there is NO '\0' termination
 * written to <p>.
 *
 * Pass <devix> >= 0 if you want a device index presented.
 *
 * Returns the number of bytes written to <p>.
 */
static inline int
vbuschannel_devinfo_to_string(ULTRA_VBUS_DEVICEINFO *devinfo,
				  char *p, int remain, int devix)
{
	char *psrc;
	int nsrc, x, i, pad;
	int chars = 0;

	psrc = &(devinfo->devType[0]);
	nsrc = sizeof(devinfo->devType);
	if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0)
		return 0;

	/* emit device index */
	if (devix >= 0) {
		VBUSCHANNEL_ADDACHAR('[', p, remain, chars);
		x = vbuschannel_itoa(p, remain, devix);
		p += x;
		remain -= x;
		chars += x;
		VBUSCHANNEL_ADDACHAR(']', p, remain, chars);
	} else {
		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
	}

	/* emit device type */
	x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
	p += x;
	remain -= x;
	chars += x;
	pad = 15 - x;		/* pad device type to be exactly 15 chars */
	for (i = 0; i < pad; i++)
		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
	VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);

	/* emit driver name */
	psrc = &(devinfo->drvName[0]);
	nsrc = sizeof(devinfo->drvName);
	x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
	p += x;
	remain -= x;
	chars += x;
	pad = 15 - x;		/* pad driver name to be exactly 15 chars */
	for (i = 0; i < pad; i++)
		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
	VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);

	/* emit strings */
	psrc = &(devinfo->infoStrings[0]);
	nsrc = sizeof(devinfo->infoStrings);
	x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
	p += x;
	remain -= x;
	chars += x;
	VBUSCHANNEL_ADDACHAR('\n', p, remain, chars);

	return chars;
}

#endif
