mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-13 23:14:46 +00:00
186 lines
4.3 KiB
C
186 lines
4.3 KiB
C
|
/*
|
||
|
* 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 <types/protocol_buffers.h>
|
||
|
|
||
|
#define PBUF_TYPE_VARINT 0
|
||
|
#define PBUF_TYPE_64BIT 1
|
||
|
#define PBUF_TYPE_LENGTH_DELIMITED 2
|
||
|
#define PBUF_TYPE_START_GROUP 3
|
||
|
#define PBUF_TYPE_STOP_GROUP 4
|
||
|
#define PBUF_TYPE_32BIT 5
|
||
|
|
||
|
#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
|
||
|
|
||
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
static inline int
|
||
|
protobuf_skip_varint(unsigned char **pos, size_t *len)
|
||
|
{
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
#endif /* _PROTO_PROTOCOL_BUFFERS_H */
|
||
|
|
||
|
/*
|
||
|
* Local variables:
|
||
|
* c-indent-level: 8
|
||
|
* c-basic-offset: 8
|
||
|
* End:
|
||
|
*/
|