char *databuf_export(DataBuf *db) { DATABUF_VALIDATE(db); databuf_shift_data_to_beginning(db); DATABUF_VALIDATE(db); return db->alloc_ptr; }
static int databuf_strcat(DataBuf *db, const char *str) { size_t str_len; DATABUF_VALIDATE(db); if (str == NULL) return 0; // +1 so the data append also copies the NULL terminator str_len = strlen(str) + 1; // If there is a NULL terminator exclude it so the subsequent // data append produces a proper string concatenation if (db->len > 0) { char *last_char = databuf_end(db) - 1; if (*last_char == 0) { db->len--; // backup over NULL terminator } } // Copy string and NULL terminator databuf_append(db, str, str_len); DATABUF_VALIDATE(db); return 1; }
static int databuf_shift_data_to_beginning(DataBuf *db) { DATABUF_VALIDATE(db); if (db->flags & DATABUF_FLAG_PRESERVE_HEAD) return -1; if (databuf_beg(db) == NULL) return 1; if (db->offset) { memmove(db->alloc_ptr, databuf_beg(db), db->len); db->offset = 0; } DATABUF_VALIDATE(db); return 1; }
void databuf_free(DataBuf *db) { DATABUF_VALIDATE(db); if (db->alloc_ptr != NULL) { free(db->alloc_ptr); } db->alloc_ptr = NULL; db->alloc_size = 0; db->offset = 0; db->len = 0; db->max_len = 0; DATABUF_VALIDATE(db); }
int databuf_append(DataBuf *db, const char *src, size_t src_size) { size_t new_size; DATABUF_VALIDATE(db); if (src == NULL || src_size == 0) return 0; new_size = db->len+src_size; #ifdef DEBUG if (debug) databuf_print(db, 1, "databuf_append() size=%zd", src_size); #endif if ((new_size > db->alloc_size) || ((db->flags & DATABUF_FLAG_PRESERVE_HEAD) && !databuf_tail_available(db, src_size))) { /* not enough room, we must realloc */ void *new_alloc; databuf_shift_data_to_beginning(db); if ((new_alloc = realloc(db->alloc_ptr, new_size))) { db->alloc_ptr = new_alloc; db->alloc_size = new_size; } else { return -1; /* realloc failed */ } } else { /* we can fit within current allocation, but can we append? */ if (!databuf_tail_available(db, src_size)) { /* we can't append in place, must create room at tail by shifting data forward to the beginning of the allocation block */ databuf_shift_data_to_beginning(db); } } #ifdef DEBUG if (debug) databuf_print(db, 1, "databuf_append() about to memmove()"); #endif /* pointers all set up and room availble, move the data and update */ memmove(databuf_end(db), src, src_size); db->len = new_size; db->max_len = MAX(db->max_len, new_size); #ifdef DEBUG if (debug) databuf_print(db, 1, "databuf_append() conclusion"); #endif DATABUF_VALIDATE(db); return 1; }
int databuf_compress(DataBuf *db) { void *new_alloc; DATABUF_VALIDATE(db); if (databuf_beg(db) == NULL || db->len == 0) return 0; databuf_shift_data_to_beginning(db); if ((new_alloc = realloc(db->alloc_ptr, db->len))) { db->alloc_ptr = new_alloc; db->alloc_size = db->len; } else { return -1; /* realloc failed */ } DATABUF_VALIDATE(db); return 1; }
int databuf_advance(DataBuf *db, size_t advance) { size_t actual_advance; DATABUF_VALIDATE(db); if (debug) databuf_print(db, 1, "databuf_advance() enter, advance=%d", advance); actual_advance = MIN(advance, db->len); db->offset += actual_advance; db->len -= actual_advance; if (debug) databuf_print(db, 1, "databuf_advance() leave, actual_advance=%d", actual_advance); DATABUF_VALIDATE(db); if (advance == actual_advance) { return 1; } else { errno = ESPIPE; // Illegal seek return -1; } }