Revert "BUG-47 : unfinished PCEP migration to generated DTOs."
[bgpcep.git] / pcep / impl / src / main / java / org / opendaylight / protocol / pcep / impl / PCEPObjectHeader.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.protocol.pcep.impl;
9
10 import java.util.Arrays;
11 import java.util.BitSet;
12
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15
16 import org.opendaylight.protocol.util.ByteArray;
17 import com.google.common.primitives.UnsignedBytes;
18
19 /**
20  * Header parser for {@link org.opendaylight.protocol.pcep.PCEPObject PCEPObject}
21  */
22 public class PCEPObjectHeader {
23
24         private static final Logger logger = LoggerFactory.getLogger(PCEPObjectHeader.class);
25
26         /*
27          * Common object header fields lengths in bytes
28          */
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;
32
33         /*
34          * size of fields inside of multi-filed in bits
35          */
36         public final static int OT_SF_LENGTH = 4;
37         public final static int FLAGS_SF_LENGTH = 4;
38
39         /*
40          * offsets of fields inside of multi-field in bits
41          */
42         public final static int OT_SF_OFFSET = 0;
43         public final static int FLAGS_SF_OFFSET = OT_SF_OFFSET + OT_SF_LENGTH;
44
45         /*
46          * flags offsets inside multi-filed
47          */
48         public final static int P_FLAG_OFFSET = 6;
49         public final static int I_FLAG_OFFSET = 7;
50
51         /*
52          * Common object header fields offsets in bytes;
53          */
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;
58
59         /*
60          * Common object header length in bytes
61          */
62         public final static int COMMON_OBJECT_HEADER_LENGTH = (OC_F_LENGTH + OT_FLAGS_MF_LENGTH + OBJ_LENGTH_F_LENGTH);
63
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;
69
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;
76
77         }
78
79         public static PCEPObjectHeader parseHeader(final byte[] bytes) {
80                 if (bytes == null)
81                         throw new IllegalArgumentException("Array of bytes is mandatory.");
82
83                 logger.trace("Attempt to parse object header from bytes: {}", ByteArray.bytesToHexString(bytes));
84
85                 final int objClass = ByteArray.bytesToInt(Arrays.copyOfRange(bytes, OC_F_OFFSET, OC_F_OFFSET + OC_F_LENGTH));
86
87                 final int objType = UnsignedBytes.toInt(ByteArray.copyBitsRange(bytes[OT_FLAGS_MF_OFFSET], OT_SF_OFFSET, OT_SF_LENGTH));
88
89                 final int objLength = ByteArray.bytesToInt(Arrays.copyOfRange(bytes, OBJ_LENGTH_F_OFFSET, OBJ_LENGTH_F_OFFSET + OBJ_LENGTH_F_LENGTH));
90
91                 final byte[] flagsBytes = { ByteArray.copyBitsRange(bytes[OT_FLAGS_MF_OFFSET], FLAGS_SF_OFFSET, FLAGS_SF_LENGTH) };
92
93                 final BitSet flags = ByteArray.bytesToBitSet(flagsBytes);
94
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);
97                 return objHeader;
98         }
99
100         public static byte[] putHeader(final PCEPObjectHeader header) {
101                 if (header == null)
102                         throw new IllegalArgumentException("PCEPObjectHeader is mandatory.");
103
104                 final byte[] retBytes = new byte[COMMON_OBJECT_HEADER_LENGTH];
105
106                 // objClass
107                 retBytes[OC_F_OFFSET] = (byte) header.objClass;
108
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;
113                 if (header.ignored)
114                         retBytes[OT_FLAGS_MF_OFFSET] |= 1 << Byte.SIZE - (I_FLAG_OFFSET) - 1;
115
116                 // objLength
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);
119
120                 return retBytes;
121         }
122
123         @Override
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);
136                 builder.append("]");
137                 return builder.toString();
138         }
139
140         @Override
141         public int hashCode() {
142                 final int prime = 31;
143                 int result = 1;
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);
149                 return result;
150         }
151
152         @Override
153         public boolean equals(final Object obj) {
154                 if (this == obj)
155                         return true;
156                 if (obj == null)
157                         return false;
158                 if (this.getClass() != obj.getClass())
159                         return false;
160                 final PCEPObjectHeader other = (PCEPObjectHeader) obj;
161                 if (this.ignored != other.ignored)
162                         return false;
163                 if (this.objClass != other.objClass)
164                         return false;
165                 if (this.objLength != other.objLength)
166                         return false;
167                 if (this.objType != other.objType)
168                         return false;
169                 if (this.processed != other.processed)
170                         return false;
171                 return true;
172         }
173
174 }