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 }
SOL_API int sol_buffer_insert_from_base64(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)]) { char *p; size_t new_size; ssize_t decoded_size, r; const size_t nul_size = nul_byte_size(buf); int err; SOL_NULL_CHECK(buf, -EINVAL); SOL_INT_CHECK(pos, > buf->used, -EINVAL); if (slice.len == 0) return 0; if (pos == buf->used) return sol_buffer_append_from_base64(buf, slice, base64_map); decoded_size = sol_util_base64_calculate_decoded_len(slice, base64_map); if (decoded_size < 0) return decoded_size; err = sol_util_size_add(buf->used, decoded_size, &new_size); if (err < 0) return err; if (nul_size) { err = sol_util_size_add(new_size, nul_size, &new_size); if (err < 0) return err; } err = sol_buffer_ensure(buf, new_size); if (err < 0) return err; p = sol_buffer_at(buf, pos); memmove(p + decoded_size, p, buf->used - pos); r = sol_util_base64_decode(p, decoded_size, slice, base64_map); if (r != decoded_size) { memmove(p, p + decoded_size, buf->used - pos); if (nul_size) sol_buffer_ensure_nul_byte(buf); if (r < 0) return r; else return -EINVAL; } buf->used += decoded_size; if (nul_size) return sol_buffer_ensure_nul_byte(buf); return 0; }