/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you 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 org.jboss.netty.handler.codec.http.multipart; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.handler.codec.http.HttpConstants; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; /** * Abstract Memory HttpData implementation */ public abstract class AbstractMemoryHttpData extends AbstractHttpData { private ChannelBuffer channelBuffer; private int chunkPosition; protected boolean isRenamed; protected AbstractMemoryHttpData(String name, Charset charset, long size) { super(name, charset, size); } public void setContent(ChannelBuffer buffer) throws IOException { if (buffer == null) { throw new NullPointerException("buffer"); } long localsize = buffer.readableBytes(); checkSize(localsize); if (definedSize > 0 && definedSize < localsize) { throw new IOException("Out of size: " + localsize + " > " + definedSize); } channelBuffer = buffer; size = localsize; completed = true; } public void setContent(InputStream inputStream) throws IOException { if (inputStream == null) { throw new NullPointerException("inputStream"); } ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); byte[] bytes = new byte[4096 * 4]; int read = inputStream.read(bytes); int written = 0; while (read > 0) { buffer.writeBytes(bytes, 0, read); written += read; checkSize(written); read = inputStream.read(bytes); } size = written; if (definedSize > 0 && definedSize < size) { throw new IOException("Out of size: " + size + " > " + definedSize); } channelBuffer = buffer; completed = true; } public void addContent(ChannelBuffer buffer, boolean last) throws IOException { if (buffer != null) { long localsize = buffer.readableBytes(); checkSize(size + localsize); if (definedSize > 0 && definedSize < size + localsize) { throw new IOException("Out of size: " + (size + localsize) + " > " + definedSize); } size += localsize; if (channelBuffer == null) { channelBuffer = buffer; } else { channelBuffer = ChannelBuffers.wrappedBuffer( channelBuffer, buffer); } } if (last) { completed = true; } else { if (buffer == null) { throw new NullPointerException("buffer"); } } } public void setContent(File file) throws IOException { if (file == null) { throw new NullPointerException("file"); } long newsize = file.length(); if (newsize > Integer.MAX_VALUE) { throw new IllegalArgumentException( "File too big to be loaded in memory"); } checkSize(newsize); FileInputStream inputStream = new FileInputStream(file); FileChannel fileChannel = inputStream.getChannel(); byte[] array = new byte[(int) newsize]; ByteBuffer byteBuffer = ByteBuffer.wrap(array); int read = 0; while (read < newsize) { read += fileChannel.read(byteBuffer); } fileChannel.close(); inputStream.close(); byteBuffer.flip(); channelBuffer = ChannelBuffers.wrappedBuffer(byteBuffer); size = newsize; completed = true; } public void delete() { // nothing to do } public byte[] get() { if (channelBuffer == null) { return new byte[0]; } byte[] array = new byte[channelBuffer.readableBytes()]; channelBuffer.getBytes(channelBuffer.readerIndex(), array); return array; } public String getString() { return getString(HttpConstants.DEFAULT_CHARSET); } public String getString(Charset encoding) { if (channelBuffer == null) { return ""; } if (encoding == null) { encoding = HttpConstants.DEFAULT_CHARSET; } return channelBuffer.toString(encoding); } /** * Utility to go from a In Memory FileUpload * to a Disk (or another implementation) FileUpload * @return the attached ChannelBuffer containing the actual bytes */ public ChannelBuffer getChannelBuffer() { return channelBuffer; } public ChannelBuffer getChunk(int length) throws IOException { if (channelBuffer == null || length == 0 || channelBuffer.readableBytes() == 0) { chunkPosition = 0; return ChannelBuffers.EMPTY_BUFFER; } int sizeLeft = channelBuffer.readableBytes() - chunkPosition; if (sizeLeft == 0) { chunkPosition = 0; return ChannelBuffers.EMPTY_BUFFER; } int sliceLength = length; if (sizeLeft < length) { sliceLength = sizeLeft; } ChannelBuffer chunk = channelBuffer.slice(chunkPosition, sliceLength); chunkPosition += sliceLength; return chunk; } public boolean isInMemory() { return true; } public boolean renameTo(File dest) throws IOException { if (dest == null) { throw new NullPointerException("dest"); } if (channelBuffer == null) { // empty file dest.createNewFile(); isRenamed = true; return true; } int length = channelBuffer.readableBytes(); FileOutputStream outputStream = new FileOutputStream(dest); FileChannel fileChannel = outputStream.getChannel(); ByteBuffer byteBuffer = channelBuffer.toByteBuffer(); int written = 0; while (written < length) { written += fileChannel.write(byteBuffer); } fileChannel.force(false); fileChannel.close(); outputStream.close(); isRenamed = true; return written == length; } public File getFile() throws IOException { throw new IOException("Not represented by a file"); } }