mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
Merge pull request #14305 from NixOS/alignment-utils
libutil: Add alignUp helper function, use in archive.cc
This commit is contained in:
commit
270f20a505
5 changed files with 45 additions and 1 deletions
18
src/libutil-tests/alignment.cc
Normal file
18
src/libutil-tests/alignment.cc
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include "nix/util/alignment.hh"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
TEST(alignUp, value)
|
||||||
|
{
|
||||||
|
for (uint64_t i = 1; i <= 8; ++i)
|
||||||
|
EXPECT_EQ(alignUp(i, 8), 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(alignUp, notAPowerOf2)
|
||||||
|
{
|
||||||
|
ASSERT_DEATH({ alignUp(1u, 42); }, "alignment must be a power of 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace nix
|
||||||
|
|
@ -44,6 +44,7 @@ config_priv_h = configure_file(
|
||||||
subdir('nix-meson-build-support/common')
|
subdir('nix-meson-build-support/common')
|
||||||
|
|
||||||
sources = files(
|
sources = files(
|
||||||
|
'alignment.cc',
|
||||||
'archive.cc',
|
'archive.cc',
|
||||||
'args.cc',
|
'args.cc',
|
||||||
'base-n.cc',
|
'base-n.cc',
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <strings.h> // for strcasecmp
|
#include <strings.h> // for strcasecmp
|
||||||
|
|
||||||
#include "nix/util/archive.hh"
|
#include "nix/util/archive.hh"
|
||||||
|
#include "nix/util/alignment.hh"
|
||||||
#include "nix/util/config-global.hh"
|
#include "nix/util/config-global.hh"
|
||||||
#include "nix/util/posix-source-accessor.hh"
|
#include "nix/util/posix-source-accessor.hh"
|
||||||
#include "nix/util/source-path.hh"
|
#include "nix/util/source-path.hh"
|
||||||
|
|
@ -133,7 +134,7 @@ static void parseContents(CreateRegularFileSink & sink, Source & source)
|
||||||
sink.preallocateContents(size);
|
sink.preallocateContents(size);
|
||||||
|
|
||||||
if (sink.skipContents) {
|
if (sink.skipContents) {
|
||||||
source.skip(size + (size % 8 ? 8 - (size % 8) : 0));
|
source.skip(alignUp(size, 8));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
23
src/libutil/include/nix/util/alignment.hh
Normal file
23
src/libutil/include/nix/util/alignment.hh
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
///@file
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
/// Aligns val upwards to be a multiple of alignment.
|
||||||
|
///
|
||||||
|
/// @pre alignment must be a power of 2.
|
||||||
|
template<typename T>
|
||||||
|
requires std::is_unsigned_v<T>
|
||||||
|
constexpr T alignUp(T val, unsigned alignment)
|
||||||
|
{
|
||||||
|
assert(std::has_single_bit(alignment) && "alignment must be a power of 2");
|
||||||
|
T mask = ~(T{alignment} - 1u);
|
||||||
|
return (val + alignment - 1) & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace nix
|
||||||
|
|
@ -4,6 +4,7 @@ include_dirs = [ include_directories('../..') ]
|
||||||
|
|
||||||
headers = files(
|
headers = files(
|
||||||
'abstract-setting-to-json.hh',
|
'abstract-setting-to-json.hh',
|
||||||
|
'alignment.hh',
|
||||||
'ansicolor.hh',
|
'ansicolor.hh',
|
||||||
'archive.hh',
|
'archive.hh',
|
||||||
'args.hh',
|
'args.hh',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue