mirror of
https://github.com/FourierTransformer/ftcsv.git
synced 2024-11-19 19:54:23 +00:00
major vanilla lua speedups
This commit is contained in:
parent
c58bd79a24
commit
e34c08b772
84
ftcsv.lua
84
ftcsv.lua
@ -27,7 +27,7 @@ local ftcsv = {
|
|||||||
]]
|
]]
|
||||||
}
|
}
|
||||||
|
|
||||||
-- lua 5.1 compat
|
-- lua 5.1 load compat
|
||||||
local M = {}
|
local M = {}
|
||||||
if type(jit) == 'table' or _ENV then
|
if type(jit) == 'table' or _ENV then
|
||||||
M.load = _G.load
|
M.load = _G.load
|
||||||
@ -35,6 +35,61 @@ else
|
|||||||
M.load = loadstring
|
M.load = loadstring
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- luajit specific speedups
|
||||||
|
-- luajit performs faster with iterating over string.byte,
|
||||||
|
-- whereas vanilla lua performs faster with string.find
|
||||||
|
if type(jit) == 'table' then
|
||||||
|
-- finds the end of an escape sequence
|
||||||
|
function M.findClosingQuote(i, inputLength, inputString, quote, doubleQuoteEscape)
|
||||||
|
-- local doubleQuoteEscape = doubleQuoteEscape
|
||||||
|
local currentChar, nextChar = string.byte(inputString, i), nil
|
||||||
|
while i <= inputLength do
|
||||||
|
-- print(i)
|
||||||
|
nextChar = string.byte(inputString, i+1)
|
||||||
|
|
||||||
|
-- this one deals with " double quotes that are escaped "" within single quotes "
|
||||||
|
-- these should be turned into a single quote at the end of the field
|
||||||
|
if currentChar == quote and nextChar == quote then
|
||||||
|
doubleQuoteEscape = true
|
||||||
|
i = i + 2
|
||||||
|
currentChar = string.byte(inputString, i)
|
||||||
|
|
||||||
|
-- identifies the escape toggle
|
||||||
|
elseif currentChar == quote and nextChar ~= quote then
|
||||||
|
-- print("exiting", i-1)
|
||||||
|
return i-1, doubleQuoteEscape
|
||||||
|
else
|
||||||
|
i = i + 1
|
||||||
|
currentChar = nextChar
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
-- vanilla lua closing quote finder
|
||||||
|
function M.findClosingQuote(i, inputLength, inputString, quote, doubleQuoteEscape)
|
||||||
|
local firstCharIndex = 1
|
||||||
|
local firstChar, iChar = nil, nil
|
||||||
|
repeat
|
||||||
|
firstCharIndex, i = inputString:find('".?', i+1)
|
||||||
|
firstChar = string.byte(inputString, firstCharIndex)
|
||||||
|
iChar = string.byte(inputString, i)
|
||||||
|
-- nextChar = string.byte(inputString, i+1)
|
||||||
|
-- print("HI", offset, i)
|
||||||
|
-- print(firstChar, iChar)
|
||||||
|
if firstChar == quote and iChar == quote then
|
||||||
|
doubleQuoteEscape = true
|
||||||
|
end
|
||||||
|
until iChar ~= quote
|
||||||
|
if i == nil then
|
||||||
|
return inputLength-1, doubleQuoteEscape
|
||||||
|
end
|
||||||
|
-- print("exiting", i-2)
|
||||||
|
return i-2, doubleQuoteEscape
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
-- load an entire file into memory
|
-- load an entire file into memory
|
||||||
local function loadFile(textFile)
|
local function loadFile(textFile)
|
||||||
local file = io.open(textFile, "r")
|
local file = io.open(textFile, "r")
|
||||||
@ -44,31 +99,6 @@ local function loadFile(textFile)
|
|||||||
return allLines
|
return allLines
|
||||||
end
|
end
|
||||||
|
|
||||||
-- finds the end of an escape sequence
|
|
||||||
local function findClosingQuote(i, inputLength, inputString, quote, doubleQuoteEscape)
|
|
||||||
-- local doubleQuoteEscape = doubleQuoteEscape
|
|
||||||
local currentChar, nextChar = string.byte(inputString, i), nil
|
|
||||||
while i <= inputLength do
|
|
||||||
-- print(i)
|
|
||||||
nextChar = string.byte(inputString, i+1)
|
|
||||||
|
|
||||||
-- this one deals with " double quotes that are escaped "" within single quotes "
|
|
||||||
-- these should be turned into a single quote at the end of the field
|
|
||||||
if currentChar == quote and nextChar == quote then
|
|
||||||
doubleQuoteEscape = true
|
|
||||||
i = i + 2
|
|
||||||
currentChar = string.byte(inputString, i)
|
|
||||||
|
|
||||||
-- identifies the escape toggle
|
|
||||||
elseif currentChar == quote and nextChar ~= quote then
|
|
||||||
return i-1, doubleQuoteEscape
|
|
||||||
else
|
|
||||||
i = i + 1
|
|
||||||
currentChar = nextChar
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- creates a new field and adds it to the main table
|
-- creates a new field and adds it to the main table
|
||||||
local function createNewField(inputString, quote, fieldStart, i, line, fieldNum, doubleQuoteEscape, fieldsToKeep)
|
local function createNewField(inputString, quote, fieldStart, i, line, fieldNum, doubleQuoteEscape, fieldsToKeep)
|
||||||
-- print(lineNum, fieldNum, fieldStart, i-1)
|
-- print(lineNum, fieldNum, fieldStart, i-1)
|
||||||
@ -193,7 +223,7 @@ function ftcsv.parse(inputFile, delimiter, options)
|
|||||||
elseif currentChar == quote and nextChar ~= quote then
|
elseif currentChar == quote and nextChar ~= quote then
|
||||||
-- print("ESCAPE TOGGLE")
|
-- print("ESCAPE TOGGLE")
|
||||||
fieldStart = i + 1
|
fieldStart = i + 1
|
||||||
i, doubleQuoteEscape = findClosingQuote(i+1, inputLength, inputString, quote, doubleQuoteEscape)
|
i, doubleQuoteEscape = M.findClosingQuote(i+1, inputLength, inputString, quote, doubleQuoteEscape)
|
||||||
-- print("I VALUE", i, doubleQuoteEscape)
|
-- print("I VALUE", i, doubleQuoteEscape)
|
||||||
skipChar = 1
|
skipChar = 1
|
||||||
-- end
|
-- end
|
||||||
|
@ -34,6 +34,7 @@ describe("csv decode", function()
|
|||||||
local json = loadFile("spec/json/" .. value .. ".json")
|
local json = loadFile("spec/json/" .. value .. ".json")
|
||||||
json = cjson.decode(json)
|
json = cjson.decode(json)
|
||||||
local parse = ftcsv.parse("spec/csvs/" .. value .. ".csv", ",")
|
local parse = ftcsv.parse("spec/csvs/" .. value .. ".csv", ",")
|
||||||
|
assert.are.same(#json, #parse)
|
||||||
assert.are.same(json, parse)
|
assert.are.same(json, parse)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user