Utils.java

/*
 * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.jersey.jdk.connector.internal;

import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.Buffer;

/**
 * @author Petr Janouch
 */
public class Utils {

    /**
     * Concatenates two buffers into one. If buffer given as first argument has enough space for putting
     * the other one, it will be done and the original buffer will be returned. Otherwise new buffer will
     * be created.
     *
     * @param buffer  first buffer.
     * @param buffer1 second buffer.
     * @return concatenation.
     */
    static ByteBuffer appendBuffers(ByteBuffer buffer, ByteBuffer buffer1, int incomingBufferSize, int BUFFER_STEP_SIZE) {

        final int limit = ((Buffer) buffer).limit();
        final int capacity = ((Buffer) buffer).capacity();
        final int remaining = ((Buffer) buffer).remaining();
        final int len = ((Buffer) buffer1).remaining();

        // buffer1 will be appended to buffer
        if (len < (capacity - limit)) {

            ((Buffer) buffer).mark();
            ((Buffer) buffer).position(limit);
            ((Buffer) buffer).limit(capacity);
            buffer.put(buffer1);
            ((Buffer) buffer).limit(limit + len);
            ((Buffer) buffer).reset();
            return buffer;
            // Remaining data is moved to left. Then new data is appended
        } else if (remaining + len < capacity) {
            buffer.compact();
            buffer.put(buffer1);
            ((Buffer) buffer).flip();
            return buffer;
            // create new buffer
        } else {
            int newSize = remaining + len;
            if (newSize > incomingBufferSize) {
                throw new IllegalArgumentException("Buffer overflow");
            } else {
                final int roundedSize =
                        (newSize % BUFFER_STEP_SIZE) > 0 ? ((newSize / BUFFER_STEP_SIZE) + 1) * BUFFER_STEP_SIZE : newSize;
                final ByteBuffer result = ByteBuffer.allocate(roundedSize > incomingBufferSize ? newSize : roundedSize);
                result.put(buffer);
                result.put(buffer1);
                ((Buffer) result).flip();
                return result;
            }
        }
    }

    static ByteBuffer split(ByteBuffer buffer, int position) {
        int bytesLength = position - ((Buffer) buffer).position();
        byte[] bytes = new byte[bytesLength];
        buffer.get(bytes);
        return ByteBuffer.wrap(bytes);
    }

    static int getPort(URI uri) {
        if (uri.getPort() != -1) {
            return uri.getPort();
        }

        if ("https".equals(uri.getScheme())) {
            return 443;
        }

        return 80;
    }
}