X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fdynamic-string.c;h=03efac074df77e224b5ce33fa078c7480222d47b;hb=refs%2Fheads%2Ffor-nox%2F0.4;hp=ca141783e27d5dbf76412f1f4b9ea41c52c70f91;hpb=0415ee1ac948dbedf76ce58dcd98aa934c2923f7;p=sliver-openvswitch.git diff --git a/lib/dynamic-string.c b/lib/dynamic-string.c index ca141783e..03efac074 100644 --- a/lib/dynamic-string.c +++ b/lib/dynamic-string.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include "timeval.h" #include "util.h" void @@ -52,6 +54,15 @@ ds_clear(struct ds *ds) ds->length = 0; } +void +ds_truncate(struct ds *ds, size_t new_length) +{ + if (ds->length > new_length) { + ds->length = new_length; + ds->string[new_length] = '\0'; + } +} + void ds_reserve(struct ds *ds, size_t min_length) { @@ -62,21 +73,38 @@ ds_reserve(struct ds *ds, size_t min_length) } } +char * +ds_put_uninit(struct ds *ds, size_t n) +{ + ds_reserve(ds, ds->length + n); + ds->length += n; + ds->string[ds->length] = '\0'; + return &ds->string[ds->length - n]; +} + void ds_put_char(struct ds *ds, char c) { - ds_reserve(ds, ds->length + 1); - ds->string[ds->length++] = c; - ds->string[ds->length] = '\0'; + *ds_put_uninit(ds, 1) = c; +} + +void +ds_put_char_multiple(struct ds *ds, char c, size_t n) +{ + memset(ds_put_uninit(ds, n), c, n); +} + +void +ds_put_buffer(struct ds *ds, const char *s, size_t n) +{ + memcpy(ds_put_uninit(ds, n), s, n); } void ds_put_cstr(struct ds *ds, const char *s) { size_t s_len = strlen(s); - ds_reserve(ds, ds->length + s_len); - memcpy(&ds->string[ds->length], s, s_len + 1); - ds->length += s_len; + memcpy(ds_put_uninit(ds, s_len), s, s_len); } void @@ -132,13 +160,47 @@ ds_put_printable(struct ds *ds, const char *s, size_t n) } } +void +ds_put_strftime(struct ds *ds, const char *template, const struct tm *tm) +{ + if (!tm) { + time_t now = time_now(); + tm = localtime(&now); + } + for (;;) { + size_t avail = ds->string ? ds->allocated - ds->length + 1 : 0; + size_t used = strftime(&ds->string[ds->length], avail, template, tm); + if (used) { + ds->length += used; + return; + } + ds_reserve(ds, ds->length + (avail < 32 ? 64 : 2 * avail)); + } +} + +int +ds_get_line(struct ds *ds, FILE *file) +{ + ds_clear(ds); + for (;;) { + int c = getc(file); + if (c == EOF) { + return ds->length ? 0 : EOF; + } else if (c == '\n') { + return 0; + } else { + ds_put_char(ds, c); + } + } +} + char * ds_cstr(struct ds *ds) { if (!ds->string) { ds_reserve(ds, 0); - ds->string[0] = '\0'; } + ds->string[ds->length] = '\0'; return ds->string; } @@ -200,3 +262,17 @@ ds_put_hex_dump(struct ds *ds, const void *buf_, size_t size, size -= n; } } + +int +ds_last(const struct ds *ds) +{ + return ds->length > 0 ? (unsigned char) ds->string[ds->length - 1] : EOF; +} + +void +ds_chomp(struct ds *ds, int c) +{ + if (ds->length > 0 && ds->string[ds->length - 1] == (char) c) { + ds->string[--ds->length] = '\0'; + } +}