2 * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.mdsal.model.ietf.util;
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import javax.annotation.Nonnull;
13 import org.opendaylight.yangtools.yang.binding.util.StringValueObjectFactory;
16 * Abstract utility class for dealing with MAC addresses as defined in the ietf-yang-types model. This class is
17 * used by revision-specific classes.
20 public abstract class AbstractIetfYangUtil<T> {
21 private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
22 private final StringValueObjectFactory<T> factory;
24 protected AbstractIetfYangUtil(final Class<T> clazz) {
25 this.factory = StringValueObjectFactory.create(clazz, "00:00:00:00:00:00");
28 private static final void appendHexByte(final StringBuilder sb, final byte b) {
29 final int v = Byte.toUnsignedInt(b);
30 sb.append(HEX_CHARS[v >>> 4]);
31 sb.append(HEX_CHARS[v & 15]);
35 * Make sure an array of characters does not include capital letters. This method assumes input conforms to
36 * MAC address format, e.g. it is composed of 6 groups of hexadecimal digits separated by colons. Behavior is
37 * undefined if the input does not meet this criteria.
39 * @param chars Input characters, may not be null
40 * @return True if the array has been modified
41 * @throws NullPointerException if input is null
43 private static boolean ensureLowerCase(@Nonnull final char[] chars) {
46 for (int i = 0; i < chars.length; ++i) {
47 final char c = chars[i];
48 if (c >= 'A' && c <= 'F') {
49 chars[i] = Character.toLowerCase(c);
58 * Convert an array of 6 bytes into canonical MAC address representation, that is 6 groups of two hexadecimal
59 * lower-case digits each, separated by colons.
61 * @param bytes Input bytes, may not be null
62 * @return Canonical MAC address string
63 * @throws NullPointerException if input is null
64 * @throws IllegalArgumentException if length of input is not 6 bytes
66 @Nonnull private static String bytesToString(@Nonnull final byte[] bytes) {
67 Preconditions.checkArgument(bytes.length == 6, "MAC address should have 6 bytes, not %s", bytes.length);
69 final StringBuilder sb = new StringBuilder(17);
70 appendHexByte(sb, bytes[0]);
71 for (int i = 1; i < bytes.length; ++i) {
73 appendHexByte(sb, bytes[i]);
80 * Convert the value of a MacAddress into the canonical representation.
82 * @param macAddress Input MAC address
83 * @return A MacAddress containing the canonical representation.
84 * @throws NullPointerException if macAddress is null
86 @Nonnull public final T canonizeMacAddress(@Nonnull final T macAddress) {
87 final char[] input = getValue(macAddress).toCharArray();
88 if (ensureLowerCase(input)) {
89 return factory.newInstance(input.toString());
96 * Create a MacAddress object holding the canonical representation of the 6 bytes
97 * passed in as argument.
98 * @param bytes 6-byte input array
99 * @return MacAddress with canonical string derived from input bytes
100 * @throws NullPointerException if bytes is null
101 * @throws IllegalArgumentException if length of input is not 6 bytes
103 @Nonnull public final T macAddressFor(@Nonnull final byte[] bytes) {
104 return factory.newInstance(bytesToString(bytes));
107 protected abstract String getValue(T macAddress);