Coverage Report

Created: 2026-11-12 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/swift-protobuf/Sources/SwiftProtobuf/Varint.swift
Line
Count
Source
1
// Sources/SwiftProtobuf/Varint.swift - Varint encoding/decoding helpers
2
//
3
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
4
// Licensed under Apache License v2.0 with Runtime Library Exception
5
//
6
// See LICENSE.txt for license information:
7
// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
8
//
9
// -----------------------------------------------------------------------------
10
///
11
/// Helper functions to varint-encode and decode integers.
12
///
13
// -----------------------------------------------------------------------------
14
15
/// Contains helper methods to varint-encode and decode integers.
16
package enum Varint {
17
18
    /// Computes the number of bytes that would be needed to store a 32-bit varint.
19
    ///
20
    /// - Parameter value: The number whose varint size should be calculated.
21
    /// - Returns: The size, in bytes, of the 32-bit varint.
22
    @usableFromInline
23
2.36M
    package static func encodedSize(of value: UInt32) -> Int {
24
2.36M
        // This logic comes from the upstream C++ for CodedOutputStream::VarintSize32(uint32_t),
25
2.36M
        // it provides a branchless calculation of the size.
26
2.36M
        let clz = value.leadingZeroBitCount
27
2.36M
        return ((UInt32.bitWidth &* 9 &+ 64) &- (clz &* 9)) / 64
28
2.36M
    }
29
30
    /// Computes the number of bytes that would be needed to store a signed 32-bit varint, if it were
31
    /// treated as an unsigned integer with the same bit pattern.
32
    ///
33
    /// - Parameter value: The number whose varint size should be calculated.
34
    /// - Returns: The size, in bytes, of the 32-bit varint.
35
    @inline(__always)
36
292k
    package static func encodedSize(of value: Int32) -> Int {
37
292k
        // Must sign-extend.
38
292k
        encodedSize(of: Int64(value))
39
292k
    }
40
41
    /// Computes the number of bytes that would be needed to store a 64-bit varint.
42
    ///
43
    /// - Parameter value: The number whose varint size should be calculated.
44
    /// - Returns: The size, in bytes, of the 64-bit varint.
45
    @inline(__always)
46
33.2k
    static func encodedSize(of value: Int64) -> Int {
47
33.2k
        encodedSize(of: UInt64(bitPattern: value))
48
33.2k
    }
49
50
    /// Computes the number of bytes that would be needed to store an unsigned 64-bit varint, if it
51
    /// were treated as a signed integer with the same bit pattern.
52
    ///
53
    /// - Parameter value: The number whose varint size should be calculated.
54
    /// - Returns: The size, in bytes, of the 64-bit varint.
55
    @usableFromInline
56
3.68M
    static func encodedSize(of value: UInt64) -> Int {
57
3.68M
        // This logic comes from the upstream C++ for CodedOutputStream::VarintSize64(uint64_t),
58
3.68M
        // it provides a branchless calculation of the size.
59
3.68M
        let clz = value.leadingZeroBitCount
60
3.68M
        return ((UInt64.bitWidth &* 9 &+ 64) &- (clz &* 9)) / 64
61
3.68M
    }
62
63
    /// Counts the number of distinct varints in a packed byte buffer.
64
7
    static func countVarintsInBuffer(start: UnsafeRawPointer, count: Int) -> Int {
65
7
        // We don't need to decode all the varints to count how many there
66
7
        // are.  Just observe that every varint has exactly one byte with
67
7
        // value < 128. So we just count those...
68
7
        var n = 0
69
7
        var ints = 0
70
214
        while n < count {
71
207
            if start.load(fromByteOffset: n, as: UInt8.self) < 128 {
72
188
                ints &+= 1
73
188
            }
74
207
            n &+= 1
75
207
        }
76
7
        return ints
77
7
    }
78
}