/*
 * include/proto/protocol_buffers.h
 * This file contains functions and macros declarations for protocol buffers decoding.
 *
 * Copyright 2012 Willy Tarreau <w@1wt.eu>
 *
 * 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, version 2.1
 * exclusively.
 *
 * This library 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _PROTO_PROTOCOL_BUFFERS_H
#define _PROTO_PROTOCOL_BUFFERS_H

#include <inttypes.h>
#include <haproxy/arg-t.h>
#include <haproxy/sample-t.h>
#include <types/protocol_buffers.h>

#define PBUF_VARINT_DONT_STOP_BIT       7
#define PBUF_VARINT_DONT_STOP_BITMASK  (1 << PBUF_VARINT_DONT_STOP_BIT)
#define PBUF_VARINT_DATA_BITMASK            ~PBUF_VARINT_DONT_STOP_BITMASK

/* .skip and .smp_store prototypes. */
int protobuf_skip_varint(unsigned char **pos, size_t *len, size_t vlen);
int protobuf_smp_store_varint(struct sample *smp, int type,
                              unsigned char *pos, size_t len, size_t vlen);
int protobuf_skip_64bit(unsigned char **pos, size_t *len, size_t vlen);
int protobuf_smp_store_64bit(struct sample *smp, int type,
                             unsigned char *pos, size_t len, size_t vlen);
int protobuf_skip_vlen(unsigned char **pos, size_t *len, size_t vlen);
int protobuf_smp_store_vlen(struct sample *smp, int type,
                            unsigned char *pos, size_t len, size_t vlen);
int protobuf_skip_32bit(unsigned char **pos, size_t *len, size_t vlen);
int protobuf_smp_store_32bit(struct sample *smp, int type,
                             unsigned char *pos, size_t len, size_t vlen);

struct protobuf_parser_def protobuf_parser_defs [] = {
	[PBUF_TYPE_VARINT          ] = {
		.skip      = protobuf_skip_varint,
		.smp_store = protobuf_smp_store_varint,
	},
	[PBUF_TYPE_64BIT           ] = {
		.skip      = protobuf_skip_64bit,
		.smp_store = protobuf_smp_store_64bit,
	},
	[PBUF_TYPE_LENGTH_DELIMITED] = {
		.skip      = protobuf_skip_vlen,
		.smp_store = protobuf_smp_store_vlen,
	},
	[PBUF_TYPE_START_GROUP     ] = {
		/* XXX Deprecated XXX */
	},
	[PBUF_TYPE_STOP_GROUP      ] = {
		/* XXX Deprecated XXX */
	},
	[PBUF_TYPE_32BIT           ] = {
		.skip      = protobuf_skip_32bit,
		.smp_store = protobuf_smp_store_32bit,
	},
};

/*
 * Note that the field values with protocol buffers 32bit and 64bit fixed size as type
 * are sent in little-endian byte order to the network.
 */

/* Convert a little-endian ordered 32bit integer to the byte order of the host. */
static inline uint32_t pbuf_le32toh(uint32_t v)
{
	uint8_t *p = (uint8_t *)&v;
	return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24));
}

/* Convert a little-endian ordered 64bit integer to the byte order of the host. */
static inline uint64_t pbuf_le64toh(uint64_t v)
{
	return (uint64_t)(pbuf_le32toh(v >> 32)) << 32 | pbuf_le32toh(v);
}

/*
 * Return a protobuf type enum from <s> string if succedeed, -1 if not.
 */
int protobuf_type(const char *s)
{
	/* varint types. */
	if (!strcmp(s, "int32"))
		return PBUF_T_VARINT_INT32;
	else if (!strcmp(s, "uint32"))
		return PBUF_T_VARINT_UINT32;
	else if (!strcmp(s, "sint32"))
		return PBUF_T_VARINT_SINT32;
	else if (!strcmp(s, "int64"))
		return PBUF_T_VARINT_INT64;
	else if (!strcmp(s, "uint64"))
		return PBUF_T_VARINT_UINT64;
	else if (!strcmp(s, "sint64"))
		return PBUF_T_VARINT_SINT64;
	else if (!strcmp(s, "bool"))
		return PBUF_T_VARINT_BOOL;
	else if (!strcmp(s, "enum"))
		return PBUF_T_VARINT_ENUM;

	/* 32bit fixed size types. */
	else if (!strcmp(s, "fixed32"))
		return PBUF_T_32BIT_FIXED32;
	else if (!strcmp(s, "sfixed32"))
		return PBUF_T_32BIT_SFIXED32;
	else if (!strcmp(s, "float"))
		return PBUF_T_32BIT_FLOAT;

	/* 64bit fixed size types. */
	else if (!strcmp(s, "fixed64"))
		return PBUF_T_64BIT_FIXED64;
	else if (!strcmp(s, "sfixed64"))
		return PBUF_T_64BIT_SFIXED64;
	else if (!strcmp(s, "double"))
		return PBUF_T_64BIT_DOUBLE;
	else
		return -1;
}

/*
 * Decode a protocol buffers varint located in a buffer at <pos> address with
 * <len> as length. The decoded value is stored at <val>.
 * Returns 1 if succeeded, 0 if not.
 */
static inline int
protobuf_varint(uint64_t *val, unsigned char *pos, size_t len)
{
	unsigned int shift;

	*val = 0;
	shift = 0;

	while (len > 0) {
		int stop = !(*pos & PBUF_VARINT_DONT_STOP_BITMASK);

		*val |= ((uint64_t)(*pos & PBUF_VARINT_DATA_BITMASK)) << shift;

		++pos;
		--len;

		if (stop)
			break;
		else if (!len)
			return 0;

		shift += 7;
		/* The maximum length in bytes of a 64-bit encoded value is 10. */
		if (shift > 63)
			return 0;
	}

	return 1;
}

/*
 * Decode a protocol buffers varint located in a buffer at <pos> offset address with
 * <len> as length address. Update <pos> and <len> consequently. Decrease <*len>
 * by the number of decoded bytes. The decoded value is stored at <val>.
 * Returns 1 if succeeded, 0 if not.
 */
static inline int
protobuf_decode_varint(uint64_t *val, unsigned char **pos, size_t *len)
{
	unsigned int shift;

	*val = 0;
	shift = 0;

	while (*len > 0) {
		int stop = !(**pos & PBUF_VARINT_DONT_STOP_BITMASK);

		*val |= ((uint64_t)**pos & PBUF_VARINT_DATA_BITMASK) << shift;

		++*pos;
		--*len;

		if (stop)
			break;
		else if (!*len)
			return 0;

		shift += 7;
		/* The maximum length in bytes of a 64-bit encoded value is 10. */
		if (shift > 63)
			return 0;
	}

	return 1;
}

/*
 * Skip a protocol buffer varint found at <pos> as position address with <len>
 * as available length address. Update <*pos> to make it point to the next
 * available byte. Decrease <*len> by the number of skipped bytes.
 * Returns 1 if succeeded, 0 if not.
 */
int
protobuf_skip_varint(unsigned char **pos, size_t *len, size_t vlen)
{
	unsigned int shift;

	shift = 0;

	while (*len > 0) {
		int stop = !(**pos & PBUF_VARINT_DONT_STOP_BITMASK);

		++*pos;
		--*len;

		if (stop)
			break;
		else if (!*len)
			return 0;

		shift += 7;
		/* The maximum length in bytes of a 64-bit encoded value is 10. */
		if (shift > 63)
			return 0;
	}

	return 1;
}

/*
 * If succeeded, return the length of a prococol buffers varint found at <pos> as
 * position address, with <len> as address of the available bytes at <*pos>.
 * Update <*pos> to make it point to the next available byte. Decrease <*len>
 * by the number of bytes used to encode this varint.
 * Return -1 if failed.
 */
static inline int
protobuf_varint_getlen(unsigned char *pos, size_t len)
{
	unsigned char *spos;
	unsigned int shift;

	shift = 0;
	spos = pos;

	while (len > 0) {
		int stop = !(*pos & PBUF_VARINT_DONT_STOP_BITMASK);

		++pos;
		--len;

		if (stop)
			break;
		else if (!len)
			return -1;

		shift += 7;
		/* The maximum length in bytes of a 64-bit encoded value is 10. */
		if (shift > 63)
			return -1;
	}

	return pos - spos;
}

/*
 * Store a varint field value in a sample from <pos> buffer
 * with <len> available bytes after having decoded it if needed
 * depending on <type> the expected protocol buffer type of the field.
 * Return 1 if succeeded, 0 if not.
 */
int protobuf_smp_store_varint(struct sample *smp, int type,
                              unsigned char *pos, size_t len, size_t vlen)
{
	switch (type) {
	case PBUF_T_BINARY:
	{
		int varint_len;

		varint_len = protobuf_varint_getlen(pos, len);
		if (varint_len == -1)
			return 0;

		smp->data.type = SMP_T_BIN;
		smp->data.u.str.area = (char *)pos;
		smp->data.u.str.data = varint_len;
		smp->flags = SMP_F_VOL_TEST;
		break;
	}

	case PBUF_T_VARINT_INT32 ... PBUF_T_VARINT_ENUM:
	{
		uint64_t varint;

		if (!protobuf_varint(&varint, pos, len))
			return 0;

		smp->data.u.sint = varint;
		smp->data.type = SMP_T_SINT;
		break;
	}

	case PBUF_T_VARINT_SINT32 ... PBUF_T_VARINT_SINT64:
	{
		uint64_t varint;

		if (!protobuf_varint(&varint, pos, len))
			return 0;

		/* zigzag decoding. */
		smp->data.u.sint = (varint >> 1) ^ -(varint & 1);
		smp->data.type = SMP_T_SINT;
		break;
	}

	default:
		return 0;

	}

	return 1;
}

/*
 * Move forward <*pos> buffer by 8 bytes. Used to skip a 64bit field.
 */
int protobuf_skip_64bit(unsigned char **pos, size_t *len, size_t vlen)
{
	if (*len < sizeof(uint64_t))
	    return 0;

	*pos += sizeof(uint64_t);
	*len -= sizeof(uint64_t);

	return 1;
}

/*
 * Store a fixed size 64bit field value in a sample from <pos> buffer
 * with <len> available bytes after having decoded it depending on <type>
 * the expected protocol buffer type of the field.
 * Return 1 if succeeded, 0 if not.
 */
int protobuf_smp_store_64bit(struct sample *smp, int type,
                             unsigned char *pos, size_t len, size_t vlen)
{
	if (len < sizeof(uint64_t))
	    return 0;

	switch (type) {
	case PBUF_T_BINARY:
		smp->data.type = SMP_T_BIN;
		smp->data.u.str.area = (char *)pos;
		smp->data.u.str.data = sizeof(uint64_t);
		smp->flags = SMP_F_VOL_TEST;
		break;

	case PBUF_T_64BIT_FIXED64:
	case PBUF_T_64BIT_SFIXED64:
		smp->data.type = SMP_T_SINT;
		smp->data.u.sint = pbuf_le64toh(*(uint64_t *)pos);
		smp->flags = SMP_F_VOL_TEST;
		break;

	case PBUF_T_64BIT_DOUBLE:
		smp->data.type = SMP_T_SINT;
		smp->data.u.sint = pbuf_le64toh(*(double *)pos);
		smp->flags = SMP_F_VOL_TEST;
		break;

	default:
		return 0;
	}

	return 1;
}

/*
 * Move forward <*pos> buffer by <vlen> bytes. Use to skip a length-delimited
 * field.
 */
int protobuf_skip_vlen(unsigned char **pos, size_t *len, size_t vlen)
{
	if (*len < vlen)
		return 0;

	*pos += vlen;
	*len -= vlen;

	return 1;
}

/*
 * Store a <vlen>-bytes length-delimited field value in a sample from <pos>
 * buffer with <len> available bytes.
 * Return 1 if succeeded, 0 if not.
 */
int protobuf_smp_store_vlen(struct sample *smp, int type,
                            unsigned char *pos, size_t len, size_t vlen)
{
	if (len < vlen)
		return 0;

	if (type != PBUF_T_BINARY)
		return 0;

	smp->data.type = SMP_T_BIN;
	smp->data.u.str.area = (char *)pos;
	smp->data.u.str.data = vlen;
	smp->flags = SMP_F_VOL_TEST;

	return 1;
}

/*
 * Move forward <*pos> buffer by 4 bytes. Used to skip a 32bit field.
 */
int protobuf_skip_32bit(unsigned char **pos, size_t *len, size_t vlen)
{
	if (*len < sizeof(uint32_t))
	    return 0;

	*pos += sizeof(uint32_t);
	*len -= sizeof(uint32_t);

	return 1;
}

/*
 * Store a fixed size 32bit field value in a sample from <pos> buffer
 * with <len> available bytes after having decoded it depending on <type>
 * the expected protocol buffer type of the field.
 * Return 1 if succeeded, 0 if not.
 */
int protobuf_smp_store_32bit(struct sample *smp, int type,
                             unsigned char *pos, size_t len, size_t vlen)
{
	if (len < sizeof(uint32_t))
	    return 0;

	switch (type) {
	case PBUF_T_BINARY:
		smp->data.type = SMP_T_BIN;
		smp->data.u.str.area = (char *)pos;
		smp->data.u.str.data = sizeof(uint32_t);
		smp->flags = SMP_F_VOL_TEST;
		break;

	case PBUF_T_32BIT_FIXED32:
		smp->data.type = SMP_T_SINT;
		smp->data.u.sint = pbuf_le32toh(*(uint32_t *)pos);
		smp->flags = SMP_F_VOL_TEST;
		break;

	case PBUF_T_32BIT_SFIXED32:
		smp->data.type = SMP_T_SINT;
		smp->data.u.sint = (int32_t)pbuf_le32toh(*(uint32_t *)pos);
		smp->flags = SMP_F_VOL_TEST;
		break;

	case PBUF_T_32BIT_FLOAT:
		smp->data.type = SMP_T_SINT;
		smp->data.u.sint = pbuf_le32toh(*(float *)pos);
		smp->flags = SMP_F_VOL_TEST;
		break;

	default:
		return 0;
	}

	return 1;
}

/*
 * Lookup for a protocol buffers field whose parameters are provided by <arg_p>
 * first argument in the buffer with <pos> as address and <len> as length address.
 * If found, store its value depending on the type of storage to use provided by <arg_p>
 * second argument and return 1, 0 if not.
 */
static inline int protobuf_field_lookup(const struct arg *arg_p, struct sample *smp,
                                        unsigned char **pos, size_t *len)
{
	unsigned int *fid;
	size_t fid_sz;
	int type;
	uint64_t elen;
	int field;

	fid = arg_p[0].data.fid.ids;
	fid_sz = arg_p[0].data.fid.sz;
	type = arg_p[1].data.sint;

	/* Length of the length-delimited messages if any. */
	elen = 0;
	field = 0;

	while (field < fid_sz) {
		int found;
		uint64_t key, sleft;
		struct protobuf_parser_def *pbuf_parser = NULL;
		unsigned int wire_type, field_number;

		if ((ssize_t)*len <= 0)
			return 0;

		/* Remaining bytes saving. */
		sleft = *len;

		/* Key decoding */
		if (!protobuf_decode_varint(&key, pos, len))
			return 0;

		wire_type = key & 0x7;
		field_number = key >> 3;
		found = field_number == fid[field];

		/* Skip the data if the current field does not match. */
		switch (wire_type) {
		case PBUF_TYPE_VARINT:
		case PBUF_TYPE_32BIT:
		case PBUF_TYPE_64BIT:
			pbuf_parser = &protobuf_parser_defs[wire_type];
			if (!found && !pbuf_parser->skip(pos, len, 0))
				return 0;
			break;

		case PBUF_TYPE_LENGTH_DELIMITED:
			/* Decode the length of this length-delimited field. */
			if (!protobuf_decode_varint(&elen, pos, len) || elen > *len)
				return 0;

			/* The size of the current field is computed from here to skip
			 * the bytes used to encode the previous length.*
			 */
			sleft = *len;
			pbuf_parser = &protobuf_parser_defs[wire_type];
			if (!found && !pbuf_parser->skip(pos, len, elen))
				return 0;
			break;

		default:
			return 0;
		}

		/* Store the data if found. Note that <pbuf_parser> is not NULL */
		if (found && field == fid_sz - 1)
			return pbuf_parser->smp_store(smp, type, *pos, *len, elen);

		if ((ssize_t)(elen) > 0)
			elen -= sleft - *len;

		if (found) {
			field++;
		}
		else if ((ssize_t)elen <= 0) {
			field = 0;
		}
	}

	return 0;
}

#endif /* _PROTO_PROTOCOL_BUFFERS_H */

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */
