Thu, 04 Jan 2024 21:05:32 +0100
migrate remaining buffer tests - relates to #342
tests/test_buffer.c | file | annotate | diff | comparison | revisions | |
tests/test_buffer.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/tests/test_buffer.c Wed Jan 03 22:17:40 2024 +0100 1.2 +++ b/tests/test_buffer.c Thu Jan 04 21:05:32 2024 +0100 1.3 @@ -430,7 +430,7 @@ 1.4 #define TEST_BUFFER_SHIFT_TEARDOWN(buf) \ 1.5 cxBufferDestroy(&buf); \ 1.6 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); \ 1.7 - cx_testing_allocator_destroy(&talloc); 1.8 + cx_testing_allocator_destroy(&talloc) 1.9 1.10 1.11 CX_TEST(test_buffer_shift_left_zero) { 1.12 @@ -585,6 +585,529 @@ 1.13 } 1.14 } 1.15 1.16 +static size_t mock_write_limited_rate( 1.17 + void const *ptr, 1.18 + size_t size, 1.19 + __attribute__((unused)) size_t nitems, 1.20 + CxBuffer *buffer 1.21 +) { 1.22 + // simulate limited target drain capacity 1.23 + static bool full = false; 1.24 + if (full) { 1.25 + full = false; 1.26 + return 0; 1.27 + } else { 1.28 + full = true; 1.29 + return cxBufferWrite(ptr, size, nitems > 2 ? 2 : nitems, buffer); 1.30 + } 1.31 +} 1.32 + 1.33 +CX_TEST(test_buffer_write_size_one_fit) { 1.34 + CxBuffer buf, target; 1.35 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.36 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.37 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.38 + buf.capacity = 8; 1.39 + buf.size = buf.pos = 4; 1.40 + const char *data = "test"; 1.41 + CX_TEST_DO { 1.42 + size_t written = cxBufferWrite(data, 1, 4, &buf); 1.43 + CX_TEST_ASSERT(written == 4); 1.44 + CX_TEST_ASSERT(buf.size == 8); 1.45 + CX_TEST_ASSERT(buf.pos == 8); 1.46 + CX_TEST_ASSERT(buf.capacity == 8); 1.47 + CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); 1.48 + } 1.49 + 1.50 + cxBufferDestroy(&buf); 1.51 + cxBufferDestroy(&target); 1.52 +} 1.53 + 1.54 +CX_TEST(test_buffer_write_size_one_discard) { 1.55 + CxBuffer buf, target; 1.56 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.57 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.58 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.59 + buf.capacity = 8; 1.60 + buf.size = buf.pos = 4; 1.61 + const char *data = "testing"; 1.62 + CX_TEST_DO { 1.63 + size_t written = cxBufferWrite(data, 1, 7, &buf); 1.64 + CX_TEST_ASSERT(written == 4); 1.65 + CX_TEST_ASSERT(buf.size == 8); 1.66 + CX_TEST_ASSERT(buf.pos == 8); 1.67 + CX_TEST_ASSERT(buf.capacity == 8); 1.68 + CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest\0", 9)); 1.69 + } 1.70 + cxBufferDestroy(&buf); 1.71 + cxBufferDestroy(&target); 1.72 +} 1.73 + 1.74 +CX_TEST(test_buffer_write_size_one_extend) { 1.75 + CxBuffer buf, target; 1.76 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.77 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.78 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.79 + buf.capacity = 8; 1.80 + buf.size = buf.pos = 4; 1.81 + buf.flags |= CX_BUFFER_AUTO_EXTEND; 1.82 + const char *data = "testing"; 1.83 + CX_TEST_DO { 1.84 + size_t written = cxBufferWrite(data, 1, 7, &buf); 1.85 + CX_TEST_ASSERT(written == 7); 1.86 + CX_TEST_ASSERT(buf.size == 11); 1.87 + CX_TEST_ASSERT(buf.pos == 11); 1.88 + CX_TEST_ASSERT(buf.capacity >= 11); 1.89 + CX_TEST_ASSERT(0 == memcmp(buf.space, "preptesting", 11)); 1.90 + } 1.91 + cxBufferDestroy(&buf); 1.92 + cxBufferDestroy(&target); 1.93 +} 1.94 + 1.95 +CX_TEST(test_buffer_write_multibyte_fit) { 1.96 + CxBuffer buf, target; 1.97 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.98 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.99 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.100 + buf.capacity = 8; 1.101 + buf.size = buf.pos = 4; 1.102 + const char *data = "test"; 1.103 + CX_TEST_DO { 1.104 + size_t written = cxBufferWrite(data, 2, 2, &buf); 1.105 + CX_TEST_ASSERT(written == 2); 1.106 + CX_TEST_ASSERT(buf.size == 8); 1.107 + CX_TEST_ASSERT(buf.pos == 8); 1.108 + CX_TEST_ASSERT(buf.capacity == 8); 1.109 + CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); 1.110 + } 1.111 + cxBufferDestroy(&buf); 1.112 + cxBufferDestroy(&target); 1.113 +} 1.114 + 1.115 +CX_TEST(test_buffer_write_multibyte_discard) { 1.116 + CxBuffer buf, target; 1.117 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.118 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.119 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.120 + buf.capacity = 8; 1.121 + buf.size = 4; 1.122 + buf.pos = 3; 1.123 + const char *data = "testing"; 1.124 + CX_TEST_DO { 1.125 + size_t written = cxBufferWrite(data, 2, 4, &buf); 1.126 + // remember: whole elements are discarded if they do not fit 1.127 + CX_TEST_ASSERT(written == 2); 1.128 + CX_TEST_ASSERT(buf.size == 7); 1.129 + CX_TEST_ASSERT(buf.pos == 7); 1.130 + CX_TEST_ASSERT(buf.capacity == 8); 1.131 + CX_TEST_ASSERT(0 == memcmp(buf.space, "pretest\0", 8)); 1.132 + } 1.133 + cxBufferDestroy(&buf); 1.134 + cxBufferDestroy(&target); 1.135 +} 1.136 + 1.137 +CX_TEST(test_buffer_write_multibyte_extend) { 1.138 + CxBuffer buf, target; 1.139 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.140 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.141 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.142 + buf.capacity = 8; 1.143 + buf.size = 4; 1.144 + buf.pos = 3; 1.145 + buf.flags |= CX_BUFFER_AUTO_EXTEND; 1.146 + const char *data = "tester"; 1.147 + CX_TEST_DO { 1.148 + size_t written = cxBufferWrite(data, 2, 3, &buf); 1.149 + // remember: whole elements are discarded if they do not fit 1.150 + CX_TEST_ASSERT(written == 3); 1.151 + CX_TEST_ASSERT(buf.size == 9); 1.152 + CX_TEST_ASSERT(buf.pos == 9); 1.153 + CX_TEST_ASSERT(buf.capacity >= 9); 1.154 + CX_TEST_ASSERT(0 == memcmp(buf.space, "pretester", 9)); 1.155 + } 1.156 + cxBufferDestroy(&buf); 1.157 + cxBufferDestroy(&target); 1.158 +} 1.159 + 1.160 +CX_TEST(test_buffer_put_fit) { 1.161 + CxBuffer buf, target; 1.162 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.163 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.164 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.165 + buf.capacity = 8; 1.166 + buf.size = buf.pos = 4; 1.167 + CX_TEST_DO { 1.168 + int c = cxBufferPut(&buf, 0x200 | 'a'); 1.169 + CX_TEST_ASSERT(c == 'a'); 1.170 + CX_TEST_ASSERT(buf.size == 5); 1.171 + CX_TEST_ASSERT(buf.pos == 5); 1.172 + CX_TEST_ASSERT(buf.capacity == 8); 1.173 + CX_TEST_ASSERT(0 == memcmp(buf.space, "prepa\0", 6)); 1.174 + } 1.175 + cxBufferDestroy(&buf); 1.176 + cxBufferDestroy(&target); 1.177 +} 1.178 + 1.179 +CX_TEST(test_buffer_put_discard) { 1.180 + CxBuffer buf, target; 1.181 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.182 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.183 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.184 + buf.capacity = 8; 1.185 + buf.size = 4; 1.186 + buf.pos = 8; 1.187 + CX_TEST_DO { 1.188 + int c = cxBufferPut(&buf, 0x200 | 'a'); 1.189 + CX_TEST_ASSERT(c == EOF); 1.190 + CX_TEST_ASSERT(buf.size == 4); 1.191 + CX_TEST_ASSERT(buf.pos == 8); 1.192 + CX_TEST_ASSERT(buf.capacity == 8); 1.193 + CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0\0\0\0\0", 9)); 1.194 + } 1.195 + cxBufferDestroy(&buf); 1.196 + cxBufferDestroy(&target); 1.197 +} 1.198 + 1.199 +CX_TEST(test_buffer_put_extend) { 1.200 + CxBuffer buf, target; 1.201 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.202 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.203 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.204 + buf.capacity = 8; 1.205 + buf.size = 4; 1.206 + buf.pos = 8; 1.207 + buf.flags |= CX_BUFFER_AUTO_EXTEND; 1.208 + CX_TEST_DO { 1.209 + int c = cxBufferPut(&buf, 0x200 | 'a'); 1.210 + CX_TEST_ASSERT(c == 'a'); 1.211 + CX_TEST_ASSERT(buf.size == 9); 1.212 + CX_TEST_ASSERT(buf.pos == 9); 1.213 + CX_TEST_ASSERT(buf.capacity >= 9); 1.214 + CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0\0\0\0a", 9)); 1.215 + } 1.216 + cxBufferDestroy(&buf); 1.217 + cxBufferDestroy(&target); 1.218 +} 1.219 + 1.220 +CX_TEST(test_buffer_put_string_fit) { 1.221 + CxBuffer buf, target; 1.222 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.223 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.224 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.225 + buf.capacity = 8; 1.226 + buf.size = buf.pos = 4; 1.227 + const char *data = "test"; 1.228 + CX_TEST_DO { 1.229 + size_t written = cxBufferPutString(&buf, data); 1.230 + CX_TEST_ASSERT(written == 4); 1.231 + CX_TEST_ASSERT(buf.size == 8); 1.232 + CX_TEST_ASSERT(buf.pos == 8); 1.233 + CX_TEST_ASSERT(buf.capacity == 8); 1.234 + CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); 1.235 + } 1.236 + cxBufferDestroy(&buf); 1.237 + cxBufferDestroy(&target); 1.238 +} 1.239 + 1.240 +CX_TEST(test_buffer_put_string_discard) { 1.241 + CxBuffer buf, target; 1.242 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.243 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.244 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.245 + buf.capacity = 8; 1.246 + buf.size = buf.pos = 4; 1.247 + const char *data = "testing"; 1.248 + CX_TEST_DO { 1.249 + size_t written = cxBufferPutString(&buf, data); 1.250 + CX_TEST_ASSERT(written == 4); 1.251 + CX_TEST_ASSERT(buf.size == 8); 1.252 + CX_TEST_ASSERT(buf.pos == 8); 1.253 + CX_TEST_ASSERT(buf.capacity == 8); 1.254 + CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest\0", 9)); 1.255 + } 1.256 + cxBufferDestroy(&buf); 1.257 + cxBufferDestroy(&target); 1.258 +} 1.259 + 1.260 +CX_TEST(test_buffer_put_string_extend) { 1.261 + CxBuffer buf, target; 1.262 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.263 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.264 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.265 + buf.capacity = 8; 1.266 + buf.size = buf.pos = 4; 1.267 + buf.flags |= CX_BUFFER_AUTO_EXTEND; 1.268 + const char *data = "testing"; 1.269 + CX_TEST_DO { 1.270 + size_t written = cxBufferPutString(&buf, data); 1.271 + CX_TEST_ASSERT(written == 7); 1.272 + CX_TEST_ASSERT(buf.size == 11); 1.273 + CX_TEST_ASSERT(buf.pos == 11); 1.274 + CX_TEST_ASSERT(buf.capacity >= 11); 1.275 + CX_TEST_ASSERT(0 == memcmp(buf.space, "preptesting", 11)); 1.276 + } 1.277 + cxBufferDestroy(&buf); 1.278 + cxBufferDestroy(&target); 1.279 +} 1.280 + 1.281 +CX_TEST(test_buffer_write_size_overflow) { 1.282 + CxBuffer buf, target; 1.283 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.284 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.285 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.286 + buf.capacity = 8; 1.287 + buf.size = buf.pos = 4; 1.288 + const char *data = "testing"; 1.289 + CX_TEST_DO { 1.290 + size_t written = cxBufferWrite(data, 8, SIZE_MAX / 4, &buf); 1.291 + CX_TEST_ASSERT(written == 0); 1.292 + CX_TEST_ASSERT(buf.capacity == 8); 1.293 + CX_TEST_ASSERT(buf.pos == 4); 1.294 + CX_TEST_ASSERT(buf.size == 4); 1.295 + CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0", 5)); 1.296 + } 1.297 + cxBufferDestroy(&buf); 1.298 + cxBufferDestroy(&target); 1.299 +} 1.300 + 1.301 +CX_TEST(test_buffer_write_capacity_overflow) { 1.302 + CxBuffer buf, target; 1.303 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.304 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.305 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.306 + buf.capacity = 8; 1.307 + buf.size = buf.pos = 4; 1.308 + buf.flags |= CX_BUFFER_AUTO_EXTEND; 1.309 + const char *data = "testing"; 1.310 + CX_TEST_DO { 1.311 + size_t written = cxBufferWrite(data, 1, SIZE_MAX - 2, &buf); 1.312 + CX_TEST_ASSERT(written == 0); 1.313 + CX_TEST_ASSERT(buf.capacity == 8); 1.314 + CX_TEST_ASSERT(buf.pos == 4); 1.315 + CX_TEST_ASSERT(buf.size == 4); 1.316 + CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0", 5)); 1.317 + } 1.318 + cxBufferDestroy(&buf); 1.319 + cxBufferDestroy(&target); 1.320 +} 1.321 + 1.322 +CX_TEST(test_buffer_write_only_overwrite) { 1.323 + CxBuffer buf, target; 1.324 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.325 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.326 + memcpy(buf.space, "preptest\0\0\0\0\0\0\0\0", 16); 1.327 + buf.capacity = 8; 1.328 + buf.pos = 3; 1.329 + buf.size = 8; 1.330 + buf.flags |= CX_BUFFER_AUTO_EXTEND; 1.331 + CX_TEST_DO { 1.332 + size_t written = cxBufferWrite("XXX", 2, 2, &buf); 1.333 + CX_TEST_ASSERT(written == 2); 1.334 + CX_TEST_ASSERT(buf.capacity == 8); 1.335 + CX_TEST_ASSERT(buf.size == 8); 1.336 + CX_TEST_ASSERT(buf.pos == 7); 1.337 + CX_TEST_ASSERT(0 == memcmp(buf.space, "preXXX\0t", 8)); 1.338 + } 1.339 + cxBufferDestroy(&buf); 1.340 + cxBufferDestroy(&target); 1.341 +} 1.342 + 1.343 +CX_TEST(test_buffer_write_flush_at_capacity) { 1.344 + CxBuffer buf, target; 1.345 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.346 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.347 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.348 + buf.capacity = 8; 1.349 + buf.size = buf.pos = 4; 1.350 + buf.flush_target = ⌖ 1.351 + buf.flush_func = (cx_write_func)cxBufferWrite; 1.352 + buf.flush_blkmax = 1; 1.353 + CX_TEST_DO { 1.354 + size_t written = cxBufferWrite("foo", 1, 3, &buf); 1.355 + CX_TEST_ASSERT(written == 3); 1.356 + CX_TEST_ASSERT(buf.pos == 7); 1.357 + CX_TEST_ASSERT(buf.size == 7); 1.358 + CX_TEST_ASSERT(target.pos == 0); 1.359 + CX_TEST_ASSERT(target.size == 0); 1.360 + written = cxBufferWrite("hello", 1, 5, &buf); 1.361 + CX_TEST_ASSERT(written == 5); 1.362 + CX_TEST_ASSERT(buf.pos == 0); 1.363 + CX_TEST_ASSERT(buf.size == 0); 1.364 + CX_TEST_ASSERT(buf.capacity == 8); 1.365 + CX_TEST_ASSERT(target.pos == 12); 1.366 + CX_TEST_ASSERT(target.size == 12); 1.367 + CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoohello", 12)); 1.368 + } 1.369 + cxBufferDestroy(&buf); 1.370 + cxBufferDestroy(&target); 1.371 +} 1.372 + 1.373 +CX_TEST(test_buffer_write_flush_at_threshold) { 1.374 + CxBuffer buf, target; 1.375 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.376 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.377 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.378 + buf.capacity = 8; 1.379 + buf.size = buf.pos = 4; 1.380 + buf.flush_target = ⌖ 1.381 + buf.flush_func = (cx_write_func)cxBufferWrite; 1.382 + buf.flush_blkmax = 1; 1.383 + buf.flush_threshold = 12; 1.384 + buf.flags |= CX_BUFFER_AUTO_EXTEND; 1.385 + CX_TEST_DO { 1.386 + size_t written = cxBufferWrite("foobar", 1, 6, &buf); 1.387 + CX_TEST_ASSERT(written == 6); 1.388 + CX_TEST_ASSERT(buf.pos == 10); 1.389 + CX_TEST_ASSERT(buf.size == 10); 1.390 + CX_TEST_ASSERT(buf.capacity >= 10); 1.391 + CX_TEST_ASSERT(buf.capacity <= 12); 1.392 + CX_TEST_ASSERT(target.pos == 0); 1.393 + CX_TEST_ASSERT(target.size == 0); 1.394 + written = cxBufferWrite("hello", 1, 5, &buf); 1.395 + CX_TEST_ASSERT(written == 5); 1.396 + CX_TEST_ASSERT(buf.pos == 0); 1.397 + CX_TEST_ASSERT(buf.size == 0); 1.398 + CX_TEST_ASSERT(buf.capacity <= 12); 1.399 + CX_TEST_ASSERT(target.pos == 15); 1.400 + CX_TEST_ASSERT(target.size == 15); 1.401 + CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoobarhello", 15)); 1.402 + } 1.403 + cxBufferDestroy(&buf); 1.404 + cxBufferDestroy(&target); 1.405 +} 1.406 + 1.407 +CX_TEST(test_buffer_write_flush_rate_limited) { 1.408 + CxBuffer buf, target; 1.409 + cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 1.410 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.411 + memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1.412 + buf.capacity = 8; 1.413 + buf.size = buf.pos = 4; 1.414 + buf.flush_target = ⌖ 1.415 + buf.flush_blkmax = 1; 1.416 + // limit the rate of the flush function and the capacity of the target 1.417 + buf.flush_func = (cx_write_func) mock_write_limited_rate; 1.418 + target.capacity = 16; 1.419 + target.flags &= ~CX_BUFFER_AUTO_EXTEND; 1.420 + CX_TEST_DO { 1.421 + size_t written = cxBufferWrite("foo", 1, 3, &buf); 1.422 + CX_TEST_ASSERT(written == 3); 1.423 + CX_TEST_ASSERT(buf.pos == 7); 1.424 + CX_TEST_ASSERT(buf.size == 7); 1.425 + CX_TEST_ASSERT(target.pos == 0); 1.426 + CX_TEST_ASSERT(target.size == 0); 1.427 + written = cxBufferWrite("hello, world!", 1, 13, &buf); 1.428 + // " world!" fits into this buffer, the remaining stuff is flushed out 1.429 + CX_TEST_ASSERT(written == 13); 1.430 + CX_TEST_ASSERT(buf.pos == 7); 1.431 + CX_TEST_ASSERT(buf.size == 7); 1.432 + CX_TEST_ASSERT(buf.capacity == 8); 1.433 + CX_TEST_ASSERT(0 == memcmp(buf.space, " world!", 7)); 1.434 + CX_TEST_ASSERT(target.pos == 13); 1.435 + CX_TEST_ASSERT(target.size == 13); 1.436 + CX_TEST_ASSERT(target.capacity == 16); 1.437 + CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoohello,", 13)); 1.438 + } 1.439 + cxBufferDestroy(&buf); 1.440 + cxBufferDestroy(&target); 1.441 +} 1.442 + 1.443 +CX_TEST(test_buffer_get) { 1.444 + CxBuffer buf; 1.445 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.446 + memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1.447 + buf.capacity = 12; 1.448 + buf.size = 9; 1.449 + buf.pos = 2; 1.450 + CX_TEST_DO { 1.451 + CX_TEST_ASSERT(cxBufferGet(&buf) == 'm'); 1.452 + CX_TEST_ASSERT(cxBufferGet(&buf) == 'e'); 1.453 + CX_TEST_ASSERT(cxBufferGet(&buf) == ' '); 1.454 + CX_TEST_ASSERT(cxBufferGet(&buf) == 'd'); 1.455 + CX_TEST_ASSERT(buf.pos == 6); 1.456 + } 1.457 + cxBufferDestroy(&buf); 1.458 +} 1.459 + 1.460 +CX_TEST(test_buffer_get_eof) { 1.461 + CxBuffer buf; 1.462 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.463 + memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1.464 + buf.capacity = 12; 1.465 + buf.pos = buf.size = 9; 1.466 + CX_TEST_DO { 1.467 + CX_TEST_ASSERT(cxBufferGet(&buf) == EOF); 1.468 + } 1.469 + cxBufferDestroy(&buf); 1.470 +} 1.471 + 1.472 +CX_TEST(test_buffer_read) { 1.473 + CxBuffer buf; 1.474 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.475 + memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1.476 + buf.capacity = 12; 1.477 + buf.size = 9; 1.478 + buf.pos = 2; 1.479 + CX_TEST_DO { 1.480 + char target[4]; 1.481 + size_t read = cxBufferRead(&target, 1, 4, &buf); 1.482 + CX_TEST_ASSERT(read == 4); 1.483 + CX_TEST_ASSERT(0 == memcmp(&target, "me d", 4)); 1.484 + CX_TEST_ASSERT(buf.pos == 6); 1.485 + } 1.486 + cxBufferDestroy(&buf); 1.487 +} 1.488 + 1.489 +CX_TEST(test_buffer_read_oob) { 1.490 + CxBuffer buf; 1.491 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.492 + memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1.493 + buf.capacity = 12; 1.494 + buf.size = 9; 1.495 + buf.pos = 6; 1.496 + CX_TEST_DO { 1.497 + char target[4]; 1.498 + size_t read = cxBufferRead(&target, 1, 4, &buf); 1.499 + CX_TEST_ASSERT(read == 3); 1.500 + CX_TEST_ASSERT(0 == memcmp(&target, "ata", 3)); 1.501 + CX_TEST_ASSERT(buf.pos == 9); 1.502 + } 1.503 + cxBufferDestroy(&buf); 1.504 +} 1.505 + 1.506 +CX_TEST(test_buffer_read_oob_multibyte) { 1.507 + CxBuffer buf; 1.508 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.509 + memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1.510 + buf.capacity = 12; 1.511 + buf.size = 9; 1.512 + buf.pos = 6; 1.513 + CX_TEST_DO { 1.514 + char target[4]; 1.515 + target[2] = '\0'; 1.516 + size_t read = cxBufferRead(&target, 2, 2, &buf); 1.517 + CX_TEST_ASSERT(read == 1); 1.518 + CX_TEST_ASSERT(0 == memcmp(&target, "at\0", 3)); 1.519 + CX_TEST_ASSERT(buf.pos == 8); 1.520 + } 1.521 + cxBufferDestroy(&buf); 1.522 +} 1.523 + 1.524 +CX_TEST(test_buffer_read_eof) { 1.525 + CxBuffer buf; 1.526 + cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1.527 + memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1.528 + buf.capacity = 12; 1.529 + buf.size = buf.pos = 9; 1.530 + CX_TEST_DO { 1.531 + char target[4]; 1.532 + size_t read = cxBufferRead(&target, 1, 1, &buf); 1.533 + CX_TEST_ASSERT(read == 0); 1.534 + CX_TEST_ASSERT(buf.pos == 9); 1.535 + } 1.536 + cxBufferDestroy(&buf); 1.537 +} 1.538 + 1.539 CxTestSuite *cx_test_suite_buffer(void) { 1.540 CxTestSuite *suite = cx_test_suite_new("buffer"); 1.541 1.542 @@ -623,6 +1146,30 @@ 1.543 cx_test_register(suite, test_buffer_shift_right_overshift_discard); 1.544 cx_test_register(suite, test_buffer_shift_right_overshift_extend); 1.545 cx_test_register(suite, test_buffer_shift_right_offset_interface); 1.546 - 1.547 + cx_test_register(suite, test_buffer_write_size_one_fit); 1.548 + cx_test_register(suite, test_buffer_write_size_one_discard); 1.549 + cx_test_register(suite, test_buffer_write_size_one_extend); 1.550 + cx_test_register(suite, test_buffer_write_multibyte_fit); 1.551 + cx_test_register(suite, test_buffer_write_multibyte_discard); 1.552 + cx_test_register(suite, test_buffer_write_multibyte_extend); 1.553 + cx_test_register(suite, test_buffer_put_fit); 1.554 + cx_test_register(suite, test_buffer_put_discard); 1.555 + cx_test_register(suite, test_buffer_put_extend); 1.556 + cx_test_register(suite, test_buffer_put_string_fit); 1.557 + cx_test_register(suite, test_buffer_put_string_discard); 1.558 + cx_test_register(suite, test_buffer_put_string_extend); 1.559 + cx_test_register(suite, test_buffer_write_size_overflow); 1.560 + cx_test_register(suite, test_buffer_write_capacity_overflow); 1.561 + cx_test_register(suite, test_buffer_write_only_overwrite); 1.562 + cx_test_register(suite, test_buffer_write_flush_at_capacity); 1.563 + cx_test_register(suite, test_buffer_write_flush_at_threshold); 1.564 + cx_test_register(suite, test_buffer_write_flush_rate_limited); 1.565 + cx_test_register(suite, test_buffer_get); 1.566 + cx_test_register(suite, test_buffer_get_eof); 1.567 + cx_test_register(suite, test_buffer_read); 1.568 + cx_test_register(suite, test_buffer_read_oob); 1.569 + cx_test_register(suite, test_buffer_read_oob_multibyte); 1.570 + cx_test_register(suite, test_buffer_read_eof); 1.571 + 1.572 return suite; 1.573 }
2.1 --- a/tests/test_buffer.cpp Wed Jan 03 22:17:40 2024 +0100 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,412 +0,0 @@ 2.4 -/* 2.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2.6 - * 2.7 - * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 2.8 - * 2.9 - * Redistribution and use in source and binary forms, with or without 2.10 - * modification, are permitted provided that the following conditions are met: 2.11 - * 2.12 - * 1. Redistributions of source code must retain the above copyright 2.13 - * notice, this list of conditions and the following disclaimer. 2.14 - * 2.15 - * 2. Redistributions in binary form must reproduce the above copyright 2.16 - * notice, this list of conditions and the following disclaimer in the 2.17 - * documentation and/or other materials provided with the distribution. 2.18 - * 2.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2.29 - * POSSIBILITY OF SUCH DAMAGE. 2.30 - */ 2.31 - 2.32 -#include "cx/buffer.h" 2.33 - 2.34 -#include <gtest/gtest.h> 2.35 -#include "util_allocator.h" 2.36 - 2.37 -class BufferWrite : public ::testing::Test { 2.38 -protected: 2.39 - CxBuffer buf{}, target{}; 2.40 - 2.41 - void SetUp() override { 2.42 - cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); 2.43 - cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 2.44 - buf.capacity = 8; // artificially reduce capacity to check OOB writes 2.45 - memset(buf.space, 0, 16); 2.46 - memcpy(buf.space, "prep", 4); 2.47 - buf.size = buf.pos = 4; 2.48 - } 2.49 - 2.50 - void TearDown() override { 2.51 - cxBufferDestroy(&buf); 2.52 - cxBufferDestroy(&target); 2.53 - } 2.54 - 2.55 - void enableFlushing() { 2.56 - buf.flush_target = ⌖ 2.57 - buf.flush_func = reinterpret_cast<cx_write_func>(cxBufferWrite); 2.58 - buf.flush_blkmax = 1; 2.59 - } 2.60 -}; 2.61 - 2.62 -static size_t mock_write_limited_rate( 2.63 - void const *ptr, 2.64 - size_t size, 2.65 - __attribute__((unused)) size_t nitems, 2.66 - CxBuffer *buffer 2.67 -) { 2.68 - // simulate limited target drain capacity 2.69 - static bool full = false; 2.70 - if (full) { 2.71 - full = false; 2.72 - return 0; 2.73 - } else { 2.74 - full = true; 2.75 - return cxBufferWrite(ptr, size, nitems > 2 ? 2 : nitems, buffer); 2.76 - } 2.77 -} 2.78 - 2.79 -TEST_F(BufferWrite, SizeOneFit) { 2.80 - const char *data = "test"; 2.81 - CX_TEST_ASSERT(buf.capacity == 8); 2.82 - CX_TEST_ASSERT(buf.pos == 4); 2.83 - CX_TEST_ASSERT(buf.size == 4); 2.84 - size_t written = cxBufferWrite(data, 1, 4, &buf); 2.85 - CX_TEST_ASSERT(written == 4); 2.86 - CX_TEST_ASSERT(buf.size == 8); 2.87 - CX_TEST_ASSERT(buf.pos == 8); 2.88 - CX_TEST_ASSERT(buf.capacity == 8); 2.89 - EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0); 2.90 -} 2.91 - 2.92 -TEST_F(BufferWrite, SizeOneDiscard) { 2.93 - const char *data = "testing"; 2.94 - CX_TEST_ASSERT(buf.capacity == 8); 2.95 - CX_TEST_ASSERT(buf.pos == 4); 2.96 - CX_TEST_ASSERT(buf.size == 4); 2.97 - size_t written = cxBufferWrite(data, 1, 7, &buf); 2.98 - CX_TEST_ASSERT(written == 4); 2.99 - CX_TEST_ASSERT(buf.size == 8); 2.100 - CX_TEST_ASSERT(buf.pos == 8); 2.101 - CX_TEST_ASSERT(buf.capacity == 8); 2.102 - EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0); 2.103 -} 2.104 - 2.105 -TEST_F(BufferWrite, SizeOneExtend) { 2.106 - buf.flags |= CX_BUFFER_AUTO_EXTEND; 2.107 - const char *data = "testing"; 2.108 - CX_TEST_ASSERT(buf.capacity == 8); 2.109 - CX_TEST_ASSERT(buf.pos == 4); 2.110 - CX_TEST_ASSERT(buf.size == 4); 2.111 - size_t written = cxBufferWrite(data, 1, 7, &buf); 2.112 - CX_TEST_ASSERT(written == 7); 2.113 - CX_TEST_ASSERT(buf.size == 11); 2.114 - CX_TEST_ASSERT(buf.pos == 11); 2.115 - EXPECT_GE(buf.capacity, 11); 2.116 - EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0); 2.117 -} 2.118 - 2.119 -TEST_F(BufferWrite, MultibyteFit) { 2.120 - const char *data = "test"; 2.121 - CX_TEST_ASSERT(buf.capacity == 8); 2.122 - CX_TEST_ASSERT(buf.pos == 4); 2.123 - CX_TEST_ASSERT(buf.size == 4); 2.124 - size_t written = cxBufferWrite(data, 2, 2, &buf); 2.125 - CX_TEST_ASSERT(written == 2); 2.126 - CX_TEST_ASSERT(buf.size == 8); 2.127 - CX_TEST_ASSERT(buf.pos == 8); 2.128 - CX_TEST_ASSERT(buf.capacity == 8); 2.129 - EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0); 2.130 -} 2.131 - 2.132 -TEST_F(BufferWrite, MultibyteDiscard) { 2.133 - const char *data = "testing"; 2.134 - CX_TEST_ASSERT(buf.capacity == 8); 2.135 - CX_TEST_ASSERT(buf.size == 4); 2.136 - buf.pos = 3; 2.137 - size_t written = cxBufferWrite(data, 2, 4, &buf); 2.138 - // remember: whole elements are discarded if they do not fit 2.139 - CX_TEST_ASSERT(written == 2); 2.140 - CX_TEST_ASSERT(buf.size == 7); 2.141 - CX_TEST_ASSERT(buf.pos == 7); 2.142 - CX_TEST_ASSERT(buf.capacity == 8); 2.143 - EXPECT_EQ(memcmp(buf.space, "pretest\0", 8), 0); 2.144 -} 2.145 - 2.146 -TEST_F(BufferWrite, MultibyteExtend) { 2.147 - buf.flags |= CX_BUFFER_AUTO_EXTEND; 2.148 - const char *data = "tester"; 2.149 - CX_TEST_ASSERT(buf.capacity == 8); 2.150 - CX_TEST_ASSERT(buf.size == 4); 2.151 - buf.pos = 3; 2.152 - size_t written = cxBufferWrite(data, 2, 3, &buf); 2.153 - // remember: whole elements are discarded if they do not fit 2.154 - CX_TEST_ASSERT(written == 3); 2.155 - CX_TEST_ASSERT(buf.size == 9); 2.156 - CX_TEST_ASSERT(buf.pos == 9); 2.157 - EXPECT_GE(buf.capacity, 9); 2.158 - EXPECT_EQ(memcmp(buf.space, "pretester", 9), 0); 2.159 -} 2.160 - 2.161 -TEST_F(BufferWrite, PutcWrapperFit) { 2.162 - CX_TEST_ASSERT(buf.capacity == 8); 2.163 - CX_TEST_ASSERT(buf.pos == 4); 2.164 - CX_TEST_ASSERT(buf.size == 4); 2.165 - int c = cxBufferPut(&buf, 0x200 | 'a'); 2.166 - CX_TEST_ASSERT(c == 'a'); 2.167 - CX_TEST_ASSERT(buf.size == 5); 2.168 - CX_TEST_ASSERT(buf.pos == 5); 2.169 - CX_TEST_ASSERT(buf.capacity == 8); 2.170 - EXPECT_EQ(memcmp(buf.space, "prepa\0", 6), 0); 2.171 -} 2.172 - 2.173 -TEST_F(BufferWrite, PutcWrapperDiscard) { 2.174 - CX_TEST_ASSERT(buf.capacity == 8); 2.175 - CX_TEST_ASSERT(buf.size == 4); 2.176 - buf.pos = 8; 2.177 - int c = cxBufferPut(&buf, 0x200 | 'a'); 2.178 - CX_TEST_ASSERT(c == EOF); 2.179 - CX_TEST_ASSERT(buf.size == 4); 2.180 - CX_TEST_ASSERT(buf.pos == 8); 2.181 - CX_TEST_ASSERT(buf.capacity == 8); 2.182 - EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0\0", 9), 0); 2.183 -} 2.184 - 2.185 -TEST_F(BufferWrite, PutcWrapperExtend) { 2.186 - buf.flags |= CX_BUFFER_AUTO_EXTEND; 2.187 - CX_TEST_ASSERT(buf.capacity == 8); 2.188 - CX_TEST_ASSERT(buf.size == 4); 2.189 - buf.pos = 8; 2.190 - int c = cxBufferPut(&buf, 0x200 | 'a'); 2.191 - CX_TEST_ASSERT(c == 'a'); 2.192 - CX_TEST_ASSERT(buf.size == 9); 2.193 - CX_TEST_ASSERT(buf.pos == 9); 2.194 - EXPECT_GE(buf.capacity, 9); 2.195 - EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0a", 9), 0); 2.196 -} 2.197 - 2.198 -TEST_F(BufferWrite, PutStringWrapperFit) { 2.199 - const char *data = "test"; 2.200 - CX_TEST_ASSERT(buf.capacity == 8); 2.201 - CX_TEST_ASSERT(buf.pos == 4); 2.202 - CX_TEST_ASSERT(buf.size == 4); 2.203 - size_t written = cxBufferPutString(&buf, data); 2.204 - CX_TEST_ASSERT(written == 4); 2.205 - CX_TEST_ASSERT(buf.size == 8); 2.206 - CX_TEST_ASSERT(buf.pos == 8); 2.207 - CX_TEST_ASSERT(buf.capacity == 8); 2.208 - EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0); 2.209 -} 2.210 - 2.211 -TEST_F(BufferWrite, PutStringWrapperDiscard) { 2.212 - const char *data = "testing"; 2.213 - CX_TEST_ASSERT(buf.capacity == 8); 2.214 - CX_TEST_ASSERT(buf.pos == 4); 2.215 - CX_TEST_ASSERT(buf.size == 4); 2.216 - size_t written = cxBufferPutString(&buf, data); 2.217 - CX_TEST_ASSERT(written == 4); 2.218 - CX_TEST_ASSERT(buf.size == 8); 2.219 - CX_TEST_ASSERT(buf.pos == 8); 2.220 - CX_TEST_ASSERT(buf.capacity == 8); 2.221 - EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0); 2.222 -} 2.223 - 2.224 -TEST_F(BufferWrite, PutStringWrapperExtend) { 2.225 - buf.flags |= CX_BUFFER_AUTO_EXTEND; 2.226 - const char *data = "testing"; 2.227 - CX_TEST_ASSERT(buf.capacity == 8); 2.228 - CX_TEST_ASSERT(buf.pos == 4); 2.229 - CX_TEST_ASSERT(buf.size == 4); 2.230 - size_t written = cxBufferPutString(&buf, data); 2.231 - CX_TEST_ASSERT(written == 7); 2.232 - CX_TEST_ASSERT(buf.size == 11); 2.233 - CX_TEST_ASSERT(buf.pos == 11); 2.234 - EXPECT_GE(buf.capacity, 11); 2.235 - EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0); 2.236 -} 2.237 - 2.238 -TEST_F(BufferWrite, MultOverflow) { 2.239 - const char *data = "testing"; 2.240 - CX_TEST_ASSERT(buf.capacity == 8); 2.241 - CX_TEST_ASSERT(buf.pos == 4); 2.242 - CX_TEST_ASSERT(buf.size == 4); 2.243 - size_t written = cxBufferWrite(data, 8, SIZE_MAX / 4, &buf); 2.244 - CX_TEST_ASSERT(written == 0); 2.245 - CX_TEST_ASSERT(buf.capacity == 8); 2.246 - CX_TEST_ASSERT(buf.pos == 4); 2.247 - CX_TEST_ASSERT(buf.size == 4); 2.248 - EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0); 2.249 -} 2.250 - 2.251 -TEST_F(BufferWrite, MaxCapaOverflow) { 2.252 - buf.flags |= CX_BUFFER_AUTO_EXTEND; 2.253 - const char *data = "testing"; 2.254 - CX_TEST_ASSERT(buf.capacity == 8); 2.255 - CX_TEST_ASSERT(buf.pos == 4); 2.256 - CX_TEST_ASSERT(buf.size == 4); 2.257 - size_t written = cxBufferWrite(data, 1, SIZE_MAX - 2, &buf); 2.258 - CX_TEST_ASSERT(written == 0); 2.259 - CX_TEST_ASSERT(buf.capacity == 8); 2.260 - CX_TEST_ASSERT(buf.pos == 4); 2.261 - CX_TEST_ASSERT(buf.size == 4); 2.262 - EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0); 2.263 -} 2.264 - 2.265 -TEST_F(BufferWrite, OnlyOverwrite) { 2.266 - buf.flags |= CX_BUFFER_AUTO_EXTEND; 2.267 - CX_TEST_ASSERT(buf.capacity == 8); 2.268 - memcpy(buf.space, "preptest", 8); 2.269 - buf.pos = 3; 2.270 - buf.size = 8; 2.271 - size_t written = cxBufferWrite("XXX", 2, 2, &buf); 2.272 - CX_TEST_ASSERT(written == 2); 2.273 - CX_TEST_ASSERT(buf.capacity == 8); 2.274 - CX_TEST_ASSERT(buf.size == 8); 2.275 - CX_TEST_ASSERT(buf.pos == 7); 2.276 - EXPECT_EQ(memcmp(buf.space, "preXXX\0t", 8), 0); 2.277 -} 2.278 - 2.279 -TEST_F(BufferWrite, FlushAtCapacity) { 2.280 - enableFlushing(); 2.281 - CX_TEST_ASSERT(buf.capacity == 8); 2.282 - CX_TEST_ASSERT(buf.pos == 4); 2.283 - size_t written = cxBufferWrite("foo", 1, 3, &buf); 2.284 - CX_TEST_ASSERT(written == 3); 2.285 - CX_TEST_ASSERT(buf.pos == 7); 2.286 - CX_TEST_ASSERT(buf.size == 7); 2.287 - CX_TEST_ASSERT(target.pos == 0); 2.288 - CX_TEST_ASSERT(target.size == 0); 2.289 - written = cxBufferWrite("hello", 1, 5, &buf); 2.290 - CX_TEST_ASSERT(written == 5); 2.291 - CX_TEST_ASSERT(buf.pos == 0); 2.292 - CX_TEST_ASSERT(buf.size == 0); 2.293 - CX_TEST_ASSERT(buf.capacity == 8); 2.294 - CX_TEST_ASSERT(target.pos == 12); 2.295 - CX_TEST_ASSERT(target.size == 12); 2.296 - EXPECT_EQ(memcmp(target.space, "prepfoohello", 12), 0); 2.297 -} 2.298 - 2.299 -TEST_F(BufferWrite, FlushAtThreshold) { 2.300 - enableFlushing(); 2.301 - buf.flush_threshold = 12; 2.302 - buf.flags |= CX_BUFFER_AUTO_EXTEND; 2.303 - CX_TEST_ASSERT(buf.capacity == 8); 2.304 - CX_TEST_ASSERT(buf.pos == 4); 2.305 - size_t written = cxBufferWrite("foobar", 1, 6, &buf); 2.306 - CX_TEST_ASSERT(written == 6); 2.307 - CX_TEST_ASSERT(buf.pos == 10); 2.308 - CX_TEST_ASSERT(buf.size == 10); 2.309 - ASSERT_GE(buf.capacity, 10); 2.310 - ASSERT_LE(buf.capacity, 12); 2.311 - CX_TEST_ASSERT(target.pos == 0); 2.312 - CX_TEST_ASSERT(target.size == 0); 2.313 - written = cxBufferWrite("hello", 1, 5, &buf); 2.314 - CX_TEST_ASSERT(written == 5); 2.315 - CX_TEST_ASSERT(buf.pos == 0); 2.316 - CX_TEST_ASSERT(buf.size == 0); 2.317 - EXPECT_LE(buf.capacity, 12); 2.318 - CX_TEST_ASSERT(target.pos == 15); 2.319 - CX_TEST_ASSERT(target.size == 15); 2.320 - EXPECT_EQ(memcmp(target.space, "prepfoobarhello", 15), 0); 2.321 -} 2.322 - 2.323 -TEST_F(BufferWrite, FlushRateLimited) { 2.324 - enableFlushing(); 2.325 - // limit the rate of the flush function and the capacity of the target 2.326 - target.capacity = 16; 2.327 - target.flags &= ~CX_BUFFER_AUTO_EXTEND; 2.328 - buf.flush_func = (cx_write_func) mock_write_limited_rate; 2.329 - CX_TEST_ASSERT(buf.capacity == 8); 2.330 - CX_TEST_ASSERT(buf.pos == 4); 2.331 - size_t written = cxBufferWrite("foo", 1, 3, &buf); 2.332 - CX_TEST_ASSERT(written == 3); 2.333 - CX_TEST_ASSERT(buf.pos == 7); 2.334 - CX_TEST_ASSERT(buf.size == 7); 2.335 - CX_TEST_ASSERT(target.pos == 0); 2.336 - CX_TEST_ASSERT(target.size == 0); 2.337 - written = cxBufferWrite("hello, world!", 1, 13, &buf); 2.338 - // " world!" fits into this buffer, the remaining stuff is flushed out 2.339 - CX_TEST_ASSERT(written == 13); 2.340 - CX_TEST_ASSERT(buf.pos == 7); 2.341 - CX_TEST_ASSERT(buf.size == 7); 2.342 - CX_TEST_ASSERT(buf.capacity == 8); 2.343 - EXPECT_EQ(memcmp(buf.space, " world!", 7), 0); 2.344 - CX_TEST_ASSERT(target.pos == 13); 2.345 - CX_TEST_ASSERT(target.size == 13); 2.346 - CX_TEST_ASSERT(target.capacity == 16); 2.347 - EXPECT_EQ(memcmp(target.space, "prepfoohello,", 13), 0); 2.348 -} 2.349 - 2.350 -class BufferRead : public ::testing::Test { 2.351 -protected: 2.352 - CxBuffer buf{}; 2.353 - 2.354 - void SetUp() override { 2.355 - cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); 2.356 - buf.capacity = 8; // artificially reduce capacity to check OOB writes 2.357 - memset(buf.space, 0, 16); 2.358 - memcpy(buf.space, "some data", 9); 2.359 - buf.size = 9; 2.360 - } 2.361 - 2.362 - void TearDown() override { 2.363 - cxBufferDestroy(&buf); 2.364 - } 2.365 -}; 2.366 - 2.367 -TEST_F(BufferRead, GetByte) { 2.368 - buf.pos = 2; 2.369 - EXPECT_EQ(cxBufferGet(&buf), 'm'); 2.370 - EXPECT_EQ(cxBufferGet(&buf), 'e'); 2.371 - EXPECT_EQ(cxBufferGet(&buf), ' '); 2.372 - EXPECT_EQ(cxBufferGet(&buf), 'd'); 2.373 - CX_TEST_ASSERT(buf.pos == 6); 2.374 -} 2.375 - 2.376 -TEST_F(BufferRead, GetEof) { 2.377 - buf.pos = buf.size; 2.378 - EXPECT_EQ(cxBufferGet(&buf), EOF); 2.379 -} 2.380 - 2.381 -TEST_F(BufferRead, ReadWithinBounds) { 2.382 - buf.pos = 2; 2.383 - char target[4]; 2.384 - auto read = cxBufferRead(&target, 1, 4, &buf); 2.385 - CX_TEST_ASSERT(read == 4); 2.386 - EXPECT_EQ(memcmp(&target, "me d", 4), 0); 2.387 - CX_TEST_ASSERT(buf.pos == 6); 2.388 -} 2.389 - 2.390 -TEST_F(BufferRead, ReadOutOfBounds) { 2.391 - buf.pos = 6; 2.392 - char target[4]; 2.393 - auto read = cxBufferRead(&target, 1, 4, &buf); 2.394 - CX_TEST_ASSERT(read == 3); 2.395 - EXPECT_EQ(memcmp(&target, "ata", 3), 0); 2.396 - CX_TEST_ASSERT(buf.pos == 9); 2.397 -} 2.398 - 2.399 -TEST_F(BufferRead, ReadOutOfBoundsMultibyte) { 2.400 - buf.pos = 6; 2.401 - char target[4]; 2.402 - target[2] = '\0'; 2.403 - auto read = cxBufferRead(&target, 2, 2, &buf); 2.404 - CX_TEST_ASSERT(read == 1); 2.405 - EXPECT_EQ(memcmp(&target, "at\0", 3), 0); 2.406 - CX_TEST_ASSERT(buf.pos == 8); 2.407 -} 2.408 - 2.409 -TEST_F(BufferRead, ReadEof) { 2.410 - buf.pos = 9; 2.411 - char target[4]; 2.412 - auto read = cxBufferRead(&target, 1, 1, &buf); 2.413 - CX_TEST_ASSERT(read == 0); 2.414 - CX_TEST_ASSERT(buf.pos == 9); 2.415 -}