<commit_before>/*
 * Copyright (c) 2013 <NAME> 
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.fimtra.tcpchannel;

import java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Queue;

import com.fimtra.channel.ChannelUtils;
import com.fimtra.channel.IReceiver;
import com.fimtra.channel.TransportTechnologyEnum;
import com.fimtra.util.Log;
import com.fimtra.util.ObjectUtils;

/**
 * Utility methods for a {@link TcpChannel}
 * <p>
 * Socket options for the runtime can be set using system properties in the form
 * <code>tcpchannel.{SocketOptions_constant}</code> e.g.
 * 
 * <pre>
 * -Dtcpchannel.TCP_NODELAY=true -Dtcpchannel.SO_RCVBUF=65535
 * </pre>
 * 
 * @author <NAME>
 */
public abstract class TcpChannelUtils
{
    static final Map<String, String> SOCKET_OPTIONS = new HashMap<String, String>();
    static
    {
        Map.Entry<Object, Object> entry = null;
        Object key = null;
        Object value = null;
        for (Iterator<Map.Entry<Object, Object>> it = System.getProperties().entrySet().iterator(); it.hasNext();)
        {
            try
            {
                entry = it.next();
                key = entry.getKey();
                value = entry.getValue();
                if (key.toString().startsWith("tcpchannel."))
                {
                    SOCKET_OPTIONS.put(key.toString().substring("tcpchannel.".length()), value.toString());
                }
            }
            catch (Exception e)
            {
                Log.log(TcpChannelUtils.class, "Could not read socket option " + ObjectUtils.safeToString(key)
                    + " from system properties", e);
            }
        }
        Log.log(TcpChannelUtils.class, "Socket options: ", ObjectUtils.safeToString(SOCKET_OPTIONS));
    }

    /**
     * Thrown when a TCP channel buffer cannot hold the incoming message. In these situations, the
     * {@link TcpChannel} can be constructed with a bigger receive buffer.
     * 
     * @see TcpChannel#TcpChannel(String, int, IReceiver, int)
     * @author <NAME>
     */
    public static class BufferOverflowException extends RuntimeException
    {
        private static final long serialVersionUID = 1L;

        public BufferOverflowException(String message)
        {
            super(message);
        }
    }

    /**
     * Get the next free TCP server port in the passed in ranges for the given host.
     * 
     * @param hostName
     *            the hostname to use to find the next free default TCP server
     * @return a free TCP server port that can have a TCP server socket bound to it, -1 if there is
     *         not a free port
     */
    public synchronized static int getNextFreeTcpServerPort(String hostName, int startPortRangeInclusive,
        int endPortRangeExclusive)
    {
        if (ChannelUtils.TRANSPORT == TransportTechnologyEnum.SOLACE)
        {
            return System.identityHashCode(Runtime.getRuntime()) + (int) System.nanoTime();
        }

        String hostAddress = TcpChannelUtils.LOCALHOST_IP;
        try
        {
            hostAddress = InetAddress.getByName(hostName).getHostAddress();
        }
        catch (UnknownHostException e)
        {
        }
        for (int i = startPortRangeInclusive; i < endPortRangeExclusive; i++)
        {
            try
            {
                Log.log(TcpChannelUtils.class, "Trying ", hostAddress, ":", Integer.toString(i));
                final ServerSocket serverSocket = new ServerSocket();
                serverSocket.bind(new InetSocketAddress(hostAddress, i));
                serverSocket.close();
                Log.log(TcpChannelUtils.class, "Using ", hostAddress, ":", Integer.toString(i));
                return i;
            }
            catch (IOException e)
            {
                Log.log(TcpChannelUtils.class, e.getMessage());
            }<commit_msg>Add logic to wait (max 1 sec) for free server socket to close<commit_after>/*
 * Copyright (c) 2013 <NAME> 
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.fimtra.tcpchannel;

import java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Queue;

import com.fimtra.channel.ChannelUtils;
import com.fimtra.channel.IReceiver;
import com.fimtra.channel.TransportTechnologyEnum;
import com.fimtra.util.Log;
import com.fimtra.util.ObjectUtils;

/**
 * Utility methods for a {@link TcpChannel}
 * <p>
 * Socket options for the runtime can be set using system properties in the form
 * <code>tcpchannel.{SocketOptions_constant}</code> e.g.
 * 
 * <pre>
 * -Dtcpchannel.TCP_NODELAY=true -Dtcpchannel.SO_RCVBUF=65535
 * </pre>
 * 
 * @author <NAME>
 */
public abstract class TcpChannelUtils
{
    static final Map<String, String> SOCKET_OPTIONS = new HashMap<String, String>();
    static
    {
        Map.Entry<Object, Object> entry = null;
        Object key = null;
        Object value = null;
        for (Iterator<Map.Entry<Object, Object>> it = System.getProperties().entrySet().iterator(); it.hasNext();)
        {
            try
            {
                entry = it.next();
                key = entry.getKey();
                value = entry.getValue();
                if (key.toString().startsWith("tcpchannel."))
                {
                    SOCKET_OPTIONS.put(key.toString().substring("tcpchannel.".length()), value.toString());
                }
            }
            catch (Exception e)
            {
                Log.log(TcpChannelUtils.class, "Could not read socket option " + ObjectUtils.safeToString(key)
                    + " from system properties", e);
            }
        }
        Log.log(TcpChannelUtils.class, "Socket options: ", ObjectUtils.safeToString(SOCKET_OPTIONS));
    }

    /**
     * Thrown when a TCP channel buffer cannot hold the incoming message. In these situations, the
     * {@link TcpChannel} can be constructed with a bigger receive buffer.
     * 
     * @see TcpChannel#TcpChannel(String, int, IReceiver, int)
     * @author <NAME>
     */
    public static class BufferOverflowException extends RuntimeException
    {
        private static final long serialVersionUID = 1L;

        public BufferOverflowException(String message)
        {
            super(message);
        }
    }

    /**
     * Get the next free TCP server port in the passed in ranges for the given host.
     * 
     * @param hostName
     *            the hostname to use to find the next free default TCP server
     * @return a free TCP server port that can have a TCP server socket bound to it, -1 if there is
     *         not a free port
     */
    public synchronized static int getNextFreeTcpServerPort(String hostName, int startPortRangeInclusive,
        int endPortRangeExclusive)
    {
        if (ChannelUtils.TRANSPORT == TransportTechnologyEnum.SOLACE)
        {
            return System.identityHashCode(Runtime.getRuntime()) + (int) System.nanoTime();
        }

        String hostAddress = TcpChannelUtils.LOCALHOST_IP;
        try
        {
            hostAddress = InetAddress.getByName(hostName).getHostAddress();
        }
        catch (UnknownHostException e)
        {
        }
        for (int i = startPortRangeInclusive; i < endPortRangeExclusive; i++)
        {
            try
            {
                Log.log(TcpChannelUtils.class, "Trying ", hostAddress, ":", Integer.toString(i));
                final ServerSocket serverSocket = new ServerSocket();
                serverSocket.bind(new InetSocketAddress(hostAddress, i));
                serverSocket.close();
                // now ensure the server socket is closed before saying we can use it
                try
                {
                    int j = 0;
                    while (j++ < 10)
                    {
                        new Socket(hostAddress, i).close();
                        Thread.sleep(100);
                    }
                }
                catch (Exception e)
                {
                }
                Log.log(TcpChannelUtils.class, "Using ", hostAddress, ":", Integer.toString(i));
                return i;
            }
            catch (IOException e)
            {
                Log.log(TcpChannelUtils.class, e.getMessage());
            }
{'fraction_non_alphanumeric': 0.09511058216800555, 'fraction_numerical': 0.003669542794803134, 'mean_word_length': 2.258158319870759, 'pattern_counts': {'":': 4, '<': 32, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4737125', 'n_tokens_mistral': 2743, 'n_tokens_neox': 2660, 'n_words': 787}