/* * 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; } }