forked from jasder/antlr
Fix UnbufferedCharStream.
The call to stream.read needs to use buffer.count, not buffer.capacity, as the maxLength. Otherwise, some bytes get dropped on the floor and the stream is corrupted. Remove the code to pad self.data back to up to its previous capacity when copying data at the end of release. This came over from the Java port, but I don't think it makes sense in Swift, given the copy-on-write Array value semantics. Instead, just copy the tail of the buffer if there is anything left to read (i.e. self.data gets smaller) and when there is nothing in the buffer to read, reset to the specified bufferSize (i.e. self.data goes back to the specified self.bufferSize. Remove debug print statement that was accidentally left in.
This commit is contained in:
parent
64ae36b3e8
commit
afd4e0bc3f
|
@ -19,6 +19,8 @@ import Foundation
|
|||
* code points in the buffer as ints.
|
||||
*/
|
||||
open class UnbufferedCharStream: CharStream {
|
||||
private let bufferSize: Int
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -77,6 +79,7 @@ open class UnbufferedCharStream: CharStream {
|
|||
|
||||
public init(_ input: InputStream, _ bufferSize: Int = 256) {
|
||||
self.input = input
|
||||
self.bufferSize = bufferSize
|
||||
self.data = [Int](repeating: 0, count: bufferSize)
|
||||
let si = UInt8StreamIterator(input)
|
||||
self.unicodeIterator = UnicodeScalarStreamIterator(si)
|
||||
|
@ -159,13 +162,6 @@ open class UnbufferedCharStream: CharStream {
|
|||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
// p is last valid char; move nothing if p==n as we have no valid char
|
||||
let dataCapacity = data.capacity
|
||||
data = Array(data[p ..< n])
|
||||
data += [Int](repeating: 0, count: dataCapacity - (n - p))
|
||||
precondition(data.capacity == dataCapacity)
|
||||
n = n - p
|
||||
if p == n {
|
||||
if data.count != bufferSize {
|
||||
data = [Int](repeating: 0, count: bufferSize)
|
||||
}
|
||||
n = 0
|
||||
}
|
||||
else {
|
||||
data = Array(data[p ..< n])
|
||||
n -= p
|
||||
}
|
||||
p = 0
|
||||
lastCharBufferStart = lastChar
|
||||
}
|
||||
|
@ -344,11 +345,14 @@ fileprivate struct UInt8StreamIterator: IteratorProtocol {
|
|||
break
|
||||
}
|
||||
|
||||
let count = stream.read(&buffer, maxLength: buffer.capacity)
|
||||
if count <= 0 {
|
||||
let count = stream.read(&buffer, maxLength: buffer.count)
|
||||
if count < 0 {
|
||||
hasErrorOccurred = true
|
||||
return nil
|
||||
}
|
||||
else if count == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
buffGen = buffer.prefix(count).makeIterator()
|
||||
return buffGen.next()
|
||||
|
|
Loading…
Reference in New Issue