File: BitArray%2BCodable.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (73 lines) | stat: -rw-r--r-- 2,886 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Collections open source project
//
// Copyright (c) 2022 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

extension BitArray: Codable {
  /// Encodes this bit array into the given encoder.
  ///
  /// Bit arrays are encoded as an unkeyed container of `UInt64` values,
  /// representing the total number of bits in the array, followed by
  /// UInt64-sized pieces of the underlying bitmap.
  ///
  /// - Parameter encoder: The encoder to write data to.
  public func encode(to encoder: Encoder) throws {
    var container = encoder.unkeyedContainer()
    try container.encode(UInt64(truncatingIfNeeded: _count))
    try _storage._encodeAsUInt64(to: &container)
  }

  /// Creates a new bit array by decoding from the given decoder.
  ///
  /// Bit arrays are encoded as an unkeyed container of `UInt64` values,
  /// representing the total number of bits in the array, followed by
  /// UInt64-sized pieces of the underlying bitmap.
  ///
  /// - Parameter decoder: The decoder to read data from.
  public init(from decoder: Decoder) throws {
    var container = try decoder.unkeyedContainer()
    guard let count = UInt(exactly: try container.decode(UInt64.self)) else {
      let context = DecodingError.Context(
        codingPath: container.codingPath,
        debugDescription: "Bit Array too long")
      throw DecodingError.dataCorrupted(context)
    }
    var words = try [_Word](
      _fromUInt64: &container,
      reservingCount: container.count.map { Swift.max(1, $0) - 1 })
    if _Word.capacity < UInt64.bitWidth,
        count <= (words.count - 1) * _Word.capacity
    {
      let last = words.removeLast()
      guard last.isEmpty else {
        let context = DecodingError.Context(
          codingPath: container.codingPath,
          debugDescription: "Unexpected bits after end")
        throw DecodingError.dataCorrupted(context)
      }
    }
    guard
      count <= words.count * _Word.capacity,
      count > (words.count - 1) * _Word.capacity
    else {
      let context = DecodingError.Context(
        codingPath: container.codingPath,
        debugDescription: "Decoded words don't match expected count")
      throw DecodingError.dataCorrupted(context)
    }
    let bit = _BitPosition(count).bit
    if bit > 0, !words.last!.subtracting(_Word(upTo: bit)).isEmpty {
      let context = DecodingError.Context(
        codingPath: container.codingPath,
        debugDescription: "Unexpected bits after end")
      throw DecodingError.dataCorrupted(context)
    }
    self.init(_storage: words, count: count)
  }
}