OpenSplice Java 5 DCPS  v6.x
OpenSplice Java 5 OpenSplice Data Distribution Service Data-Centric Publish-Subscribe API
DurationImpl.java
Go to the documentation of this file.
1 /*
2  * Vortex OpenSplice
3  *
4  * This software and documentation are Copyright 2006 to 2021 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;
27 
28 public class DurationImpl extends Duration {
29  private static final long serialVersionUID = -3177410803404504645L;
30  private final transient OsplServiceEnvironment environment;
31  private final long seconds;
32  private final long nanoseconds;
33  private final long totalNanos;
34  public final static int INFINITE_SECONDS = DDS.DURATION_INFINITE_SEC.value;
35  public final static int INFINITE_NANOSECONDS = DDS.DURATION_INFINITE_NSEC.value;
36 
37  public DurationImpl(OsplServiceEnvironment environment, long duration,
38  TimeUnit unit) {
39  super();
40  this.environment = environment;
41 
42  if (unit == null) {
43  throw new IllegalArgumentExceptionImpl(environment,
44  "Invalid TimeUnit (null) provided.");
45  }
46 
47  if (duration == Long.MAX_VALUE) {
48  this.seconds = INFINITE_SECONDS;
49  this.nanoseconds = INFINITE_NANOSECONDS;
50  this.totalNanos = Long.MAX_VALUE;
51  } else {
52  this.seconds = TimeUnit.SECONDS.convert(duration, unit);
53  this.totalNanos = TimeUnit.NANOSECONDS.convert(duration, unit);
54  this.nanoseconds = this.totalNanos
55  - (this.seconds * 1000 * 1000 * 1000);
56  }
57  }
58 
59  public DurationImpl(OsplServiceEnvironment environment, long seconds,
60  long nanoseconds) {
61  super();
62  this.environment = environment;
63  this.seconds = seconds;
64  this.nanoseconds = nanoseconds;
65 
66  if (this.seconds == INFINITE_SECONDS
67  && this.nanoseconds == INFINITE_NANOSECONDS) {
68  this.totalNanos = Long.MAX_VALUE;
69  } else {
70  this.totalNanos = this.seconds * 1000 * 1000 * 1000
71  + this.nanoseconds;
72  }
73  }
74 
76  long sec = this.seconds;
77  long nsec = this.nanoseconds;
78 
79  if (sec == INFINITE_SECONDS) {
80  return new DurationImpl(this.environment, INFINITE_SECONDS,
81  INFINITE_NANOSECONDS);
82  }
83  while (nsec >= 1000000000) {
84  sec += 1;
85  nsec -= 1000000000;
86 
87  if (sec == INFINITE_SECONDS) {
88  return new DurationImpl(this.environment, INFINITE_SECONDS,
89  INFINITE_NANOSECONDS);
90  }
91  }
92  return new DurationImpl(this.environment, sec, nsec);
93  }
94 
95  @Override
96  public int compareTo(Duration o) {
97  if (o == null) {
98  return 1;
99  }
100  if (this.isInfinite() && o.isInfinite()) {
101  return 0;
102  }
103  long sec = o.getDuration(TimeUnit.SECONDS);
104  long nsec = o.getRemainder(TimeUnit.SECONDS, TimeUnit.NANOSECONDS);
105 
106  if ((this.nanoseconds >= 1000000000)
107  && ((this.nanoseconds != INFINITE_NANOSECONDS))) {
108  throw new IllegalArgumentExceptionImpl(this.environment,"Illegal duration "
109  + this.seconds + " seconds, " + this.nanoseconds
110  + " nanoseconds.");
111  }
112  if ((nsec >= 1000000000)
113  && ((nsec != Long.MAX_VALUE) || (sec != Long.MAX_VALUE))) {
114  throw new IllegalArgumentExceptionImpl(this.environment,"Illegal duration " + sec
115  + " seconds, " + nsec + " nanoseconds.");
116  }
117  if (this.seconds > sec)
118  return 1;
119  if (this.seconds < sec)
120  return -1;
121  if (this.nanoseconds > nsec)
122  return 1;
123  if (this.nanoseconds < nsec)
124  return -1;
125  return 0;
126  }
127 
128  @Override
130  return this.environment;
131  }
132 
133  @Override
134  public long getDuration(TimeUnit inThisUnit) {
135  if (inThisUnit == null) {
136  throw new IllegalArgumentException(
137  "Invalid TimeUnit (null) provided.");
138  }
139  if (this.isInfinite()) {
140  return Long.MAX_VALUE;
141  }
142  return inThisUnit.convert(this.totalNanos, TimeUnit.NANOSECONDS);
143  }
144 
145  @Override
146  public long getRemainder(TimeUnit primaryUnit, TimeUnit remainderUnit) {
147  if ((primaryUnit == null) || (remainderUnit == null)) {
148  throw new IllegalArgumentException(
149  "Invalid TimeUnit (null) provided.");
150  }
151  if (remainderUnit.compareTo(primaryUnit) >= 0) {
152  return 0;
153  }
154  if (this.isInfinite()) {
155  return Long.MAX_VALUE;
156  }
157  long primaryDuration = primaryUnit.convert(this.totalNanos,
158  TimeUnit.NANOSECONDS);
159  long primaryNanoDuration = TimeUnit.NANOSECONDS.convert(
160  primaryDuration, primaryUnit);
161  long leftOverNanos = this.totalNanos - primaryNanoDuration;
162 
163  return remainderUnit.convert(leftOverNanos, TimeUnit.NANOSECONDS);
164  }
165 
166  @Override
167  public boolean isZero() {
168  return (this.seconds == 0 && this.nanoseconds == 0) ? true : false;
169  }
170 
171  @Override
172  public boolean isInfinite() {
173  return (this.totalNanos == Long.MAX_VALUE) ? true
174  : false;
175  }
176 
177  @Override
178  public Duration add(Duration duration) {
179  if (duration == null) {
180  throw new IllegalArgumentException(
181  "Invalid Duration (null) provided.");
182  }
183  long sec = duration.getDuration(TimeUnit.SECONDS);
184  long nsec = duration.getRemainder(TimeUnit.SECONDS,
185  TimeUnit.NANOSECONDS);
186 
187  if (!((this.nanoseconds < 1000000000) || (this.nanoseconds == INFINITE_NANOSECONDS))) {
188  throw new IllegalArgumentExceptionImpl(this.environment,
189  "Illegal duration");
190  }
191  if (!((nsec < 1000000000) || (nsec == Long.MAX_VALUE))) {
192  throw new IllegalArgumentExceptionImpl(this.environment,
193  "Illegal duration");
194  }
195  if (this.nanoseconds == INFINITE_NANOSECONDS) {
196  if (this.seconds == INFINITE_SECONDS) {
197  return new DurationImpl(this.environment, INFINITE_SECONDS,
198  INFINITE_NANOSECONDS); /* result stays infinite. */
199  }
200  throw new IllegalArgumentExceptionImpl(this.environment,
201  "Illegal duration " + this.seconds + " seconds, "
202  + this.nanoseconds + " nanoseconds.");
203  }
204  if (nsec == Long.MAX_VALUE) {
205  if (sec == Long.MAX_VALUE) {
206  return new DurationImpl(this.environment, INFINITE_SECONDS,
207  INFINITE_NANOSECONDS); /* result stays infinite. */
208  }
209  throw new IllegalArgumentExceptionImpl(this.environment,
210  "Illegal duration " + sec + " seconds, " + nsec
211  + " nanoseconds.");
212 
213  }
214  if (sec > 0) {
215  if (INFINITE_SECONDS - sec <= this.seconds) {
216  /*
217  * is identical to 'INFINITE_SECONDS <= this.seconds + sec' In
218  * other words the sum is larger than infinite, so results must
219  * be infinite.
220  */
221  return new DurationImpl(this.environment, INFINITE_SECONDS,
222  INFINITE_NANOSECONDS);
223  }
224  }
225  long s = this.seconds + sec;
226  long ns = this.nanoseconds + nsec;
227  return new DurationImpl(this.environment, s, ns).normalize();
228 
229  }
230 
231  @Override
232  public Duration add(long duration, TimeUnit unit) {
233  DurationImpl temp = new DurationImpl(this.environment, duration, unit)
234  .normalize();
235 
236  return this.add(temp);
237  }
238 
239  @Override
240  public Duration subtract(Duration duration) {
241  if (duration == null) {
242  throw new IllegalArgumentExceptionImpl(this.environment,
243  "Invalid Duration (null) provided.");
244  }
245  if(this.isInfinite() && duration.isInfinite()){
246  throw new IllegalArgumentExceptionImpl(this.environment,
247  "Cannot subtract two infinite times.");
248  }
249  long sec = duration.getDuration(TimeUnit.SECONDS);
250  long nsec = duration.getRemainder(TimeUnit.SECONDS,
251  TimeUnit.NANOSECONDS);
252 
253 
254  if (!(this.nanoseconds < 1000000000)
255  || (this.nanoseconds == INFINITE_NANOSECONDS)) {
256  throw new IllegalArgumentExceptionImpl(this.environment,"Illegal duration "
257  + this.seconds + " seconds, " + this.nanoseconds
258  + " nanoseconds.");
259  }
260  if (!((nsec < 1000000000) || (nsec == Long.MAX_VALUE))) {
261  throw new IllegalArgumentExceptionImpl(this.environment,"Illegal duration " + sec
262  + " seconds, " + nsec + " nanoseconds.");
263  }
264 
265  if (this.nanoseconds == INFINITE_NANOSECONDS) {
266  if (this.seconds == INFINITE_SECONDS) {
267  return new DurationImpl(this.environment, INFINITE_SECONDS,
268  INFINITE_NANOSECONDS); /* result stays infinite. */
269  }
270  throw new IllegalArgumentExceptionImpl(this.environment,
271  "Illegal duration " + this.seconds + " seconds, "
272  + this.nanoseconds + " nanoseconds.");
273  }
274  if (nsec == Long.MAX_VALUE) {
275  if (sec == Long.MAX_VALUE) {
276  return new DurationImpl(this.environment, INFINITE_SECONDS,
277  INFINITE_NANOSECONDS); /* result stays infinite. */
278  }
279  throw new IllegalArgumentExceptionImpl(this.environment,
280  "Illegal duration " + sec + " seconds, " + nsec
281  + " nanoseconds.");
282  }
283  if ((sec <= 0) && (INFINITE_SECONDS + sec <= this.seconds)) {
284  /* is identical to '-(INFINITE_SECONDS >= this.seconds - sec)' In
285  * other words the sum is larger than infinite, so results must be
286  * infinite. */
287  return new DurationImpl(this.environment, INFINITE_SECONDS,
288  INFINITE_NANOSECONDS);
289  }
290  long s = this.seconds - sec;
291 
292  if (s == INFINITE_SECONDS) {
293  return new DurationImpl(this.environment, INFINITE_SECONDS,
294  INFINITE_NANOSECONDS);
295  }
296  long ns = this.nanoseconds - nsec;
297 
298  if (ns < 0) {
299  s--;
300  ns += 1000000000;
301  }
302  return new DurationImpl(this.environment, s, ns).normalize();
303 
304  }
305 
306  @Override
307  public Duration subtract(long duration, TimeUnit unit) {
308  DurationImpl temp = new DurationImpl(this.environment, duration, unit)
309  .normalize();
310 
311  return this.subtract(temp);
312  }
313 
314  public DDS.Duration_t convert() {
315  return new DDS.Duration_t((int) this.seconds, (int) this.nanoseconds);
316  }
317 
318  @Override
319  public boolean equals(Object other) {
320  if (!(other instanceof DurationImpl)) {
321  return false;
322  }
323  DurationImpl d = (DurationImpl) other;
324 
325  if (d.totalNanos != this.totalNanos) {
326  return false;
327  }
328  return true;
329  }
330 
331  @Override
332  public int hashCode() {
333  return 31 * 17 + (int) (this.totalNanos ^ (this.totalNanos >>> 32));
334  }
335 
336  @Override
337  public String toString(){
338  if(this.isInfinite()){
339  return "infinite";
340  }
341  return this.totalNanos + " ns";
342  }
343 }
DurationImpl(OsplServiceEnvironment environment, long seconds, long nanoseconds)
long getRemainder(TimeUnit primaryUnit, TimeUnit remainderUnit)
abstract boolean isInfinite()
Report whether this duration lasts forever.
Duration add(long duration, TimeUnit unit)
Duration subtract(long duration, TimeUnit unit)
long getDuration(TimeUnit inThisUnit)
abstract long getRemainder(TimeUnit primaryUnit, TimeUnit remainderUnit)
If getting the magnitude of this duration in the given primaryUnit would cause truncation with respec...
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 ...
Duration subtract(Duration duration)
DurationImpl(OsplServiceEnvironment environment, long duration, TimeUnit unit)
Duration add(Duration duration)