/**************************************************************************
* File name : RelativeTime.java
*
* This file is part a SCJ Level 0 and Level 1 implementation,
* based on SCJ Draft, Version 0.94 25 June 2013.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This SCJ Level 0 and Level 1 implementation is distributed in the hope
* that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this SCJ Level 0 and Level 1 implementation.
* If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012
* @authors Anders P. Ravn, Aalborg University, DK
* Stephan E. Korsholm and Hans Søndergaard,
* VIA University College, DK
*************************************************************************/
package javax.realtime;
import javax.safetycritical.annotate.SCJAllowed;
/**
* An object that represents a duration in milliseconds and nanoseconds.
* The time interval is kept in normalized form. <br>
* A negative duration relative to now represents time in the past.
* For add and subtract negative values behave as they do in arithmetic. <br>
* <b>Caution</b>: This class is explicitly unsafe in multithreaded situations when it
* is being changed. No synchronization is done.
*
* @version 1.2; - December 2013
*
* @author Anders P. Ravn, Aalborg University,
* <A HREF="mailto:apr@cs.aau.dk">apr@cs.aau.dk</A>, <br>
* Hans Søndergaard, VIA University College, Denmark,
* <A HREF="mailto:hso@viauc.dk">hso@via.dk</A>
*
*/
@SCJAllowed
public class RelativeTime extends HighResolutionTime {
/**
* Equivalent to <code>RelativeTime(0,0)</code>.
*/
public RelativeTime() {
this(0, 0);
}
/**
* Construct a RelativeTime object representing a duration based on the parameter <code>millis</code>
* plus the parameter <code>nanos</code>. The construction is subject to normalization of these values.
* <br>
* The clock association is implicitly made with the real-time clock.
*
* @param millis is the milliseconds.
* @param nanos is the nanoseconds.
*/
public RelativeTime(long millis, int nanos) {
this(millis, nanos, Clock.getRealtimeClock());
}
/**
* Constructs a duration of zero milliseconds and zero nanoseconds.
* The clock association is made with the <code>clock</code> parameter.
* If <code>clock</code> is null the association is made with the real-time clock.
* @param clock is the clock argument.
*/
public RelativeTime(Clock clock) {
this(0, 0, clock == null ? Clock.getRealtimeClock() : clock);
}
/**
* Constructs a <code>RelativeTime</code> object representing a duration based on the parameters.
* If <code>clock </code> is null the association is made with the real-time clock.
* @param millis is the milliseconds
* @param nanos is the nanoseconds
* @param clock is the clock
*/
public RelativeTime(long millis, int nanos, Clock clock) {
super(millis, nanos, clock == null ? Clock.getRealtimeClock() : clock);
}
/**
* Makes a new <code>RelativeTime</code> object from the given <code>RelativeTime</code> object.
*
* @param time is the copied object.
*
* @throws IllegalArgumentException if <code>time</code> is null.
*/
public RelativeTime(RelativeTime time) {
this();
if (time != null) {
millis = time.millis;
nanos = time.nanos;
clock = time.clock;
} else
throw new IllegalArgumentException();
}
/**
* Creates a new object representing the result of adding <code>millis</code> and <code>nanos</code> to the values
* from <code>this</code> and normalizing the result. The result will have the same clock association as <code>this</code>.
* @param millis is the milliseconds to be added.
* @param nanos is the nanoseconds to be added.
* @return the new object with the added durations.
*/
public RelativeTime add(long millis, int nanos) {
return new RelativeTime(this.millis + millis, this.nanos + nanos,
this.clock);
}
/**
* Creates a new object representing the result of adding <code>time</code> to the value of <code>this</code>.
* @param time is the duration to be added.
* @return the new object with the added durations.
* @throws IllegalArgumentException if <code>time</code> is null.
* @throws IllegalArgumentException if the clock associated with <code>this</code> and the clock associated with
* the <code>time</code> parameter are different.
*/
public RelativeTime add(RelativeTime time) {
if (time == null)
throw new IllegalArgumentException("time is null");
if (this.clock != time.clock)
throw new IllegalArgumentException("clock mismatch");
return new RelativeTime(this.millis + time.getMilliseconds(),
this.nanos + time.getNanoseconds(), time.getClock());
}
/**
* Returns an object containing the value resulting from adding <code>millis</code> and <code>nanos</code>
* to <code>this</code> and normalizing the result. If <code>dest</code> is not null, the result is
* placed there and returned. Otherwise, a new object is allocated for the result.
* The result will have the same clock association as <code>this</code>, and the clock association
* of <code>dest</code> is ignored.
*
* @param millis is the milliseconds to be added.
* @param nanos is the nanoseconds to be added.
* @param dest is the destination, if initially null a <code>new RelativeTime()</code> object is created.
* @return the the resulting value.
*/
public RelativeTime add(long millis, int nanos, RelativeTime dest) {
if (dest == null) {
dest = new RelativeTime(this.millis + millis, this.nanos + nanos);
} else {
dest.set(this.millis + millis, this.nanos + nanos);
}
return dest;
}
/**
* Returns an object containing the value resulting from adding <code>time</code> to <code>this</code>
* and normalizing the result. If <code>dest</code> is not null, the result is placed there
* and returned. Otherwise, a new object is allocated for the result. The clock associated with <code>this</code>
* and the clock associated with the <code>time</code> parameter are expected to be the same, and
* it is used for the result. The clock associated with the <code>dest</code> parameter is ignored.
*
* @param time is the time to be added
* @param dest is the destination, if null a <code>new RelativeTime()</code> object is created
* @return the resulting value.
*
* @throws IllegalArgumentException if <code>time</code> is null.
* @throws IllegalArgumentException if the clock associated with <code>this</code> and the clock associated with
* the <code>time</code> parameter are different.
*/
public RelativeTime add(RelativeTime time, RelativeTime dest) {
if (time == null)
throw new IllegalArgumentException("time is null");
if (this.clock != time.clock)
throw new IllegalArgumentException("clock mismatch");
return this.add(time.getMilliseconds(), time.getNanoseconds(), dest);
}
/**
* Creates a new <code>RelativeTime</code> object representing the result
* of subtracting <code>time</code> from the value of <code>this</code>.
* @param time the value to be subtracted.
* @return the difference between durations.
*
* @throws IllegalArgumentException if <code>time</code> is null.
* @throws IllegalArgumentException if the clock associated with <code>this</code> and the clock associated with
* the <code>time</code> parameter are different.
*/
public RelativeTime subtract(RelativeTime time) {
if (time == null)
throw new IllegalArgumentException("time is null");
if (this.clock != time.clock)
throw new IllegalArgumentException("clock mismatch");
return new RelativeTime(this.millis - time.getMilliseconds(),
this.nanos - time.getNanoseconds(), this.clock);
}
/**
* Creates a new <code>RelativeTime</code> object representing the result
* of subtracting <code>time</code> from the value of <code>this</code>.
* If <code>dest</code> is not null, the result is placed there and returned.
* Otherwise, a new object is allocated for the result.
* The clock associated with this and the clock associated with the time
* parameter are expected to be the same, and such association is used for the result.
* The clock associated with the <code>dest</code> parameter is ignored.
*
* @param time is the duration to be subtracted
* @param dest is the destination, if null a <code>new RelativeTime()</code> object is created
* @return the <code>dest</code> object with the resulting value.
*
* @throws IllegalArgumentException if <code>time</code> is null.
* @throws IllegalArgumentException if the clock associated with <code>this</code>
* and the clock associated with the <code>time</code> parameter are different.
*/
public RelativeTime subtract(RelativeTime time, RelativeTime dest) {
if (time == null)
throw new IllegalArgumentException("time is null");
if (this.clock != time.clock)
throw new IllegalArgumentException("clock mismatch");
if (dest == null) {
dest = new RelativeTime(this.millis - time.getMilliseconds(),
this.nanos - time.getNanoseconds(), this.clock);
} else {
dest.set(this.millis - time.getMilliseconds(),
this.nanos - time.getNanoseconds());
}
return dest;
}
}