diff options
author | iphydf <iphydf@users.noreply.github.com> | 2018-08-26 09:42:08 +0000 |
---|---|---|
committer | iphydf <iphydf@users.noreply.github.com> | 2018-08-26 17:32:19 +0000 |
commit | a1035cf81494c3ab22c49b01788ca8ad933c5eb0 (patch) | |
tree | fee86f8751cc93eca9702fd50c3380483ff0f86a /toxcore/ping_array.c | |
parent | 64ddb7fff21e8cfcd197ba31bbb08ee6d3964c54 (diff) |
Add some tests for `ping_array`.
No timeout test here yet, because we don't yet have the ability to
manipulate time at will, so we would have to actually sleep.
Diffstat (limited to 'toxcore/ping_array.c')
-rw-r--r-- | toxcore/ping_array.c | 59 |
1 files changed, 21 insertions, 38 deletions
diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c index 9130254e..6669b4bd 100644 --- a/toxcore/ping_array.c +++ b/toxcore/ping_array.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include "mono_time.h" | 34 | #include "mono_time.h" |
35 | #include "util.h" | 35 | #include "util.h" |
36 | 36 | ||
37 | |||
38 | typedef struct Ping_Array_Entry { | 37 | typedef struct Ping_Array_Entry { |
39 | void *data; | 38 | void *data; |
40 | uint32_t length; | 39 | uint32_t length; |
@@ -46,25 +45,23 @@ struct Ping_Array { | |||
46 | Ping_Array_Entry *entries; | 45 | Ping_Array_Entry *entries; |
47 | 46 | ||
48 | uint32_t last_deleted; /* number representing the next entry to be deleted. */ | 47 | uint32_t last_deleted; /* number representing the next entry to be deleted. */ |
49 | uint32_t last_added; /* number representing the last entry to be added. */ | 48 | uint32_t last_added; /* number representing the last entry to be added. */ |
50 | uint32_t total_size; /* The length of entries */ | 49 | uint32_t total_size; /* The length of entries */ |
51 | uint32_t timeout; /* The timeout after which entries are cleared. */ | 50 | uint32_t timeout; /* The timeout after which entries are cleared. */ |
52 | }; | 51 | }; |
53 | 52 | ||
54 | /* Initialize a Ping_Array. | ||
55 | * size represents the total size of the array and should be a power of 2. | ||
56 | * timeout represents the maximum timeout in seconds for the entry. | ||
57 | * | ||
58 | * return 0 on success. | ||
59 | * return -1 on failure. | ||
60 | */ | ||
61 | Ping_Array *ping_array_new(uint32_t size, uint32_t timeout) | 53 | Ping_Array *ping_array_new(uint32_t size, uint32_t timeout) |
62 | { | 54 | { |
63 | if (size == 0 || timeout == 0) { | 55 | if (size == 0 || timeout == 0) { |
64 | return nullptr; | 56 | return nullptr; |
65 | } | 57 | } |
66 | 58 | ||
67 | Ping_Array *empty_array = (Ping_Array *)calloc(1, sizeof(Ping_Array)); | 59 | if ((size & (size - 1)) != 0) { |
60 | // Not a power of 2. | ||
61 | return nullptr; | ||
62 | } | ||
63 | |||
64 | Ping_Array *const empty_array = (Ping_Array *)calloc(1, sizeof(Ping_Array)); | ||
68 | 65 | ||
69 | if (empty_array == nullptr) { | 66 | if (empty_array == nullptr) { |
70 | return nullptr; | 67 | return nullptr; |
@@ -86,19 +83,15 @@ Ping_Array *ping_array_new(uint32_t size, uint32_t timeout) | |||
86 | 83 | ||
87 | static void clear_entry(Ping_Array *array, uint32_t index) | 84 | static void clear_entry(Ping_Array *array, uint32_t index) |
88 | { | 85 | { |
86 | const Ping_Array_Entry empty = {nullptr}; | ||
89 | free(array->entries[index].data); | 87 | free(array->entries[index].data); |
90 | array->entries[index].data = nullptr; | 88 | array->entries[index] = empty; |
91 | array->entries[index].length = 0; | ||
92 | array->entries[index].time = 0; | ||
93 | array->entries[index].ping_id = 0; | ||
94 | } | 89 | } |
95 | 90 | ||
96 | /* Free all the allocated memory in a Ping_Array. | ||
97 | */ | ||
98 | void ping_array_kill(Ping_Array *array) | 91 | void ping_array_kill(Ping_Array *array) |
99 | { | 92 | { |
100 | while (array->last_deleted != array->last_added) { | 93 | while (array->last_deleted != array->last_added) { |
101 | uint32_t index = array->last_deleted % array->total_size; | 94 | const uint32_t index = array->last_deleted % array->total_size; |
102 | clear_entry(array, index); | 95 | clear_entry(array, index); |
103 | ++array->last_deleted; | 96 | ++array->last_deleted; |
104 | } | 97 | } |
@@ -112,7 +105,7 @@ void ping_array_kill(Ping_Array *array) | |||
112 | static void ping_array_clear_timedout(Ping_Array *array, const Mono_Time *mono_time) | 105 | static void ping_array_clear_timedout(Ping_Array *array, const Mono_Time *mono_time) |
113 | { | 106 | { |
114 | while (array->last_deleted != array->last_added) { | 107 | while (array->last_deleted != array->last_added) { |
115 | uint32_t index = array->last_deleted % array->total_size; | 108 | const uint32_t index = array->last_deleted % array->total_size; |
116 | 109 | ||
117 | if (!mono_time_is_timeout(mono_time, array->entries[index].time, array->timeout)) { | 110 | if (!mono_time_is_timeout(mono_time, array->entries[index].time, array->timeout)) { |
118 | break; | 111 | break; |
@@ -123,15 +116,11 @@ static void ping_array_clear_timedout(Ping_Array *array, const Mono_Time *mono_t | |||
123 | } | 116 | } |
124 | } | 117 | } |
125 | 118 | ||
126 | /* Add a data with length to the Ping_Array list and return a ping_id. | 119 | uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const uint8_t *data, |
127 | * | 120 | uint32_t length) |
128 | * return ping_id on success. | ||
129 | * return 0 on failure. | ||
130 | */ | ||
131 | uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const uint8_t *data, uint32_t length) | ||
132 | { | 121 | { |
133 | ping_array_clear_timedout(array, mono_time); | 122 | ping_array_clear_timedout(array, mono_time); |
134 | uint32_t index = array->last_added % array->total_size; | 123 | const uint32_t index = array->last_added % array->total_size; |
135 | 124 | ||
136 | if (array->entries[index].data != nullptr) { | 125 | if (array->entries[index].data != nullptr) { |
137 | array->last_deleted = array->last_added - array->total_size; | 126 | array->last_deleted = array->last_added - array->total_size; |
@@ -161,21 +150,14 @@ uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const uin | |||
161 | return ping_id; | 150 | return ping_id; |
162 | } | 151 | } |
163 | 152 | ||
164 | 153 | int32_t ping_array_check(Ping_Array *array, const Mono_Time *mono_time, uint8_t *data, | |
165 | /* Check if ping_id is valid and not timed out. | 154 | size_t length, uint64_t ping_id) |
166 | * | ||
167 | * On success, copies the data into data of length, | ||
168 | * | ||
169 | * return length of data copied on success. | ||
170 | * return -1 on failure. | ||
171 | */ | ||
172 | int32_t ping_array_check(Ping_Array *array, const Mono_Time *mono_time, uint8_t *data, size_t length, uint64_t ping_id) | ||
173 | { | 155 | { |
174 | if (ping_id == 0) { | 156 | if (ping_id == 0) { |
175 | return -1; | 157 | return -1; |
176 | } | 158 | } |
177 | 159 | ||
178 | uint32_t index = ping_id % array->total_size; | 160 | const uint32_t index = ping_id % array->total_size; |
179 | 161 | ||
180 | if (array->entries[index].ping_id != ping_id) { | 162 | if (array->entries[index].ping_id != ping_id) { |
181 | return -1; | 163 | return -1; |
@@ -189,12 +171,13 @@ int32_t ping_array_check(Ping_Array *array, const Mono_Time *mono_time, uint8_t | |||
189 | return -1; | 171 | return -1; |
190 | } | 172 | } |
191 | 173 | ||
174 | // TODO(iphydf): This can't happen? If it indeed can't, turn it into an assert. | ||
192 | if (array->entries[index].data == nullptr) { | 175 | if (array->entries[index].data == nullptr) { |
193 | return -1; | 176 | return -1; |
194 | } | 177 | } |
195 | 178 | ||
196 | memcpy(data, array->entries[index].data, array->entries[index].length); | 179 | memcpy(data, array->entries[index].data, array->entries[index].length); |
197 | uint32_t len = array->entries[index].length; | 180 | const uint32_t len = array->entries[index].length; |
198 | clear_entry(array, index); | 181 | clear_entry(array, index); |
199 | return len; | 182 | return len; |
200 | } | 183 | } |