/* SignalMLCodecReader.java created 2007-09-18 * */ package org.signalml.codec; import java.lang.reflect.Method; import java.util.HashMap; import java.nio.DoubleBuffer; import java.nio.FloatBuffer; import java.nio.BufferUnderflowException; import org.apache.log4j.Logger; import org.signalml.codec.generator.xml.XMLCodecException; /** SignalMLCodecReader * * * @author most of the code Copyright (C) 2003 Dobieslaw Ircha <dircha@eranet.pl> Artur Biesiadowski <abies@adres.pl> Piotr J. Durka <Piotr-J.Durka@fuw.edu.pl> * adapted by Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o. */ public class SignalMLCodecReaderImpl implements SignalMLCodecReader { protected static final Logger logger = Logger.getLogger(SignalMLCodecReader.class); private SMLCodec delegate = null; private Class<?> delegateClass = null; private SignalMLCodec codec = null; private HashMap<String,Method> methodMap = new HashMap<String, Method>(); private Method openMethod; private Method closeMethod; private Object[] singleArg = new Object[1]; private Object[] noArg = new Object[0]; private String currentFilename = null; private short cached_data_offset = -1; public SignalMLCodecReaderImpl(Class<?> cobj, SignalMLCodec codec) throws SignalMLCodecException { this.codec = codec; this.delegateClass = cobj; if (!SMLCodec.class.isAssignableFrom(cobj)) { logger.error("Bad codec class [" + cobj + "]"); throw new SignalMLCodecException("Bad codec class"); } try { delegate = (SMLCodec) cobj.newInstance(); // try { // delegate = new EASYS(); // } catch (XMLCodecException e) { // // TODO Auto-generated catch block // logger.error("", e); // } } catch (InstantiationException ex) { logger.error("Failed to instantiate codec delegate", ex); throw new SignalMLCodecException("Failed to instantiate", ex); } catch (IllegalAccessException ex) { logger.error("Failed to instantiate codec delegate", ex); throw new SignalMLCodecException("Failed to instantiate", ex); } } public SignalMLCodec getCodec() { return codec; } private void setValue(String name, int value) throws SignalMLCodecException { if (delegate != null) { try { Method m = methodMap.get(name+" _int"); if (m == null) { Class<?> targs[] = { int.class }; m = delegateClass.getMethod(name, targs); methodMap.put(name+" _int", m); } singleArg[0] = new Integer(value); m.invoke(delegate, singleArg); } catch (Exception e) { throw new SignalMLCodecException(e); } } else { throw new SignalMLCodecException("object is null"); } } private void setValue(String name, float value) throws SignalMLCodecException { if (delegate != null) { try { Method m = methodMap.get(name+" _float"); if (m == null) { Class<?> targs[] = { float.class }; m = delegateClass.getMethod(name, targs); methodMap.put(name+" _float", m); } singleArg[0] = new Float(value); m.invoke(delegate, singleArg); } catch (Exception e) { throw new SignalMLCodecException(e); } } else { throw new SignalMLCodecException("object is null"); } } private Object getValue(String name) throws SignalMLCodecException { try { Method m = methodMap.get(name); if (m == null) { m = delegateClass.getMethod(name, (Class<?>[]) null); if (m == null) { throw new Exception("method: " + name + " not found"); } methodMap.put(name, m); } return m.invoke(delegate, noArg); } catch (Exception e) { throw new SignalMLCodecException(e); } } private int getInteger(Object o) throws SignalMLCodecException { if (o instanceof Integer) { return ((Integer) o).intValue(); } else if (o instanceof Float) { return ((Float) o).intValue(); } else if (o instanceof Double) { return ((Double) o).intValue(); } else if (o instanceof Short) { return ((Short) o).intValue(); } else if (o instanceof String) { try { return Integer.parseInt((String) o); } catch (NumberFormatException e) { throw new SignalMLCodecException(e); } } else if (o instanceof Byte) { return ((Byte) o).intValue(); } else { throw new SignalMLCodecException("Integer: type not supported !"); } } private String getString(Object o) { return (o instanceof String) ? (String) o : o.toString(); } private boolean getBoolean(Object o) { if (o instanceof Boolean) { return ((Boolean) o).booleanValue(); } else { return false; } } private float getFloat(Object o) throws SignalMLCodecException { if (o instanceof Integer) { return ((Integer) o).intValue(); } else if (o instanceof Float) { return ((Float) o).floatValue(); } else if (o instanceof Double) { return (float)((Double) o).doubleValue(); } else if (o instanceof Short) { return ((Short) o).intValue(); } else if (o instanceof Byte) { return ((Byte) o).intValue(); } else if (o instanceof String) { try { return Float.valueOf((String) o).floatValue(); } catch (NumberFormatException e) { throw new SignalMLCodecException(e); } } else if (o instanceof float[]) { float[] arr = (float[]) o; float max = 0; for (int i=0; i<arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } return max; } else { throw new SignalMLCodecException("Unable to interpret float value of class [" + o.getClass().getName() + "]"); } } private float getFloat(Object o, int index) throws SignalMLCodecException { if (o instanceof Integer) { return ((Integer) o).intValue(); } else if (o instanceof Float) { return ((Float) o).floatValue(); } else if (o instanceof Double) { return (float)((Double) o).doubleValue(); } else if (o instanceof Short) { return ((Short) o).intValue(); } else if (o instanceof Byte) { return ((Byte) o).intValue(); } else if (o instanceof String) { try { return Float.valueOf((String) o).floatValue(); } catch (NumberFormatException e) { throw new SignalMLCodecException(e); } } else if (o instanceof float[]) { float[] arr = (float[]) o; try { return arr[index]; } catch (IndexOutOfBoundsException ex) { throw new SignalMLCodecException(ex); } } else { throw new SignalMLCodecException("Unable to interpret float value of class [" + o.getClass().getName() + "]"); } } public void open(String filename) throws SignalMLCodecException { if (delegate != null) { try { if (openMethod == null) { Class<?> targs[] = { String.class }; openMethod = delegateClass.getMethod("open", targs); } singleArg[0] = filename; openMethod.invoke(delegate, singleArg); } catch (Exception e) { throw new SignalMLCodecException(e); } } else { throw new SignalMLCodecException("object is null"); } this.currentFilename = filename; } public void close() { if (delegate != null) { try { if (closeMethod == null) { closeMethod = delegateClass.getMethod("close", (Class<?>[]) null); } closeMethod.invoke(delegate, noArg); } catch (Exception e) { ; } finally { delegate = null; delegateClass = null; currentFilename = null; } } } public boolean is_number_of_channels() throws SignalMLCodecException { return getBoolean(getValue("is_number_of_channels")); } public int get_number_of_channels() throws SignalMLCodecException { return getInteger(getValue("get_number_of_channels")); } public String getFormatID() throws SignalMLCodecException { return getString(getValue("getFormatID")); } public String getFormatDescription() throws SignalMLCodecException { return getString(getValue("getFormatDescription")); } public float get_sampling_frequency(int channel) throws SignalMLCodecException { return getFloat(getValue("get_sampling_frequency"), channel); } public float get_sampling_frequency() throws SignalMLCodecException { return getFloat(getValue("get_sampling_frequency")); } public boolean is_sampling_frequency() throws SignalMLCodecException { return getBoolean(getValue("is_sampling_frequency")); } public boolean is_uniform_sampling_frequency() throws SignalMLCodecException { Object value = getValue("get_sampling_frequency"); if (value instanceof float[]) { return false; } return true; } public int get_max_offset() throws SignalMLCodecException { return getInteger(getValue("get_max_offset")); } public boolean is_channel_names() throws SignalMLCodecException { return getBoolean(getValue("is_channel_names")); } public String[] get_channel_names() throws SignalMLCodecException { Object o = getValue("get_channel_names"); if (o instanceof String[]) { return (String[]) o; } throw new SignalMLCodecException("Invalid return type: " + o.getClass()); } public boolean is_calibration() throws SignalMLCodecException { return getBoolean(getValue("is_calibration")); } public float get_calibration(int channel) throws SignalMLCodecException { return getFloat(getValue("get_calibration"), channel); } public float get_calibration() throws SignalMLCodecException { return getFloat(getValue("get_calibration")); } public void set_sampling_frequency(float freq) throws SignalMLCodecException { setValue("set_sampling_frequency", freq); } public void set_number_of_channels(int n) throws SignalMLCodecException { setValue("set_number_of_channels", n); } public void set_calibration(float calib) throws SignalMLCodecException { setValue("set_calibration", calib); } public boolean is_good_spec() throws SignalMLCodecException { return is_calibration() && is_sampling_frequency() && is_number_of_channels(); } public float[] getSample(long offset) throws SignalMLCodecException { if (delegate != null) { try { return delegate.getSample(offset); } catch (Exception e) { throw new SignalMLCodecException(e); } } else { throw new SignalMLCodecException("object is null"); } } public float getChannelSample(long offset, int chn) throws SignalMLCodecException { if (delegate != null) { try { return delegate.getChannelSample(offset,chn); } catch (Exception e) { throw new SignalMLCodecException(e); } } else { throw new SignalMLCodecException("object is null"); } } @Override public void getSamples(FloatBuffer dst, int chn, long sample) throws SignalMLCodecException { try{ while(dst.hasRemaining()) dst.put(this.getChannelSample(sample++, chn)); } catch(BufferUnderflowException e) { throw new SignalMLCodecException("empty", e); } } @Override public void getSamples(DoubleBuffer dst, int chn, long sample) throws SignalMLCodecException { try{ while(dst.hasRemaining()) dst.put(this.getChannelSample(sample++, chn)); } catch(BufferUnderflowException e) { throw new SignalMLCodecException("empty", e); } } private short get_data_offset() throws XMLCodecException { if (cached_data_offset < 0) { cached_data_offset = this.delegate.read_short(28); } return cached_data_offset; } public String getCurrentFilename() { return currentFilename; } }