/*
 * 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 <types/arg.h>
#include <types/protocol_buffers.h>
#include <proto/sample.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 > 70)
			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 > 70)
			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 > 70)
			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 > 70)
			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:
 */
