/*
 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/* @test
   @bug 4526754
 * @summary Test Pipe scattering reads
 */

import java.nio.channels.*;
import java.nio.*;
import java.util.Random;

public class ScatteringRead {

    private static Random generator = new Random();

    public static void main(String[] args) throws Exception {
        scScatter();
    }

    private static void scScatter() throws Exception {
        Pipe p = Pipe.open();
        Pipe.SinkChannel sink = p.sink();
        Pipe.SourceChannel source = p.source();
        sink.configureBlocking(false);

        ByteBuffer outgoingdata = ByteBuffer.allocateDirect(30);
        byte[] someBytes = new byte[30];
        generator.nextBytes(someBytes);
        outgoingdata.put(someBytes);
        outgoingdata.flip();

        int totalWritten = 0;
        while (totalWritten < 30) {
            int written = sink.write(outgoingdata);
            if (written < 0)
                throw new Exception("Write failed");
            totalWritten += written;
        }

        ByteBuffer[] bufs = new ByteBuffer[3];
        for(int i=0; i<3; i++)
            bufs[i] = ByteBuffer.allocateDirect(10);
        long numBytesRead = source.read(bufs);
        if (numBytesRead < 30)
            throw new Exception("Pipe test failed");
        sink.close();
        source.close();
    }

}
