Coverage Report

Created: 2025-09-08 06:42

/src/swift-nio/Sources/NIOCore/IntegerBitPacking.swift
Line
Count
Source (jump to first uncovered line)
1
//===----------------------------------------------------------------------===//
2
//
3
// This source file is part of the SwiftNIO open source project
4
//
5
// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors
6
// Licensed under Apache License v2.0
7
//
8
// See LICENSE.txt for license information
9
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10
//
11
// SPDX-License-Identifier: Apache-2.0
12
//
13
//===----------------------------------------------------------------------===//
14
15
// FIXME: Duplicated in NIO.
16
17
@usableFromInline
18
enum _IntegerBitPacking: Sendable {}
19
20
extension _IntegerBitPacking {
21
    @inlinable
22
    static func packUU<
23
        Left: FixedWidthInteger & UnsignedInteger,
24
        Right: FixedWidthInteger & UnsignedInteger,
25
        Result: FixedWidthInteger & UnsignedInteger
26
    >(
27
        _ left: Left,
28
        _ right: Right,
29
        type: Result.Type = Result.self
30
2.75G
    ) -> Result {
31
2.75G
        assert(MemoryLayout<Left>.size + MemoryLayout<Right>.size <= MemoryLayout<Result>.size)
32
2.75G
33
2.75G
        let resultLeft = Result(left)
34
2.75G
        let resultRight = Result(right)
35
2.75G
        let result = (resultLeft << Right.bitWidth) | resultRight
36
2.75G
        assert(result.nonzeroBitCount == left.nonzeroBitCount + right.nonzeroBitCount)
37
2.75G
        return result
38
2.75G
    }
39
40
    @inlinable
41
    static func unpackUU<
42
        Input: FixedWidthInteger & UnsignedInteger,
43
        Left: FixedWidthInteger & UnsignedInteger,
44
        Right: FixedWidthInteger & UnsignedInteger
45
    >(
46
        _ input: Input,
47
        leftType: Left.Type = Left.self,
48
        rightType: Right.Type = Right.self
49
1.78G
    ) -> (Left, Right) {
50
1.78G
        assert(MemoryLayout<Left>.size + MemoryLayout<Right>.size <= MemoryLayout<Input>.size)
51
1.78G
52
1.78G
        let leftMask = Input(Left.max)
53
1.78G
        let rightMask = Input(Right.max)
54
1.78G
        let right = input & rightMask
55
1.78G
        let left = (input >> Right.bitWidth) & leftMask
56
1.78G
57
1.78G
        assert(input.nonzeroBitCount == left.nonzeroBitCount + right.nonzeroBitCount)
58
1.78G
        return (Left(left), Right(right))
59
1.78G
    }
60
}
61
62
@usableFromInline
63
enum IntegerBitPacking: Sendable {}
64
65
extension IntegerBitPacking {
66
    @inlinable
67
0
    static func packUInt32UInt16UInt8(_ left: UInt32, _ middle: UInt16, _ right: UInt8) -> UInt64 {
68
0
        _IntegerBitPacking.packUU(
69
0
            _IntegerBitPacking.packUU(right, middle, type: UInt32.self),
70
0
            left
71
0
        )
72
0
    }
73
74
    @inlinable
75
0
    static func unpackUInt32UInt16UInt8(_ value: UInt64) -> (UInt32, UInt16, UInt8) {
76
0
        let leftRight = _IntegerBitPacking.unpackUU(value, leftType: UInt32.self, rightType: UInt32.self)
77
0
        let left = _IntegerBitPacking.unpackUU(leftRight.0, leftType: UInt8.self, rightType: UInt16.self)
78
0
        return (leftRight.1, left.1, left.0)
79
0
    }
80
81
    @inlinable
82
0
    static func packUInt8UInt8(_ left: UInt8, _ right: UInt8) -> UInt16 {
83
0
        _IntegerBitPacking.packUU(left, right)
84
0
    }
85
86
    @inlinable
87
0
    static func unpackUInt8UInt8(_ value: UInt16) -> (UInt8, UInt8) {
88
0
        _IntegerBitPacking.unpackUU(value)
89
0
    }
90
91
    @inlinable
92
2.27G
    static func packUInt16UInt8(_ left: UInt16, _ right: UInt8) -> UInt32 {
93
2.27G
        _IntegerBitPacking.packUU(left, right)
94
2.27G
    }
95
96
    @inlinable
97
1.78G
    static func unpackUInt16UInt8(_ value: UInt32) -> (UInt16, UInt8) {
98
1.78G
        _IntegerBitPacking.unpackUU(value)
99
1.78G
    }
100
101
    @inlinable
102
0
    static func packUInt32CInt(_ left: UInt32, _ right: CInt) -> UInt64 {
103
0
        _IntegerBitPacking.packUU(left, UInt32(truncatingIfNeeded: right))
104
0
    }
105
106
    @inlinable
107
0
    static func unpackUInt32CInt(_ value: UInt64) -> (UInt32, CInt) {
108
0
        let unpacked = _IntegerBitPacking.unpackUU(value, leftType: UInt32.self, rightType: UInt32.self)
109
0
        return (unpacked.0, CInt(truncatingIfNeeded: unpacked.1))
110
0
    }
111
}