OpenSplice Java 5 DCPS  v6.x
OpenSplice Java 5 OpenSplice Data Distribution Service Data-Centric Publish-Subscribe API
ModifiableTimeImpl.java
Go to the documentation of this file.
1 /*
2  * Vortex OpenSplice
3  *
4  * This software and documentation are Copyright 2006 to 2024 ADLINK
5  * Technology Limited, its affiliated companies and licensors. All rights
6  * reserved.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 package org.opensplice.dds.core;
22 
23 import java.util.concurrent.TimeUnit;
24 
25 import org.omg.dds.core.Duration;
28 import org.omg.dds.core.Time;
29 
30 public class ModifiableTimeImpl extends ModifiableTime {
31  private static final long serialVersionUID = -5170318400663698911L;
32  protected final transient OsplServiceEnvironment environment;
33  private long seconds;
34  private long nanoseconds;
35  private long totalNanos;
36  private final static int INFINITE_SECONDS = DurationImpl.INFINITE_SECONDS;
37  private final static int INFINITE_NANOSECONDS = DurationImpl.INFINITE_NANOSECONDS;
38 
40  long duration, TimeUnit unit) {
41  super();
42 
43  if (unit == null) {
44  throw new IllegalArgumentExceptionImpl(environment,
45  "Illegal TimeUnit provided (null).");
46  }
47  this.environment = environment;
48  if (duration == Long.MAX_VALUE) {
49  this.seconds = INFINITE_SECONDS;
50  this.nanoseconds = INFINITE_NANOSECONDS;
51  this.totalNanos = Long.MAX_VALUE;
52  } else {
53  this.seconds = TimeUnit.SECONDS.convert(duration, unit);
54  this.totalNanos = TimeUnit.NANOSECONDS.convert(duration, unit);
55  this.nanoseconds = this.totalNanos
56  - (this.seconds * 1000 * 1000 * 1000);
57  }
58  }
59 
60  public ModifiableTimeImpl(OsplServiceEnvironment environment, long seconds,
61  long nanoseconds) {
62  super();
63  this.environment = environment;
64  this.seconds = seconds;
65  this.nanoseconds = nanoseconds;
66 
67  if (this.seconds == INFINITE_SECONDS
68  && this.nanoseconds == INFINITE_NANOSECONDS) {
69  this.totalNanos = Long.MAX_VALUE;
70  } else {
71  this.totalNanos = this.seconds * 1000 * 1000 * 1000
72  + this.nanoseconds;
73  }
74  }
75 
77  long sec = this.seconds;
78  long nsec = this.nanoseconds;
79 
80  if (sec == INFINITE_SECONDS) {
81  return new ModifiableTimeImpl(this.environment, INFINITE_SECONDS,
82  INFINITE_NANOSECONDS);
83  }
84  while (nsec >= 1000000000) {
85  sec += 1;
86  nsec -= 1000000000;
87 
88  if (sec == INFINITE_SECONDS) {
89  return new ModifiableTimeImpl(this.environment,
90  INFINITE_SECONDS, INFINITE_NANOSECONDS);
91  }
92  }
93  return new ModifiableTimeImpl(this.environment, sec, nsec);
94  }
95 
96  protected void normalizeMe() {
97  ModifiableTimeImpl normalized = this.normalize();
98  this.seconds = normalized.seconds;
99  this.nanoseconds = normalized.nanoseconds;
100  this.totalNanos = normalized.totalNanos;
101  }
102 
103  @Override
104  public int compareTo(Time o) {
105  if (o == null) {
106  return 1;
107  }
108  long sec = o.getTime(TimeUnit.SECONDS);
109  long nsec = o.getRemainder(TimeUnit.SECONDS, TimeUnit.NANOSECONDS);
110 
111  if ((this.nanoseconds >= 1000000000)
112  && ((this.nanoseconds != INFINITE_NANOSECONDS) || (this.seconds != INFINITE_SECONDS))) {
113  throw new IllegalArgumentExceptionImpl(this.environment,
114  "Illegal Time " + this.seconds + " seconds, "
115  + this.nanoseconds + " nanoseconds.");
116  }
117  if ((nsec >= 1000000000)
118  && ((nsec != Long.MAX_VALUE) || (sec != Long.MAX_VALUE))) {
119  throw new IllegalArgumentExceptionImpl(this.environment,
120  "Illegal Time " + sec + " seconds, " + nsec
121  + " nanoseconds.");
122  }
123  if (this.seconds > sec)
124  return 1;
125  if (this.seconds < sec)
126  return -1;
127  if (this.nanoseconds > nsec)
128  return 1;
129  if (this.nanoseconds < nsec)
130  return -1;
131  return 0;
132  }
133 
134  @Override
135  public boolean equals(Object other) {
136  if (other instanceof ModifiableTimeImpl) {
137  if (((ModifiableTimeImpl) other).compareTo(this) == 0) {
138  return true;
139  }
140  }
141  return false;
142  }
143 
144  @Override
145  public int hashCode() {
146  return 31 * 17 + (int) (this.totalNanos ^ (this.totalNanos >>> 32));
147  }
148 
149  @Override
151  return this.environment;
152  }
153 
154  @Override
155  public void copyFrom(Time src) {
156  if (src == null) {
157  throw new IllegalArgumentExceptionImpl(this.environment,
158  "Illegal Time (null) provided.");
159  }
160  this.seconds = src.getTime(TimeUnit.SECONDS);
161  this.nanoseconds = src.getRemainder(TimeUnit.SECONDS,
162  TimeUnit.NANOSECONDS);
163  this.totalNanos = this.nanoseconds + this.seconds * 1000 * 1000 * 1000;
164 
165  }
166 
167  @Override
168  public Time immutableCopy() {
169  return new TimeImpl(this.environment, this.seconds, this.nanoseconds);
170  }
171 
172  @Override
173  public void setTime(long time, TimeUnit unit) {
174  if (unit == null) {
175  throw new IllegalArgumentExceptionImpl(this.environment,
176  "Illegal TimeUnit (null) provided.");
177  }
178  this.seconds = TimeUnit.SECONDS.convert(time, unit);
179  this.totalNanos = TimeUnit.NANOSECONDS.convert(time, unit);
180  this.nanoseconds = this.totalNanos
181  - (this.seconds * 1000 * 1000 * 1000);
182 
183  }
184 
185  @Override
186  public void add(Duration duration) {
187  if (duration == null) {
188  throw new IllegalArgumentExceptionImpl(this.environment,
189  "Illegal Duration (null) provided.");
190  }
191  if (!this.isValid()) {
192  throw new IllegalArgumentExceptionImpl(this.environment,
193  "Cannot add duration to invalid time.");
194  }
195  long sec = duration.getDuration(TimeUnit.SECONDS);
196  long nsec = duration.getRemainder(TimeUnit.SECONDS,
197  TimeUnit.NANOSECONDS);
198 
199  if (!((this.nanoseconds < 1000000000) || (this.nanoseconds == INFINITE_NANOSECONDS))) {
200  throw new IllegalArgumentExceptionImpl(this.environment,
201  "Illegal duration");
202  }
203  if (!((nsec < 1000000000) || (nsec == Long.MAX_VALUE))) {
204  throw new IllegalArgumentExceptionImpl(this.environment,
205  "Illegal duration");
206  }
207 
208  if (this.nanoseconds == INFINITE_NANOSECONDS) {
209  if (this.seconds == INFINITE_SECONDS) {
210  this.seconds = INFINITE_SECONDS;
211  this.nanoseconds = INFINITE_NANOSECONDS;
212  this.totalNanos = Long.MAX_VALUE;
213  return;
214  }
215  throw new IllegalArgumentExceptionImpl(this.environment,
216  "Illegal duration " + this.seconds + " seconds, "
217  + this.nanoseconds + " nanoseconds.");
218 
219  }
220  if (nsec == Long.MAX_VALUE) {
221  if (sec == Long.MAX_VALUE) {
222  this.seconds = INFINITE_SECONDS;
223  this.nanoseconds = INFINITE_NANOSECONDS;
224  this.totalNanos = Long.MAX_VALUE;
225  return;
226  }
227  throw new IllegalArgumentExceptionImpl(this.environment,
228  "Illegal duration " + sec + " seconds, " + nsec
229  + " nanoseconds.");
230  }
231  if (sec > 0) {
232  if (INFINITE_SECONDS - sec <= this.seconds) {
233  /*
234  * is identical to 'INFINITE_SECONDS <= this.seconds + sec' In
235  * other words the sum is larger than infinite, so results must
236  * be infinite.
237  */
238  this.seconds = INFINITE_SECONDS;
239  this.nanoseconds = INFINITE_NANOSECONDS;
240  this.totalNanos = Long.MAX_VALUE;
241  return;
242  }
243  }
244  this.seconds += sec;
245  this.nanoseconds += nsec;
246  this.normalizeMe();
247 
248  }
249 
250  @Override
251  public void add(long duration, TimeUnit unit) {
252  DurationImpl temp = new DurationImpl(this.environment, duration, unit)
253  .normalize();
254 
255  this.add(temp);
256  }
257 
258  public boolean isInfinite() {
259  return (this.totalNanos == Long.MAX_VALUE) ? true : false;
260  }
261 
262  @Override
263  public void subtract(Duration duration) {
264  if (duration == null) {
265  throw new IllegalArgumentExceptionImpl(this.environment,
266  "Illegal Duration (null) provided.");
267  }
268  if (!this.isValid()) {
269  throw new IllegalArgumentExceptionImpl(this.environment,
270  "Cannot subtract duration from invalid time.");
271  }
272  if (this.isInfinite() && duration.isInfinite()) {
273  throw new IllegalArgumentExceptionImpl(this.environment,
274  "Cannot subtract infinite duration from infinite time.");
275  }
276  long sec = duration.getDuration(TimeUnit.SECONDS);
277  long nsec = duration.getRemainder(TimeUnit.SECONDS,
278  TimeUnit.NANOSECONDS);
279 
280  if (!((this.nanoseconds < 1000000000) || (this.nanoseconds == INFINITE_NANOSECONDS))) {
281  throw new IllegalArgumentExceptionImpl(this.environment,
282  "Illegal duration " + this.seconds + " seconds, "
283  + this.nanoseconds + " nanoseconds.");
284  }
285  if (!((nsec < 1000000000) || (nsec == Long.MAX_VALUE))) {
286  throw new IllegalArgumentExceptionImpl(this.environment,
287  "Illegal duration " + sec + " seconds, " + nsec
288  + " nanoseconds.");
289  }
290 
291  if (this.nanoseconds == INFINITE_NANOSECONDS) {
292  if (this.seconds == INFINITE_SECONDS) {
293  this.seconds = INFINITE_SECONDS;
294  this.nanoseconds = INFINITE_NANOSECONDS;
295  this.totalNanos = Long.MAX_VALUE;
296  return;
297  }
298  throw new IllegalArgumentExceptionImpl(this.environment,
299  "Illegal duration " + this.seconds + " seconds, "
300  + this.nanoseconds + " nanoseconds.");
301  }
302  if (nsec == Long.MAX_VALUE) {
303  if (sec == Long.MAX_VALUE) {
304  this.seconds = INFINITE_SECONDS;
305  this.nanoseconds = INFINITE_NANOSECONDS;
306  this.totalNanos = Long.MAX_VALUE;
307  return;
308  }
309  throw new IllegalArgumentExceptionImpl(this.environment,
310  "Illegal duration " + sec + " seconds, " + nsec
311  + " nanoseconds.");
312  }
313  if ((sec <= 0) && (INFINITE_SECONDS + sec <= this.seconds)) {
314  /*
315  * is identical to '-(INFINITE_SECONDS >= this.seconds - sec)' In
316  * other words the sum is larger than infinite, so results must be
317  * infinite.
318  */
319  this.seconds = INFINITE_SECONDS;
320  this.nanoseconds = INFINITE_NANOSECONDS;
321  this.totalNanos = Long.MAX_VALUE;
322  return;
323  }
324  this.seconds -= sec;
325 
326  if (this.seconds == INFINITE_SECONDS) {
327  this.seconds = INFINITE_SECONDS;
328  this.nanoseconds = INFINITE_NANOSECONDS;
329  this.totalNanos = Long.MAX_VALUE;
330  return;
331  }
332  this.nanoseconds -= nsec;
333 
334  if (this.nanoseconds < 0) {
335  this.seconds--;
336  this.nanoseconds += 1000000000;
337  }
338  this.normalizeMe();
339  }
340 
341  @Override
342  public void subtract(long duration, TimeUnit unit) {
343  if (unit == null) {
344  throw new IllegalArgumentExceptionImpl(this.environment,
345  "Illegal TimeUnit (null) provided.");
346  }
347  DurationImpl temp = new DurationImpl(this.environment, duration, unit)
348  .normalize();
349 
350  this.subtract(temp);
351  }
352 
353  @Override
354  public long getTime(TimeUnit inThisUnit) {
355  if (inThisUnit == null) {
356  throw new IllegalArgumentExceptionImpl(this.environment,
357  "Illegal TimeUnit (null) provided.");
358  }
359  if (this.isInfinite()) {
360  return Long.MAX_VALUE;
361  }
362  return inThisUnit.convert(this.totalNanos, TimeUnit.NANOSECONDS);
363  }
364 
365  @Override
366  public long getRemainder(TimeUnit primaryUnit, TimeUnit remainderUnit) {
367  if ((primaryUnit == null) || (remainderUnit == null)) {
368  throw new IllegalArgumentExceptionImpl(this.environment,
369  "Illegal TimeUnit (null) provided.");
370  }
371  if (remainderUnit.compareTo(primaryUnit) >= 0) {
372  return 0;
373  }
374  if (this.isInfinite()) {
375  return Long.MAX_VALUE;
376  }
377  long primaryDuration = primaryUnit.convert(this.totalNanos,
378  TimeUnit.NANOSECONDS);
379  long primaryNanoDuration = TimeUnit.NANOSECONDS.convert(
380  primaryDuration, primaryUnit);
381  long leftOverNanos = this.totalNanos - primaryNanoDuration;
382 
383  return remainderUnit.convert(leftOverNanos, TimeUnit.NANOSECONDS);
384  }
385 
386  @Override
387  public boolean isValid() {
388  if (this.seconds == DDS.TIMESTAMP_INVALID_SEC.value
389  && this.nanoseconds == DDS.TIMESTAMP_INVALID_NSEC.value) {
390  return false;
391  }
392  if ((this.nanoseconds >= 1000000000)
393  && ((this.nanoseconds != INFINITE_NANOSECONDS) || (this.seconds != INFINITE_SECONDS))) {
394  return false;
395  }
396  return true;
397  }
398 
399  @Override
401  return new ModifiableTimeImpl(this.environment, this.seconds,
402  this.nanoseconds);
403  }
404 
405  public DDS.Time_t convert() {
406  return new DDS.Time_t((int) this.seconds, (int) this.nanoseconds);
407  }
408 
409  @Override
410  public String toString() {
411  if (this.isInfinite()) {
412  return "infinite";
413  }
414  return this.totalNanos + " ns";
415  }
416 }
abstract long getTime(TimeUnit inThisUnit)
Truncate this time to a whole-number quantity of the given time unit.
abstract long getRemainder(TimeUnit primaryUnit, TimeUnit remainderUnit)
If getting the magnitude of this time in the given primaryUnit would cause truncation with respect to...
abstract boolean isInfinite()
Report whether this duration lasts forever.
ModifiableTimeImpl(OsplServiceEnvironment environment, long seconds, long nanoseconds)
ModifiableTimeImpl(OsplServiceEnvironment environment, long duration, TimeUnit unit)
final transient OsplServiceEnvironment environment
void subtract(long duration, TimeUnit unit)
abstract long getRemainder(TimeUnit primaryUnit, TimeUnit remainderUnit)
If getting the magnitude of this duration in the given primaryUnit would cause truncation with respec...
void add(long duration, TimeUnit unit)
abstract long getDuration(TimeUnit inThisUnit)
Truncate this duration to a whole-number quantity of the given time unit.
A span of elapsed time expressed with nanosecond precision.
Definition: Duration.java:35
DDS implementations are rooted in this class, a concrete subclass of which can be instantiated based ...
A moment in time expressed with nanosecond precision (though not necessarily nanosecond accuracy)...
Definition: Time.java:34
long getRemainder(TimeUnit primaryUnit, TimeUnit remainderUnit)