/**
* This source code belongs to Moon Zang, the author. To use it for
* commercial/business purpose, please contact DeepNightTwo@gmail.com
*
* @author Moon Zang
*
*/
package picturefarm.image.util;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
public class FormDataExtractor {
private static byte[] NEW_LINE = new byte[] { '\r', '\n' };
private static char FORM_END = '-';
private static final String CONTENT_TYPE_SEP = "Content-Type: ";
private String boundary = null;
private byte[] data;
private int current;
private Map<String, String> formAttributes = new HashMap<String, String>();
public Map<String, String> getFormAttributes() {
return formAttributes;
}
public List<FormImage> getFormImageData() {
return formImageData;
}
public void setFormImageData(List<FormImage> formImageData) {
this.formImageData = formImageData;
}
private List<FormImage> formImageData = new ArrayList<FormImage>();
public FormDataExtractor(HttpServletRequest req) throws IOException {
int len = req.getContentLength();
data = new byte[len];
ServletInputStream sis = req.getInputStream();
loadAllData(sis, data);
current = 0;
}
private void loadAllData(ServletInputStream sis, byte[] data)
throws IOException {
int loaded = 0;
int all = data.length;
while (loaded != all) {
int read = sis.read(data, loaded, all - loaded);
loaded += read;
}
}
public void extractFormData() {
boundary = readLine();
while (true) {
String line1 = readLine();
String line2 = readLine();
if (line2.length() == 0) {
addFormAttributeData(line1);
} else {
formImageData.add(getFormImageData(line1, line2));
}
if (!filterBoundary()) {
return;
}
}
}
private void addFormAttributeData(String contentLine) {
char separator = '\"';
int s1 = contentLine.indexOf(separator, 0);
int s2 = contentLine.indexOf(separator, s1 + 1);
String name = contentLine.substring(s1 + 1, s2);
formAttributes.put(name, readLine());
}
private FormImage getFormImageData(String contentLine,
String contentTypeLine) {
readLine();
char separator = '\"';
int s1 = contentLine.indexOf(separator, 0);
int s2 = contentLine.indexOf(separator, s1 + 1);
int s3 = contentLine.indexOf(separator, s2 + 1);
int s4 = contentLine.indexOf(separator, s3 + 1);
String name = contentLine.substring(s1 + 1, s2);
String fileName = contentLine.substring(s3 + 1, s4);
byte[] bouChas = ("\r\n" + boundary).getBytes();
int start = current;
boolean matched = false;
while (!matched) {
for (int i = 0; i < bouChas.length; i++) {
if (data[current + i] != bouChas[i]) {
break;
}
if (i == bouChas.length - 1) {
matched = true;
break;
}
}
current++;
}
int end = current - 1;
// skip the \r\n, keep the same status with read line.
current++;
String contentType = contentTypeLine.substring(CONTENT_TYPE_SEP
.length());
FormImage image = new FormImage();
image.setAttributeName(name);
image.setFileName(fileName);
image.setContentType(contentType);
image.setStart(start);
image.setEnd(end);
image.setData(data);
return image;
}
private String readLine() {
StringBuffer sb = new StringBuffer();
char ch1 = (char) data[current];
current++;
char ch2 = (char) data[current];
current++;
while (true) {
if (ch1 == NEW_LINE[0] && ch2 == NEW_LINE[1]) {
break;
}
sb.append(ch1);
ch1 = ch2;
ch2 = (char) data[current];
current++;
}
return sb.toString();
}
private boolean filterBoundary() {
current += boundary.length();
if (data[current] == FORM_END && data[current + 1] == FORM_END) {
// reach the end of form data
return false;
} else {
// filter \r\n
current += 2;
return true;
}
}
}