Function to parse a CSV file
I want to be able to use spreadsheets as data files in my current project - and obviously want Sphere to be able to read them, the easiest method seemed to be to save as CSV and then parse it, so I wrote a simple CSV parser (only tested with UTF-8 character encoding may need tweaking for different formats), anyway thought I'd share it in case any else wants this functionality.
Notes:
- sphere version 1 (sorry Fat Cerberus)
- has to use a length variable for the current field byte array (out_Rdata) as miniSphere doesn't let you dynamically resize byte arrays
- only supports 200 bytes per field - though you can change this by increasing the number on line 5
- returns the data as a 2D array where output[1][2] would be the value from the 2nd row and 3rd column. output[0][0] = value from 1st row and 1st column etc. It converts numbers into JS numbers and returns anything else as strings.
function parseCSV(input)
{
var file = OpenRawFile(input);
var in_data = file.read(file.getSize());
var out_Rdata = CreateByteArray(200);
var R_length = 0;
var out_data = [[]];
var in_quotes = false;
function convert_data(Rdata)
{
if(!(Rdata * 1))
{
out_data[out_data.length-1].push(Rdata);
}
else
{
out_data[out_data.length-1].push(Rdata*1);
}
}
for(var i = 0; i<in_data.length; ++i)
{
if(in_quotes)
{
if(in_data[i] == 0x22)
{
in_quotes = false;
}
else
{
out_Rdata[R_length]=in_data[i];
++R_length;
}
}
else
{
switch(in_data[i])
{
case(0x2C)://comma
{
if(R_length > 0)
{
convert_data(CreateStringFromByteArray(out_Rdata.slice(0,R_length)));
}
else
{
out_data[out_data.length-1].push("");
}
R_length =0;
break;
}
case(0x22)://quotes
{
in_quotes = true;
break;
}
case(0x0D)://Carriage Return -ignored as followed by LineFeed
{
break;
}
case(0x0A)://Line Feed - push the data and then move down a line
{
if(R_length > 0)
{
convert_data(CreateStringFromByteArray(out_Rdata.slice(0,R_length)));
}
else
{
out_data[out_data.length-1].push("");
}
R_length = 0;
out_data.push([]);
break;
}
default://anything else
{
out_Rdata[R_length]=in_data[i];
++R_length;
}
}
}
}
if(out_Rdata.length > 0)//push the last piece of data as there's no terminator character
{
convert_data(CreateStringFromByteArray(out_Rdata.slice(0,R_length)));
}
else
{
out_data[out_data.length-1].push("");
}
return out_data;
}