Skip to content

Commit f81e902

Browse files
authored
Merge pull request #120 from owenv/serialized-diags
Move LLVM Bitstream Utils from swift-driver and add a Swift/Clang Serialized Diags Reader
2 parents 8b60325 + 08bd94f commit f81e902

File tree

7 files changed

+785
-0
lines changed

7 files changed

+785
-0
lines changed

Sources/TSCUtility/Bits.swift

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2020 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
13+
struct Bits: RandomAccessCollection {
14+
var buffer: Data
15+
16+
var startIndex: Int { return 0 }
17+
var endIndex: Int { return buffer.count * 8 }
18+
19+
subscript(index: Int) -> UInt8 {
20+
let byte = buffer[index / 8]
21+
return (byte >> UInt8(index % 8)) & 1
22+
}
23+
24+
func readBits(atOffset offset: Int, count: Int) -> UInt64 {
25+
precondition(count >= 0 && count <= 64)
26+
precondition(offset >= 0)
27+
precondition(offset &+ count >= offset)
28+
precondition(offset &+ count <= self.endIndex)
29+
30+
return buffer.withUnsafeBytes { (bytes: UnsafeRawBufferPointer) in
31+
let upperBound = offset &+ count
32+
let topByteIndex = upperBound >> 3
33+
var result: UInt64 = 0
34+
if upperBound & 7 != 0 {
35+
let mask: UInt8 = (1 << UInt8(upperBound & 7)) &- 1
36+
result = UInt64(bytes[topByteIndex] & mask)
37+
}
38+
for i in ((offset >> 3)..<(upperBound >> 3)).reversed() {
39+
result <<= 8
40+
result |= UInt64(bytes[i])
41+
}
42+
if offset & 7 != 0 {
43+
result >>= UInt64(offset & 7)
44+
}
45+
return result
46+
}
47+
}
48+
49+
struct Cursor {
50+
enum Error: Swift.Error { case bufferOverflow }
51+
52+
let buffer: Bits
53+
private var offset: Int = 0
54+
55+
init(buffer: Bits) {
56+
self.buffer = buffer
57+
}
58+
59+
init(buffer: Data) {
60+
self.init(buffer: Bits(buffer: buffer))
61+
}
62+
63+
var isAtEnd: Bool {
64+
return offset == buffer.count
65+
}
66+
67+
func peek(_ count: Int) throws -> UInt64 {
68+
if buffer.count - offset < count { throw Error.bufferOverflow }
69+
return buffer.readBits(atOffset: offset, count: count)
70+
}
71+
72+
mutating func read(_ count: Int) throws -> UInt64 {
73+
defer { offset += count }
74+
return try peek(count)
75+
}
76+
77+
mutating func read(bytes count: Int) throws -> Data {
78+
precondition(count >= 0)
79+
precondition(offset & 0b111 == 0)
80+
let newOffset = offset &+ (count << 3)
81+
precondition(newOffset >= offset)
82+
if newOffset > buffer.count { throw Error.bufferOverflow }
83+
defer { offset = newOffset }
84+
return buffer.buffer.dropFirst(offset >> 3).prefix((newOffset - offset) >> 3)
85+
}
86+
87+
mutating func advance(toBitAlignment align: Int) throws {
88+
precondition(align > 0)
89+
precondition(offset &+ (align&-1) >= offset)
90+
precondition(align & (align &- 1) == 0)
91+
if offset % align == 0 { return }
92+
offset = (offset &+ align) & ~(align &- 1)
93+
if offset > buffer.count { throw Error.bufferOverflow }
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)