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 }