BUG-58: refactor to take advantage of netty
[bgpcep.git] / pcep / impl / src / main / java / org / opendaylight / protocol / pcep / impl / PCEPMessageHeader.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
12 import org.opendaylight.protocol.util.ByteArray;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15
16 import com.google.common.primitives.UnsignedBytes;
17
18 /**
19  * Header parser for {@link org.opendaylight.protocol.pcep.PCEPMessage PCEPMessage}
20  */
21 public final class PCEPMessageHeader {
22
23         public static final Logger logger = LoggerFactory.getLogger(PCEPMessageHeader.class);
24
25         /*
26          * lengths of fields in bytes
27          */
28         private static final int VER_FLAGS_MF_LENGTH = 1;
29         private static final int TYPE_F_LENGTH = 1;
30         private static final int LENGTH_F_LENGTH = 2;
31
32         /*
33          * lengths of subfields inside multi-field in bits
34          */
35         private static final int VERSION_SF_LENGTH = 3;
36
37         /*
38          * offsets of field in bytes
39          */
40         private static final int VER_FLAGS_MF_OFFSET = 0;
41         private static final int TYPE_F_OFFSET = VER_FLAGS_MF_LENGTH + VER_FLAGS_MF_OFFSET;
42         private static final int LENGTH_F_OFFSET = TYPE_F_LENGTH + TYPE_F_OFFSET;
43
44         /*
45          * offsets of subfields inside multi-filed in bits
46          */
47
48         private static final int VERSION_SF_OFFSET = 0;
49
50         /*
51          * COMMON HEADER LENGTH
52          */
53         public static final int COMMON_HEADER_LENGTH = VER_FLAGS_MF_LENGTH + TYPE_F_LENGTH + LENGTH_F_LENGTH;
54
55         private final int type;
56         private final int length;
57         private final int version;
58
59         public PCEPMessageHeader(final int type, final int length, final int version) {
60                 this.type = type;
61                 this.length = length;
62                 this.version = version;
63         }
64
65         public static PCEPMessageHeader fromBytes(final byte[] bytes) {
66                 if (bytes == null) {
67                         throw new IllegalArgumentException("Array of bytes is mandatory");
68                 }
69
70                 logger.trace("Attempt to parse message header: {}", ByteArray.bytesToHexString(bytes));
71
72                 if (bytes.length < COMMON_HEADER_LENGTH) {
73                         throw new IllegalArgumentException("Too few bytes in passed array. Passed: " + bytes.length + "; Expected: >= " + COMMON_HEADER_LENGTH + ".");
74                 }
75
76                 final int type = UnsignedBytes.toInt(bytes[TYPE_F_OFFSET]);
77
78                 final int length = ByteArray.bytesToInt(Arrays.copyOfRange(bytes,
79                                 LENGTH_F_OFFSET, LENGTH_F_OFFSET + LENGTH_F_LENGTH));
80
81                 final int version = ByteArray.copyBitsRange(bytes[VER_FLAGS_MF_OFFSET], VERSION_SF_OFFSET, VERSION_SF_LENGTH);
82
83                 final PCEPMessageHeader ret = new PCEPMessageHeader(type, length, version);
84
85                 logger.trace("Message header was parsed. {}", ret);
86                 return ret;
87         }
88
89         public byte[] toBytes() {
90                 final byte[] retBytes = new byte[COMMON_HEADER_LENGTH];
91
92                 // msgVer_Flag
93                 retBytes[VER_FLAGS_MF_OFFSET] = (byte) (this.version << (Byte.SIZE - VERSION_SF_LENGTH));
94
95                 // msgType
96                 retBytes[TYPE_F_OFFSET] = (byte) this.type;
97
98                 // msgLength
99                 System.arraycopy(ByteArray.intToBytes(this.length), Integer.SIZE / Byte.SIZE - LENGTH_F_LENGTH, retBytes, LENGTH_F_OFFSET, LENGTH_F_LENGTH);
100
101                 return retBytes;
102         }
103
104         public int getLength() {
105                 return this.length;
106         }
107
108         public int getVersion() {
109                 return this.version;
110         }
111
112         public int getType() {
113                 return this.type;
114         }
115
116         @Override
117         public String toString() {
118                 final StringBuilder builder = new StringBuilder();
119                 builder.append("PCEPMessageHeader [type=");
120                 builder.append(this.type);
121                 builder.append(", length=");
122                 builder.append(this.length);
123                 builder.append(", version=");
124                 builder.append(this.version);
125                 builder.append("]");
126                 return builder.toString();
127         }
128 }