static void test_no_nul_byte(void) { struct sol_buffer buf; int32_t backend; int32_t value = 0xdeadbeef; int err; sol_buffer_init_flags(&buf, &backend, sizeof(backend), SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED | SOL_BUFFER_FLAGS_NO_NUL_BYTE); err = sol_buffer_ensure(&buf, sizeof(int32_t)); ASSERT_INT_EQ(err, 0); err = sol_buffer_append_slice(&buf, SOL_STR_SLICE_STR((const char *)&value, sizeof(value))); ASSERT_INT_EQ(err, 0); err = sol_buffer_append_slice(&buf, SOL_STR_SLICE_STR((const char *)&value, sizeof(value))); ASSERT_INT_NE(err, 0); sol_buffer_fini(&buf); sol_buffer_init_flags(&buf, NULL, 0, SOL_BUFFER_FLAGS_NO_NUL_BYTE); err = sol_buffer_append_printf(&buf, "123"); ASSERT_INT_EQ(err, 0); err = sol_buffer_append_printf(&buf, "4"); ASSERT_INT_EQ(err, 0); ASSERT(sol_str_slice_eq(sol_buffer_get_slice(&buf), SOL_STR_SLICE_STR("1234", 4))); sol_buffer_fini(&buf); }
static void test_remove_data(void) { struct sol_buffer buf; struct sol_str_slice slice; int err; sol_buffer_init(&buf); slice = sol_str_slice_from_str("ABCDEFGHI"); err = sol_buffer_append_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("ABCDEFGHI")); ASSERT_STR_EQ(buf.data, "ABCDEFGHI"); err = sol_buffer_remove_data(&buf, strlen("ABC"), 0); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("DEFGHI")); err = sol_buffer_remove_data(&buf, strlen("GHI"), 3); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("DEF")); err = sol_buffer_remove_data(&buf, strlen("DEF"), 0); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, 0); err = sol_buffer_remove_data(&buf, 100, 0); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, 0); err = sol_buffer_remove_data(&buf, 0, 100); ASSERT_INT_EQ(err, -EINVAL); sol_buffer_fini(&buf); }
static void test_append_from_base16(void) { struct sol_buffer buf; struct sol_str_slice slice; const char to_decode[] = "546573742001090a0f2048656c6c6f"; int err; #define B16_DECODED "Test \x01\x09\x0a\x0f Hello" sol_buffer_init(&buf); slice = sol_str_slice_from_str("XYZ"); err = sol_buffer_append_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("XYZ")); ASSERT_STR_EQ(buf.data, "XYZ"); slice = sol_str_slice_from_str(to_decode); err = sol_buffer_append_from_base16(&buf, slice, SOL_DECODE_LOWERCASE); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("XYZ" B16_DECODED)); ASSERT_STR_EQ(buf.data, "XYZ" B16_DECODED); sol_buffer_fini(&buf); #undef B16_DECODED }
static void test_append_from_base64(void) { struct sol_buffer buf; struct sol_str_slice slice; const char to_decode[] = "VGhpcyBpcyBhIG1lc3NhZ2UgdGhhdCBpcyBtdWx0aXBsZSBvZiAzIGNoYXJz"; int err; #define B64_DECODED "This is a message that is multiple of 3 chars" sol_buffer_init(&buf); slice = sol_str_slice_from_str("XYZ"); err = sol_buffer_append_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("XYZ")); ASSERT_STR_EQ(buf.data, "XYZ"); slice = sol_str_slice_from_str(to_decode); err = sol_buffer_append_from_base64(&buf, slice, SOL_BASE64_MAP); ASSERT_INT_EQ(err, 0); ASSERT_INT_EQ(buf.used, strlen("XYZ" B64_DECODED)); ASSERT_STR_EQ(buf.data, "XYZ" B64_DECODED); sol_buffer_fini(&buf); #undef B64_DECODED }
static bool producer_make_data(void *data) { void *v; size_t size; struct sol_blob *blob; struct sol_buffer buf = SOL_BUFFER_INIT_EMPTY; static uint16_t packets_created = 0; bool keep_running = true; int r; //Stop the production until the pendind blob is sent if (pending_blob) { printf("Waiting for blob data: %.*s to be transfered.\n", SOL_STR_SLICE_PRINT(sol_str_slice_from_blob(pending_blob))); return true; } packets_created++; //Generate data if (packets_created != MAX_PACKETS) r = sol_util_uuid_gen(true, true, &buf); else { r = sol_buffer_append_slice(&buf, sol_str_slice_from_str("close")); keep_running = false; } if (r < 0) { fprintf(stderr, "Could not create the UUID - Reason: %s\n", sol_util_strerrora(-r)); goto err_exit; } v = sol_buffer_steal(&buf, &size); blob = sol_blob_new(&SOL_BLOB_TYPE_DEFAULT, NULL, v, size + 1); if (!blob) { fprintf(stderr, "Could not alloc memory for the blob\n"); goto err_exit; } //Send it if (!send_blob(blob)) goto err_exit; if (!keep_running) goto exit; return true; err_exit: sol_quit(); exit: producer_timeout = NULL; return false; }
/* * If index is between [' and '] we need to unescape the ' char and to remove * the [' and '] separator. */ static int json_path_parse_object_key(const struct sol_str_slice slice, struct sol_buffer *buffer) { const char *end, *p, *p2; struct sol_str_slice key; int r; if (slice.data[0] != '[') { sol_buffer_init_flags(buffer, (char *)slice.data, slice.len, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED | SOL_BUFFER_FLAGS_NO_NUL_BYTE); buffer->used = buffer->capacity; return 0; } //remove [' and '] key = SOL_STR_SLICE_STR(slice.data + 2, slice.len - 4); //unescape '\'' if necessary sol_buffer_init_flags(buffer, NULL, 0, SOL_BUFFER_FLAGS_NO_NUL_BYTE); end = key.data + key.len; for (p = key.data; p < end; p = p2 + 1) { p2 = memchr(p, '\'', end - p); if (!p2) break; //Append string preceding ' r = sol_buffer_append_slice(buffer, SOL_STR_SLICE_STR(p, p2 - p - 1)); SOL_INT_CHECK(r, < 0, r); r = sol_buffer_append_char(buffer, '\''); SOL_INT_CHECK(r, < 0, r); } if (!buffer->data) { sol_buffer_init_flags(buffer, (char *)key.data, key.len, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED | SOL_BUFFER_FLAGS_NO_NUL_BYTE); buffer->used = buffer->capacity; return 0; } //Append the string leftover r = sol_buffer_append_slice(buffer, SOL_STR_SLICE_STR(p, end - p)); SOL_INT_CHECK(r, < 0, r); return 0; }
/* * This function takes mdata->to_regexp and copies it into a struct * sol_buffer, with all the number ref entries already replaced by the * due text. It assumes that @a buf is already initialized. */ static int get_unescaped_regexp_replacement_str(struct string_regexp_replace_data *mdata, struct sol_buffer *buf, int *match_vector, size_t match_cnt) { int r; struct sol_str_slice slice; char *ptr = mdata->to_regexp; SOL_NULL_CHECK(buf, -EINVAL); /* \g<number> or \<number> syntax. Go on as far as numbers are in * [0-9] range. Leading zeros are permitted. */ while (*ptr) { if (*ptr == '\\') { int n; uint64_t grp_num = 0; ptr++; if (*ptr == 'g') ptr++; for (; (n = *ptr - '0') >= 0 && n <= 9; ptr++) { if (!grp_num && !n) { continue; } r = sol_util_uint64_mul(grp_num, 10, &grp_num); SOL_INT_CHECK_GOTO(r, < 0, err); r = sol_util_uint64_add(grp_num, n, &grp_num); SOL_INT_CHECK_GOTO(r, < 0, err); } if (!grp_num || grp_num > match_cnt) { sol_flow_send_error_packet(mdata->node, EINVAL, "Could not process '%s' pattern's reference " "to non-existent subpattern on '%s'", mdata->to_regexp, mdata->regexp); r = -EINVAL; goto err; } slice = SOL_STR_SLICE_STR(mdata->orig_string + match_vector[grp_num * 2], match_vector[grp_num * 2 + 1] - match_vector[grp_num * 2]); r = sol_buffer_append_slice(buf, slice); SOL_INT_CHECK_GOTO(r, < 0, err); } else {
static void test_memory_not_owned(void) { struct sol_buffer buf; struct sol_str_slice slice; char backend[10]; int err; sol_buffer_init_flags(&buf, backend, sizeof(backend), SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED); err = sol_buffer_ensure(&buf, 0); ASSERT_INT_EQ(err, 0); /* ensure considers null-byte, so we use sizeof - 1 */ err = sol_buffer_ensure(&buf, sizeof(backend) - 1); ASSERT_INT_EQ(err, 0); err = sol_buffer_ensure(&buf, sizeof(backend) * 2); ASSERT_INT_EQ(err, -ENOMEM); err = sol_buffer_resize(&buf, 0); ASSERT_INT_EQ(err, -EPERM); slice = sol_str_slice_from_str("test"); err = sol_buffer_append_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_STR_EQ(buf.data, "test"); slice = sol_str_slice_from_str("other"); err = sol_buffer_append_slice(&buf, slice); ASSERT_INT_EQ(err, 0); ASSERT_STR_EQ(buf.data, "testother"); slice = sol_str_slice_from_str("OVERFLOW"); err = sol_buffer_append_slice(&buf, slice); ASSERT_INT_EQ(err, -ENOMEM); sol_buffer_fini(&buf); }
static int string_concat_to_buffer(struct sol_buffer *buffer, char **string, uint32_t var_initialized, const char *separator) { int r; struct sol_str_slice sep_slice; uint8_t i, count = 0; if (separator) sep_slice = sol_str_slice_from_str(separator); for (i = 0; i < CONCATENATE_IN_LEN; i++) { if (!(var_initialized & (1u << i))) continue; if (count && separator) { r = sol_buffer_append_slice(buffer, sep_slice); SOL_INT_CHECK(r, < 0, r); } r = sol_buffer_append_slice(buffer, sol_str_slice_from_str(string[i])); SOL_INT_CHECK(r, < 0, r); count++; }
static void test_append_slice(void) { struct sol_buffer buf; struct sol_str_slice slice; const char *str = "Hello"; const char *expected_str = "HelloHello"; char *backend; int err; backend = strdup(str); slice = sol_str_slice_from_str(backend); sol_buffer_init(&buf); err = sol_buffer_set_slice(&buf, slice); ASSERT(err >= 0); ASSERT_INT_EQ(buf.used, strlen(backend)); ASSERT_STR_EQ(buf.data, backend); err = sol_buffer_append_slice(&buf, slice); ASSERT(err >= 0); ASSERT_INT_EQ(buf.used, strlen(expected_str)); backend[1] = 'a'; ASSERT_STR_NE(buf.data, backend); ASSERT_STR_EQ(buf.data, expected_str); slice = sol_buffer_get_slice(&buf); ASSERT_INT_EQ(slice.len, buf.used); ASSERT_STR_EQ(slice.data, buf.data); slice = sol_buffer_get_slice_at(&buf, 2); ASSERT_INT_EQ(slice.len, buf.used - 2); ASSERT_STR_EQ(slice.data, (char *)buf.data + 2); sol_buffer_fini(&buf); free(backend); }
SOL_API int sol_buffer_insert_slice(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice) { const size_t nul_size = nul_byte_size(buf); char *p; size_t new_size; int err; SOL_NULL_CHECK(buf, -EINVAL); SOL_INT_CHECK(pos, > buf->used, -EINVAL); if (pos == buf->used) return sol_buffer_append_slice(buf, slice); err = sol_util_size_add(buf->used, slice.len, &new_size); if (err < 0) return err; /* Extra room for the ending NUL-byte. */ if (new_size >= SIZE_MAX - nul_size) return -EOVERFLOW; err = sol_buffer_ensure(buf, new_size + nul_size); if (err < 0) return err; p = sol_buffer_at(buf, pos); memmove(p + slice.len, p, buf->used - pos); memcpy(p, slice.data, slice.len); buf->used += slice.len; if (nul_size) { p = sol_buffer_at_end(buf); p[0] = '\0'; } return 0; }
sol_flow_send_error_packet(mdata->node, EINVAL, "Could not process '%s' pattern's reference " "to non-existent subpattern on '%s'", mdata->to_regexp, mdata->regexp); r = -EINVAL; goto err; } slice = SOL_STR_SLICE_STR(mdata->orig_string + match_vector[grp_num * 2], match_vector[grp_num * 2 + 1] - match_vector[grp_num * 2]); r = sol_buffer_append_slice(buf, slice); SOL_INT_CHECK_GOTO(r, < 0, err); } else { slice = SOL_STR_SLICE_STR(ptr++, 1); r = sol_buffer_append_slice(buf, slice); SOL_INT_CHECK_GOTO(r, < 0, err); } } if (buf->used >= (SIZE_MAX - 1) || sol_buffer_ensure(buf, buf->used + 1) < 0) goto err; *(char *)sol_buffer_at(buf, buf->used) = '\0'; return 0; err: return r; }