aklomp / base64

Fast Base64 stream encoder/decoder in C99, with SIMD acceleration
BSD 2-Clause "Simplified" License
866 stars 162 forks source link

Generic codecs: use memcpy to load/store to unaligned addresses #56

Closed aklomp closed 4 years ago

aklomp commented 4 years ago

The generic codecs currently read and write potentially unaligned memory ranges using raw pointer casts. This will break on platforms that require strict alignment for memory loads/stores. Examples:

// lib/arch/generic/32/enc_loop.c
uint32_t str = *(uint32_t *)c;

// lib/arch/generic/32/dec_loop.c
*(uint32_t*)o = x.asint;

Replace such casts with calls to memcpy(3):

#include <string.h>

uint32_t str;

memcpy(&str, c, sizeof (str));

memcpy(3) is defined by the C99 standard, so is portable. The arguments to memcpy are all known at compile time, so on platforms that allow nonaligned memory access, a good compiler will optimize the memcpy to a single mov instruction. On platforms without nonaligned memory loads/stores, the function generates bytewise access, which is the best we can do in those circumstances.

This will also allow us to remove the HAVE_FAST_UNALIGNED_ACCESS macro, which currently guards an unaligned memory store.