ool.core.interpreter.2.6.0.source-code.CSV Maven / Gradle / Ivy
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import org.overture.ast.expressions.PExp;
import org.overture.ast.lex.Dialect;
import org.overture.interpreter.messages.Console;
import org.overture.interpreter.runtime.Context;
import org.overture.interpreter.runtime.Interpreter;
import org.overture.interpreter.runtime.VdmRuntime;
import org.overture.interpreter.utilities.stdlibs.CsvParser;
import org.overture.interpreter.utilities.stdlibs.CsvResult;
import org.overture.interpreter.utilities.stdlibs.CsvValueBuilder;
import org.overture.interpreter.values.BooleanValue;
import org.overture.interpreter.values.CPUValue;
import org.overture.interpreter.values.IntegerValue;
import org.overture.interpreter.values.NilValue;
import org.overture.interpreter.values.SeqValue;
import org.overture.interpreter.values.TupleValue;
import org.overture.interpreter.values.Value;
import org.overture.interpreter.values.ValueList;
import org.overture.parser.lex.LexTokenReader;
import org.overture.parser.syntax.ExpressionReader;
/**
* Basic CSV file support for VDM
*
* @author kela
*/
public class CSV extends IO implements Serializable
{
private static final long serialVersionUID = 1L;
private static String lastError = "";
public static Value ferror()
{
return new SeqValue(lastError);
}
/**
* Writes a seq of ? in a CSV format to the file specified
*
* @param fval
* the filename
* @param tval
* the sequence to write
* @param dval
* append to or start a new file
* @return
*/
public static Value fwriteval(Value fval, Value tval, Value dval)
{
File file = getFile(fval);
String fdir = dval.toString(); // |
StringBuffer text = new StringBuffer();
if (tval instanceof SeqValue)
{
for (Value val : ((SeqValue) tval).values)
{
text.append(val.toString());
text.append(",");
}
}
if (text.length() > 0 && text.charAt(text.length() - 1) == ',')
{
text.deleteCharAt(text.length() - 1);
}
text.append('\n');
try
{
FileOutputStream fos = new FileOutputStream(file, fdir.equals(""));
fos.write(text.toString().getBytes(Console.charset));
fos.close();
} catch (IOException e)
{
lastError = e.getMessage();
return new BooleanValue(false);
}
return new BooleanValue(true);
}
/**
* Read a CSV live as a seq of ? in VDM
*
* @param fval
* name of the file to read from
* @param indexVal
* the line index
* @return true + seq of ? or false and nil
*/
public static Value freadval(Value fval, Value indexVal)
{
ValueList result = new ValueList();
try
{
File file = getFile(fval);
long index = indexVal.intValue(null);
SeqValue lineCells = new SeqValue();
boolean success = false;
try
{
CsvParser parser = new CsvParser(new CsvValueBuilder()
{
@Override
public Value createValue(String value)
throws Exception
{
return CSV.createValue("CSV", "freadval", value);
}
});
CsvResult res = parser.parseValues(getLine(file, index));
if(!res.dataOk())
{
lastError = res.getErrorMsg();
success = false;
}
else
{
lineCells.values.addAll(res.getValues());
success = true;
}
} catch (Exception e)
{
success = false;
lastError = e.getMessage();
// OK
}
result.add(new BooleanValue(success));
result.add(lineCells);
} catch (Exception e)
{
lastError = e.toString();
result = new ValueList();
result.add(new BooleanValue(false));
result.add(new NilValue());
}
return new TupleValue(result);
}
/**
* Gets the line count of the CSV file
*
* @param fval
* name of the file
* @return int value with count
*/
public static Value flinecount(Value fval)
{
ValueList result = new ValueList();
try
{
File file = getFile(fval);
long count = getLineCount(file);
result.add(new BooleanValue(true));
result.add(new IntegerValue(count));
} catch (Exception e)
{
lastError = e.toString();
result = new ValueList();
result.add(new BooleanValue(false));
result.add(new NilValue());
}
return new TupleValue(result);
}
private static int getLineCount(File file) throws IOException
{
BufferedReader bufRdr = new BufferedReader(new FileReader(file));
int lines = 0;
try
{
while (bufRdr.readLine() != null)
{
lines++;
}
} finally
{
bufRdr.close();
}
return lines;
}
private static String getLine(File file, long index)
throws IOException
{
BufferedReader bufRdr = new BufferedReader(new FileReader(file));
String line = null;
int lineIndex = 0;
if (index < 1)
{
bufRdr.close();
throw new IOException("CSV line index before first entry");
}
try
{
while ((line = bufRdr.readLine()) != null)
{
lineIndex++;
if (lineIndex == index)
{
break;
}
}
} finally
{
bufRdr.close();
}
if (line == null)
{
throw new IOException("CSV no data read. Empty line.");
}
return line;
}
private static Value createValue(String module, String method, String value)
throws Exception
{
LexTokenReader ltr = new LexTokenReader(value, Dialect.VDM_PP);
ExpressionReader reader = new ExpressionReader(ltr);
reader.setCurrentModule(module);
PExp exp = reader.readExpression();
Interpreter ip = Interpreter.getInstance();
ip.typeCheck(exp, ip.getGlobalEnvironment());
Context ectxt = new Context(ip.getAssistantFactory(), null, method, null);
ectxt.setThreadState(null, CPUValue.vCPU);
return exp.apply(VdmRuntime.getExpressionEvaluator(), ectxt);
}
}