blob: c5b712f9ab9233c1bc76aad0c0db1a7be6d45449 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string.h>
template <typename T>
size_t WritePaddedInternal(T* buffer, const void* msg, size_t length) {
size_t needs_padding = (length % sizeof(T)) > 0;
size_t padding = sizeof(T) - (length % sizeof(T));
// Multiply by needs_padding to set padding to 0 if no padding
// is necessary. This avoids unnecessary branching.
padding *= needs_padding;
// If we added padding -- zero the padding bytes in a single write operation
size_t is_nonzero_length = length != 0;
size_t eof_in_bytes = length + padding;
size_t eof_in_words = eof_in_bytes / sizeof(T);
size_t last_word = eof_in_words - is_nonzero_length;
// Set the last word in the buffer to zero before writing
// the data to it if we added padding. If we didn't add padding,
// multiply by 1 which ends up writing back the current contents of that word
// resulting in a NOP.
buffer[last_word] *= !needs_padding;
memcpy(buffer, msg, length);
return (length + padding) / sizeof(T);
}