Add buffer size tests

This commit is contained in:
Yasuhiro Hatta 2016-06-12 17:30:57 +09:00
parent e3842e3db7
commit bec2704832
2 changed files with 96 additions and 32 deletions

View File

@ -25,23 +25,30 @@ internal let utf32LittleEndianBOM: [UInt8] = [0xff, 0xfe, 0x00, 0x00]
public class CSV: SequenceType, GeneratorType { public class CSV: SequenceType, GeneratorType {
private let stream: NSInputStream internal let stream: NSInputStream
private let encoding: NSStringEncoding internal let encoding: NSStringEncoding
private let delimiter: UInt32 internal let delimiter: UInt32
private let bufferSize: Int internal let bufferSize: Int
private var buffer: UnsafeMutablePointer<UInt8>! internal var buffer: UnsafeMutablePointer<UInt8>!
private var bufferOffset: Int internal var bufferOffset: Int
private var lastReadCount: Int internal var lastReadCount: Int
private let charWidth: Int internal let charWidth: Int
private let fieldBuffer: NSMutableData internal let fieldBuffer: NSMutableData
internal var closed: Bool = false
/**
CSV header row. To set a value for this property, you set `true` to `hasHeaerRow` in initializer.
*/
public var headerRow: [String]? { return _headerRow }
private var _headerRow: [String]? = nil private var _headerRow: [String]? = nil
private var closed: Bool = false /**
The value is set when an error occurs.
/** The value is set when an error occurs. */ */
public private(set) var lastError: CSVError? = nil public private(set) var lastError: CSVError? = nil
/** /**
@ -70,7 +77,11 @@ public class CSV: SequenceType, GeneratorType {
if bs < 8 { if bs < 8 {
bs = 8 bs = 8
} }
self.bufferSize = bs + (4 - (bs % 4)) let mod = bs % 4
if mod != 0 {
bs += 4 - mod
}
self.bufferSize = bs
self.delimiter = UInt32(delimiter) self.delimiter = UInt32(delimiter)
@ -175,18 +186,10 @@ public class CSV: SequenceType, GeneratorType {
free(buffer) free(buffer)
buffer = nil buffer = nil
} }
_headerRow = nil
closed = true closed = true
} }
} }
/**
CSV header row. To set a value for this property, you set `true` to `hasHeaerRow` in initializer.
*/
public var headerRow: [String]? {
return _headerRow
}
// MARK: GeneratorType // MARK: GeneratorType
public func next() -> [String]? { public func next() -> [String]? {
@ -259,11 +262,7 @@ public class CSV: SequenceType, GeneratorType {
escaping = true escaping = true
} }
if c == delimiter && prev == DQUOTE && (quotationCount % 2 == 0) { if (c == delimiter || c == CR || c == LF) && prev == DQUOTE && (quotationCount % 2 == 0) {
escaping = false
}
if (c == CR || c == LF) && prev == DQUOTE && (quotationCount % 2 == 0) {
escaping = false escaping = false
} }
@ -365,30 +364,46 @@ extension CSV {
public convenience init( public convenience init(
path: String, path: String,
hasHeaderRow: Bool = defaultHasHeaderRow, hasHeaderRow: Bool = defaultHasHeaderRow,
encoding: NSStringEncoding = defaultEncoding) encoding: NSStringEncoding = defaultEncoding,
delimiter: CChar = defaultDelimiter,
bufferSize: Int = defaultBufferSize)
throws throws
{ {
guard let stream = NSInputStream(fileAtPath: path) else { guard let stream = NSInputStream(fileAtPath: path) else {
throw CSVError.StreamError throw CSVError.StreamError
} }
try self.init(stream: stream, hasHeaderRow: hasHeaderRow, encoding: encoding) try self.init(
stream: stream,
hasHeaderRow: hasHeaderRow,
encoding: encoding,
delimiter: delimiter,
bufferSize: bufferSize)
} }
public convenience init( public convenience init(
url: NSURL, url: NSURL,
hasHeaderRow: Bool = defaultHasHeaderRow, hasHeaderRow: Bool = defaultHasHeaderRow,
encoding: NSStringEncoding = defaultEncoding) encoding: NSStringEncoding = defaultEncoding,
delimiter: CChar = defaultDelimiter,
bufferSize: Int = defaultBufferSize)
throws throws
{ {
guard let stream = NSInputStream(URL: url) else { guard let stream = NSInputStream(URL: url) else {
throw CSVError.StreamError throw CSVError.StreamError
} }
try self.init(stream: stream, hasHeaderRow: hasHeaderRow, encoding: encoding) try self.init(
stream: stream,
hasHeaderRow: hasHeaderRow,
encoding: encoding,
delimiter: delimiter,
bufferSize: bufferSize)
} }
public convenience init( public convenience init(
string: String, string: String,
hasHeaderRow: Bool = defaultHasHeaderRow) hasHeaderRow: Bool = defaultHasHeaderRow,
delimiter: CChar = defaultDelimiter,
bufferSize: Int = defaultBufferSize)
throws throws
{ {
let encoding = defaultEncoding let encoding = defaultEncoding
@ -396,7 +411,12 @@ extension CSV {
throw CSVError.StringEncodingMismatch throw CSVError.StringEncodingMismatch
} }
let memoryStream = NSInputStream(data: data) let memoryStream = NSInputStream(data: data)
try self.init(stream: memoryStream, hasHeaderRow: hasHeaderRow, encoding: encoding) try self.init(
stream: memoryStream,
hasHeaderRow: hasHeaderRow,
encoding: encoding,
delimiter: delimiter,
bufferSize: bufferSize)
} }
} }

View File

@ -84,4 +84,48 @@ class CSVTests: XCTestCase {
XCTAssertEqual(i, 3) XCTAssertEqual(i, 3)
} }
func testBufferSizeMod0() {
let csvString = "0,1,2,3,4,5,6,7,8,9\n"
let csv = try! CSV(string: csvString, bufferSize: 12)
XCTAssertEqual(csv.bufferSize, 12)
}
func testBufferSizeMod1() {
let csvString = "0,1,2,3,4,5,6,7,8,9\n"
let csv = try! CSV(string: csvString, bufferSize: 13)
XCTAssertEqual(csv.bufferSize, 16)
}
func testBufferSizeMod2() {
let csvString = "0,1,2,3,4,5,6,7,8,9\n"
let csv = try! CSV(string: csvString, bufferSize: 14)
XCTAssertEqual(csv.bufferSize, 16)
}
func testBufferSizeMod3() {
let csvString = "0,1,2,3,4,5,6,7,8,9\n"
let csv = try! CSV(string: csvString, bufferSize: 15)
XCTAssertEqual(csv.bufferSize, 16)
}
func testBufferSizeMod4() {
let csvString = "0,1,2,3,4,5,6,7,8,9\n"
let csv = try! CSV(string: csvString, bufferSize: 16)
XCTAssertEqual(csv.bufferSize, 16)
}
func testSmallBufferSize() {
let line = "0,1,2,3,4,5,6,7,8,9\n"
var csv = ""
for _ in 0..<10000 {
csv += line
}
var i = 0
for row in try! CSV(string: csv, bufferSize: 10) {
XCTAssertEqual(row, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"])
i += 1
}
XCTAssertEqual(i, 10000)
}
} }