Add C runtime

This commit is contained in:
James McKaskill 2013-04-23 01:06:10 -04:00
commit a0f30f5604
2 changed files with 986 additions and 0 deletions

145
capn.h Normal file
View file

@ -0,0 +1,145 @@
/* vim: set sw=8 ts=8 sts=8 noet: */
#ifndef CAPN_H
#define CAPN_H
#include <stdint.h>
enum CAPN_TYPE {
CAPN_NULL = 0,
CAPN_FAR = 2,
CAPN_DOUBLE_FAR = 6,
CAPN_STRUCT = 7,
CAPN_VOID_LIST = 8,
CAPN_1BIT_LIST = 9,
CAPN_1BYTE_LIST = 10,
CAPN_2BYTE_LIST = 11,
CAPN_4BYTE_LIST = 12,
CAPN_8BYTE_LIST = 13,
CAPN_POINTER_LIST = 14,
CAPN_COMPOSITE_LIST = 15,
};
struct capn_ptr {
/* should not be used unless capn_deref_ptr has been called first */
enum CAPN_TYPE type;
int elements;
/* rest is private */
union {
struct {
uint16_t datasz;
uint16_t ptrsz;
} s;
uint32_t id;
} u;
struct capn_segment *seg;
char *data;
};
int capn_deref_ptr(struct capn_ptr*);
/* length is optional and can be set to NULL */
char *capn_to_string(struct capn_ptr*, int *length);
/* capn_*_struct reads/writes data to a from a struct. These should not be
* called directly, but read|write_TYPE should be called instead (created by
* the generator).
*
* WARNING: Fields in structs are always in little endian format. Use
* capn_to_* when dealing with struct fields.
*/
void capn_read_struct(struct capn_ptr*, void *p, int data, int ptrs);
void capn_write_struct(struct capn_ptr*, const void *p, int data, int ptrs);
/* capn_read_* functions are read data from a list.
*
* The length of the list is given by capn_elements. off specifies how far
* into the list to start, sz indicates the number of elements to read.
*
* With capn_read_1 off and sz are in bytes (_not_ bits).
* Bits read are in little endian (lowest bit first) order.
*
* If off+sz > elements in list, then only elements up to the end of the list
* will be read.
*
* Data read is in native byte order.
*/
void capn_read_1(struct capn_ptr*, int off, uint8_t*, int sz);
void capn_read_8(struct capn_ptr*, int off, uint8_t*, int sz);
void capn_read_16(struct capn_ptr*, int off, uint16_t*, int sz);
void capn_read_32(struct capn_ptr*, int off, uint32_t*, int sz);
void capn_read_64(struct capn_ptr*, int off, uint64_t*, int sz);
struct capn_ptr capn_read_ptr(struct capn_ptr*, int off);
/* capn_write_* functions write data to a list.
*
* Only up to the end of the list is written as given by capn_elemnts.
*
* With capn_write_1 off and sz are in bytes (_not_ bits). Bits are presented
* in little endian (lowest bit and lowest byte first).
*
* Data provided should be in native byte order.
*/
void capn_write_1(struct capn_ptr*, int off, const void*, int sz);
void capn_write_8(struct capn_ptr*, int off, const uint8_t*, int sz);
void capn_write_16(struct capn_ptr*, int off, const uint16_t*, int sz);
void capn_write_32(struct capn_ptr*, int off, const uint32_t*, int sz);
void capn_write_64(struct capn_ptr*, int off, const uint64_t*, int sz);
int capn_write_ptr(struct capn_ptr*, int off, struct capn_ptr *to);
struct capn_ptr capn_new_struct(struct capn_segment*, int datasz, int ptrs, int want_tag);
struct capn_ptr capn_new_list(struct capn_segment*, enum CAPN_TYPE, int sz, int want_tag);
struct capn_ptr capn_new_composite(struct capn_segment*, int elems, int datasz, int ptrs, int want_tag);
/* use sz == -1 for null terminated string */
struct capn_ptr capn_new_string(struct capn_segment*, const char *s, int sz, int want_tag);
int capn_copy(struct capn_ptr *to, struct capn_ptr *from);
typedef struct capn_segment *(*capn_create_t)(void* /*user*/, int /*sz*/);
typedef struct capn_segment *(*capn_lookup_t)(void* /*user*/, uint32_t /*id*/);
struct capn *capn_new(void);
void capn_free(struct capn*);
void capn_add(struct capn*, struct capn_segment*);
void capn_set_lookup(struct capn*, capn_lookup_t lookup, void *user);
void capn_set_create(struct capn*, capn_create_t create, void *user);
struct capn_segment *capn_new_segment(void *data, int len, int cap, void (*free)(void*));
#define T(IDX) s.v[IDX] = (uint8_t) (v >> (8*IDX))
#define F(SZ, IDX) ((uint ## SZ ## _t) (s.v[IDX]) << (IDX*8))
static uint16_t capn_to_le_16(uint16_t v) {
union { uint16_t u; uint8_t v[2]; } s;
T(0); T(1);
return s.u;
}
static uint32_t capn_to_le_32(uint32_t v) {
union { uint32_t u; uint16_t v[2]; } s;
T(0); T(1); T(2); T(3);
return s.u;
}
static uint64_t capn_to_le_64(uint64_t v) {
union { uint64_t u; uint32_t v[2]; } s;
T(0); T(1); T(2); T(3); T(4); T(5); T(6); T(7);
return s.u;
}
static uint16_t capn_from_le_16(uint16_t v) {
union { uint16_t u; uint8_t v[2]; } s;
s.u = v;
return F(16, 1) | F(16, 0);
}
static uint32_t capn_from_le_32(uint32_t v) {
union { uint32_t u; uint8_t v[4]; } s;
s.u = v;
return F(32, 3) | F(32, 2) | F(32, 1) | F(32, 0);
}
static uint64_t capn_from_le_64(uint64_t v) {
union { uint64_t u; uint8_t v[8]; } s;
s.u = v;
return F(64,7) | F(64,6) | F(64,5) | F(64,4) | F(64,3) | F(64,2) | F(64,1) | F(64,0);
}
#undef T
#undef F
#endif