Added an openstring function, by wrapping the string in an object

that supports read(bytes) and passing the object to the underlying
code. Modified all the tests to run with both open and openstring.

Changed the default buffer size in csv.lua to match the value in the
README, and added the crucial blank line to test-data/blankline.csv
This commit is contained in:
Kevin Martin 2014-05-18 18:52:16 +01:00
parent 1ed256e9f5
commit f28dfe0720
6 changed files with 81 additions and 8 deletions

View File

@ -1 +1,2 @@
Leyland, Geoff
Leyland, Geoff
Martin, Kevin

View File

@ -1,4 +1,5 @@
Copyright (c) 2013 Incremental IP Limited
Copyright (c) 2014 Kevin Martin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -54,6 +54,9 @@ controlling how the file is read:
+ `buffer_size` controls the size of the blocks the file is read in. The
default is 4096, which is what `pagesize` says on my system.
`csv.openstring` works exactly like `csv.open` except the first argument
is the contents of the csv file. In this case `buffer_size` is set to
the length of the string.
## 3. Requirements

View File

@ -11,9 +11,10 @@
-- likely gets something wrong.
-- (c) Copyright 2013 Incremental IP Limited.
-- (c) Copyright 2014 Kevin Martin
-- Available under the MIT licence. See LICENSE for more information.
local DEFAULT_BUFFER_SIZE = 1024
local DEFAULT_BUFFER_SIZE = 4096
------------------------------------------------------------------------------
@ -322,6 +323,9 @@ local file_mt =
close = function(t)
t.file:close()
end,
name = function(t)
return t.parameters.filename
end,
}
file_mt.__index = file_mt
@ -349,6 +353,52 @@ end
------------------------------------------------------------------------------
return { open = open, use = use }
local stringfh_mt =
{
read = function(self, bytes)
if not self._string then return nil end
local read_rv
read_rv, self._string =
self._string:sub(1, bytes), self._string:sub(bytes+1)
if #self._string == 0 then
self._string = nil
end
return read_rv
end,
close = function()
end
}
stringfh_mt.__index = stringfh_mt
--- Open a string for reading as a delimited file
-- @return a file object
local function openstring(
filecontents, -- string: The contents of the delimited file
parameters) -- ?table: parameters controlling reading the file.
-- See README.md
parameters = parameters or {}
local function makename()
local t = {}
t[#t+1] = "<(String) "
t[#t+1] = (filecontents:gmatch("[^\n]+")() or ""):sub(1,15)
if #t[#t] > 14 then t[#t+1] = "..." end
t[#t+1] = " >"
return table.concat(t)
end
parameters.filename = parameters.filename or makename()
parameters.buffer_size = parameters.buffer_size or #filecontents
local fileh = setmetatable({_string = filecontents}, stringfh_mt)
return use(fileh, parameters)
end
------------------------------------------------------------------------------
return { open = open, openstring = openstring, use = use }
------------------------------------------------------------------------------

View File

@ -3,10 +3,9 @@ local csv = require"csv"
local errors = 0
local function test(filename, correct_result, parameters)
local function testhandle(handle, correct_result)
local result = {}
local f = csv.open(filename, parameters)
for r in f:lines() do
for r in handle:lines() do
if not r[1] then
local r2 = {}
for k, v in pairs(r) do r2[#r2+1] = k..":"..tostring(v) end
@ -15,15 +14,33 @@ local function test(filename, correct_result, parameters)
end
result[#result+1] = table.concat(r, ",")
end
handle:close()
result = table.concat(result, "\n")
if result ~= correct_result then
io.stderr:write(
("Error reading '%s':\nExpected output:\n%s\n\nActual output:\n%s\n\n"):
format(filename, correct_result, result))
format(handle:name(), correct_result, result))
errors = errors + 1
return false
end
return true
end
local function test(filename, correct_result, parameters)
local f = csv.open(filename, parameters)
local fileok = testhandle(f, correct_result)
if fileok then
f = io.open(filename, "r")
local data = f:read("*a")
f:close()
f = csv.openstring(data, parameters)
testhandle(f, correct_result)
end
end
test("../test-data/embedded-newlines.csv", [[
embedded
@ -62,4 +79,4 @@ else
io.stdout:write(("%d errors\n"):format(errors))
end
os.exit(errors)
os.exit(errors)

View File

@ -1 +1,2 @@
this,file,ends,with,a,blank,line

1 this file ends with a blank line
2