Skip to content

Commit

Permalink
Refactor dynType_sequence_alloc and dynType_sequence_reserve.
Browse files Browse the repository at this point in the history
  • Loading branch information
PengZheng committed Jan 7, 2024
1 parent 90dd0c0 commit 78b7d2d
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 42 deletions.
52 changes: 52 additions & 0 deletions libs/dfi/gtest/src/dyn_type_ei_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ class DynTypeErrorInjectionTestSuite : public ::testing::Test {
}

~DynTypeErrorInjectionTestSuite() override {
celix_ei_expect_realloc(nullptr, 0, nullptr);
celix_ei_expect_strdup(nullptr, 0, nullptr);
celix_ei_expect_calloc(nullptr, 0, nullptr);
celix_ei_expect_fmemopen(nullptr, 0, nullptr);
celix_err_resetErrors();
}
// delete other constructors and assign operators
DynTypeErrorInjectionTestSuite(DynTypeErrorInjectionTestSuite const&) = delete;
Expand Down Expand Up @@ -120,3 +122,53 @@ TEST_F(DynTypeErrorInjectionTestSuite, AllocateErrors) {
ASSERT_NE(0, rc);
ASSERT_STREQ("Error allocating memory for type 'E'", celix_err_popLastError());
}

TEST_F(DynTypeErrorInjectionTestSuite, SequenceAllocateError) {
struct double_sequence {
uint32_t cap;
uint32_t len;
double* buf;
};

dyn_type *type = NULL;
int rc = 0;
rc = dynType_parseWithStr("[D", NULL, NULL, &type);
ASSERT_EQ(0, rc);

struct double_sequence *seq = NULL;
rc = dynType_alloc(type, (void **)&seq);
ASSERT_EQ(0, rc);
ASSERT_TRUE(seq != NULL);
celix_ei_expect_calloc((void*)dynType_sequence_alloc, 0, nullptr);
rc = dynType_sequence_alloc(type, seq, 1);
ASSERT_NE(0, rc);
ASSERT_STREQ("Error allocating memory for buf", celix_err_popLastError());

dynType_free(type, seq);
dynType_destroy(type);
}

TEST_F(DynTypeErrorInjectionTestSuite, SequenceReserveError) {
struct double_sequence {
uint32_t cap;
uint32_t len;
double* buf;
};

dyn_type *type = NULL;
int rc = 0;
rc = dynType_parseWithStr("[D", NULL, NULL, &type);
ASSERT_EQ(0, rc);

struct double_sequence *seq = NULL;
rc = dynType_alloc(type, (void **)&seq);
ASSERT_EQ(0, rc);
ASSERT_TRUE(seq != NULL);
celix_ei_expect_realloc((void*)dynType_sequence_reserve, 0, nullptr);
rc = dynType_sequence_reserve(type, seq, 1);
ASSERT_NE(0, rc);
ASSERT_STREQ("Error allocating memory for buf", celix_err_popLastError());

dynType_free(type, seq);
dynType_destroy(type);
}
79 changes: 66 additions & 13 deletions libs/dfi/gtest/src/dyn_type_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ TEST_F(DynTypeTests, SequenceWithPointerTest) {
struct val val;
double c;
double d;
long e;
int64_t e;
};

struct item_sequence {
Expand All @@ -260,30 +260,83 @@ TEST_F(DynTypeTests, SequenceWithPointerTest) {

dyn_type *type = NULL;
int rc = 0;
rc = dynType_parseWithStr("Tval={DD a b};Titem={Jtlval;DDJ a text val c d e};**[Litem;", NULL, NULL, &type);
rc = dynType_parseWithStr("Tval={DD a b};Titem={Jtlval;DDJ a text val c d e};[Litem;", NULL, NULL, &type);
ASSERT_EQ(0, rc);

struct item_sequence *seq = NULL;
rc = dynType_alloc(type, (void **)&seq);
ASSERT_EQ(0, rc);
ASSERT_TRUE(seq != NULL);

rc = dynType_sequence_alloc(type, seq, 1);
ASSERT_EQ(0, rc);
struct item **loc = NULL;
rc = dynType_sequence_increaseLengthAndReturnLastLoc(type, seq, (void **)&loc);
ASSERT_EQ(0, rc);
ASSERT_EQ(loc, &seq->buf[0]);
ASSERT_EQ(sizeof(struct item), dynType_size(dynType_typedPointer_getTypedType(dynType_sequence_itemType(type))));
rc = dynType_alloc(dynType_typedPointer_getTypedType(dynType_sequence_itemType(type)), (void**)loc);
ASSERT_EQ(0, rc);
ASSERT_EQ(seq->buf[0], *loc);
dynType_free(type, seq);

/*
rc = dynType_sequence_alloc(type, nullptr, 1);
ASSERT_NE(0, rc);
ASSERT_STREQ("Error null sequence", celix_err_popLastError());

dynType_destroy(type);
}

struct item_sequence *items = (struct item_sequence *) calloc(1,sizeof(struct item_sequence));
items->buf = (struct item **) calloc(2, sizeof(struct item *));
items->cap = 2;
items->len = 2;
items->buf[0] = (struct item *)calloc(1, sizeof(struct item));
items->buf[0]->text = strdup("boe");
items->buf[1] = (struct item *)calloc(1, sizeof(struct item));
items->buf[1]->text = strdup("boe2");

dynType_free(type, items);
*/
TEST_F(DynTypeTests, SequenceReserve) {

struct val {
double a;
double b;
};

struct item {
int64_t a;
const char *text;
struct val val;
double c;
double d;
int64_t e;
};

struct item_sequence {
uint32_t cap;
uint32_t len;
struct item **buf;
};

dyn_type *type = NULL;
int rc = 0;
rc = dynType_parseWithStr("Tval={DD a b};Titem={Jtlval;DDJ a text val c d e};[Litem;", NULL, NULL, &type);
ASSERT_EQ(0, rc);

struct item_sequence *seq = NULL;

// sequence buffer should be zeroed
rc = dynType_alloc(type, (void **)&seq);
ASSERT_EQ(0, rc);
ASSERT_TRUE(seq != NULL);
rc = dynType_sequence_reserve(type, seq, 2);
ASSERT_EQ(0, rc);
ASSERT_EQ(nullptr, seq->buf[0]);
ASSERT_EQ(nullptr, seq->buf[1]);
ASSERT_EQ(2, seq->cap);
ASSERT_EQ(0, seq->len);

// no need to expand capacity
rc = dynType_sequence_reserve(type, seq, 1);
ASSERT_EQ(0, rc);
dynType_free(type, seq);

// try to reverse for null seq
rc = dynType_sequence_reserve(type, nullptr, 2);
ASSERT_NE(0, rc);
ASSERT_STREQ("Error null sequence", celix_err_popLastError());

dynType_destroy(type);
}
Expand Down
57 changes: 28 additions & 29 deletions libs/dfi/src/dyn_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,44 +580,43 @@ void dynType_sequence_init(const dyn_type* type, void* inst) {

int dynType_sequence_alloc(const dyn_type* type, void* inst, uint32_t cap) {
assert(type->type == DYN_TYPE_SEQUENCE);
int status = OK;
struct generic_sequence* seq = inst;
if (seq != NULL) {
size_t size = dynType_size(type->sequence.itemType);
seq->buf = calloc(cap, size);
if (seq->buf != NULL) {
seq->cap = cap;
seq->len = 0;
} else {
seq->cap = 0;
status = MEM_ERROR;
celix_err_pushf("Error allocating memory for buf");
}
} else {
status = MEM_ERROR;
celix_err_pushf("Error allocating memory for seq");
if (seq == NULL) {
celix_err_pushf("Error null sequence");
return ERROR;
}
return status;
size_t size = dynType_size(type->sequence.itemType);
seq->buf = calloc(cap, size);
if (seq->buf == NULL) {
seq->cap = 0;
celix_err_pushf("Error allocating memory for buf");
return MEM_ERROR;
}
seq->cap = cap;
seq->len = 0;
return OK;
}

int dynType_sequence_reserve(const dyn_type* type, void* inst, uint32_t cap) {
assert(type->type == DYN_TYPE_SEQUENCE);
int status = OK;
struct generic_sequence* seq = inst;
if (seq != NULL && seq->cap < cap) {
size_t size = dynType_size(type->sequence.itemType);
seq->buf = realloc(seq->buf, (size_t)(cap * size));
if (seq->buf != NULL) {
seq->cap = cap;
} else {
seq->cap = 0;
status = MEM_ERROR;
celix_err_pushf("Error allocating memory for buf");
}
} else {
status = MEM_ERROR;
celix_err_pushf("Error allocating memory for seq");
if (seq == NULL) {
celix_err_pushf("Error null sequence");
return ERROR;
}
if (seq->cap >= cap) {
return OK;
}
size_t size = dynType_size(type->sequence.itemType);
seq->buf = realloc(seq->buf, (size_t)(cap * size));
if (seq->buf == NULL) {
seq->cap = 0;
celix_err_pushf("Error allocating memory for buf");
return MEM_ERROR;
}
memset(seq->buf+seq->cap*size, 0, (cap-seq->cap)*size);
seq->cap = cap;
return status;
}

Expand Down

0 comments on commit 78b7d2d

Please sign in to comment.