156 lines
4.4 KiB
C#
156 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using CsvHelper;
|
|
using CsvHelper.Configuration;
|
|
using LeafWeb.Core.Models;
|
|
|
|
namespace LeafWeb.Core.Services
|
|
{
|
|
public class LeafInputCsvParser : IDisposable
|
|
{
|
|
private readonly FileSystemInfo _csvFile;
|
|
private readonly StreamReader _reader;
|
|
private readonly CsvReader _csv;
|
|
|
|
public LeafInputCsvParser(FileSystemInfo csvFile)
|
|
{
|
|
_csvFile = csvFile;
|
|
if (!csvFile.Exists)
|
|
throw new FileNotFoundException("Cannot find file '" + csvFile.Name + "'");
|
|
|
|
_reader = File.OpenText(csvFile.FullName);
|
|
var csvConfiguration = new CsvConfiguration {HasHeaderRecord = false};
|
|
_csv = new CsvReader(_reader, csvConfiguration);
|
|
}
|
|
|
|
public LeafInput Parse()
|
|
{
|
|
// First 10 lines
|
|
var leafInput = ParseLeafInput();
|
|
leafInput.FileName = _csvFile.Name;
|
|
|
|
// Next 3 (Header, Units, and Values)
|
|
leafInput.Site = ParseLeafInputSite();
|
|
|
|
// Next 3 (Header, Units, and Values)
|
|
leafInput.Photosynthetic = ParseLeafInputPhotosynthetic();
|
|
|
|
// Remaining lines (Header, Units, and Data)
|
|
leafInput.Data = ParseLeafInputData();
|
|
|
|
return leafInput;
|
|
}
|
|
|
|
private LeafInput ParseLeafInput()
|
|
{
|
|
var items = new List<string>();
|
|
for (var i = 0; i < 10; i++)
|
|
{
|
|
if (!_csv.Read())
|
|
throw new ParseException("Could not read line number " + _csv.Row);
|
|
|
|
string field;
|
|
if (!_csv.TryGetField(0, out field))
|
|
throw new ParseException("Could not read first field on line number " + _csv.Row);
|
|
items.Add(field);
|
|
}
|
|
return ParsedObjectFactory<LeafInput>.Create(items.ToArray());
|
|
}
|
|
|
|
private string[] GetNextCsvRowValues()
|
|
{
|
|
// get values from row
|
|
if (!_csv.Read())
|
|
return null;
|
|
|
|
// put all the values from this row into an array
|
|
var values = new List<string>();
|
|
var index = 0;
|
|
string value;
|
|
while (_csv.TryGetField(index, out value))
|
|
{
|
|
values.Add(value);
|
|
index++;
|
|
}
|
|
return values.ToArray();
|
|
}
|
|
|
|
private LeafInputSite ParseLeafInputSite()
|
|
{
|
|
var titles = GetNextCsvRowValues();
|
|
if (titles == null)
|
|
throw new ParseException("Could not read site header row on line number " + _csv.Row);
|
|
var units = GetNextCsvRowValues();
|
|
if (units == null)
|
|
throw new ParseException("Could not read site units row on line number " + _csv.Row);
|
|
var values = GetNextCsvRowValues();
|
|
if (values == null)
|
|
throw new ParseException("Could not read site value row on line number " + _csv.Row);
|
|
|
|
var items = new List<Tuple<string, string>>();
|
|
for (var i = 0; i < titles.Length && i < values.Length; i++)
|
|
{
|
|
var item = Tuple.Create(titles[i], values[i]);
|
|
items.Add(item);
|
|
}
|
|
return ParsedObjectFactory<LeafInputSite>.Create(items.ToArray());
|
|
}
|
|
|
|
private LeafInputPhotosynthetic ParseLeafInputPhotosynthetic()
|
|
{
|
|
var titles = GetNextCsvRowValues();
|
|
if (titles == null)
|
|
throw new ParseException("Could not read photosynthetic header row on line number " + _csv.Row);
|
|
var units = GetNextCsvRowValues();
|
|
if (units == null)
|
|
throw new ParseException("Could not read photosynthetic units row on line number " + _csv.Row);
|
|
var values = GetNextCsvRowValues();
|
|
if (values == null)
|
|
throw new ParseException("Could not read photosynthetic value row on line number " + _csv.Row);
|
|
|
|
var items = new List<Tuple<string, string>>();
|
|
for (var i = 0; i < titles.Length && i < values.Length; i++)
|
|
{
|
|
var item = Tuple.Create(titles[i], values[i]);
|
|
items.Add(item);
|
|
}
|
|
return ParsedObjectFactory<LeafInputPhotosynthetic>.Create(items.ToArray());
|
|
}
|
|
|
|
private LeafInputData[] ParseLeafInputData()
|
|
{
|
|
var titles = GetNextCsvRowValues();
|
|
if (titles == null)
|
|
throw new ParseException("Could not read data header row on line number " + _csv.Row);
|
|
var units = GetNextCsvRowValues();
|
|
if (units == null)
|
|
throw new ParseException("Could not read data units row on line number " + _csv.Row);
|
|
|
|
var valueArrays = new List<string[]>();
|
|
while (true)
|
|
{
|
|
var values = GetNextCsvRowValues();
|
|
if (values == null)
|
|
break;
|
|
valueArrays.Add(values);
|
|
}
|
|
return ParsedObjectFactory<LeafInputData>.Create(titles, valueArrays.ToArray());
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_reader.Dispose();
|
|
}
|
|
|
|
public static void ExportCsv(string filename, IEnumerable<LeafInput> leafInputs)
|
|
{
|
|
using (var textWriter = new StreamWriter(filename))
|
|
{
|
|
var csv = new CsvWriter(textWriter);
|
|
csv.WriteRecords(leafInputs);
|
|
}
|
|
}
|
|
}
|
|
}
|