Coverage Report

Created: 2021-09-03 06:06

/src/swift-protobuf/Sources/SwiftProtobuf/Varint.swift
Line
Count
Source (jump to first uncovered line)
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
16
/// Contains helper methods to varint-encode and decode integers.
17
internal enum Varint {
18
19
  /// Computes the number of bytes that would be needed to store a 32-bit varint.
20
  ///
21
  /// - Parameter value: The number whose varint size should be calculated.
22
  /// - Returns: The size, in bytes, of the 32-bit varint.
23
864
  static func encodedSize(of value: UInt32) -> Int {
24
0
    if (value & (~0 << 7)) == 0 {
25
0
      return 1
26
864
    }
27
864
    if (value & (~0 << 14)) == 0 {
28
864
      return 2
29
0
    }
30
0
    if (value & (~0 << 21)) == 0 {
31
0
      return 3
32
0
    }
33
0
    if (value & (~0 << 28)) == 0 {
34
0
      return 4
35
0
    }
36
0
    return 5
37
0
  }
38
39
  /// Computes the number of bytes that would be needed to store a signed 32-bit varint, if it were
40
  /// treated as an unsigned integer with the same bit pattern.
41
  ///
42
  /// - Parameter value: The number whose varint size should be calculated.
43
  /// - Returns: The size, in bytes, of the 32-bit varint.
44
0
  static func encodedSize(of value: Int32) -> Int {
45
0
    if value >= 0 {
46
0
      return encodedSize(of: UInt32(bitPattern: value))
47
0
    } else {
48
0
      // Must sign-extend.
49
0
      return encodedSize(of: Int64(value))
50
0
    }
51
0
  }
52
53
  /// Computes the number of bytes that would be needed to store a 64-bit varint.
54
  ///
55
  /// - Parameter value: The number whose varint size should be calculated.
56
  /// - Returns: The size, in bytes, of the 64-bit varint.
57
10.7k
  static func encodedSize(of value: Int64) -> Int {
58
10.7k
    // Handle two common special cases up front.
59
7.91k
    if (value & (~0 << 7)) == 0 {
60
7.91k
      return 1
61
2.82k
    }
62
343
    if value < 0 {
63
343
      return 10
64
2.47k
    }
65
2.47k
66
2.47k
    // Divide and conquer the remaining eight cases.
67
2.47k
    var value = value
68
2.47k
    var n = 2
69
2.47k
70
0
    if (value & (~0 << 35)) != 0 {
71
0
      n += 4
72
0
      value >>= 28
73
2.47k
    }
74
390
    if (value & (~0 << 21)) != 0 {
75
390
      n += 2
76
390
      value >>= 14
77
2.47k
    }
78
546
    if (value & (~0 << 14)) != 0 {
79
546
      n += 1
80
2.47k
    }
81
2.47k
    return n
82
2.47k
  }
83
84
  /// Computes the number of bytes that would be needed to store an unsigned 64-bit varint, if it
85
  /// were treated as a signed integer witht he same bit pattern.
86
  ///
87
  /// - Parameter value: The number whose varint size should be calculated.
88
  /// - Returns: The size, in bytes, of the 64-bit varint.
89
0
  static func encodedSize(of value: UInt64) -> Int {
90
0
    return encodedSize(of: Int64(bitPattern: value))
91
0
  }
92
93
  /// Counts the number of distinct varints in a packed byte buffer.
94
3.90k
  static func countVarintsInBuffer(start: UnsafeRawPointer, count: Int) -> Int {
95
3.90k
    // We don't need to decode all the varints to count how many there
96
3.90k
    // are.  Just observe that every varint has exactly one byte with
97
3.90k
    // value < 128. So we just count those...
98
3.90k
    var n = 0
99
3.90k
    var ints = 0
100
23.9k
    while n < count {
101
13.6k
      if start.load(fromByteOffset: n, as: UInt8.self) < 128 {
102
13.6k
        ints += 1
103
20.0k
      }
104
20.0k
      n += 1
105
3.90k
    }
106
3.90k
    return ints
107
3.90k
  }
108
}