/* * Copyright 2012 McEvoy Software Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program 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 for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * This file is part of Picasa Photo Uploader. * * Picasa Photo Uploader is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Picasa Photo Uploader 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 for more details. * * You should have received a copy of the GNU General Public License * along with Picasa Photo Uploader. If not, see <http://www.gnu.org/licenses/>. */ package com.ettrema.android.photouploader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import org.apache.http.protocol.HTTP; import org.apache.http.util.ByteArrayBuffer; /** * Class to create MultiPart related body for use in uploading to Picasa * * @author Jan Peter Hooiveld */ public class Multipart { /** * The name of the file being uploaded */ private final String name; /** * Defines the boundary used in the body for each part */ private String boundary; /** * Buffer that holds the content */ private ByteArrayBuffer buffer = new ByteArrayBuffer( 0 ); /** * Line ending */ private static final String CR_LF = "\r\n"; /** * Dashes for the boundary */ private static final String DASHES = "--"; /** * Constructor * * @param description Description of the body contents * @param boundary Defines the boundary used in the body for each part * @throws UnsupportedEncodingException */ public Multipart( String name, String boundary ) throws UnsupportedEncodingException { this.name = name; this.boundary = CR_LF + DASHES + boundary; } /** * Returns the boundary * * @return Boundary */ public String getBoundary() { return boundary.substring( 4 ); } /** * Adds new file to the body * * @param file File object * @param contentType File content type * @throws UnsupportedEncodingException * @throws FileNotFoundException * @throws IOException */ public void addPart( File file, String contentType ) throws UnsupportedEncodingException, FileNotFoundException, IOException { // merge start into content String disp = "form-data; name=\"name\"; filename=\"" + name + "\""; mergePart( boundary + CR_LF ); mergePart( addHeader( "Content-Disposition", disp ) ); mergePart( addHeader( "Content-Type", contentType ) ); mergePart( CR_LF ); // create vars to reas file InputStream is = new FileInputStream( file ); byte[] bytes = new byte[(int) file.length()]; int offset = 0; int numRead = 0; // reaf file into byte array while( offset < bytes.length && ( numRead = is.read( bytes, offset, bytes.length - offset ) ) >= 0 ) { offset += numRead; } // errror checking if( offset < bytes.length ) { throw new IOException( "Could not completely read file " + file.getName() ); } // close input stream is.close(); // merge the file into content mergePart( bytes ); } /** * Accumulate body content and return it * * @return Body content * @throws UnsupportedEncodingException */ public byte[] getContent() throws UnsupportedEncodingException { // create new byte array buffer and get start and end as byte arrays ByteArrayBuffer endBuffer = new ByteArrayBuffer( 0 ); byte[] start = buffer.toByteArray(); byte[] end = ( boundary + DASHES ).getBytes( HTTP.DEFAULT_CONTENT_CHARSET ); // append the start and end to new byte array buffer endBuffer.append( start, 0, start.length ); endBuffer.append( end, 0, end.length ); // return buffer as content return endBuffer.toByteArray(); } /** * Creates start of a part * * @param contentType Content type of the part * @return Start of a part */ private String addHeader( String headerName, String contentType ) { return headerName + ": " + contentType + CR_LF; } /** * Merge content data from part * * @param input Part data to merge into content * @throws UnsupportedEncodingException */ private void mergePart( Object input ) throws UnsupportedEncodingException { byte[] bytes = null; if( input instanceof String ) { bytes = ( (String) input ).getBytes( HTTP.DEFAULT_CONTENT_CHARSET ); } else if( input instanceof byte[] ) { bytes = (byte[]) input; } if( bytes != null ) { buffer.append( bytes, 0, bytes.length ); } } }