package jmathlib.toolbox.io; import jmathlib.core.tokens.Token; import jmathlib.core.tokens.OperandToken; import jmathlib.core.tokens.numbertokens.DoubleNumberToken; import jmathlib.core.tokens.CharToken; import jmathlib.core.functions.ExternalFunction; import jmathlib.core.interpreter.ErrorLogger; import jmathlib.core.interpreter.Errors; import jmathlib.core.interpreter.GlobalValues; import java.io.*; import java.util.Stack; /**An external function for loading a matrix from a csv file*/ public class csvread extends ExternalFunction { /** Check that the operand is a string then open the file referenced. @param operands[0] = string which specifies the csv file to load @param operands[1] = the start row (optional) @param operands[2] = the start column (optional) @param operands[3] = range(optional, not implemented) @return the matrix as an OperandToken*/ public OperandToken evaluate(Token[] operands, GlobalValues globals) { DoubleNumberToken result = null; // at least one operand if (getNArgIn(operands) < 1) throwMathLibException("CSVRead: number of arguments must be > 0"); if(operands[0] instanceof CharToken) { String fileName = ((CharToken)operands[0]).toString(); File CSVFile = new File(globals.getWorkingDirectory(), fileName); if(!CSVFile.exists()) return null; ErrorLogger.debugLine("loading CSV>"+fileName+"<"); int startLine = 0; int startColumn = 0; if(operands.length > 1) { if(operands[1] instanceof DoubleNumberToken) startLine = ((DoubleNumberToken)operands[1]).getIntValue(0,0); if(operands.length > 2) { if(operands[2] instanceof DoubleNumberToken) startColumn = ((DoubleNumberToken)operands[2]).getIntValue(0,0); } } try { Stack rows = new Stack(); String line = " "; // load file BufferedReader inReader = new BufferedReader( new FileReader(CSVFile)); try { //move to the first line for(int lineNo = 0; lineNo < startLine; lineNo++) { inReader.readLine(); } int count = 0; while ( line != null) { line= inReader.readLine(); if(line != null) { line = line.substring(startColumn, line.length()); double[] row = processLine(line); rows.push(row); count++; } } double[][] values = new double[count][]; for(int yy = count - 1; yy >=0; yy--) { Object temp = rows.pop(); if(temp != null) values[yy] = ((double[])temp); } result = new DoubleNumberToken(values); } catch(Exception e) { ErrorLogger.debugLine("CSVRead: load function exception - " + e.getMessage()); } inReader.close(); } catch (Exception e) { ErrorLogger.debugLine("CSVRead: load function exception - " + e.getMessage()); } } else Errors.throwMathLibException(ERR_INVALID_PARAMETER, new Object[] {"CharToken", operands[0].getClass().getName()}); return result; } private double[] processLine(String line) { Stack columns = new Stack(); int index = 0; int count = 0; do { index = line.indexOf(","); if(index > -1) { String temp = line.substring(0, index); if(!(temp.equals(""))) { double val = Double.parseDouble(temp); columns.push(new DoubleNumberToken(val)); count++; } line = line.substring(index + 1); } }while(index > -1); ErrorLogger.debugLine("0"); double val = Double.parseDouble(line); columns.push(new DoubleNumberToken(val)); ErrorLogger.debugLine("1"); count++; double[] values = new double[count]; ErrorLogger.debugLine("2"); for(int xx = count - 1; xx >= 0; xx--) { ErrorLogger.debugLine("3"); Object temp = columns.pop(); if(temp != null) { val = ((DoubleNumberToken)temp).getValueRe(); values[xx] = val; ErrorLogger.debugLine("4"); } else values[xx] = 0; } return values; } } /* @GROUP IO @SYNTAX matrix=csvread(filename, startrow, endrow) @DOC Reads in a matrix from a comma seperated value file. @EXAMPLES <programlisting> cvsreac("testfile.csv", 0, 0)=[1,2;3,4] </programlisting> @SEE csvwrite, urlread, dir, cd */