@@ -27,14 +27,69 @@ local ftcsv = {
27
27
]]
28
28
}
29
29
30
- -- lua 5.1 compat
30
+ -- lua 5.1 load compat
31
31
local M = {}
32
32
if type (jit ) == ' table' or _ENV then
33
33
M .load = _G .load
34
34
else
35
35
M .load = loadstring
36
36
end
37
37
38
+ -- luajit specific speedups
39
+ -- luajit performs faster with iterating over string.byte,
40
+ -- whereas vanilla lua performs faster with string.find
41
+ if type (jit ) == ' table' then
42
+ -- finds the end of an escape sequence
43
+ function M .findClosingQuote (i , inputLength , inputString , quote , doubleQuoteEscape )
44
+ -- local doubleQuoteEscape = doubleQuoteEscape
45
+ local currentChar , nextChar = string.byte (inputString , i ), nil
46
+ while i <= inputLength do
47
+ -- print(i)
48
+ nextChar = string.byte (inputString , i + 1 )
49
+
50
+ -- this one deals with " double quotes that are escaped "" within single quotes "
51
+ -- these should be turned into a single quote at the end of the field
52
+ if currentChar == quote and nextChar == quote then
53
+ doubleQuoteEscape = true
54
+ i = i + 2
55
+ currentChar = string.byte (inputString , i )
56
+
57
+ -- identifies the escape toggle
58
+ elseif currentChar == quote and nextChar ~= quote then
59
+ -- print("exiting", i-1)
60
+ return i - 1 , doubleQuoteEscape
61
+ else
62
+ i = i + 1
63
+ currentChar = nextChar
64
+ end
65
+ end
66
+ end
67
+
68
+ else
69
+ -- vanilla lua closing quote finder
70
+ function M .findClosingQuote (i , inputLength , inputString , quote , doubleQuoteEscape )
71
+ local firstCharIndex = 1
72
+ local firstChar , iChar = nil , nil
73
+ repeat
74
+ firstCharIndex , i = inputString :find (' ".?' , i + 1 )
75
+ firstChar = string.byte (inputString , firstCharIndex )
76
+ iChar = string.byte (inputString , i )
77
+ -- nextChar = string.byte(inputString, i+1)
78
+ -- print("HI", offset, i)
79
+ -- print(firstChar, iChar)
80
+ if firstChar == quote and iChar == quote then
81
+ doubleQuoteEscape = true
82
+ end
83
+ until iChar ~= quote
84
+ if i == nil then
85
+ return inputLength - 1 , doubleQuoteEscape
86
+ end
87
+ -- print("exiting", i-2)
88
+ return i - 2 , doubleQuoteEscape
89
+ end
90
+
91
+ end
92
+
38
93
-- load an entire file into memory
39
94
local function loadFile (textFile )
40
95
local file = io.open (textFile , " r" )
@@ -44,31 +99,6 @@ local function loadFile(textFile)
44
99
return allLines
45
100
end
46
101
47
- -- finds the end of an escape sequence
48
- local function findClosingQuote (i , inputLength , inputString , quote , doubleQuoteEscape )
49
- -- local doubleQuoteEscape = doubleQuoteEscape
50
- local currentChar , nextChar = string.byte (inputString , i ), nil
51
- while i <= inputLength do
52
- -- print(i)
53
- nextChar = string.byte (inputString , i + 1 )
54
-
55
- -- this one deals with " double quotes that are escaped "" within single quotes "
56
- -- these should be turned into a single quote at the end of the field
57
- if currentChar == quote and nextChar == quote then
58
- doubleQuoteEscape = true
59
- i = i + 2
60
- currentChar = string.byte (inputString , i )
61
-
62
- -- identifies the escape toggle
63
- elseif currentChar == quote and nextChar ~= quote then
64
- return i - 1 , doubleQuoteEscape
65
- else
66
- i = i + 1
67
- currentChar = nextChar
68
- end
69
- end
70
- end
71
-
72
102
-- creates a new field and adds it to the main table
73
103
local function createNewField (inputString , quote , fieldStart , i , line , fieldNum , doubleQuoteEscape , fieldsToKeep )
74
104
-- print(lineNum, fieldNum, fieldStart, i-1)
@@ -193,7 +223,7 @@ function ftcsv.parse(inputFile, delimiter, options)
193
223
elseif currentChar == quote and nextChar ~= quote then
194
224
-- print("ESCAPE TOGGLE")
195
225
fieldStart = i + 1
196
- i , doubleQuoteEscape = findClosingQuote (i + 1 , inputLength , inputString , quote , doubleQuoteEscape )
226
+ i , doubleQuoteEscape = M . findClosingQuote (i + 1 , inputLength , inputString , quote , doubleQuoteEscape )
197
227
-- print("I VALUE", i, doubleQuoteEscape)
198
228
skipChar = 1
199
229
-- end
0 commit comments