/*
* Copyright (c) 2004-2009, Jean-Marc Fran�ois. All Rights Reserved.
* Licensed under the New BSD license. See the LICENSE file.
*/
package be.ac.ulg.montefiore.run.jahmm.io;
import java.io.IOException;
import java.io.StreamTokenizer;
import be.ac.ulg.montefiore.run.jahmm.Opdf;
import java.util.LinkedList;
/**
* Reads an observation distribution textual description.
*/
public abstract class OpdfReader<O extends Opdf<?>>
{
/**
* Returns the keyword identifying the distribution read.
* It must be the word beginning the distribution's description.
*
* @return The keyword.
*/
abstract String keyword();
/**
* Reads an
* {@link be.ac.ulg.montefiore.run.jahmm.Opdf Opdf} out of a
* {@link java.io.StreamTokenizer}.
* <p>
* The stream tokenizer syntax table must be set according to
* of <code>HmmReader.initSyntaxTable(StreamTokenizer)
* </code> before the call to this method and reset to this state if
* modified before it returns.
*
* @param st A stream tokenizer.
* @return An Opdf.
*/
public abstract O read(StreamTokenizer st)
throws IOException, FileFormatException;
/**
* Reads a sequence of numbers. The sequence is between brackets
* and numbers are separated by spaces. Empty array are not allowed.
*
* @param st The tokenizer to read the sequence from.
* @param length The expected length of the sequence or a strictly negative
* number if it must not be checked.
* @return The array read.
*/
static protected double[] read(StreamTokenizer st, int length)
throws IOException, FileFormatException
{
LinkedList<String> l = new LinkedList<String>();
HmmReader.readWords(st, "[");
while ((st.nextToken() == StreamTokenizer.TT_NUMBER)
|| (st.ttype == StreamTokenizer.TT_WORD)) {
String token = null;
if(st.ttype == StreamTokenizer.TT_NUMBER) {
token = Double.toString(st.nval);
}
if(st.ttype == StreamTokenizer.TT_WORD) {
String word = st.sval;
String nval = l.removeLast();
token = nval + word;
}
l.addLast(token);
}
st.pushBack();
HmmReader.readWords(st, "]");
if (length >= 0 && l.size() != length)
throw new FileFormatException(st.lineno(),
"Wrong length of number sequence");
if (l.size() == 0)
throw new FileFormatException(st.lineno(),
"Invalid empty sequence");
double[] a = new double[l.size()];
for (int i = 0; i < a.length; i++) {
try {
a[i] = Double.parseDouble(l.get(i));
} catch(NumberFormatException e) {
e.printStackTrace();
}
}
return a;
}
}