import com.google.common.annotations.Beta;
import java.util.Arrays;
-import javax.annotation.Nonnull;
+import java.util.UUID;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.spec.reflect.StringValueObjectFactory;
/**
* @param <P> phys-address type
*/
@Beta
-public abstract class AbstractIetfYangUtil<M, P> {
+public abstract class AbstractIetfYangUtil<M, P, H, Q, U> {
private static final int MAC_BYTE_LENGTH = 6;
private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
- private static final byte[] HEX_VALUES;
+ private static final byte @NonNull[] EMPTY_BYTES = new byte[0];
+ private static final byte @NonNull[] HEX_VALUES;
+
static {
final byte[] b = new byte['f' + 1];
Arrays.fill(b, (byte)-1);
private final StringValueObjectFactory<M> macFactory;
private final StringValueObjectFactory<P> physFactory;
+ private final StringValueObjectFactory<H> hexFactory;
+ private final StringValueObjectFactory<Q> quadFactory;
+ private final StringValueObjectFactory<U> uuidFactory;
- protected AbstractIetfYangUtil(final Class<M> macClass, final Class<P> physClass) {
+ protected AbstractIetfYangUtil(final Class<M> macClass, final Class<P> physClass, final Class<H> hexClass,
+ final Class<Q> quadClass, final Class<U> uuidClass) {
this.macFactory = StringValueObjectFactory.create(macClass, "00:00:00:00:00:00");
this.physFactory = StringValueObjectFactory.create(physClass, "00:00");
+ this.hexFactory = StringValueObjectFactory.create(hexClass, "00");
+ this.quadFactory = StringValueObjectFactory.create(quadClass, "0.0.0.0");
+ this.uuidFactory = StringValueObjectFactory.create(uuidClass, "f81d4fae-7dec-11d0-a765-00a0c91e6bf6");
}
-
/**
* Convert the value of a MacAddress into the canonical representation.
*
* @return A MacAddress containing the canonical representation.
* @throws NullPointerException if macAddress is null
*/
- @Nonnull public final M canonizeMacAddress(@Nonnull final M macAddress) {
+ public final @NonNull M canonizeMacAddress(final @NonNull M macAddress) {
final char[] input = getValue(macAddress).toCharArray();
return ensureLowerCase(input) ? macFactory.newInstance(String.valueOf(input)) : macAddress;
}
* @throws NullPointerException if bytes is null
* @throws IllegalArgumentException if length of input is not 6 bytes
*/
- @Nonnull public final M macAddressFor(@Nonnull final byte[] bytes) {
+ public final @NonNull M macAddressFor(final byte @NonNull[] bytes) {
checkArgument(bytes.length == MAC_BYTE_LENGTH, "MAC address should have 6 bytes, not %s",
bytes.length);
return macFactory.newInstance(bytesToString(bytes, 17));
}
+ public final byte @NonNull[] macAddressBytes(final @NonNull M macAddress) {
+ return stringToBytes(getValue(macAddress), MAC_BYTE_LENGTH);
+ }
+
/**
* Convert the value of a PhysAddress into the canonical representation.
*
* @return A PhysAddress containing the canonical representation.
* @throws NullPointerException if physAddress is null
*/
- @Nonnull public final P canonizePhysAddress(@Nonnull final P physAddress) {
+ public final @NonNull P canonizePhysAddress(final @NonNull P physAddress) {
final char[] input = getPhysValue(physAddress).toCharArray();
return ensureLowerCase(input) ? physFactory.newInstance(String.valueOf(input)) : physAddress;
}
* @throws NullPointerException if bytes is null
* @throws IllegalArgumentException if length of input is not at least 1 byte
*/
- @Nonnull public final P physAddressFor(@Nonnull final byte[] bytes) {
+ public final @NonNull P physAddressFor(final byte @NonNull[] bytes) {
checkArgument(bytes.length > 0, "Physical address should have at least one byte");
- return physFactory.newInstance(bytesToString(bytes, (bytes.length + 1) / 3));
+ return physFactory.newInstance(bytesToString(bytes, bytes.length * 3 - 1));
}
- @Nonnull public final byte[] bytesFor(@Nonnull final M macAddress) {
- final String mac = getValue(macAddress);
- final byte[] ret = new byte[MAC_BYTE_LENGTH];
+ public final byte @NonNull[] physAddressBytes(final @NonNull P physAddress) {
+ final String str = getPhysValue(physAddress);
+ return str.isEmpty() ? EMPTY_BYTES : stringToBytes(str, str.length() / 3 + 1);
+ }
- for (int i = 0, base = 0; i < MAC_BYTE_LENGTH; ++i, base += 3) {
- ret[i] = (byte) (hexValue(mac.charAt(base)) << 4 | hexValue(mac.charAt(base + 1)));
- }
+ @Deprecated
+ public final byte @NonNull[] bytesFor(final @NonNull M macAddress) {
+ return macAddressBytes(macAddress);
+ }
- return ret;
+ public final @NonNull H hexStringFor(final byte @NonNull[] bytes) {
+ checkArgument(bytes.length > 0, "Hex string should have at least one byte");
+ return hexFactory.newInstance(bytesToString(bytes, bytes.length * 3 - 1));
+ }
+
+ public final byte @NonNull[] hexStringBytes(final @NonNull H hexString) {
+ final String str = getHexValue(hexString);
+ return stringToBytes(str, str.length() / 3 + 1);
+ }
+
+ public final @NonNull Q dottedQuadFor(final byte @NonNull[] bytes) {
+ checkArgument(bytes.length == 4, "Dotted-quad should have 4 bytes");
+ return quadFactory.newInstance(AbstractIetfInetUtil.addressStringV4(bytes));
+ }
+
+ public final @NonNull Q dottedQuadFor(final int bits) {
+ return quadFactory.newInstance(Ipv4Utils.addressString(bits));
+ }
+
+ public final int dottedQuadBits(final @NonNull Q dottedQuad) {
+ final String str = getQuadValue(dottedQuad);
+ return Ipv4Utils.addressBits(str, str.length());
+ }
+
+ public final byte @NonNull[] dottedQuadBytes(final @NonNull Q dottedQuad) {
+ final String str = getQuadValue(dottedQuad);
+ return Ipv4Utils.addressBytes(str, str.length());
+ }
+
+ public final @NonNull U uuidFor(final @NonNull UUID uuid) {
+ return uuidFactory.newInstance(uuid.toString());
}
protected abstract String getValue(M macAddress);
protected abstract String getPhysValue(P physAddress);
- static byte hexValue(final char c) {
- byte v;
+ protected abstract String getHexValue(H hexString);
+
+ protected abstract String getQuadValue(Q dottedQuad);
+
+ static byte hexValue(final char ch) {
+ byte value;
try {
// Performance optimization: access the array and rely on the VM for catching
// illegal access (which boils down to illegal character, which should never happen.
- v = HEX_VALUES[c];
+ value = HEX_VALUES[ch];
} catch (IndexOutOfBoundsException e) {
- v = -1;
+ value = -1;
}
- if (v < 0) {
- throw new IllegalArgumentException("Invalid character '" + c + "' encountered");
+ if (value < 0) {
+ throw new IllegalArgumentException("Invalid character '" + ch + "' encountered");
}
- return v;
+ return value;
}
/**
* @return True if the array has been modified
* @throws NullPointerException if input is null
*/
- private static boolean ensureLowerCase(@Nonnull final char[] chars) {
+ private static boolean ensureLowerCase(final char @NonNull[] chars) {
boolean ret = false;
for (int i = 0; i < chars.length; ++i) {
* @throws NullPointerException if input is null
* @throws IllegalArgumentException if length of input is not 6 bytes
*/
- @Nonnull private static String bytesToString(@Nonnull final byte[] bytes, final int charHint) {
+ private static @NonNull String bytesToString(final byte @NonNull[] bytes, final int charHint) {
final StringBuilder sb = new StringBuilder(charHint);
appendHexByte(sb, bytes[0]);
for (int i = 1; i < bytes.length; ++i) {
return sb.toString();
}
- private static final void appendHexByte(final StringBuilder sb, final byte b) {
- final int v = Byte.toUnsignedInt(b);
- sb.append(HEX_CHARS[v >>> 4]).append(HEX_CHARS[v & 15]);
+ private static void appendHexByte(final StringBuilder sb, final byte byteVal) {
+ final int intVal = Byte.toUnsignedInt(byteVal);
+ sb.append(HEX_CHARS[intVal >>> 4]).append(HEX_CHARS[intVal & 15]);
+ }
+
+ private static byte @NonNull[] stringToBytes(final String str, final int length) {
+ final byte[] ret = new byte[length];
+ for (int i = 0, base = 0; i < length; ++i, base += 3) {
+ ret[i] = (byte) (hexValue(str.charAt(base)) << 4 | hexValue(str.charAt(base + 1)));
+ }
+ return ret;
}
}