| 1 | package org.docx4j.utils; |
|---|
| 2 | |
|---|
| 3 | import java.io.BufferedInputStream; |
|---|
| 4 | import java.io.BufferedOutputStream; |
|---|
| 5 | import java.io.ByteArrayOutputStream; |
|---|
| 6 | import java.io.IOException; |
|---|
| 7 | import java.io.InputStream; |
|---|
| 8 | import java.net.MalformedURLException; |
|---|
| 9 | import java.net.URL; |
|---|
| 10 | import java.net.URLConnection; |
|---|
| 11 | import java.nio.ByteBuffer; |
|---|
| 12 | import java.nio.ByteOrder; |
|---|
| 13 | import java.nio.channels.Channels; |
|---|
| 14 | import java.nio.channels.ReadableByteChannel; |
|---|
| 15 | import java.util.Iterator; |
|---|
| 16 | import java.util.LinkedList; |
|---|
| 17 | import java.util.List; |
|---|
| 18 | |
|---|
| 19 | import org.apache.log4j.Logger; |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | public class BufferUtil { |
|---|
| 23 | |
|---|
| 24 | private static Logger log = Logger.getLogger(BufferUtil.class); |
|---|
| 25 | |
|---|
| 26 | |
|---|
| 27 | private static final int BUFFER_SIZE = 1024; |
|---|
| 28 | |
|---|
| 29 | /** |
|---|
| 30 | * Fully reads the given InputStream, returning its contents as a ByteBuffer |
|---|
| 31 | * |
|---|
| 32 | * @param in an <code>InputStream</code> value |
|---|
| 33 | * @return a <code>ByteBuffer</code> value |
|---|
| 34 | * @exception IOException if an error occurs |
|---|
| 35 | */ |
|---|
| 36 | public static ByteBuffer readInputStream(InputStream in) throws IOException { |
|---|
| 37 | /** |
|---|
| 38 | * Some useful methods for reading URLs or streams and returning the data as Direct Buffers |
|---|
| 39 | * |
|---|
| 40 | * @author Ivan Z. Ganza |
|---|
| 41 | * @author Robert Schuster |
|---|
| 42 | * @author Bart LEBOEUF |
|---|
| 43 | * |
|---|
| 44 | * Originally from com.lilly.chorus.eSignatures.utils.BufferUtil |
|---|
| 45 | */ |
|---|
| 46 | |
|---|
| 47 | /* |
|---|
| 48 | * Converts the InputStream into a channels which allows us to read into |
|---|
| 49 | * a ByteBuffer. |
|---|
| 50 | */ |
|---|
| 51 | ReadableByteChannel ch = Channels.newChannel(in); |
|---|
| 52 | |
|---|
| 53 | // Creates a list that stores the intermediate buffers. |
|---|
| 54 | List list = new LinkedList(); |
|---|
| 55 | |
|---|
| 56 | // A variable storing the accumulated size of the data. |
|---|
| 57 | int sum = 0, read = 0; |
|---|
| 58 | |
|---|
| 59 | /* |
|---|
| 60 | * Reads all the bytes from the channel and stores them in various |
|---|
| 61 | * buffer objects. |
|---|
| 62 | */ |
|---|
| 63 | do { |
|---|
| 64 | ByteBuffer b = createByteBuffer(BUFFER_SIZE); |
|---|
| 65 | read = ch.read(b); |
|---|
| 66 | |
|---|
| 67 | if (read > 0) { |
|---|
| 68 | b.flip(); // make ready for reading later |
|---|
| 69 | list.add(b); |
|---|
| 70 | sum += read; |
|---|
| 71 | } |
|---|
| 72 | } while (read != -1); |
|---|
| 73 | |
|---|
| 74 | /* |
|---|
| 75 | * If there is only one buffer used we do not need to merge the data. |
|---|
| 76 | */ |
|---|
| 77 | if (list.size() == 1) { |
|---|
| 78 | return (ByteBuffer) list.get(0); |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | ByteBuffer bb = createByteBuffer(sum); |
|---|
| 82 | |
|---|
| 83 | /* Merges all buffers into the Buffer bb */ |
|---|
| 84 | Iterator ite = list.iterator(); |
|---|
| 85 | while (ite.hasNext()) { |
|---|
| 86 | bb.put((ByteBuffer) ite.next()); |
|---|
| 87 | } |
|---|
| 88 | |
|---|
| 89 | list.clear(); |
|---|
| 90 | |
|---|
| 91 | return bb; |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | |
|---|
| 95 | public static ByteBuffer createByteBuffer(int capacity) { |
|---|
| 96 | return ByteBuffer.allocateDirect(capacity).order(ByteOrder.nativeOrder()); |
|---|
| 97 | } |
|---|
| 98 | |
|---|
| 99 | /** |
|---|
| 100 | * Returns an input stream for a ByteBuffer. |
|---|
| 101 | * The read() methods use the relative ByteBuffer get() methods. |
|---|
| 102 | */ |
|---|
| 103 | public static InputStream newInputStream(final ByteBuffer buf) |
|---|
| 104 | { |
|---|
| 105 | |
|---|
| 106 | // From http://docs.jboss.org/jbossas/javadoc/4.0.2/org/jboss/media/util/ByteBufferUtils.java.html |
|---|
| 107 | |
|---|
| 108 | // Not working properly? Make sure any method being called is implemented |
|---|
| 109 | |
|---|
| 110 | return new InputStream() |
|---|
| 111 | { |
|---|
| 112 | public synchronized int read() throws IOException |
|---|
| 113 | { |
|---|
| 114 | if (!buf.hasRemaining()) |
|---|
| 115 | { |
|---|
| 116 | log.debug("done"); |
|---|
| 117 | return -1; |
|---|
| 118 | } |
|---|
| 119 | log.debug("#"); |
|---|
| 120 | return buf.get(); |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | public synchronized int read(byte[] bytes) throws IOException |
|---|
| 124 | { |
|---|
| 125 | if (!buf.hasRemaining()) |
|---|
| 126 | { |
|---|
| 127 | log.debug("done"); |
|---|
| 128 | return -1; |
|---|
| 129 | } |
|---|
| 130 | log.debug("#"); |
|---|
| 131 | |
|---|
| 132 | int len = Math.min(bytes.length, buf.remaining()); |
|---|
| 133 | buf.get(bytes, 0, len ); |
|---|
| 134 | return len; |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | public synchronized int read(byte[] bytes, int off, int len) |
|---|
| 138 | throws IOException |
|---|
| 139 | { |
|---|
| 140 | // Read only what's left |
|---|
| 141 | len = Math.min(len, buf.remaining()); |
|---|
| 142 | buf.get(bytes, off, len); |
|---|
| 143 | return len; |
|---|
| 144 | } |
|---|
| 145 | }; |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | public static byte[] getBytesFromInputStream(InputStream is) |
|---|
| 149 | throws IOException { |
|---|
| 150 | |
|---|
| 151 | BufferedInputStream bufIn = new BufferedInputStream(is); |
|---|
| 152 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
|---|
| 153 | BufferedOutputStream bos = new BufferedOutputStream(baos); |
|---|
| 154 | int c = bufIn.read(); |
|---|
| 155 | while (c != -1) { |
|---|
| 156 | bos.write(c); |
|---|
| 157 | c = bufIn.read(); |
|---|
| 158 | } |
|---|
| 159 | bos.flush(); |
|---|
| 160 | baos.flush(); |
|---|
| 161 | bufIn.close(); |
|---|
| 162 | bos.close(); |
|---|
| 163 | return baos.toByteArray(); |
|---|
| 164 | } |
|---|
| 165 | |
|---|
| 166 | |
|---|
| 167 | } |
|---|