/* * Write the first <size> bytes of <data> to <fd>, for which the disOnData function must have been * called previously. You may write to <fd> via any other means, but if you use this function the * data will be written out, possibly piece by piece but always without blocking, when the given * file descriptor becomes writable. */ void disWrite(Dispatcher *dis, int fd, const char *data, size_t size) { DIS_File *file = paGet(&dis->files, fd); dbgAssert(stderr, file != NULL, "unknown file descriptor: %d\n", fd); bufAdd(&file->outgoing, data, size); }
static void ns_handle_data(Dispatcher *dis, int fd, void *udata) { char data[9000]; NS *ns = (NS *) dis; NS_Connection *conn = paGet(&ns->connections, fd); int n; P dbgPrint(stderr, "Reading from fd %d...\n", fd); n = read(fd, data, sizeof(data)); P dbgPrint(stderr, "read() returned %d.\n", n); if (n > 0) { P dbgPrint(stderr, "Adding to incoming buffer.\n"); bufAdd(&conn->incoming, data, n); if (ns->on_socket_cb != NULL) { P dbgPrint(stderr, "Calling on_socket_cb.\n"); ns->on_socket_cb(ns, fd, bufGet(&conn->incoming), bufLen(&conn->incoming), ns->on_socket_udata); } } else if (n == 0) { P dbgPrint(stderr, "End of file, disconnecting.\n"); nsDisconnect(ns, fd); if (ns->on_disconnect_cb != NULL) { P dbgPrint(stderr, "Calling on_disconnect_cb.\n"); ns->on_disconnect_cb(ns, fd, ns->on_disconnect_udata); } } else { P dbgPrint(stderr, "Error, disconnecting.\n"); nsDisconnect(ns, fd); if (ns->on_error_cb != NULL) { P dbgPrint(stderr, "Calling on_error_cb.\n"); ns->on_error_cb(ns, fd, errno, ns->on_error_udata); } } }
int main(int argc, char *argv[]) { Buffer buf1 = { 0 }; Buffer buf2 = { 0 }; Buffer *buf3; bufClear(&buf1); make_sure_that(bufLen(&buf1) == 0); make_sure_that(bufIsEmpty(&buf1)); bufAdd(&buf1, "ABCDEF", 3); make_sure_that(bufLen(&buf1) == 3); make_sure_that(!bufIsEmpty(&buf1)); make_sure_that(strcmp(bufGet(&buf1), "ABC") == 0); bufAddC(&buf1, 'D'); make_sure_that(bufLen(&buf1) == 4); make_sure_that(strcmp(bufGet(&buf1), "ABCD") == 0); bufAddF(&buf1, "%d", 1234); make_sure_that(bufLen(&buf1) == 8); make_sure_that(strcmp(bufGet(&buf1), "ABCD1234") == 0); bufAddS(&buf1, "XYZ"); make_sure_that(bufLen(&buf1) == 11); make_sure_that(strcmp(bufGet(&buf1), "ABCD1234XYZ") == 0); bufSet(&buf1, "ABCDEF", 3); make_sure_that(bufLen(&buf1) == 3); make_sure_that(strcmp(bufGet(&buf1), "ABC") == 0); bufSetC(&buf1, 'D'); make_sure_that(bufLen(&buf1) == 1); make_sure_that(strcmp(bufGet(&buf1), "D") == 0); bufSetF(&buf1, "%d", 1234); make_sure_that(bufLen(&buf1) == 4); make_sure_that(strcmp(bufGet(&buf1), "1234") == 0); bufSetS(&buf1, "ABCDEF"); make_sure_that(bufLen(&buf1) == 6); make_sure_that(strcmp(bufGet(&buf1), "ABCDEF") == 0); bufClear(&buf1); make_sure_that(bufLen(&buf1) == 0); make_sure_that(strcmp(bufGet(&buf1), "") == 0); bufSet(&buf1, "ABC", 3); bufSet(&buf2, "DEF", 3); buf3 = bufCat(&buf1, &buf2); make_sure_that(&buf1 == buf3); make_sure_that(bufLen(&buf1) == 6); make_sure_that(strcmp(bufGet(&buf1), "ABCDEF") == 0); make_sure_that(bufLen(&buf2) == 3); make_sure_that(strcmp(bufGet(&buf2), "DEF") == 0); bufSetF(&buf1, "ABCDEF"); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 0, 0)), "ABCDEF") == 0); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 1, 0)), "BCDEF") == 0); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 0, 1)), "BCDE") == 0); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 1, 1)), "CD") == 0); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 3, 3)), "") == 0); bufPack(&buf1, PACK_INT8, 0x01, PACK_INT16, 0x0123, PACK_INT32, 0x01234567, PACK_INT64, 0x0123456789ABCDEF, PACK_FLOAT, 0.0, PACK_DOUBLE, 0.0, PACK_STRING, "Hoi1", PACK_DATA, "Hoi2", 4, PACK_RAW, "Hoi3", 4, END); make_sure_that(bufLen(&buf1) == 47); make_sure_that(memcmp(bufGet(&buf1), "\x01" "\x01\x23" "\x01\x23\x45\x67" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x04Hoi1" "\x00\x00\x00\x04Hoi2" "Hoi3", 47) == 0); { uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64; float f32; double f64; char *string, *data, raw[4]; int data_size; bufUnpack(&buf1, PACK_INT8, &u8, PACK_INT16, &u16, PACK_INT32, &u32, PACK_INT64, &u64, PACK_FLOAT, &f32, PACK_DOUBLE, &f64, PACK_STRING, &string, PACK_DATA, &data, &data_size, PACK_RAW, &raw, sizeof(raw), END); make_sure_that(u8 == 0x01); make_sure_that(u16 == 0x0123); make_sure_that(u32 == 0x01234567); make_sure_that(u64 == 0x0123456789ABCDEF); make_sure_that(f32 == 0.0); make_sure_that(f64 == 0.0); make_sure_that(memcmp(string, "Hoi1", 5) == 0); make_sure_that(memcmp(data, "Hoi2", 4) == 0); make_sure_that(data_size == 4); make_sure_that(memcmp(raw, "Hoi3", 4) == 0); } { bufUnpack(&buf1, PACK_INT8, NULL, PACK_INT16, NULL, PACK_INT32, NULL, PACK_INT64, NULL, PACK_FLOAT, NULL, PACK_DOUBLE, NULL, PACK_STRING, NULL, PACK_DATA, NULL, NULL, PACK_RAW, NULL, 4, END); } { const char *name[] = { "Mills", "Berry", "Buck", "Stipe" }; bufClear(&buf1); bufList(&buf1, ", ", " and ", TRUE, TRUE, "%s", name[0]); make_sure_that(strcmp(bufGet(&buf1), "Mills") == 0); bufClear(&buf1); bufList(&buf1, ", ", " and ", TRUE, FALSE, "%s", name[0]); bufList(&buf1, ", ", " and ", FALSE, TRUE, "%s", name[1]); make_sure_that(strcmp(bufGet(&buf1), "Mills and Berry") == 0); bufClear(&buf1); bufList(&buf1, ", ", " and ", TRUE, FALSE, "%s", name[0]); bufList(&buf1, ", ", " and ", FALSE, FALSE, "%s", name[1]); bufList(&buf1, ", ", " and ", FALSE, TRUE, "%s", name[2]); make_sure_that(strcmp(bufGet(&buf1), "Mills, Berry and Buck") == 0); bufClear(&buf1); bufList(&buf1, ", ", " and ", TRUE, FALSE, "%s", name[0]); bufList(&buf1, ", ", " and ", FALSE, FALSE, "%s", name[1]); bufList(&buf1, ", ", " and ", FALSE, FALSE, "%s", name[2]); bufList(&buf1, ", ", " and ", FALSE, TRUE, "%s", name[3]); make_sure_that(strcmp(bufGet(&buf1), "Mills, Berry, Buck and Stipe") == 0); } bufReset(&buf1); bufReset(&buf2); return errors; }
/* * Concatenate <addition> onto <base> and return <base>. */ Buffer *bufCat(Buffer *base, const Buffer *addition) { bufAdd(base, bufGet(addition), bufLen(addition)); return base; }
/* * Set <buf> to the single character <c>. */ Buffer *bufSetC(Buffer *buf, char c) { bufClear(buf); return bufAdd(buf, &c, 1); }
/* * Replace <buf> with the <len> bytes starting at <data>. */ Buffer *bufSet(Buffer *buf, const void *data, size_t len) { bufClear(buf); return bufAdd(buf, data, len); }
/* * Append the null-terminated string <str> to <buf>. */ Buffer *bufAddS(Buffer *buf, const char *str) { return bufAdd(buf, str, strlen(str)); }
/* * Add the single character <c> to <buf>. */ Buffer *bufAddC(Buffer *buf, char c) { bufAdd(buf, &c, 1); return buf; }