#ifndef _HCLINK_H_
#define _HCLINK_H_
#define HC_BUFSIZE 65536
struct HCHostDesc {
struct HCHostDesc *next;
intptr_t desc;
int type;
void *data;
};
struct HostConf;
typedef struct HCTransaction {
char rbuf[HC_BUFSIZE];
char wbuf[HC_BUFSIZE];
struct HostConf *hc;
uint16_t id;
int swap;
int windex;
enum { HCT_IDLE, HCT_SENT, HCT_REPLIED, HCT_DONE, HCT_FAIL } state;
} *hctransaction_t;
struct HostConf {
char *host;
int fdin;
int fdout;
int error;
pid_t pid;
int version;
struct HCHostDesc *hostdescs;
struct HCTransaction trans;
};
struct HCHead {
int32_t magic;
int32_t bytes;
int16_t cmd;
uint16_t id;
int32_t error;
} __aligned(8);
#define HCMAGIC 0x48435052
#define HCC_ALIGN(bytes) (((bytes) + 7) & ~7)
struct HCLeaf {
int16_t leafid;
int16_t reserved;
int32_t bytes;
} __aligned(8);
#define HCF_CONTINUE 0x4000
#define HCF_REPLY 0x8000
#define LCF_TYPEMASK 0x0F00
#define LCF_INT32 0x0100
#define LCF_INT64 0x0200
#define LCF_STRING 0x0300
#define LCF_BINARY 0x0F00
struct HCDesc {
int16_t cmd;
int (*func)(hctransaction_t, struct HCHead *);
};
#define HCC_STRING(item) ((const char *)((item) + 1))
#define HCC_INT32(item) (*(int32_t *)((item) + 1))
#define HCC_INT64(item) (*(int64_t *)((item) + 1))
#define HCC_BINARYDATA(item) ((void *)((item) + 1))
#define FOR_EACH_ITEM(item, trans, head) \
for (item = hcc_firstitem(trans, head); item; \
item = hcc_nextitem(trans, head, item))
int hcc_connect(struct HostConf *hc, int readonly);
int hcc_slave(int fdin, int fdout, struct HCDesc *descs, int count);
struct HCHead *hcc_read_command(struct HostConf *hc, hctransaction_t trans);
hctransaction_t hcc_start_command(struct HostConf *hc, int16_t cmd);
struct HCHead *hcc_finish_command(hctransaction_t trans);
void hcc_leaf_string(hctransaction_t trans, int16_t leafid, const char *str);
void hcc_leaf_data(hctransaction_t trans, int16_t leafid, const void *ptr, int bytes);
void hcc_leaf_int32(hctransaction_t trans, int16_t leafid, int32_t value);
void hcc_leaf_int64(hctransaction_t trans, int16_t leafid, int64_t value);
int hcc_check_space(hctransaction_t trans, struct HCHead *head, int n, int size);
intptr_t hcc_alloc_descriptor(struct HostConf *hc, void *ptr, int type);
void *hcc_get_descriptor(struct HostConf *hc, intptr_t desc, int type);
void hcc_set_descriptor(struct HostConf *hc, intptr_t desc, void *ptr, int type);
struct HCLeaf *hcc_nextitem(hctransaction_t trans, struct HCHead *head, struct HCLeaf *item);
#define hcc_firstitem(trans, head) hcc_nextitem(trans, head, NULL)
struct HCLeaf *hcc_nextchaineditem(struct HostConf *hc, struct HCHead *head);
struct HCLeaf *hcc_currentchaineditem(struct HostConf *hc, struct HCHead *head);
void hcc_debug_dump(struct HCHead *head);
#endif