SOL_API int sol_buffer_insert_as_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 encoded_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_as_base64(buf, slice, base64_map); encoded_size = sol_util_base64_calculate_encoded_len(slice, base64_map); if (encoded_size < 0) return encoded_size; err = sol_util_size_add(buf->used, encoded_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 + encoded_size, p, buf->used - pos); r = sol_util_base64_encode(p, encoded_size, slice, base64_map); if (r != encoded_size) { memmove(p, p + encoded_size, buf->used - pos); if (nul_size) sol_buffer_ensure_nul_byte(buf); if (r < 0) return r; else return -EINVAL; } buf->used += encoded_size; if (nul_size) return sol_buffer_ensure_nul_byte(buf); return 0; }
SOL_API ssize_t sol_util_base64_encode(void *buf, size_t buflen, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)]) { char *output; const uint8_t *input; size_t req_len; size_t i, o; uint8_t c; SOL_NULL_CHECK(buf, -EINVAL); SOL_NULL_CHECK(slice.data, -EINVAL); if (slice.len == 0) return 0; req_len = sol_util_base64_calculate_encoded_len(slice, base64_map); SOL_INT_CHECK(buflen, < req_len, -ENOMEM); input = (const uint8_t *)slice.data; output = buf; for (i = 0, o = 0; i + 3 <= slice.len; i += 3) { c = (input[i] & (((1 << 6) - 1) << 2)) >> 2; output[o++] = base64_map[c]; c = (input[i] & ((1 << 2) - 1)) << 4; c |= (input[i + 1] & (((1 << 4) - 1) << 4)) >> 4; output[o++] = base64_map[c]; c = (input[i + 1] & ((1 << 4) - 1)) << 2; c |= (input[i + 2] & (((1 << 2) - 1) << 6)) >> 6; output[o++] = base64_map[c]; c = input[i + 2] & ((1 << 6) - 1); output[o++] = base64_map[c]; } if (i + 1 == slice.len) { c = (input[i] & (((1 << 6) - 1) << 2)) >> 2; output[o++] = base64_map[c]; c = (input[i] & ((1 << 2) - 1)) << 4; output[o++] = base64_map[c]; output[o++] = base64_map[64]; output[o++] = base64_map[64]; } else if (i + 2 == slice.len) {