-/*******************************************************************************\r
- * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.history.util;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.accessor.ArrayAccessor;\r
-import org.simantics.databoard.accessor.error.AccessorException;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.RecordBinding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.history.HistoryException;\r
-\r
-/**\r
- * Stream iterator iterates sample entries in an array.\r
- * \r
- * Is scans the next sample and knows its time stamp.\r
- * \r
- * @author toni.kalajainen\r
- */\r
-public class StreamIterator {\r
-\r
- // Sample binding\r
- RecordBinding sampleBinding;\r
- \r
- // Array accessor\r
- ArrayAccessor aa;\r
- // Array stream\r
- Stream stream;\r
- // From and end times of the whole stream\r
- double from, end;\r
- \r
- // Current and next sample\r
- Object current, next;\r
-\r
- // Utility for reading sample\r
- ValueBand valueBand, nextValueBand;\r
- // Start and end time of current sample\r
- double startTime, endTime;\r
- \r
- int index = -1;\r
- int size;\r
- \r
- public StreamIterator(ArrayAccessor aa) throws HistoryException {\r
- try {\r
- this.aa = aa;\r
- sampleBinding = (RecordBinding) Bindings.getBeanBinding( aa.type().componentType );\r
- current = sampleBinding.createDefault();\r
- next = sampleBinding.createDefault();\r
- valueBand = new ValueBand(sampleBinding, current);\r
- nextValueBand = new ValueBand(sampleBinding, next);\r
- stream = new Stream( aa, sampleBinding );\r
- size = aa.size();\r
- if ( size>0 ) {\r
- aa.get(0, sampleBinding, current);\r
- from = valueBand.getTimeDouble();\r
- aa.get(size-1, sampleBinding, current);\r
- end = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();\r
- }\r
- } catch (BindingException e) {\r
- throw new HistoryException( e );\r
- } catch (AccessorException e) {\r
- throw new HistoryException( e );\r
- } \r
- }\r
- \r
- /**\r
- * Go to time using random access\r
- * @param time\r
- * @return true if sample was found\r
- * @throws HistoryException \r
- */\r
- public boolean gotoTime(double time) throws HistoryException {\r
- // Outside range\r
- if ( time<from || time>end ) {\r
- index = -1;\r
- return false;\r
- }\r
- \r
- // Already at cursor\r
- if ( time>=startTime && time<endTime ) return hasValue();\r
- int i = stream.binarySearch(Bindings.DOUBLE, time);\r
- if (i>=0) {\r
- gotoIndex( i );\r
- } else {\r
- int insertPos = -i-2;\r
- if ( insertPos<0 || insertPos>=size ) {\r
- index = -1;\r
- } else {\r
- gotoIndex( insertPos );\r
- if ( endTime<time ) index = -1;\r
- }\r
- }\r
- \r
- return hasValue(); \r
- }\r
- \r
- /**\r
- * Proceed to time using sequential seek.\r
- * \r
- * @param time\r
- * @return true if sample was found\r
- * @throws HistoryException \r
- */\r
- public boolean proceedToTime(double time) throws HistoryException {\r
- // Outside range\r
- if ( time<from || time>end ) {\r
- index = -1;\r
- return false;\r
- }\r
-\r
- // No position, or going to past\r
- if (index<0 || startTime>time) {\r
- gotoTime(time);\r
- return hasValue();\r
- }\r
- \r
- // Proceed until end hit\r
- while (time>=endTime && hasNext()) gotoIndex(index+1);\r
- return hasValue();\r
- }\r
- \r
- /**\r
- * Go to index. If element does not exist, index is set to -1;\r
- * @param pos\r
- * @throws HistoryException\r
- */\r
- public void gotoIndex(int pos) throws HistoryException {\r
- if (pos == index) return;\r
- \r
- if (pos<0 || pos>=size) {\r
- index = -1;\r
- return;\r
- }\r
-\r
- try {\r
- // Read current value\r
- if (pos == index+1 && index>=0) {\r
- sampleBinding.readFrom(sampleBinding, next, current);\r
- } else {\r
- aa.get(pos, sampleBinding, current);\r
- }\r
- startTime = valueBand.getTimeDouble();\r
- \r
- // Read next value\r
- if (pos+1<size) {\r
- aa.get(pos+1, sampleBinding, next);\r
- //endTime = valueBand.isValidValue() ? nextValueBand.getTimeDouble() : ( nextValueBand.isValidValue() ? nextValueBand.getTimeDouble() : nextValueBand.getTimeDouble() );\r
- endTime = nextValueBand.getTimeDouble();\r
- } else { \r
- endTime = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();\r
- }\r
- \r
- // \r
- index = pos;\r
- } catch (AccessorException e) {\r
- throw new HistoryException( e );\r
- } catch (BindingException e) {\r
- throw new HistoryException( e );\r
- }\r
- }\r
-\r
- \r
- public boolean hasNext() {\r
- return index<size-1;\r
- }\r
-\r
- public void next() throws HistoryException {\r
- //if (index>=0) \r
- gotoIndex( index+1 );\r
- }\r
- \r
- public ValueBand getValueBand() {\r
- return valueBand;\r
- }\r
- \r
- public Object getValue(Binding binding) throws HistoryException {\r
- return valueBand.getValue(binding);\r
- }\r
- \r
- public Object getSample() {\r
- return current;\r
- }\r
- \r
- public RecordBinding getSampleBinding() {\r
- return sampleBinding;\r
- }\r
- \r
- public boolean hasValue() {\r
- return index!=-1;\r
- }\r
- \r
- public boolean hasValidValue() throws HistoryException {\r
- return index!=-1 && !valueBand.isNanSample() && !valueBand.isNullValue();\r
- }\r
- /**\r
- * Get the start time. The value is valid if index != -1\r
- * @return start time\r
- */\r
- public double getStartTime() {\r
- return startTime;\r
- }\r
- \r
- /**\r
- * Get end time, the value is valid if index != -1\r
- * @return end time\r
- */\r
- public double getEndTime() {\r
- return endTime;\r
- }\r
- \r
- public Double getNextTime() throws HistoryException {\r
- if ( size==0 ) return null;\r
- if ( index==-1 ) return from;\r
- return (Double) nextValueBand.getTime(Bindings.DOUBLE);\r
- }\r
- \r
- public Double getNextTime( double currentTime ) throws HistoryException {\r
- if ( size==0 ) return null;\r
- if ( index==-1 ) return from;\r
- \r
- if ( valueBand.hasEndTime() ) {\r
- Double endTime = (Double) valueBand.getEndTime(Bindings.DOUBLE);\r
- if ( endTime>currentTime ) return endTime;\r
- }\r
- \r
- double nextTime = (Double) nextValueBand.getTime(Bindings.DOUBLE);\r
- return nextTime;\r
- }\r
- \r
- \r
- \r
- /**\r
- * get index of the cursor\r
- * @return index or -1\r
- */\r
- public int getIndex() {\r
- return index;\r
- }\r
- \r
- @Override\r
- public String toString() {\r
- Binding valueBinding = valueBand.getValueBinding();\r
- String valueStr;\r
- try {\r
- valueStr = valueBinding.toString( valueBand.getValue() );\r
- } catch (BindingException e) {\r
- valueStr = e.toString();\r
- } catch (HistoryException e) {\r
- valueStr = e.toString();\r
- }\r
- if ( hasValue() ) {\r
- return "i="+index+", time=["+startTime+"-"+endTime+"], value="+valueStr;\r
- } else {\r
- return "<no value>";\r
- }\r
- }\r
- \r
- /**\r
- * Get start time of the first sample.\r
- * @return time\r
- */\r
- public double getFirstTime() {\r
- return from;\r
- }\r
- \r
- /**\r
- * Get end time of the last sample.\r
- * @return time\r
- */\r
- public double getLastTime() {\r
- return end;\r
- }\r
- \r
- public int size() {\r
- return size;\r
- }\r
- \r
- public boolean isEmpty() {\r
- return size==0;\r
- }\r
- \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.history.util;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.accessor.ArrayAccessor;
+import org.simantics.databoard.accessor.error.AccessorException;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.RecordBinding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.history.HistoryException;
+
+/**
+ * Stream iterator iterates sample entries in an array.
+ *
+ * Is scans the next sample and knows its time stamp.
+ *
+ * @author toni.kalajainen
+ */
+public class StreamIterator {
+
+ // Sample binding
+ RecordBinding sampleBinding;
+
+ // Array accessor
+ ArrayAccessor aa;
+ // Array stream
+ Stream stream;
+ // From and end times of the whole stream
+ double from, end;
+
+ // Current and next sample
+ Object current, next;
+
+ // Utility for reading sample
+ ValueBand valueBand, nextValueBand;
+ // Start and end time of current sample
+ double startTime, endTime;
+
+ int index = -1;
+ int size;
+
+ public StreamIterator(ArrayAccessor aa) throws HistoryException {
+ try {
+ this.aa = aa;
+ sampleBinding = (RecordBinding) Bindings.getBeanBinding( aa.type().componentType );
+ current = sampleBinding.createDefault();
+ next = sampleBinding.createDefault();
+ valueBand = new ValueBand(sampleBinding, current);
+ nextValueBand = new ValueBand(sampleBinding, next);
+ stream = new Stream( aa, sampleBinding );
+ size = aa.size();
+ if ( size>0 ) {
+ aa.get(0, sampleBinding, current);
+ from = valueBand.getTimeDouble();
+ aa.get(size-1, sampleBinding, current);
+ end = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();
+ }
+ } catch (BindingException e) {
+ throw new HistoryException( e );
+ } catch (AccessorException e) {
+ throw new HistoryException( e );
+ }
+ }
+
+ /**
+ * Go to time using random access
+ * @param time
+ * @return true if sample was found
+ * @throws HistoryException
+ */
+ public boolean gotoTime(double time) throws HistoryException {
+ // Outside range
+ if ( time<from || time>end ) {
+ index = -1;
+ return false;
+ }
+
+ // Already at cursor
+ if ( time>=startTime && time<endTime ) return hasValue();
+ int i = stream.binarySearch(Bindings.DOUBLE, time);
+ if (i>=0) {
+ gotoIndex( i );
+ } else {
+ int insertPos = -i-2;
+ if ( insertPos<0 || insertPos>=size ) {
+ index = -1;
+ } else {
+ gotoIndex( insertPos );
+ if ( endTime<time ) index = -1;
+ }
+ }
+
+ return hasValue();
+ }
+
+ /**
+ * Proceed to time using sequential seek.
+ *
+ * @param time
+ * @return true if sample was found
+ * @throws HistoryException
+ */
+ public boolean proceedToTime(double time) throws HistoryException {
+ // Outside range
+ if ( time<from || time>end ) {
+ index = -1;
+ return false;
+ }
+
+ // No position, or going to past
+ if (index<0 || startTime>time) {
+ gotoTime(time);
+ return hasValue();
+ }
+
+ // Proceed until end hit
+ while (time>=endTime && hasNext()) gotoIndex(index+1);
+ return hasValue();
+ }
+
+ /**
+ * Go to index. If element does not exist, index is set to -1;
+ * @param pos
+ * @throws HistoryException
+ */
+ public void gotoIndex(int pos) throws HistoryException {
+ if (pos == index) return;
+
+ if (pos<0 || pos>=size) {
+ index = -1;
+ return;
+ }
+
+ try {
+ // Read current value
+ if (pos == index+1 && index>=0) {
+ sampleBinding.readFrom(sampleBinding, next, current);
+ } else {
+ aa.get(pos, sampleBinding, current);
+ }
+ startTime = valueBand.getTimeDouble();
+
+ // Read next value
+ if (pos+1<size) {
+ aa.get(pos+1, sampleBinding, next);
+ //endTime = valueBand.isValidValue() ? nextValueBand.getTimeDouble() : ( nextValueBand.isValidValue() ? nextValueBand.getTimeDouble() : nextValueBand.getTimeDouble() );
+ endTime = nextValueBand.getTimeDouble();
+ } else {
+ endTime = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();
+ }
+
+ //
+ index = pos;
+ } catch (AccessorException e) {
+ throw new HistoryException( e );
+ } catch (BindingException e) {
+ throw new HistoryException( e );
+ }
+ }
+
+
+ public boolean hasNext() {
+ return index<size-1;
+ }
+
+ public void next() throws HistoryException {
+ //if (index>=0)
+ gotoIndex( index+1 );
+ }
+
+ public ValueBand getValueBand() {
+ return valueBand;
+ }
+
+ public Object getValue(Binding binding) throws HistoryException {
+ return valueBand.getValue(binding);
+ }
+
+ public Object getSample() {
+ return current;
+ }
+
+ public RecordBinding getSampleBinding() {
+ return sampleBinding;
+ }
+
+ public boolean hasValue() {
+ return index!=-1;
+ }
+
+ public boolean hasValidValue() throws HistoryException {
+ return index!=-1 && !valueBand.isNanSample() && !valueBand.isNullValue();
+ }
+ /**
+ * Get the start time. The value is valid if index != -1
+ * @return start time
+ */
+ public double getStartTime() {
+ return startTime;
+ }
+
+ /**
+ * Get end time, the value is valid if index != -1
+ * @return end time
+ */
+ public double getEndTime() {
+ return endTime;
+ }
+
+ public Double getNextTime() throws HistoryException {
+ if ( size==0 ) return null;
+ if ( index==-1 ) return from;
+ return (Double) nextValueBand.getTime(Bindings.DOUBLE);
+ }
+
+ public Double getNextTime( double currentTime ) throws HistoryException {
+ if ( size==0 ) return null;
+ if ( index==-1 ) return from;
+
+ if ( valueBand.hasEndTime() ) {
+ Double endTime = (Double) valueBand.getEndTime(Bindings.DOUBLE);
+ if ( endTime>currentTime ) return endTime;
+ }
+
+ double nextTime = (Double) nextValueBand.getTime(Bindings.DOUBLE);
+ return nextTime;
+ }
+
+
+
+ /**
+ * get index of the cursor
+ * @return index or -1
+ */
+ public int getIndex() {
+ return index;
+ }
+
+ @Override
+ public String toString() {
+ Binding valueBinding = valueBand.getValueBinding();
+ String valueStr;
+ try {
+ valueStr = valueBinding.toString( valueBand.getValue() );
+ } catch (BindingException e) {
+ valueStr = e.toString();
+ } catch (HistoryException e) {
+ valueStr = e.toString();
+ }
+ if ( hasValue() ) {
+ return "i="+index+", time=["+startTime+"-"+endTime+"], value="+valueStr;
+ } else {
+ return "<no value>";
+ }
+ }
+
+ /**
+ * Get start time of the first sample.
+ * @return time
+ */
+ public double getFirstTime() {
+ return from;
+ }
+
+ /**
+ * Get end time of the last sample.
+ * @return time
+ */
+ public double getLastTime() {
+ return end;
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public boolean isEmpty() {
+ return size==0;
+ }
+
+}