*/
package org.opendaylight.protocol.pcep.ietf.stateful07;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
import org.opendaylight.protocol.pcep.spi.TlvParser;
import org.opendaylight.protocol.pcep.spi.TlvSerializer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.path.binding.tlv.path.binding.binding.type.value.MplsLabelEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.path.binding.tlv.path.binding.binding.type.value.MplsLabelEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Tlv;
-import org.opendaylight.yangtools.concepts.IllegalArgumentCodec;
import org.opendaylight.yangtools.yang.common.Uint16;
import org.opendaylight.yangtools.yang.common.Uint32;
import org.opendaylight.yangtools.yang.common.Uint8;
private static final int LABEL_SHIFT = 12;
private static final int TC_SHIFT = LABEL_SHIFT - 3;
private static final int S_SHIFT = TC_SHIFT - 1;
- private static final int MPLS_ENTRY_LENGTH = 4;
- private static final int MPLS_BINDING_LENGTH = MPLS_ENTRY_LENGTH + 2;
+ // 2 bytes type + 4 bytes binding
+ private static final int MPLS_BINDING_LENGTH = 6;
private static final Map<Uint16, PathBindingTlvCodec> BT_PARSERS;
private static final Map<Class<? extends BindingTypeValue>, PathBindingTlvCodec> BT_SERIALIZERS;
final PathBindingTlvCodec codec = BT_SERIALIZERS.get(bindingTypeValue.implementedInterface());
Preconditions.checkArgument(codec != null,
"Unsupported Path Binding Type: %s", bindingTypeValue.implementedInterface());
- ByteBufUtils.writeMandatory(body, codec.getBindingType(), "bindingType");
- body.writeBytes(codec.serialize(bindingTypeValue));
+ codec.writeBinding(body, bindingTypeValue);
TlvUtil.formatTlv(TYPE, body, buffer);
}
if (codec == null) {
throw new PCEPDeserializerException("Unsupported Path Binding Type: " + type);
}
- return new PathBindingBuilder().setBindingTypeValue(codec.deserialize(buffer)).build();
+ return new PathBindingBuilder().setBindingTypeValue(codec.readEntry(buffer)).build();
}
- private static final class MplsLabelCodec implements PathBindingTlvCodec {
+ private static final class MplsLabelCodec extends PathBindingTlvCodec {
+ MplsLabelCodec() {
+ super(MPLS_LABEL);
+ }
@Override
- public ByteBuf serialize(final BindingTypeValue bindingValue) {
+ void writeEntry(final ByteBuf buf, final BindingTypeValue bindingValue) {
Preconditions.checkArgument(bindingValue instanceof MplsLabel, "bindingValue is not MplsLabel");
final MplsLabel mplsLabel = (MplsLabel) bindingValue;
- final ByteBuf value = Unpooled.buffer(MPLS_ENTRY_LENGTH);
- ByteBufWriteUtil.writeUnsignedInt(Uint32.valueOf(getMplsStackEntry(mplsLabel.getMplsLabel())), value);
- return value;
- }
-
- @Override
- public BindingTypeValue deserialize(final ByteBuf buffer) {
- final MplsLabelBuilder builder = new MplsLabelBuilder();
- builder.setMplsLabel(getMplsLabel(buffer.readUnsignedInt()));
- return builder.build();
+ ByteBufWriteUtil.writeUnsignedInt(Uint32.valueOf(getMplsStackEntry(mplsLabel.getMplsLabel())), buf);
}
@Override
- public Uint16 getBindingType() {
- return MPLS_LABEL;
+ BindingTypeValue readEntry(final ByteBuf buffer) {
+ return new MplsLabelBuilder().setMplsLabel(getMplsLabel(buffer.readUnsignedInt())).build();
}
}
- private static final class MplsLabelEntryCodec implements PathBindingTlvCodec {
+ private static final class MplsLabelEntryCodec extends PathBindingTlvCodec {
+ MplsLabelEntryCodec() {
+ super(MPLS_STACK_ENTRY);
+ }
@Override
- public ByteBuf serialize(final BindingTypeValue bindingValue) {
+ void writeEntry(final ByteBuf buf, final BindingTypeValue bindingValue) {
Preconditions.checkArgument(bindingValue instanceof MplsLabelEntry,
"bindingValue is not MplsLabelEntry");
final MplsLabelEntry mplsEntry = (MplsLabelEntry) bindingValue;
- final ByteBuf value = Unpooled.buffer(MPLS_ENTRY_LENGTH);
final long entry = getMplsStackEntry(mplsEntry.getLabel())
| mplsEntry.getTrafficClass().toJava() << TC_SHIFT
| (mplsEntry.isBottomOfStack() ? 1 : 0) << S_SHIFT
| mplsEntry.getTimeToLive().toJava();
- ByteBufWriteUtil.writeUnsignedInt(Uint32.valueOf(entry), value);
- return value;
+ ByteBufWriteUtil.writeUnsignedInt(Uint32.valueOf(entry), buf);
}
@Override
- public BindingTypeValue deserialize(final ByteBuf buffer) {
+ BindingTypeValue readEntry(final ByteBuf buffer) {
final long entry = buffer.readUnsignedInt();
- final MplsLabelEntryBuilder builder = new MplsLabelEntryBuilder()
+ return new MplsLabelEntryBuilder()
.setLabel(getMplsLabel(entry))
.setTrafficClass(Uint8.valueOf(entry >> TC_SHIFT & TC_MASK))
.setBottomOfStack((entry >> S_SHIFT & S_MASK) == 1)
- .setTimeToLive(Uint8.valueOf(entry & TTL_MASK));
- return builder.build();
+ .setTimeToLive(Uint8.valueOf(entry & TTL_MASK))
+ .build();
}
+ }
- @Override
- public Uint16 getBindingType() {
- return MPLS_STACK_ENTRY;
+ private abstract static class PathBindingTlvCodec {
+ private final @NonNull Uint16 bindingType;
+
+ PathBindingTlvCodec(final Uint16 bindingType) {
+ this.bindingType = requireNonNull(bindingType);
}
- }
- private interface PathBindingTlvCodec extends IllegalArgumentCodec<ByteBuf, BindingTypeValue> {
- Uint16 getBindingType();
+ final @NonNull Uint16 getBindingType() {
+ return bindingType;
+ }
+
+ final void writeBinding(final ByteBuf buf, final BindingTypeValue binding) {
+ ByteBufUtils.writeMandatory(buf, bindingType, "bindingType");
+ writeEntry(buf, binding);
+ }
+
+ abstract BindingTypeValue readEntry(ByteBuf buf);
+
+ abstract void writeEntry(ByteBuf buf, BindingTypeValue value);
}
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",