/** * @brief Merges two dbuffers * @param[in] old the source buffer * @param[in] old2 the second source buffer * @return the newly allocated buffer * Allocates a new dbuffer and initialises it to contain a copy of the * data in old ones */ struct dbuffer *dbuffer_merge (struct dbuffer *old, struct dbuffer *old2) { /* element we're currently reading from */ const struct dbuffer_element *e; struct dbuffer *buf = new_dbuffer(); const char *p; e = old->head; p = old->start; while (e && (e->len > 0)) { dbuffer_add(buf, p, e->len); e = e->next; p = &e->data[0]; } e = old2->head; p = old2->start; while (e && (e->len > 0)) { dbuffer_add(buf, p, e->len); e = e->next; p = &e->data[0]; } return buf; }
static void testDBuffer (void) { int i; const int size = 10000000; dbuffer* buf = new_dbuffer(); char data[128]; size_t dataSize = sizeof(data); for (i = 0; i < size; i++) dbuffer_add(buf, "b", 1); CU_ASSERT_EQUAL(size, dbuffer_len(buf)); CU_ASSERT_EQUAL(dataSize, dbuffer_get(buf, data, dataSize)); CU_ASSERT_EQUAL(size, dbuffer_len(buf)); CU_ASSERT_EQUAL(dataSize, dbuffer_extract(buf, data, dataSize)); CU_ASSERT_EQUAL(size - dataSize, dbuffer_len(buf)); free_dbuffer(buf); buf = new_dbuffer(); dbuffer_add(buf, "b", 1); CU_ASSERT_EQUAL(1, dbuffer_len(buf)); CU_ASSERT_EQUAL(1, dbuffer_get(buf, data, dataSize)); CU_ASSERT_EQUAL(1, dbuffer_len(buf)); CU_ASSERT_EQUAL(1, dbuffer_extract(buf, data, dataSize)); CU_ASSERT_EQUAL(0, dbuffer_len(buf)); buf = dbuffer_dup(buf); CU_ASSERT_EQUAL(0, dbuffer_len(buf)); for (i = 0; i <= dataSize; i++) dbuffer_add(buf, "b", 1); CU_ASSERT_EQUAL(dataSize + 1, dbuffer_len(buf)); CU_ASSERT_EQUAL(dataSize, dbuffer_extract(buf, data, dataSize)); CU_ASSERT_EQUAL(1, dbuffer_len(buf)); CU_ASSERT_EQUAL(1, dbuffer_remove(buf, 1)); CU_ASSERT_EQUAL(0, dbuffer_len(buf)); CU_ASSERT_EQUAL(0, dbuffer_remove(buf, 1)); CU_ASSERT_EQUAL(0, dbuffer_get_at(buf, 1, data, dataSize)); for (i = 0; i <= dataSize; i++) dbuffer_add(buf, "b", 1); CU_ASSERT_EQUAL(dataSize + 1, dbuffer_len(buf)); CU_ASSERT_EQUAL(dataSize, dbuffer_get_at(buf, 1, data, dataSize)); CU_ASSERT_EQUAL(dataSize + 1, dbuffer_len(buf)); }
/** * @brief Allocate a dbuffer and prepend the given data to it * @param[in] old The source buffer * @param[in] data The data to insert at the beginning * @param[in] len The length of that data * @return the newly allocated buffer * Allocates a new dbuffer and initialises it to contain a copy of the * data in old */ struct dbuffer *dbuffer_prepend (struct dbuffer *old, const char *data, size_t len) { /* element we're currently reading from */ const struct dbuffer_element *e; struct dbuffer *buf = new_dbuffer(); const char *p; dbuffer_add(buf, data, len); e = old->head; p = old->start; while (e && (e->len > 0)) { dbuffer_add(buf, p, e->len); e = e->next; p = &e->data[0]; } return buf; }
static void testDBufferBigData (void) { int i; int count = 100; byte *data; /* this entity string may not contain any inline models, we don't have the bsp tree loaded here */ const int size = FS_LoadFile("game/entity.txt", &data); dbuffer* buf = new_dbuffer(); for (i = 0; i < count; i++) { dbuffer_add(buf, (char *)data, size); } CU_ASSERT_EQUAL(size * count, dbuffer_len(buf)); free_dbuffer(buf); FS_FreeFile(data); }