// Path: src/main/java/com/lmax/angler/monitoring/network/monitor/util/TokenHandler.java
// public interface TokenHandler
// {
//     /**
//      * Handle a single token.
//      * @param src data source
//      * @param startPosition the start position of the token
//      * @param endPosition the end position of the token
//      */
//     void handleToken(final ByteBuffer src, final int startPosition, final int endPosition);
// 
//     /**
//      * Current token set is complete.
//      */
//     void complete();
// 
//     /**
//      * Reset state in preparation for handling a new data set.
//      */
//     void reset();
// }
// 
// Path: src/main/java/com/lmax/angler/monitoring/network/monitor/util/AsciiBytesToLongDecoder.java
// public static long decodeAscii(final ByteBuffer src, final int startPosition, final int endPosition)
// {
//     final int length = endPosition - startPosition;
//     if(length == 0)
//     {
//         throw new IllegalArgumentException("Cannot decode zero-length ascii string.");
//     }
//     long decoded = 0L;
//     for(int offset = 0; offset < length; offset++)
//     {
//         decoded *= 10;
// 
//         final byte digit = src.get(startPosition + offset);
// 
//         if(digit < '0' || digit > '9')
//         {
//             throw new IllegalArgumentException("Invalid digit: " + (char) digit);
//         }
// 
//         decoded += digit - '0';
//     }
// 
//     return decoded;
// }


import com.lmax.angler.monitoring.network.monitor.util.TokenHandler;
import java.nio.ByteBuffer;
import static com.lmax.angler.monitoring.network.monitor.util.AsciiBytesToLongDecoder.decodeAscii;
import static java.nio.charset.StandardCharsets.UTF_8;
package com.lmax.angler.monitoring.network.monitor.system.snmp.udp;




/**
 * TokenHandler for UDP-specific data in /proc/net/snmp.
 */
public final class SnmpUdpStatisticsColumnHandler implements TokenHandler
{
    private static final long HEADER_ROW_FIRST_COLUMN_VALUE = ByteBuffer.wrap("Udp: InD".getBytes(UTF_8)).getLong();
    private static final int UDP_ROW_FIRST_COLUMN_VALUE = ByteBuffer.wrap("Udp:".getBytes(UTF_8)).getInt();
    private final SnmpUdpStatisticsHandler globalUdpStatisticsConsumer;
    private final GlobalUdpStatistics entry = new GlobalUdpStatistics();
    private int currentColumn = 0;
    private boolean currentRowIsUdpDataRow;

    public SnmpUdpStatisticsColumnHandler(final SnmpUdpStatisticsHandler globalUdpStatisticsConsumer)
    {
        this.globalUdpStatisticsConsumer = globalUdpStatisticsConsumer;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void handleToken(final ByteBuffer src, final int startPosition, final int endPosition)
    {
        switch (currentColumn)
        {
            case 0:
                if(src.getInt(startPosition) == UDP_ROW_FIRST_COLUMN_VALUE &&
                   src.getLong(startPosition) != HEADER_ROW_FIRST_COLUMN_VALUE)
                {
                    currentRowIsUdpDataRow = true;
                }
                break;
            case 3:
                // InErrors
                if(currentRowIsUdpDataRow)
                {
// Path: src/main/java/com/lmax/angler/monitoring/network/monitor/util/TokenHandler.java
// public interface TokenHandler
// {
//     /**
//      * Handle a single token.
//      * @param src data source
//      * @param startPosition the start position of the token
//      * @param endPosition the end position of the token
//      */
//     void handleToken(final ByteBuffer src, final int startPosition, final int endPosition);
// 
//     /**
//      * Current token set is complete.
//      */
//     void complete();
// 
//     /**
//      * Reset state in preparation for handling a new data set.
//      */
//     void reset();
// }
// 
// Path: src/main/java/com/lmax/angler/monitoring/network/monitor/util/AsciiBytesToLongDecoder.java
// public static long decodeAscii(final ByteBuffer src, final int startPosition, final int endPosition)
// {
//     final int length = endPosition - startPosition;
//     if(length == 0)
//     {
//         throw new IllegalArgumentException("Cannot decode zero-length ascii string.");
//     }
//     long decoded = 0L;
//     for(int offset = 0; offset < length; offset++)
//     {
//         decoded *= 10;
// 
//         final byte digit = src.get(startPosition + offset);
// 
//         if(digit < '0' || digit > '9')
//         {
//             throw new IllegalArgumentException("Invalid digit: " + (char) digit);
//         }
// 
//         decoded += digit - '0';
//     }
// 
//     return decoded;
// }


// Path: src/main/java/com/lmax/angler/monitoring/network/monitor/system/snmp/udp/SnmpUdpStatisticsColumnHandler.java
import com.lmax.angler.monitoring.network.monitor.util.TokenHandler;
import java.nio.ByteBuffer;
import static com.lmax.angler.monitoring.network.monitor.util.AsciiBytesToLongDecoder.decodeAscii;
import static java.nio.charset.StandardCharsets.UTF_8;

package com.lmax.angler.monitoring.network.monitor.system.snmp.udp;




/**
 * TokenHandler for UDP-specific data in /proc/net/snmp.
 */
public final class SnmpUdpStatisticsColumnHandler implements TokenHandler
{
    private static final long HEADER_ROW_FIRST_COLUMN_VALUE = ByteBuffer.wrap("Udp: InD".getBytes(UTF_8)).getLong();
    private static final int UDP_ROW_FIRST_COLUMN_VALUE = ByteBuffer.wrap("Udp:".getBytes(UTF_8)).getInt();
    private final SnmpUdpStatisticsHandler globalUdpStatisticsConsumer;
    private final GlobalUdpStatistics entry = new GlobalUdpStatistics();
    private int currentColumn = 0;
    private boolean currentRowIsUdpDataRow;

    public SnmpUdpStatisticsColumnHandler(final SnmpUdpStatisticsHandler globalUdpStatisticsConsumer)
    {
        this.globalUdpStatisticsConsumer = globalUdpStatisticsConsumer;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void handleToken(final ByteBuffer src, final int startPosition, final int endPosition)
    {
        switch (currentColumn)
        {
            case 0:
                if(src.getInt(startPosition) == UDP_ROW_FIRST_COLUMN_VALUE &&
                   src.getLong(startPosition) != HEADER_ROW_FIRST_COLUMN_VALUE)
                {
                    currentRowIsUdpDataRow = true;
                }
                break;
            case 3:
                // InErrors
                if(currentRowIsUdpDataRow)
                {
                    entry.setInErrors(decodeAscii(src, startPosition, endPosition));