2 * Copyright (c) 2013 Cisco Systems, Inc. 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.protocol.pcep.impl;
10 import java.util.Arrays;
11 import java.util.BitSet;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
16 import org.opendaylight.protocol.util.ByteArray;
17 import com.google.common.primitives.UnsignedBytes;
20 * Header parser for {@link org.opendaylight.protocol.pcep.PCEPObject PCEPObject}
22 public class PCEPObjectHeader {
24 private static final Logger logger = LoggerFactory.getLogger(PCEPObjectHeader.class);
27 * Common object header fields lengths in bytes
29 public final static int OC_F_LENGTH = 1;
30 public final static int OT_FLAGS_MF_LENGTH = 1; // multi-field
31 public final static int OBJ_LENGTH_F_LENGTH = 2;
34 * size of fields inside of multi-filed in bits
36 public final static int OT_SF_LENGTH = 4;
37 public final static int FLAGS_SF_LENGTH = 4;
40 * offsets of fields inside of multi-field in bits
42 public final static int OT_SF_OFFSET = 0;
43 public final static int FLAGS_SF_OFFSET = OT_SF_OFFSET + OT_SF_LENGTH;
46 * flags offsets inside multi-filed
48 public final static int P_FLAG_OFFSET = 6;
49 public final static int I_FLAG_OFFSET = 7;
52 * Common object header fields offsets in bytes;
54 public final static int OC_F_OFFSET = 0;
55 public final static int OT_FLAGS_MF_OFFSET = OC_F_OFFSET + OC_F_LENGTH;
56 public final static int OBJ_LENGTH_F_OFFSET = OT_FLAGS_MF_OFFSET + OT_FLAGS_MF_LENGTH;
57 public final static int OBJ_BODY_OFFSET = OBJ_LENGTH_F_OFFSET + OBJ_LENGTH_F_LENGTH;
60 * Common object header length in bytes
62 public final static int COMMON_OBJECT_HEADER_LENGTH = (OC_F_LENGTH + OT_FLAGS_MF_LENGTH + OBJ_LENGTH_F_LENGTH);
64 public final int objClass;
65 public final int objType;
66 public final int objLength;
67 public final boolean processed;
68 public final boolean ignored;
70 public PCEPObjectHeader(final int objClass, final int objType, final int objLength, final boolean processed, final boolean ignore) {
71 this.objClass = objClass;
72 this.objType = objType;
73 this.objLength = objLength;
74 this.processed = processed;
75 this.ignored = ignore;
79 public static PCEPObjectHeader parseHeader(final byte[] bytes) {
81 throw new IllegalArgumentException("Array of bytes is mandatory.");
83 logger.trace("Attempt to parse object header from bytes: {}", ByteArray.bytesToHexString(bytes));
85 final int objClass = ByteArray.bytesToInt(Arrays.copyOfRange(bytes, OC_F_OFFSET, OC_F_OFFSET + OC_F_LENGTH));
87 final int objType = UnsignedBytes.toInt(ByteArray.copyBitsRange(bytes[OT_FLAGS_MF_OFFSET], OT_SF_OFFSET, OT_SF_LENGTH));
89 final int objLength = ByteArray.bytesToInt(Arrays.copyOfRange(bytes, OBJ_LENGTH_F_OFFSET, OBJ_LENGTH_F_OFFSET + OBJ_LENGTH_F_LENGTH));
91 final byte[] flagsBytes = { ByteArray.copyBitsRange(bytes[OT_FLAGS_MF_OFFSET], FLAGS_SF_OFFSET, FLAGS_SF_LENGTH) };
93 final BitSet flags = ByteArray.bytesToBitSet(flagsBytes);
95 final PCEPObjectHeader objHeader = new PCEPObjectHeader(objClass, objType, objLength, flags.get(P_FLAG_OFFSET), flags.get(I_FLAG_OFFSET));
96 logger.trace("Object header was parsed. {}", objHeader);
100 public static byte[] putHeader(final PCEPObjectHeader header) {
102 throw new IllegalArgumentException("PCEPObjectHeader is mandatory.");
104 final byte[] retBytes = new byte[COMMON_OBJECT_HEADER_LENGTH];
107 retBytes[OC_F_OFFSET] = (byte) header.objClass;
109 // objType_flags multi-field
110 retBytes[OT_FLAGS_MF_OFFSET] = (byte) (header.objType << (Byte.SIZE - OT_SF_LENGTH));
111 if (header.processed)
112 retBytes[OT_FLAGS_MF_OFFSET] |= 1 << Byte.SIZE - (P_FLAG_OFFSET) - 1;
114 retBytes[OT_FLAGS_MF_OFFSET] |= 1 << Byte.SIZE - (I_FLAG_OFFSET) - 1;
117 System.arraycopy(ByteArray.intToBytes(header.objLength), Integer.SIZE / Byte.SIZE - OBJ_LENGTH_F_LENGTH, retBytes, OBJ_LENGTH_F_OFFSET,
118 OBJ_LENGTH_F_LENGTH);
124 public String toString() {
125 final StringBuilder builder = new StringBuilder();
126 builder.append("PCEPObjectHeader [objClass=");
127 builder.append(this.objClass);
128 builder.append(", objType=");
129 builder.append(this.objType);
130 builder.append(", objLength=");
131 builder.append(this.objLength);
132 builder.append(", processed=");
133 builder.append(this.processed);
134 builder.append(", ignored=");
135 builder.append(this.ignored);
137 return builder.toString();
141 public int hashCode() {
142 final int prime = 31;
144 result = prime * result + (this.ignored ? 1231 : 1237);
145 result = prime * result + this.objClass;
146 result = prime * result + this.objLength;
147 result = prime * result + this.objType;
148 result = prime * result + (this.processed ? 1231 : 1237);
153 public boolean equals(final Object obj) {
158 if (this.getClass() != obj.getClass())
160 final PCEPObjectHeader other = (PCEPObjectHeader) obj;
161 if (this.ignored != other.ignored)
163 if (this.objClass != other.objClass)
165 if (this.objLength != other.objLength)
167 if (this.objType != other.objType)
169 if (this.processed != other.processed)