/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.das2.qds.util; import java.text.ParseException; import org.das2.datum.Units; import org.das2.datum.TimeParser; import org.das2.qds.DataSetOps; import org.das2.qds.MutablePropertyDataSet; import org.das2.qds.QDataSet; /** * Parse the record by recombining the separated fields, then parsing * the combined string. This is to be used with AsciiParser. * * 2010/03/11: Indeterminate field length is used when one field is in a record. * 2010/03/11: The last field, if just one digit type (%S), can contain fractional part. * * @author jbf */ public class MultiFieldTimeParser implements AsciiParser.FieldParser { StringBuilder agg; int firstColumn; int lastColumn; TimeParser parser; Units units; String lastDigitFormat; boolean[] isNumber; private boolean multiFieldAdjacent( String spec ) { return spec.length()>3 && spec.charAt(2)=='%' && spec.charAt(3)!='%'; } private int fieldCount( String spec ) { int count=0; for ( int i=0; i1 && ( timeFormats[0].charAt(1)!='(' && timeFormats[0].charAt(1)!='{' ) ) { //Grrr. TODO: use parens internally if ( multiFieldAdjacent(timeFormats[0]) ) { timeFormat= new StringBuilder(timeFormats[0]); // to have indeterminate length for first field, we need terminator. } else { timeFormat= new StringBuilder("%-1").append( timeFormats[0].substring(1) ); //kludge for whitespace } } else { timeFormat= new StringBuilder(timeFormats[0]); } for ( int i=1; i1 && timeFormats[timeFormats.length-1].length()<3 ) { lastDigitFormat= timeFormats[timeFormats.length-1]; isNumber[timeFormats.length-1]= true; } else { lastDigitFormat=null; // we can't use this feature String lastTimeFormat= timeFormats[timeFormats.length-1]; String[] lastTimeFormats= lastTimeFormat.split("%"); StringBuilder sb= new StringBuilder(); for ( int i=1; i1 ) { // if there is a delimiter there, then we can have variable length fields. sb.append("%").append("-1").append(lastTimeFormats[i]); } else { sb.append("%").append(lastTimeFormats[i]); } } } timeFormat.append(" ").append( sb.toString() ); // to have indeterminate length for first field, we need terminator. isNumber[timeFormats.length-1]= false; } this.parser= TimeParser.create(timeFormat.toString()); //this.parser= parser; this.units= units; } /** * Either the field is accumulated in a string, and the entire string is parsed for the last field. * @param field the contents of the field. * @param columnIndex the index of the column in the table. * @return 0 or the value for the time unit if it's the last field. * @throws ParseException */ public double parseField(String field, int columnIndex) throws ParseException { double d= -1e31; if ( isNumber[columnIndex-firstColumn] ) { d= Double.parseDouble(field); // attempt to parse the number if ( d-(int)d == 0 ) { //TODO: this needs more thorough testing, to see what happens with time fields, etc. field= ""+ (int)d; // http://vho.nasa.gov/mission/helios2/H276_021.dat contains float years "1976.0000" that don't parse. } } if ( columnIndex==firstColumn ) { agg= new StringBuilder(field); return 0; } else if ( columnIndex