com.digitalpetri.enip.util.TimeoutCalculator Maven / Gradle / Ivy
package com.digitalpetri.enip.util;
import java.time.Duration;
public class TimeoutCalculator {
private static final int MIN_TIMEOUT = 1;
private static final int MAX_TIMEOUT = 8355840;
public static int calculateTimeoutBytes(Duration timeout) {
int desiredTimeout = (int) timeout.toMillis();
if (desiredTimeout < MIN_TIMEOUT) desiredTimeout = MIN_TIMEOUT;
if (desiredTimeout > MAX_TIMEOUT) desiredTimeout = MAX_TIMEOUT;
boolean precisionLost = false;
int shifts = 0;
int multiplier = desiredTimeout;
while (multiplier > 255) {
precisionLost |= (multiplier & 1) == 1;
multiplier >>= 1;
shifts += 1;
}
if (precisionLost) {
multiplier += 1;
if (multiplier > 255) {
multiplier >>= 1;
shifts += 1;
}
}
assert (shifts <= 15);
int tick = (int) Math.pow(2, shifts);
assert (tick >= 1 && tick <= 32768);
assert (multiplier >= 1 && multiplier <= 255);
return shifts << 8 | multiplier;
}
}