/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * 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 *******************************************************************************/ package org.ebayopensource.turmeric.runtime.common.utils; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.CharBuffer; import java.nio.DoubleBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; import java.nio.ShortBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** * Some usefull methods for reading URLs or streams and returning the data as * Direct Buffers. * * @author Ivan Z. Ganza * @author Robert Schuster * @author Bart LEBOEUF */ public class BufferUtil { // byte 8 bits // short 16 bits // int 32 bits // long 64 bits // char 16 bits // float 32 bits // double 64 bits private static final int BUFFER_SIZE = 1024; /** * Tries to open the given URL, get its input stream, returns the data in a * <I><B>direct</B></I> ByteBuffer. * * @param url * an <code>URL</code> value * @return a <code>ByteBuffer</code> value with the contacts of the data * present at URL * @exception IOException * if an error occurs * @exception MalformedURLException * if an error occurs */ public static ByteBuffer readURL(URL url) throws IOException, MalformedURLException { URLConnection connection = null; try { connection = url.openConnection(); return readInputStream(new BufferedInputStream(connection .getInputStream())); } catch (IOException e) { throw e; } } /** * Fully reads the given InputStream, returning its contents as a ByteBuffer. * * @param in * an <code>InputStream</code> value * @return a <code>ByteBuffer</code> value * @exception IOException * if an error occurs */ public static ByteBuffer readInputStream(InputStream in) throws IOException { /* * Converts the InputStream into a channels which allows us to read into * a ByteBuffer. */ ReadableByteChannel ch = Channels.newChannel(in); // Creates a list that stores the intermediate buffers. List<ByteBuffer> list = new LinkedList<ByteBuffer>(); // A variable storing the accumulated size of the data. int sum = 0, read = 0; /* * Reads all the bytes from the channel and stores them in various * buffer objects. */ do { ByteBuffer b = createByteBuffer(BUFFER_SIZE); read = ch.read(b); if (read > 0) { b.flip(); // make ready for reading later list.add(b); sum += read; } } while (read != -1); ByteBuffer bb = createByteBuffer(sum); /* Merges all buffers into the Buffer bb */ Iterator<ByteBuffer> ite = list.iterator(); while (ite.hasNext()) { bb.put(ite.next()); } list.clear(); return bb; } /** * Create direct(?) native type buffers. * @param capacity initial capacity * @return newly created byte buffer */ public static ByteBuffer createByteBuffer(int capacity) { // direct byte buffer would have been efficient, but // the client code uses ByteBuffer.array() without calling hasArray() //return ByteBuffer.allocateDirect(capacity).order(ByteOrder.nativeOrder()); return ByteBuffer.allocate(capacity).order(ByteOrder.nativeOrder()); } /** * Create direct(?) native type buffers. * @param values initial values to be copied to the buffer * @return newly created byte buffer */ public static ByteBuffer createByteBuffer(byte[] values) { return createByteBuffer(values.length).put(values); } /** * Create direct(?) native type buffers. * @param capacity initial capacity * @return newly created float buffer */ public static FloatBuffer createFloatBuffer(int capacity) { return createByteBuffer(capacity * 4).asFloatBuffer(); } /** * Create direct(?) native type buffers. * @param values initial values to be copied to the buffer * @return newly created float buffer */ public static FloatBuffer createFloatBuffer(float[] values) { return createFloatBuffer(values.length).put(values); } /** * Create direct(?) native type buffers. * @param capacity initial capacity * @return newly created integer buffer */ public static IntBuffer createIntBuffer(int capacity) { return createByteBuffer(capacity * 4).asIntBuffer(); } /** * Create direct(?) native type buffers. * @param values initial values to be copied to the buffer * @return newly created integer buffer */ public static IntBuffer createIntBuffer(int[] values) { return createIntBuffer(values.length).put(values); } /** * Create direct(?) native type buffers. * @param capacity initial capacity * @return newly created double buffer */ public static DoubleBuffer createDoubleBuffer(int capacity) { return createByteBuffer(capacity * 8).asDoubleBuffer(); } /** * Create direct(?) native type buffers. * @param values initial values to be copied to the buffer * @return newly created double buffer */ public static DoubleBuffer createDoubleBuffer(double[] values) { return createDoubleBuffer(values.length).put(values); } /** * Create direct(?) native type buffers. * @param capacity initial capacity * @return newly created long buffer */ public static LongBuffer createLongBuffer(int capacity) { return createByteBuffer(capacity * 8).asLongBuffer(); } /** * Create direct(?) native type buffers. * @param values initial values to be copied to the buffer * @return newly created long buffer */ public static LongBuffer createLongBuffer(long[] values) { return createLongBuffer(values.length).put(values); } /** * Create direct(?) native type buffers. * @param capacity initial capacity * @return newly created short buffer */ public static ShortBuffer createShortBuffer(int capacity) { return createByteBuffer(capacity * 2).asShortBuffer(); } /** * Create direct(?) native type buffers. * @param values initial values to be copied to the buffer * @return newly created short buffer */ public static ShortBuffer createShortBuffer(short[] values) { return createShortBuffer(values.length).put(values); } /** * Create direct(?) native type buffers. * @param capacity initial capacity * @return newly created character buffer */ public static CharBuffer createCharBuffer(int capacity) { return createByteBuffer(capacity * 2).asCharBuffer(); } /** * Create direct(?) native type buffers. * @param values initial values to be copied to the buffer * @return newly created capacity buffer */ public static CharBuffer createCharBuffer(char[] values) { return createCharBuffer(values.length).put(values); } }