Match and actions (de)serialization + fix
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / MultipartReplyMessageFactory.java
1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
2 package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;\r
3 \r
4 import io.netty.buffer.ByteBuf;\r
5 \r
6 import java.math.BigInteger;\r
7 import java.util.ArrayList;\r
8 import java.util.List;\r
9 \r
10 import org.opendaylight.openflowjava.protocol.impl.deserialization.OFDeserializer;\r
11 import org.opendaylight.openflowjava.protocol.impl.util.ActionsDeserializer;\r
12 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;\r
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags;\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupCapabilities;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType;\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupTypes;\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandType;\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterModCommand;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.BucketsList;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.BucketsListBuilder;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropBuilder;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkBuilder;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterBuilder;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregate;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateBuilder;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDesc;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescBuilder;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenter;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterBuilder;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlow;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowBuilder;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroup;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupBuilder;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDesc;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescBuilder;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesBuilder;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeter;\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterBuilder;\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfig;\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigBuilder;\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeatures;\r
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesBuilder;\r
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDesc;\r
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescBuilder;\r
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStats;\r
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsBuilder;\r
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueue;\r
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueBuilder;\r
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTable;\r
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableBuilder;\r
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow.FlowStats;\r
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow.FlowStatsBuilder;\r
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.GroupStats;\r
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.GroupStatsBuilder;\r
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.GroupDesc;\r
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.GroupDescBuilder;\r
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.group.stats.BucketStats;\r
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.group.stats.BucketStatsBuilder;\r
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.MeterStats;\r
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.MeterStatsBuilder;\r
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config.MeterConfig;\r
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config.MeterConfigBuilder;\r
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config.meter.config.Bands;\r
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config.meter.config.BandsBuilder;\r
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.meter.stats.MeterBandStats;\r
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.meter.stats.MeterBandStatsBuilder;\r
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc.Ports;\r
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc.PortsBuilder;\r
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats.PortStats;\r
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats.PortStatsBuilder;\r
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue.QueueStats;\r
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue.QueueStatsBuilder;\r
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.TableStats;\r
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.TableStatsBuilder;\r
86 \r
87 /**\r
88  * @author timotej.kubas\r
89  * @author michal.polkorab\r
90  */\r
91 public class MultipartReplyMessageFactory implements OFDeserializer<MultipartReplyMessage> {\r
92 \r
93     private static MultipartReplyMessageFactory instance;\r
94     private static final byte PADDING_IN_MULTIPART_REPLY_HEADER = 4;\r
95     \r
96     private MultipartReplyMessageFactory() {\r
97         // singleton\r
98     }\r
99     \r
100     /**\r
101      * @return singleton factory\r
102      */\r
103     public static synchronized MultipartReplyMessageFactory getInstance() {\r
104         if (instance == null){\r
105             instance = new MultipartReplyMessageFactory();\r
106         }\r
107         return instance;\r
108     }\r
109 \r
110     @Override\r
111     public MultipartReplyMessage bufferToMessage(ByteBuf rawMessage, short version) {\r
112         MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();\r
113         builder.setVersion(version);\r
114         builder.setXid(rawMessage.readUnsignedInt());\r
115         builder.setType(MultipartType.forValue(rawMessage.readUnsignedShort()));\r
116         builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0));\r
117         rawMessage.skipBytes(PADDING_IN_MULTIPART_REPLY_HEADER);\r
118 \r
119         switch (builder.getType().getIntValue()) {\r
120         case 0:  builder.setMultipartReplyBody(setDesc(rawMessage));\r
121                  break;\r
122         case 1:  builder.setMultipartReplyBody(setFlow(rawMessage));\r
123                  break;\r
124         case 2:  builder.setMultipartReplyBody(setAggregate(rawMessage));\r
125                  break;\r
126         case 3:  builder.setMultipartReplyBody(setTable(rawMessage));\r
127                  break;         \r
128         case 4:  builder.setMultipartReplyBody(setPortStats(rawMessage));\r
129                  break;\r
130         case 5:  builder.setMultipartReplyBody(setQueue(rawMessage));\r
131                  break;         \r
132         case 6:  builder.setMultipartReplyBody(setGroup(rawMessage));\r
133                  break;\r
134         case 7:  builder.setMultipartReplyBody(setGroupDesc(rawMessage));\r
135                  break;\r
136         case 8:  builder.setMultipartReplyBody(setGroupFeatures(rawMessage));\r
137                  break;\r
138         case 9:  builder.setMultipartReplyBody(setMeter(rawMessage));\r
139                  break;\r
140         case 10: builder.setMultipartReplyBody(setMeterConfig(rawMessage));\r
141                  break;\r
142         case 11: builder.setMultipartReplyBody(setMeterFeatures(rawMessage));\r
143                  break;\r
144         case 13: builder.setMultipartReplyBody(setPortDesc(rawMessage));\r
145                  break;\r
146         case 0xFFFF: builder.setMultipartReplyBody(setExperimenter(rawMessage));\r
147                  break;\r
148         default: \r
149                  break;\r
150         }\r
151         \r
152         return builder.build();\r
153     }\r
154     \r
155     private static MultipartReplyDesc setDesc(ByteBuf input) {\r
156         final int DESC_STR_LEN = 256;\r
157         final int SERIAL_NUM_LEN = 32;\r
158         MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder();\r
159         byte[] mfrDescBytes = new byte[DESC_STR_LEN];\r
160         input.readBytes(mfrDescBytes);\r
161         String mfrDesc = new String(mfrDescBytes);\r
162         descBuilder.setMfrDesc(mfrDesc.trim());\r
163         byte[] hwDescBytes = new byte[DESC_STR_LEN];\r
164         input.readBytes(hwDescBytes);\r
165         String hwDesc = new String(hwDescBytes);\r
166         descBuilder.setHwDesc(hwDesc.trim());\r
167         byte[] swDescBytes = new byte[DESC_STR_LEN];\r
168         input.readBytes(swDescBytes);\r
169         String swDesc = new String(swDescBytes);\r
170         descBuilder.setSwDesc(swDesc.trim());\r
171         byte[] serialNumBytes = new byte[SERIAL_NUM_LEN];\r
172         input.readBytes(serialNumBytes);\r
173         String serialNum = new String(serialNumBytes);\r
174         descBuilder.setSerialNum(serialNum.trim());\r
175         byte[] dpDescBytes = new byte[DESC_STR_LEN];\r
176         input.readBytes(dpDescBytes);\r
177         String dpDesc = new String(dpDescBytes);\r
178         descBuilder.setDpDesc(dpDesc.trim());\r
179         return descBuilder.build();\r
180     }\r
181     \r
182     private static MultipartReplyFlow setFlow(ByteBuf input) {\r
183         final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1;\r
184         final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4;\r
185         final byte flowLength = 2;\r
186         MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();\r
187         List<FlowStats> flowStatsList = new ArrayList<>();\r
188         FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();\r
189         while (input.readableBytes() > 0) {\r
190             input.skipBytes(flowLength);\r
191             flowStatsBuilder.setTableId(input.readUnsignedByte());\r
192             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01);\r
193             flowStatsBuilder.setDurationSec(input.readUnsignedInt());\r
194             flowStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
195             flowStatsBuilder.setPriority(input.readUnsignedShort());\r
196             flowStatsBuilder.setIdleTimeout(input.readUnsignedShort());\r
197             flowStatsBuilder.setHardTimeout(input.readUnsignedShort());\r
198             flowStatsBuilder.setFlags(createFlowModFalgsFromBitmap(input.readShort()));\r
199             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);\r
200             byte[] cookie = new byte[Long.SIZE/Byte.SIZE];\r
201             input.readBytes(cookie);\r
202             flowStatsBuilder.setCookie(new BigInteger(cookie));\r
203             byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
204             input.readBytes(packetCount);\r
205             flowStatsBuilder.setPacketCount(new BigInteger(packetCount));\r
206             byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
207             input.readBytes(byteCount);\r
208             flowStatsBuilder.setByteCount(new BigInteger(byteCount));\r
209             // TODO match\r
210             // TODO instructions\r
211             flowStatsList.add(flowStatsBuilder.build());\r
212         }\r
213         flowBuilder.setFlowStats(new ArrayList<>(flowStatsList));\r
214         flowStatsList.clear();\r
215         return flowBuilder.build();\r
216     }\r
217     \r
218     private static FlowModFlags createFlowModFalgsFromBitmap(short input){\r
219         final Boolean _oFPFFSENDFLOWREM = (input & (1 << 0)) != 0;\r
220         final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) != 0;\r
221         final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) != 0; \r
222         final Boolean _oFPFFNOPKTCOUNTS = (input & (1 << 3)) != 0;\r
223         final Boolean _oFPFFNOBYTCOUNTS = (input & (1 << 4)) != 0;\r
224         return new FlowModFlags(_oFPFFCHECKOVERLAP, _oFPFFNOBYTCOUNTS, _oFPFFNOPKTCOUNTS, _oFPFFRESETCOUNTS, _oFPFFSENDFLOWREM);\r
225     }\r
226     \r
227     private static MultipartReplyAggregate setAggregate(ByteBuf input) {\r
228         final byte PADDING_IN_AGGREGATE_HEADER = 4;\r
229         MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder();\r
230         byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
231         input.readBytes(packetCount);\r
232         builder.setPacketCount(new BigInteger(packetCount));\r
233         byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
234         input.readBytes(byteCount);\r
235         builder.setByteCount(new BigInteger(byteCount));\r
236         builder.setFlowCount(input.readUnsignedInt());\r
237         input.skipBytes(PADDING_IN_AGGREGATE_HEADER);\r
238         return builder.build();\r
239     }\r
240     \r
241     private static MultipartReplyTable setTable(ByteBuf input) {\r
242         final byte PADDING_IN_TABLE_HEADER = 3;\r
243         MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder();\r
244         TableStatsBuilder tableStatsBuilder = new TableStatsBuilder();\r
245         List<TableStats> tableStatsList = new ArrayList<>();\r
246         while (input.readableBytes() > 0) {\r
247             tableStatsBuilder.setTableId(input.readUnsignedByte());\r
248             input.skipBytes(PADDING_IN_TABLE_HEADER);\r
249             tableStatsBuilder.setActiveCount(input.readUnsignedInt());\r
250             byte[] lookupCount = new byte[Long.SIZE/Byte.SIZE];\r
251             input.readBytes(lookupCount);\r
252             tableStatsBuilder.setLookupCount(new BigInteger(lookupCount));\r
253             byte[] matchedCount = new byte[Long.SIZE/Byte.SIZE];\r
254             input.readBytes(matchedCount);\r
255             tableStatsBuilder.setMatchedCount(new BigInteger(matchedCount));\r
256             tableStatsList.add(tableStatsBuilder.build());\r
257         }\r
258         builder.setTableStats(new ArrayList<>(tableStatsList));\r
259         tableStatsList.clear();\r
260         return builder.build();\r
261     }\r
262     \r
263     private static MultipartReplyPortStats setPortStats(ByteBuf input) {\r
264         final byte PADDING_IN_PORT_STATS_HEADER = 4;\r
265         MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder();\r
266         PortStatsBuilder portStatsBuilder = new PortStatsBuilder();\r
267         List<PortStats> portStatsList = new ArrayList<>();\r
268         while (input.readableBytes() > 0) {\r
269             portStatsBuilder.setPortNo(input.readUnsignedInt());\r
270             input.skipBytes(PADDING_IN_PORT_STATS_HEADER);\r
271             \r
272             byte[] rxPackets = new byte[Long.SIZE/Byte.SIZE];\r
273             input.readBytes(rxPackets);\r
274             portStatsBuilder.setRxPackets(new BigInteger(rxPackets));\r
275             \r
276             byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];\r
277             input.readBytes(txPackets);\r
278             portStatsBuilder.setTxPackets(new BigInteger(txPackets));\r
279             \r
280             byte[] rxBytes = new byte[Long.SIZE/Byte.SIZE];\r
281             input.readBytes(rxBytes);\r
282             portStatsBuilder.setRxBytes(new BigInteger(rxBytes));\r
283             \r
284             byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];\r
285             input.readBytes(txBytes);\r
286             portStatsBuilder.setTxBytes(new BigInteger(txBytes));\r
287             \r
288             byte[] rxDropped = new byte[Long.SIZE/Byte.SIZE];\r
289             input.readBytes(rxDropped);\r
290             portStatsBuilder.setRxDropped(new BigInteger(rxDropped));\r
291             \r
292             byte[] txDropped = new byte[Long.SIZE/Byte.SIZE];\r
293             input.readBytes(txDropped);\r
294             portStatsBuilder.setTxDropped(new BigInteger(txDropped));\r
295             \r
296             byte[] rxErrors = new byte[Long.SIZE/Byte.SIZE];\r
297             input.readBytes(rxErrors);\r
298             portStatsBuilder.setRxErrors(new BigInteger(rxErrors));\r
299             \r
300             byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];\r
301             input.readBytes(txErrors);\r
302             portStatsBuilder.setTxErrors(new BigInteger(txErrors));\r
303             \r
304             byte[] rxFrameErr = new byte[Long.SIZE/Byte.SIZE];\r
305             input.readBytes(rxFrameErr);\r
306             portStatsBuilder.setRxFrameErr(new BigInteger(rxFrameErr));\r
307             \r
308             byte[] rxOverErr = new byte[Long.SIZE/Byte.SIZE];\r
309             input.readBytes(rxOverErr);\r
310             portStatsBuilder.setRxOverErr(new BigInteger(rxOverErr));\r
311             \r
312             byte[] rxCrcErr = new byte[Long.SIZE/Byte.SIZE];\r
313             input.readBytes(rxCrcErr);\r
314             portStatsBuilder.setRxCrcErr(new BigInteger(rxCrcErr));\r
315             \r
316             byte[] collisions = new byte[Long.SIZE/Byte.SIZE];\r
317             input.readBytes(collisions);\r
318             portStatsBuilder.setCollisions(new BigInteger(collisions));\r
319             \r
320             portStatsBuilder.setDurationSec(input.readUnsignedInt());\r
321             portStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
322             portStatsList.add(portStatsBuilder.build());\r
323         }\r
324         builder.setPortStats(new ArrayList<>(portStatsList));\r
325         portStatsList.clear();\r
326         return builder.build();\r
327     }\r
328     \r
329     private static MultipartReplyQueue setQueue(ByteBuf input) {\r
330         MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder();\r
331         QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder();\r
332         List<QueueStats> queueStatsList = new ArrayList<>();\r
333         \r
334         while (input.readableBytes() > 0) {\r
335             queueStatsBuilder.setPortNo(input.readUnsignedInt());\r
336             queueStatsBuilder.setQueueId(input.readUnsignedInt());\r
337 \r
338             byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];\r
339             input.readBytes(txBytes);\r
340             queueStatsBuilder.setTxBytes(new BigInteger(txBytes));\r
341 \r
342             byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];\r
343             input.readBytes(txPackets);\r
344             queueStatsBuilder.setTxPackets(new BigInteger(txPackets));\r
345 \r
346             byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];\r
347             input.readBytes(txErrors);\r
348             queueStatsBuilder.setTxErrors(new BigInteger(txErrors));\r
349 \r
350             queueStatsBuilder.setDurationSec(input.readUnsignedInt());\r
351             queueStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
352             queueStatsList.add(queueStatsBuilder.build());\r
353         }\r
354         builder.setQueueStats(new ArrayList<>(queueStatsList));\r
355         queueStatsList.clear();\r
356         return builder.build();\r
357     }\r
358     \r
359     private static MultipartReplyGroup setGroup(ByteBuf input) {\r
360         final byte PADDING_IN_GROUP_HEADER_01 = 2;\r
361         final byte PADDING_IN_GROUP_HEADER_02 = 4;\r
362         final byte BUCKET_COUNTER_LENGTH = 16;\r
363         final byte GROUP_BODY_LENGTH = 40;\r
364         int actualLength;\r
365         MultipartReplyGroupBuilder builder = new MultipartReplyGroupBuilder();\r
366         GroupStatsBuilder groupStatsBuilder = new GroupStatsBuilder();\r
367         List<GroupStats> groupStatsList = new ArrayList<>();\r
368         \r
369         BucketStatsBuilder bucketStatsBuilder = new BucketStatsBuilder();\r
370         List<BucketStats> bucketStatsList = new ArrayList<>();\r
371         \r
372         while (input.readableBytes() > 0) {\r
373             int bodyLength = input.readUnsignedShort();\r
374             actualLength = 0;\r
375             \r
376             input.skipBytes(PADDING_IN_GROUP_HEADER_01);\r
377             groupStatsBuilder.setGroupId(input.readUnsignedInt());\r
378             groupStatsBuilder.setRefCount(input.readUnsignedInt());\r
379             input.skipBytes(PADDING_IN_GROUP_HEADER_02);\r
380             byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
381             input.readBytes(packetCount);\r
382             groupStatsBuilder.setPacketCount(new BigInteger(packetCount));\r
383             byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
384             input.readBytes(byteCount);\r
385             groupStatsBuilder.setByteCount(new BigInteger(byteCount));\r
386             groupStatsBuilder.setDurationSec(input.readUnsignedInt());\r
387             groupStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
388             actualLength = GROUP_BODY_LENGTH;\r
389             \r
390             while (actualLength < bodyLength) {\r
391                 byte[] packetCountBucket = new byte[Long.SIZE/Byte.SIZE];\r
392                 input.readBytes(packetCountBucket);\r
393                 bucketStatsBuilder.setPacketCount(new BigInteger(packetCountBucket));\r
394                 byte[] byteCountBucket = new byte[Long.SIZE/Byte.SIZE];\r
395                 input.readBytes(byteCountBucket);\r
396                 bucketStatsBuilder.setByteCount(new BigInteger(byteCountBucket));\r
397                 bucketStatsList.add(bucketStatsBuilder.build());\r
398 \r
399                 actualLength = actualLength + BUCKET_COUNTER_LENGTH;\r
400             } \r
401             groupStatsBuilder.setBucketStats(new ArrayList<>(bucketStatsList));\r
402             bucketStatsList.clear();\r
403             groupStatsList.add(groupStatsBuilder.build());\r
404         }\r
405         builder.setGroupStats(new ArrayList<>(groupStatsList));\r
406         groupStatsList.clear();\r
407         return builder.build();\r
408     }\r
409     \r
410     private static MultipartReplyMeterFeatures setMeterFeatures(ByteBuf input) {\r
411         final byte PADDING_IN_METER_FEATURES_HEADER = 2;\r
412         MultipartReplyMeterFeaturesBuilder builder = new MultipartReplyMeterFeaturesBuilder();\r
413         builder.setMaxMeter(input.readUnsignedInt());\r
414         builder.setBandTypes(MeterBandType.forValue(input.readInt()));\r
415         builder.setCapabilities(decodeMeterModFlags((int) input.readUnsignedInt()));\r
416         builder.setMaxBands(input.readUnsignedByte());\r
417         builder.setMaxColor(input.readUnsignedByte());\r
418         input.skipBytes(PADDING_IN_METER_FEATURES_HEADER);\r
419         return builder.build();\r
420     }\r
421     \r
422     private static MeterFlags decodeMeterModFlags(int input){\r
423         final Boolean _oFPMFKBPS = (input & (1 << 0)) != 0;\r
424         final Boolean _oFPMFPKTPS = (input & (1 << 1)) != 0;\r
425         final Boolean _oFPMFBURST = (input & (1 << 2)) != 0; \r
426         final Boolean _oFPMFSTATS = (input & (1 << 3)) != 0;\r
427         return new MeterFlags(_oFPMFBURST, _oFPMFKBPS, _oFPMFPKTPS, _oFPMFSTATS);\r
428     }\r
429     \r
430     private static MultipartReplyMeter setMeter(ByteBuf input) {\r
431         final byte PADDING_IN_METER_STATS_HEADER = 6;\r
432         final byte METER_BAND_STATS_LENGTH = 16;\r
433         final byte METER_BODY_LENGTH = 40;\r
434         int actualLength;\r
435         MultipartReplyMeterBuilder builder = new MultipartReplyMeterBuilder();\r
436         List<MeterStats> meterStatsList = new ArrayList<>();\r
437         MeterStatsBuilder meterStatsBuilder = new MeterStatsBuilder();\r
438         List<MeterBandStats> meterBandStatsList = new ArrayList<>();\r
439         MeterBandStatsBuilder meterBandStatsBuilder = new MeterBandStatsBuilder();\r
440         while (input.readableBytes() > 0) {\r
441             meterStatsBuilder.setMeterId(input.readUnsignedInt());\r
442             actualLength = 0;\r
443             int meterStatsBodyLength = input.readUnsignedShort();\r
444             input.skipBytes(PADDING_IN_METER_STATS_HEADER);\r
445             meterStatsBuilder.setFlowCount(input.readUnsignedInt());\r
446             byte[] packetInCount = new byte[Long.SIZE/Byte.SIZE];\r
447             input.readBytes(packetInCount);\r
448             meterStatsBuilder.setPacketInCount(new BigInteger(packetInCount));\r
449             byte[] byteInCount = new byte[Long.SIZE/Byte.SIZE];\r
450             input.readBytes(byteInCount);\r
451             meterStatsBuilder.setByteInCount(new BigInteger(byteInCount));\r
452             meterStatsBuilder.setDurationSec(input.readUnsignedInt());\r
453             meterStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
454             actualLength = METER_BODY_LENGTH;\r
455             \r
456             while (actualLength < meterStatsBodyLength) {\r
457                 byte[] packetBandCount = new byte[Long.SIZE/Byte.SIZE];\r
458                 input.readBytes(packetBandCount);\r
459                 meterBandStatsBuilder.setPacketBandCount(new BigInteger(packetBandCount));\r
460                 byte[] byteBandCount = new byte[Long.SIZE/Byte.SIZE];\r
461                 input.readBytes(byteBandCount);\r
462                 meterBandStatsBuilder.setByteBandCount(new BigInteger(byteBandCount));\r
463                 \r
464                 meterBandStatsList.add(meterBandStatsBuilder.build());\r
465                 actualLength = actualLength + METER_BAND_STATS_LENGTH;\r
466             }\r
467         \r
468             meterStatsBuilder.setMeterBandStats(new ArrayList<>(meterBandStatsList));\r
469             meterBandStatsList.clear();\r
470             meterStatsList.add(meterStatsBuilder.build());\r
471         }\r
472         builder.setMeterStats(new ArrayList<>(meterStatsList));\r
473         meterStatsList.clear();\r
474         return builder.build();\r
475     }\r
476     \r
477     private static MultipartReplyMeterConfig setMeterConfig(ByteBuf input) {\r
478         final byte METER_BAND_LENGTH = 16;\r
479         final byte METER_CONFIG_LENGTH = 8;\r
480         final byte bandLength = 2;\r
481         int actualLength;\r
482         MultipartReplyMeterConfigBuilder builder = new MultipartReplyMeterConfigBuilder();\r
483         List<MeterConfig> meterConfigList = new ArrayList<>();\r
484         MeterConfigBuilder meterConfigBuilder = new MeterConfigBuilder();\r
485         List<Bands> bandsList = new ArrayList<>();\r
486         BandsBuilder bandsBuilder = new BandsBuilder();\r
487         \r
488         while (input.readableBytes() > 0) {\r
489             int meterConfigBodyLength = input.readUnsignedShort();\r
490             actualLength = 0;\r
491             meterConfigBuilder.setFlags(MeterModCommand.forValue(input.readUnsignedShort()));\r
492             meterConfigBuilder.setMeterId(input.readUnsignedInt());\r
493             actualLength = METER_CONFIG_LENGTH;\r
494             \r
495             while (actualLength < meterConfigBodyLength) {\r
496                 MeterBandDropBuilder bandDropBuilder = new MeterBandDropBuilder();\r
497                 final byte PADDING_IN_METER_BAND_DROP_HEADER = 4;\r
498                 MeterBandDscpRemarkBuilder bandDscpRemarkBuilder = new MeterBandDscpRemarkBuilder();\r
499                 final byte PADDING_IN_METER_BAND_DSCP_HEADER = 3;\r
500                 MeterBandExperimenterBuilder bandExperimenterBuilder = new MeterBandExperimenterBuilder(); \r
501                 int bandType = input.readUnsignedShort();\r
502                 switch (bandType) {\r
503                     case 1: bandDropBuilder.setType(MeterBandType.forValue(bandType));\r
504                             input.skipBytes(bandLength);\r
505                             bandDropBuilder.setRate(input.readUnsignedInt());\r
506                             bandDropBuilder.setBurstSize(input.readUnsignedInt());\r
507                             input.skipBytes(PADDING_IN_METER_BAND_DROP_HEADER);\r
508                             bandsBuilder.setMeterBand(bandDropBuilder.build());\r
509                             break;\r
510                     case 2: bandDscpRemarkBuilder.setType(MeterBandType.forValue(bandType));\r
511                             input.skipBytes(bandLength);\r
512                             bandDscpRemarkBuilder.setRate(input.readUnsignedInt());\r
513                             bandDscpRemarkBuilder.setBurstSize(input.readUnsignedInt());\r
514                             bandDscpRemarkBuilder.setPrecLevel(input.readUnsignedByte());\r
515                             input.skipBytes(PADDING_IN_METER_BAND_DSCP_HEADER);\r
516                             bandsBuilder.setMeterBand(bandDscpRemarkBuilder.build());\r
517                             break;\r
518                     case 0xFFFF: bandExperimenterBuilder.setType(MeterBandType.forValue(bandType));\r
519                                  input.skipBytes(bandLength);\r
520                                  bandExperimenterBuilder.setRate(input.readUnsignedInt());\r
521                                  bandExperimenterBuilder.setBurstSize(input.readUnsignedInt());\r
522                                  bandExperimenterBuilder.setExperimenter(input.readUnsignedInt());\r
523                                  bandsBuilder.setMeterBand(bandExperimenterBuilder.build());\r
524                                  break;\r
525                     default: break;\r
526                 }\r
527                 bandsList.add(bandsBuilder.build());\r
528                 actualLength = actualLength + METER_BAND_LENGTH;\r
529             }\r
530             meterConfigBuilder.setBands(new ArrayList<>(bandsList));\r
531             bandsList.clear();\r
532             meterConfigList.add(meterConfigBuilder.build());\r
533         }\r
534         builder.setMeterConfig(new ArrayList<>(meterConfigList));\r
535         meterConfigList.clear();\r
536         return builder.build();\r
537     }\r
538     \r
539     private static MultipartReplyExperimenter setExperimenter(ByteBuf input) {\r
540         MultipartReplyExperimenterBuilder builder = new MultipartReplyExperimenterBuilder();\r
541         builder.setExperimenter(input.readUnsignedInt());\r
542         builder.setExpType(input.readUnsignedInt());\r
543         byte[] data = new byte[Long.SIZE/Byte.SIZE];\r
544         input.readBytes(data);\r
545         builder.setData(data);\r
546         return builder.build();\r
547     }\r
548     \r
549     private static MultipartReplyPortDesc setPortDesc(ByteBuf input) {\r
550         final byte PADDING_IN_PORT_DESC_HEADER_01 = 4;\r
551         final byte PADDING_IN_PORT_DESC_HEADER_02 = 2;\r
552         final int macAddressLength = 6;\r
553         final byte MAX_PORT_NAME_LEN = 16;\r
554         MultipartReplyPortDescBuilder builder = new MultipartReplyPortDescBuilder();\r
555         List<Ports> portsList = new ArrayList<>();\r
556         PortsBuilder portsBuilder = new PortsBuilder();\r
557         \r
558         while (input.readableBytes() > 0) {\r
559             portsBuilder.setPortNo(input.readUnsignedInt());\r
560             input.skipBytes(PADDING_IN_PORT_DESC_HEADER_01);\r
561             StringBuffer macToString = new StringBuffer();\r
562             for(int i=0; i<macAddressLength; i++){\r
563                 short mac = 0;\r
564                 mac = input.readUnsignedByte();\r
565                 macToString.append(String.format("%02X", mac));\r
566             }\r
567             portsBuilder.setHwAddr(new MacAddress(macToString.toString()));\r
568             input.skipBytes(PADDING_IN_PORT_DESC_HEADER_02);\r
569             \r
570             byte[] portNameBytes = new byte[MAX_PORT_NAME_LEN];\r
571             input.readBytes(portNameBytes);\r
572             String portName = new String(portNameBytes);\r
573             portsBuilder.setName(portName.trim());\r
574             \r
575             portsBuilder.setConfig(createPortConfig(input.readUnsignedInt()));\r
576             portsBuilder.setState(createPortState(input.readUnsignedInt()));\r
577             portsBuilder.setCurrentFeatures(createPortFeatures(input.readUnsignedInt()));\r
578             portsBuilder.setAdvertisedFeatures(createPortFeatures(input.readUnsignedInt()));\r
579             portsBuilder.setSupportedFeatures(createPortFeatures(input.readUnsignedInt()));\r
580             portsBuilder.setPeerFeatures(createPortFeatures(input.readUnsignedInt()));\r
581             portsBuilder.setCurrSpeed(input.readUnsignedInt());\r
582             portsBuilder.setMaxSpeed(input.readUnsignedInt());\r
583             portsList.add(portsBuilder.build());\r
584         }\r
585         \r
586         builder.setPorts(new ArrayList<>(portsList));\r
587         portsList.clear();\r
588         return builder.build();\r
589     }\r
590     \r
591     private static PortConfig createPortConfig(long input){\r
592         final Boolean _portDown   = ((input) & (1<<0)) != 0;\r
593         final Boolean _noRecv    = ((input) & (1<<2)) != 0;\r
594         final Boolean _noFwd       = ((input) & (1<<5)) != 0;\r
595         final Boolean _noPacketIn = ((input) & (1<<6)) != 0;\r
596         return new PortConfig(_noFwd, _noPacketIn, _noRecv, _portDown);\r
597     }\r
598     \r
599     private static PortState createPortState(long input){\r
600         final Boolean _linkDown = ((input) & (1<<0)) != 0;\r
601         final Boolean _blocked  = ((input) & (1<<1)) != 0;\r
602         final Boolean _live     = ((input) & (1<<2)) != 0;\r
603         return new PortState(_linkDown, _blocked,_live);\r
604     }\r
605     \r
606     private static PortFeatures createPortFeatures(long input){\r
607         final Boolean _10mbHd = ((input) & (1<<0)) != 0;\r
608         final Boolean _10mbFd = ((input) & (1<<1)) != 0;\r
609         final Boolean _100mbHd = ((input) & (1<<2)) != 0;\r
610         final Boolean _100mbFd = ((input) & (1<<3)) != 0;\r
611         final Boolean _1gbHd = ((input) & (1<<4)) != 0;\r
612         final Boolean _1gbFd = ((input) & (1<<5)) != 0;\r
613         final Boolean _10gbFd = ((input) & (1<<6)) != 0;\r
614         final Boolean _40gbFd = ((input) & (1<<7)) != 0;\r
615         final Boolean _100gbFd = ((input) & (1<<8)) != 0;\r
616         final Boolean _1tbFd = ((input) & (1<<9)) != 0;\r
617         final Boolean _other = ((input) & (1<<10)) != 0;\r
618         final Boolean _copper = ((input) & (1<<11)) != 0;\r
619         final Boolean _fiber = ((input) & (1<<12)) != 0;\r
620         final Boolean _autoneg = ((input) & (1<<13)) != 0;\r
621         final Boolean _pause = ((input) & (1<<14)) != 0;\r
622         final Boolean _pauseAsym = ((input) & (1<<15)) != 0;\r
623         return new PortFeatures(_10mbHd, _10mbFd, _100mbHd, _100mbFd, _1gbHd, _1gbFd, _10gbFd,\r
624                 _40gbFd, _100gbFd, _1tbFd, _other, _copper, _fiber, _autoneg, _pause, _pauseAsym);\r
625     }\r
626     \r
627     private static MultipartReplyBody setGroupFeatures(ByteBuf rawMessage) {\r
628         final int SIZE_OF_MAX_GROUPS = 4;\r
629         MultipartReplyGroupFeaturesBuilder featuresBuilder = new MultipartReplyGroupFeaturesBuilder();\r
630         featuresBuilder.setTypes(createGroupType(rawMessage.readUnsignedInt()));\r
631         featuresBuilder.setCapabilities(createCapabilities(rawMessage.readUnsignedInt()));\r
632         List<Long> maxGroupsList = new ArrayList<>();\r
633         for (int i = 0; i < SIZE_OF_MAX_GROUPS ; i++) {\r
634             maxGroupsList.add(rawMessage.readUnsignedInt());\r
635         }\r
636         featuresBuilder.setMaxGroups(maxGroupsList);\r
637         // TODO - groupfeatures - actions bitmap\r
638         rawMessage.skipBytes(4);\r
639         return featuresBuilder.build();\r
640     }\r
641 \r
642     private static GroupCapabilities createCapabilities(long input) {\r
643         final Boolean OFOFPGFC_SELECT_WEIGHT = ((input) & (1<<0)) != 0;\r
644         final Boolean OFPGFC_SELECT_LIVENESS = ((input) & (1<<1)) != 0;\r
645         final Boolean OFPGFC_CHAINING = ((input) & (1<<2)) != 0;\r
646         final Boolean OFPGFC_CHAINING_CHECKS = ((input) & (1<<3)) != 0;\r
647         return new GroupCapabilities(OFPGFC_CHAINING, OFPGFC_CHAINING_CHECKS, OFPGFC_SELECT_LIVENESS, OFOFPGFC_SELECT_WEIGHT);\r
648     }\r
649 \r
650     private static GroupTypes createGroupType(long input) {\r
651         final Boolean OFPGT_ALL = ((input) & (1<<0)) != 0;\r
652         final Boolean OFPGT_SELECT = ((input) & (1<<1)) != 0;\r
653         final Boolean OFPGT_INDIRECT = ((input) & (1<<2)) != 0;\r
654         final Boolean OFPGT_FF = ((input) & (1<<3)) != 0;\r
655         return new GroupTypes(OFPGT_ALL, OFPGT_FF, OFPGT_INDIRECT, OFPGT_SELECT);\r
656     }\r
657     \r
658     private static MultipartReplyGroupDesc setGroupDesc(ByteBuf input) {\r
659         final byte PADDING_IN_GROUP_DESC_HEADER = 1;\r
660         final byte PADDING_IN_BUCKETS_HEADER = 4;\r
661         final byte GROUP_DESC_HEADER_LENGTH = 8;\r
662         int actualLength;\r
663         int bucketsLength = 0;\r
664         int bucketsCurrentLength = 0;\r
665         int bodyLength = 0;\r
666         MultipartReplyGroupDescBuilder builder = new MultipartReplyGroupDescBuilder();\r
667         GroupDescBuilder groupDescBuilder = new GroupDescBuilder();\r
668         List<GroupDesc> groupDescsList = new ArrayList<>();\r
669         BucketsListBuilder bucketsBuilder = new BucketsListBuilder();\r
670         List<BucketsList> bucketsList = new ArrayList<>();\r
671         List<ActionsList> actionsList = new ArrayList<>();\r
672         \r
673         while (input.readableBytes() > 0) {\r
674             bodyLength = input.readUnsignedShort();\r
675             actualLength = 0;\r
676             \r
677             groupDescBuilder.setType(GroupType.forValue(input.readUnsignedByte())); // TODO enum or class?\r
678             input.skipBytes(PADDING_IN_GROUP_DESC_HEADER);\r
679             groupDescBuilder.setGroupId(input.readUnsignedInt());\r
680             actualLength = GROUP_DESC_HEADER_LENGTH;\r
681             \r
682             while (actualLength < bodyLength) {\r
683                 \r
684                 bucketsLength = input.readUnsignedShort();\r
685                 bucketsBuilder.setWeight(input.readUnsignedShort());\r
686                 bucketsBuilder.setWatchPort(new PortNumber(input.readUnsignedInt()));\r
687                 bucketsBuilder.setWatchGroup(input.readUnsignedInt());\r
688                 input.skipBytes(PADDING_IN_BUCKETS_HEADER);\r
689                 bucketsCurrentLength = bucketsLength;\r
690                 actionsList = ActionsDeserializer.createActionsList(input, bucketsLength);\r
691                 bucketsBuilder.setActionsList(new ArrayList<>(actionsList));\r
692                 actionsList.clear();\r
693                 bucketsList.add(bucketsBuilder.build());\r
694                 actualLength = actualLength + bucketsCurrentLength;\r
695             }\r
696             groupDescBuilder.setBucketsList(new ArrayList<>(bucketsList));\r
697             bucketsList.clear();\r
698             groupDescsList.add(groupDescBuilder.build());\r
699         }\r
700         builder.setGroupDesc(new ArrayList<>(groupDescsList));\r
701         groupDescsList.clear();\r
702         return builder.build();\r
703     }\r
704     \r
705 }\r