]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.history/src/org/simantics/history/util/StreamIterator.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / util / StreamIterator.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2012 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.history.util;
13
14 import org.simantics.databoard.Bindings;
15 import org.simantics.databoard.accessor.ArrayAccessor;
16 import org.simantics.databoard.accessor.error.AccessorException;
17 import org.simantics.databoard.binding.Binding;
18 import org.simantics.databoard.binding.RecordBinding;
19 import org.simantics.databoard.binding.error.BindingException;
20 import org.simantics.history.HistoryException;
21
22 /**
23  * Stream iterator iterates sample entries in an array.
24  * 
25  * Is scans the next sample and knows its time stamp.
26  * 
27  * @author toni.kalajainen
28  */
29 public class StreamIterator {
30
31         // Sample binding
32         RecordBinding sampleBinding;
33         
34         // Array accessor
35         ArrayAccessor aa;
36         // Array stream
37         Stream stream;
38         // From and end times of the whole stream
39         double from, end;
40         
41         // Current and next sample
42         Object current, next;
43
44         // Utility for reading sample
45         ValueBand valueBand, nextValueBand;
46         // Start and end time of current sample
47         double startTime, endTime;
48         
49         int index = -1;
50         int size;
51         
52         public StreamIterator(ArrayAccessor aa) throws HistoryException {
53                 try {
54                         this.aa = aa;
55                         sampleBinding = (RecordBinding) Bindings.getBeanBinding( aa.type().componentType );
56                         current = sampleBinding.createDefault();
57                         next = sampleBinding.createDefault();
58                         valueBand = new ValueBand(sampleBinding, current);
59                         nextValueBand = new ValueBand(sampleBinding, next);
60                         stream = new Stream( aa, sampleBinding );
61                         size = aa.size();
62                         if ( size>0 ) {
63                         aa.get(0, sampleBinding, current);
64                                 from = valueBand.getTimeDouble();
65                         aa.get(size-1, sampleBinding, current);
66                                 end = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();
67                         }
68                 } catch (BindingException e) {
69                         throw new HistoryException( e );
70                 } catch (AccessorException e) {
71                         throw new HistoryException( e );
72                 } 
73         }
74         
75         /**
76          * Go to time using random access
77          * @param time
78          * @return true if sample was found
79          * @throws HistoryException 
80          */
81         public boolean gotoTime(double time) throws HistoryException {
82                 // Outside range
83                 if ( time<from || time>end ) {
84                         index = -1;
85                         return false;
86                 }
87                 
88                 // Already at cursor
89                 if ( time>=startTime && time<endTime ) return hasValue();
90                 int i = stream.binarySearch(Bindings.DOUBLE, time);
91                 if (i>=0) {
92                         gotoIndex( i );
93                 } else {
94                         int insertPos = -i-2;
95                         if ( insertPos<0 || insertPos>=size ) {
96                                 index = -1;
97                         } else {
98                                 gotoIndex( insertPos );
99                                 if ( endTime<time ) index = -1;
100                         }
101                 }
102                 
103                 return hasValue();              
104         }
105         
106         /**
107          * Proceed to time using sequential seek.
108          * 
109          * @param time
110          * @return true if sample was found
111          * @throws HistoryException 
112          */
113         public boolean proceedToTime(double time) throws HistoryException {
114                 // Outside range
115                 if ( time<from || time>end ) {
116                         index = -1;
117                         return false;
118                 }
119
120                 // No position, or going to past
121                 if (index<0 || startTime>time) {
122                         gotoTime(time);
123                         return hasValue();
124                 }
125                 
126                 // Proceed until end hit
127                 while (time>=endTime && hasNext()) gotoIndex(index+1);
128                 return hasValue();
129         }
130         
131         /**
132          * Go to index. If element does not exist, index is set to -1;
133          * @param pos
134          * @throws HistoryException
135          */
136         public void gotoIndex(int pos) throws HistoryException {
137                 if (pos == index) return;
138                 
139                 if (pos<0 || pos>=size) {
140                         index = -1;
141                         return;
142                 }
143
144                 try {
145                         // Read current value
146                         if (pos == index+1 && index>=0) {
147                                 sampleBinding.readFrom(sampleBinding, next, current);
148                         } else {
149                                 aa.get(pos, sampleBinding, current);
150                         }
151                         startTime = valueBand.getTimeDouble();
152                         
153                         // Read next value
154                         if (pos+1<size) {
155                                 aa.get(pos+1, sampleBinding, next);
156                                 //endTime = valueBand.isValidValue() ? nextValueBand.getTimeDouble() : ( nextValueBand.isValidValue() ? nextValueBand.getTimeDouble() : nextValueBand.getTimeDouble() );
157                                 endTime = nextValueBand.getTimeDouble();
158                         } else {                                
159                                 endTime = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();
160                         }
161                         
162                         // 
163                         index = pos;
164                 } catch (AccessorException e) {
165                         throw new HistoryException( e );
166                 } catch (BindingException e) {
167                         throw new HistoryException( e );
168                 }
169         }
170
171         
172         public boolean hasNext() {
173                 return index<size-1;
174         }
175
176         public void next() throws HistoryException {
177                 //if (index>=0) 
178                 gotoIndex( index+1 );
179         }
180         
181         public ValueBand getValueBand() {
182                 return valueBand;
183         }
184         
185         public Object getValue(Binding binding) throws HistoryException {
186                 return valueBand.getValue(binding);
187         }
188         
189         public Object getSample() {
190                 return current;
191         }
192         
193         public RecordBinding getSampleBinding() {
194                 return sampleBinding;
195         }
196         
197         public boolean hasValue() {
198                 return index!=-1;
199         }
200         
201         public boolean hasValidValue() throws HistoryException {
202                 return index!=-1 && !valueBand.isNanSample() && !valueBand.isNullValue();
203         }
204         /**
205          * Get the start time. The value is valid if index != -1
206          * @return start time
207          */
208         public double getStartTime() {
209                 return startTime;
210         }
211         
212         /**
213          * Get end time, the value is valid if index != -1
214          * @return end time
215          */
216         public double getEndTime() {
217                 return endTime;
218         }
219         
220         public Double getNextTime() throws HistoryException {
221                 if ( size==0 ) return null;
222                 if ( index==-1 ) return from;
223                 return (Double) nextValueBand.getTime(Bindings.DOUBLE);
224         }
225         
226         public Double getNextTime( double currentTime ) throws HistoryException {
227                 if ( size==0 ) return null;
228                 if ( index==-1 ) return from;
229                 
230                 if ( valueBand.hasEndTime() ) {
231                         Double endTime = (Double) valueBand.getEndTime(Bindings.DOUBLE);
232                         if ( endTime>currentTime ) return endTime;
233                 }
234                 
235                 double nextTime = (Double) nextValueBand.getTime(Bindings.DOUBLE);
236                 return nextTime;
237         }
238         
239         
240         
241         /**
242          * get index of the cursor
243          * @return index or -1
244          */
245         public int getIndex() {
246                 return index;
247         }
248         
249         @Override
250         public String toString() {
251                 Binding valueBinding = valueBand.getValueBinding();
252                 String valueStr;
253                 try {
254                         valueStr = valueBinding.toString( valueBand.getValue() );
255                 } catch (BindingException e) {
256                         valueStr = e.toString();
257                 } catch (HistoryException e) {
258                         valueStr = e.toString();
259                 }
260                 if ( hasValue() ) {
261                         return "i="+index+", time=["+startTime+"-"+endTime+"], value="+valueStr;
262                 } else {
263                         return "<no value>";
264                 }
265         }
266         
267         /**
268          * Get start time of the first sample.
269          * @return time
270          */
271         public double getFirstTime() {
272                 return from;
273         }
274         
275         /**
276          * Get end time of the last sample.
277          * @return time
278          */
279         public double getLastTime() {
280                 return end;
281         }
282         
283         public int size() {
284                 return size;
285         }
286         
287         public boolean isEmpty() {
288                 return size==0;
289         }
290         
291 }