Implement capn_write_fd
This commit is contained in:
parent
440c662c66
commit
2bdc5c476a
2 changed files with 97 additions and 0 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
struct check_segment_alignment {
|
struct check_segment_alignment {
|
||||||
unsigned int foo : (sizeof(struct capn_segment)&7) ? -1 : 1;
|
unsigned int foo : (sizeof(struct capn_segment)&7) ? -1 : 1;
|
||||||
|
|
@ -276,3 +277,98 @@ capn_write_mem(struct capn *c, uint8_t *p, size_t sz, int packed)
|
||||||
|
|
||||||
return headersz+datasz;
|
return headersz+datasz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _write_fd(ssize_t (*write_fd)(int fd, void *p, size_t count), int fd, void *p, size_t count)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int sent = 0;
|
||||||
|
|
||||||
|
while (sent < count) {
|
||||||
|
ret = write_fd(fd, ((uint8_t*)p)+sent, count-sent);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sent += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int capn_write_fd(struct capn *c, ssize_t (*write_fd)(int fd, void *p, size_t count), int fd, int packed)
|
||||||
|
{
|
||||||
|
unsigned char buf[4096];
|
||||||
|
struct capn_segment *seg;
|
||||||
|
struct capn_ptr root;
|
||||||
|
uint32_t headerlen;
|
||||||
|
size_t headersz, datasz = 0;
|
||||||
|
int ret;
|
||||||
|
struct capn_stream z;
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
if (c->segnum == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
root = capn_root(c);
|
||||||
|
header_calc(c, &headerlen, &headersz);
|
||||||
|
|
||||||
|
if (sizeof(buf) < headersz)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = header_render(c, root.seg, (uint32_t*)buf, headerlen, &datasz);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (packed) {
|
||||||
|
const int headerrem = sizeof(buf) - headersz;
|
||||||
|
const int maxpack = headersz + 2;
|
||||||
|
if (headerrem < maxpack)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(&z, 0, sizeof(z));
|
||||||
|
z.next_in = buf;
|
||||||
|
z.avail_in = headersz;
|
||||||
|
z.next_out = buf + headersz;
|
||||||
|
z.avail_out = headerrem;
|
||||||
|
ret = capn_deflate(&z);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
p = buf + headersz;
|
||||||
|
headersz = headerrem - z.avail_out;
|
||||||
|
} else {
|
||||||
|
p = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _write_fd(write_fd, fd, p, headersz);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
datasz = headersz;
|
||||||
|
for (seg = root.seg; seg; seg = seg->next) {
|
||||||
|
size_t bufsz;
|
||||||
|
if (packed) {
|
||||||
|
memset(&z, 0, sizeof(z));
|
||||||
|
z.next_in = (uint8_t*)seg->data;
|
||||||
|
z.avail_in = seg->len;
|
||||||
|
z.next_out = buf;
|
||||||
|
z.avail_out = sizeof(buf);
|
||||||
|
ret = capn_deflate(&z);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
p = buf;
|
||||||
|
bufsz = sizeof(buf) - z.avail_out;
|
||||||
|
} else {
|
||||||
|
p = (uint8_t*)seg->data;
|
||||||
|
bufsz = seg->len;
|
||||||
|
}
|
||||||
|
ret = _write_fd(write_fd, fd, p, bufsz);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
datasz += bufsz;
|
||||||
|
}
|
||||||
|
|
||||||
|
return datasz;
|
||||||
|
}
|
||||||
|
|
|
||||||
1
capn.h
1
capn.h
|
|
@ -246,6 +246,7 @@ int capn_init_mem(struct capn *c, const uint8_t *p, size_t sz, int packed);
|
||||||
*/
|
*/
|
||||||
/* TODO */
|
/* TODO */
|
||||||
/*int capn_write_fp(struct capn *c, FILE *f, int packed);*/
|
/*int capn_write_fp(struct capn *c, FILE *f, int packed);*/
|
||||||
|
int capn_write_fd(struct capn *c, ssize_t (*write_fd)(int fd, void *p, size_t count), int fd, int packed);
|
||||||
int capn_write_mem(struct capn *c, uint8_t *p, size_t sz, int packed);
|
int capn_write_mem(struct capn *c, uint8_t *p, size_t sz, int packed);
|
||||||
|
|
||||||
void capn_free(struct capn *c);
|
void capn_free(struct capn *c);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue