Merge pull request #2092 from ewanmellor/swift-fix-unbufferedcharstream

Fix UnbufferedCharStream in the Swift runtime.
This commit is contained in:
Terence Parr 2017-11-04 10:50:29 -07:00 committed by GitHub
commit 85aaf1b0d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 18 additions and 14 deletions

View File

@ -19,6 +19,8 @@ import Foundation
* code points in the buffer as ints. * code points in the buffer as ints.
*/ */
open class UnbufferedCharStream: CharStream { open class UnbufferedCharStream: CharStream {
private let bufferSize: Int
/** /**
* A moving window buffer of the data being scanned. While there's a marker, * A moving window buffer of the data being scanned. While there's a marker,
* we keep adding to buffer. Otherwise, {@link #consume consume()} resets so * we keep adding to buffer. Otherwise, {@link #consume consume()} resets so
@ -77,6 +79,7 @@ open class UnbufferedCharStream: CharStream {
public init(_ input: InputStream, _ bufferSize: Int = 256) { public init(_ input: InputStream, _ bufferSize: Int = 256) {
self.input = input self.input = input
self.bufferSize = bufferSize
self.data = [Int](repeating: 0, count: bufferSize) self.data = [Int](repeating: 0, count: bufferSize)
let si = UInt8StreamIterator(input) let si = UInt8StreamIterator(input)
self.unicodeIterator = UnicodeScalarStreamIterator(si) self.unicodeIterator = UnicodeScalarStreamIterator(si)
@ -159,13 +162,6 @@ open class UnbufferedCharStream: CharStream {
} }
public func LA(_ i: Int) throws -> Int { public func LA(_ i: Int) throws -> Int {
let result = try LA_(i)
print("LA(\(i)) -> \(result)")
return result
}
private func LA_(_ i: Int) throws -> Int {
if i == -1 { if i == -1 {
return lastChar // special case return lastChar // special case
} }
@ -212,11 +208,16 @@ open class UnbufferedCharStream: CharStream {
// Copy data[p]..data[n-1] to data[0]..data[(n-1)-p], reset ptrs // Copy data[p]..data[n-1] to data[0]..data[(n-1)-p], reset ptrs
// p is last valid char; move nothing if p==n as we have no valid char // p is last valid char; move nothing if p==n as we have no valid char
let dataCapacity = data.capacity if p == n {
data = Array(data[p ..< n]) if data.count != bufferSize {
data += [Int](repeating: 0, count: dataCapacity - (n - p)) data = [Int](repeating: 0, count: bufferSize)
precondition(data.capacity == dataCapacity) }
n = n - p n = 0
}
else {
data = Array(data[p ..< n])
n -= p
}
p = 0 p = 0
lastCharBufferStart = lastChar lastCharBufferStart = lastChar
} }
@ -344,11 +345,14 @@ fileprivate struct UInt8StreamIterator: IteratorProtocol {
break break
} }
let count = stream.read(&buffer, maxLength: buffer.capacity) let count = stream.read(&buffer, maxLength: buffer.count)
if count <= 0 { if count < 0 {
hasErrorOccurred = true hasErrorOccurred = true
return nil return nil
} }
else if count == 0 {
return nil
}
buffGen = buffer.prefix(count).makeIterator() buffGen = buffer.prefix(count).makeIterator()
return buffGen.next() return buffGen.next()