Replace Preconditions.CheckNotNull per RequireNonNull
[bgpcep.git] / bgp / util / src / main / java / org / opendaylight / protocol / bgp / util / HexDumpBGPFileParser.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.bgp.util;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.VisibleForTesting;
13 import com.google.common.base.Preconditions;
14 import com.google.common.base.Strings;
15 import com.google.common.collect.Lists;
16 import com.google.common.io.BaseEncoding;
17 import com.google.common.io.CharStreams;
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.util.List;
24 import javax.annotation.concurrent.Immutable;
25 import org.opendaylight.protocol.util.ByteArray;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Read text file, parse BGP messages. File can contain comments or other data. BGP messages are detected using 16 ff
31  * marker. New lines and spaces are ignored.
32  */
33 @Immutable
34 public final class HexDumpBGPFileParser {
35     private static final int MINIMAL_LENGTH = 19;
36     private static final Logger LOG = LoggerFactory.getLogger(HexDumpBGPFileParser.class);
37     private static final String FF_16 = Strings.repeat("FF", 16);
38
39     private HexDumpBGPFileParser() {
40         throw new UnsupportedOperationException();
41     }
42
43     public static List<byte[]> parseMessages(final File file) throws IOException {
44         Preconditions.checkArgument(file != null, "Filename cannot be null");
45         return parseMessages(new FileInputStream(file));
46     }
47
48     public static List<byte[]> parseMessages(final InputStream is) throws IOException {
49         requireNonNull(is);
50         try (InputStreamReader isr = new InputStreamReader(is, "UTF-8")) {
51             return parseMessages(CharStreams.toString(isr));
52         } finally {
53             is.close();
54         }
55     }
56
57     public static List<byte[]> parseMessages(final String c) {
58         final String content = clearWhiteSpaceToUpper(c);
59         final int sixteen = 16;
60         final int four = 4;
61         // search for 16 FFs
62
63         final List<byte[]> messages = Lists.newLinkedList();
64         int idx = content.indexOf(FF_16, 0);
65         while (idx > -1) {
66             // next 2 bytes are length
67             final int lengthIdx = idx + sixteen * 2;
68             final int messageIdx = lengthIdx + four;
69             final String hexLength = content.substring(lengthIdx, messageIdx);
70             final byte[] byteLength = BaseEncoding.base16().decode(hexLength);
71             final int length = ByteArray.bytesToInt(byteLength);
72             final int messageEndIdx = idx + length * 2;
73
74             // Assert that message is longer than minimum 19(header.length == 19)
75             // If length in BGP message would be 0, loop would never end
76             Preconditions.checkArgument(length >= MINIMAL_LENGTH, "Invalid message at index " + idx + ", length atribute is lower than "
77                     + MINIMAL_LENGTH);
78
79             final String hexMessage = content.substring(idx, messageEndIdx);
80             final byte[] message = BaseEncoding.base16().decode(hexMessage);
81             messages.add(message);
82             idx = messageEndIdx;
83             idx = content.indexOf(FF_16, idx);
84         }
85         LOG.info("Succesfully extracted {} messages", messages.size());
86         return messages;
87     }
88
89     @VisibleForTesting
90     static String clearWhiteSpaceToUpper(final String line) {
91         return line.replaceAll("\\s", "").toUpperCase();
92     }
93 }