一、前言
关于apache的commons-fileupload包中org.apache.commons.fileupload.ParameterParser参数解析类、org.apache.commons.fileupload.util.mime.MimeUtility媒体类型工具类。
二、源码说明
1.ParameterParser
package org.apache.commons.fileupload;@b@@b@import java.io.UnsupportedEncodingException;@b@import java.util.HashMap;@b@import java.util.Locale;@b@import java.util.Map;@b@import org.apache.commons.fileupload.util.mime.MimeUtility;@b@@b@public class ParameterParser@b@{@b@ private char[] chars = null;@b@@b@ private int pos = 0;@b@@b@ private int len = 0;@b@@b@ private int i1 = 0;@b@@b@ private int i2 = 0;@b@@b@ private boolean lowerCaseNames = false;@b@@b@ private boolean hasChar()@b@ {@b@ return (this.pos < this.len);@b@ }@b@@b@ private String getToken(boolean quoted)@b@ {@b@ while ((this.i1 < this.i2) && (Character.isWhitespace(this.chars[this.i1]))) {@b@ this.i1 += 1;@b@ }@b@@b@ while ((this.i2 > this.i1) && (Character.isWhitespace(this.chars[(this.i2 - 1)]))) {@b@ this.i2 -= 1;@b@ }@b@@b@ if ((quoted) && (this.i2 - this.i1 >= 2) && (this.chars[this.i1] == '"') && (this.chars[(this.i2 - 1)] == '"'))@b@ {@b@ this.i1 += 1;@b@ this.i2 -= 1;@b@ }@b@ String result = null;@b@ if (this.i2 > this.i1) {@b@ result = new String(this.chars, this.i1, this.i2 - this.i1);@b@ }@b@ return result;@b@ }@b@@b@ private boolean isOneOf(char ch, char[] charray)@b@ {@b@ boolean result = false;@b@ for (char element : charray) {@b@ if (ch == element) {@b@ result = true;@b@ break;@b@ }@b@ }@b@ return result;@b@ }@b@@b@ private String parseToken(char[] terminators)@b@ {@b@ this.i1 = this.pos;@b@ this.i2 = this.pos;@b@ while (hasChar()) {@b@ char ch = this.chars[this.pos];@b@ if (isOneOf(ch, terminators)) {@b@ break;@b@ }@b@ this.i2 += 1;@b@ this.pos += 1;@b@ }@b@ return getToken(false);@b@ }@b@@b@ private String parseQuotedToken(char[] terminators)@b@ {@b@ this.i1 = this.pos;@b@ this.i2 = this.pos;@b@ boolean quoted = false;@b@ boolean charEscaped = false;@b@ while (hasChar()) {@b@ char ch = this.chars[this.pos];@b@ if ((!(quoted)) && (isOneOf(ch, terminators))) {@b@ break;@b@ }@b@ if ((!(charEscaped)) && (ch == '"')) {@b@ quoted = !(quoted);@b@ }@b@ charEscaped = (!(charEscaped)) && (ch == '\\');@b@ this.i2 += 1;@b@ this.pos += 1;@b@ }@b@@b@ return getToken(true);@b@ }@b@@b@ public boolean isLowerCaseNames()@b@ {@b@ return this.lowerCaseNames;@b@ }@b@@b@ public void setLowerCaseNames(boolean b)@b@ {@b@ this.lowerCaseNames = b;@b@ }@b@@b@ public Map<String, String> parse(String str, char[] separators)@b@ {@b@ if ((separators == null) || (separators.length == 0)) {@b@ return new HashMap();@b@ }@b@ char separator = separators[0];@b@ if (str != null) {@b@ int idx = str.length();@b@ for (char separator2 : separators) {@b@ int tmp = str.indexOf(separator2);@b@ if ((tmp != -1) && (tmp < idx)) {@b@ idx = tmp;@b@ separator = separator2;@b@ }@b@ }@b@ }@b@ return parse(str, separator);@b@ }@b@@b@ public Map<String, String> parse(String str, char separator)@b@ {@b@ if (str == null) {@b@ return new HashMap();@b@ }@b@ return parse(str.toCharArray(), separator);@b@ }@b@@b@ public Map<String, String> parse(char[] charArray, char separator)@b@ {@b@ if (charArray == null) {@b@ return new HashMap();@b@ }@b@ return parse(charArray, 0, charArray.length, separator);@b@ }@b@@b@ public Map<String, String> parse(char[] charArray, int offset, int length, char separator)@b@ {@b@ if (charArray == null) {@b@ return new HashMap();@b@ }@b@ HashMap params = new HashMap();@b@ this.chars = charArray;@b@ this.pos = offset;@b@ this.len = length;@b@@b@ String paramName = null;@b@ String paramValue = null;@b@ while (hasChar()) {@b@ paramName = parseToken(new char[] { '=', separator });@b@@b@ paramValue = null;@b@ if ((hasChar()) && (charArray[this.pos] == '=')) {@b@ this.pos += 1;@b@ paramValue = parseQuotedToken(new char[] { separator });@b@@b@ if (paramValue != null)@b@ try {@b@ paramValue = MimeUtility.decodeText(paramValue);@b@ }@b@ catch (UnsupportedEncodingException e)@b@ {@b@ }@b@ }@b@ if ((hasChar()) && (charArray[this.pos] == separator)) {@b@ this.pos += 1;@b@ }@b@ if ((paramName != null) && (paramName.length() > 0));@b@ if (this.lowerCaseNames) {@b@ paramName = paramName.toLowerCase(Locale.ENGLISH);@b@ }@b@@b@ params.put(paramName, paramValue);@b@ }@b@@b@ return params;@b@ }@b@}
2.MimeUtility
package org.apache.commons.fileupload.util.mime;@b@@b@import java.io.ByteArrayOutputStream;@b@import java.io.IOException;@b@import java.io.UnsupportedEncodingException;@b@import java.util.HashMap;@b@import java.util.Locale;@b@import java.util.Map;@b@@b@public final class MimeUtility@b@{@b@ private static final String US_ASCII_CHARSET = "US-ASCII";@b@ private static final String BASE64_ENCODING_MARKER = "B";@b@ private static final String QUOTEDPRINTABLE_ENCODING_MARKER = "Q";@b@ private static final String ENCODED_TOKEN_MARKER = "=?";@b@ private static final String ENCODED_TOKEN_FINISHER = "?=";@b@ private static final String LINEAR_WHITESPACE = " \t\r\n";@b@ private static final Map<String, String> MIME2JAVA = new HashMap();@b@@b@ public static String decodeText(String text)@b@ throws UnsupportedEncodingException@b@ {@b@ if (text.indexOf("=?") < 0) {@b@ return text;@b@ }@b@@b@ int offset = 0;@b@ int endOffset = text.length();@b@@b@ int startWhiteSpace = -1;@b@ int endWhiteSpace = -1;@b@@b@ StringBuilder decodedText = new StringBuilder(text.length());@b@@b@ boolean previousTokenEncoded = false;@b@@b@ while (offset < endOffset) {@b@ char ch = text.charAt(offset);@b@@b@ if (" \t\r\n".indexOf(ch) != -1) {@b@ startWhiteSpace = offset;@b@ while (true) { if (offset >= endOffset)@b@ break label229;@b@ ch = text.charAt(offset);@b@ if (" \t\r\n".indexOf(ch) == -1) break;@b@ ++offset;@b@ }@b@@b@ label229: endWhiteSpace = offset;@b@ }@b@ else@b@ {@b@ int wordStart = offset;@b@@b@ while (offset < endOffset)@b@ {@b@ ch = text.charAt(offset);@b@ if (" \t\r\n".indexOf(ch) != -1) break;@b@ ++offset;@b@ }@b@@b@ String word = text.substring(wordStart, offset);@b@@b@ if (word.startsWith("=?"));@b@ try@b@ {@b@ String decodedWord = decodeWord(word);@b@@b@ if ((!(previousTokenEncoded)) && (startWhiteSpace != -1)) {@b@ decodedText.append(text.substring(startWhiteSpace, endWhiteSpace));@b@ startWhiteSpace = -1;@b@ }@b@@b@ previousTokenEncoded = true;@b@@b@ decodedText.append(decodedWord);@b@ }@b@ catch (ParseException e)@b@ {@b@ if (startWhiteSpace != -1) {@b@ decodedText.append(text.substring(startWhiteSpace, endWhiteSpace));@b@ startWhiteSpace = -1;@b@ }@b@@b@ previousTokenEncoded = false;@b@ decodedText.append(word);@b@ }@b@ }@b@ }@b@ return decodedText.toString();@b@ }@b@@b@ private static String decodeWord(String word)@b@ throws ParseException, UnsupportedEncodingException@b@ {@b@ if (!(word.startsWith("=?"))) {@b@ throw new ParseException("Invalid RFC 2047 encoded-word: " + word);@b@ }@b@@b@ int charsetPos = word.indexOf(63, 2);@b@ if (charsetPos == -1) {@b@ throw new ParseException("Missing charset in RFC 2047 encoded-word: " + word);@b@ }@b@@b@ String charset = word.substring(2, charsetPos).toLowerCase();@b@@b@ int encodingPos = word.indexOf(63, charsetPos + 1);@b@ if (encodingPos == -1) {@b@ throw new ParseException("Missing encoding in RFC 2047 encoded-word: " + word);@b@ }@b@@b@ String encoding = word.substring(charsetPos + 1, encodingPos);@b@@b@ int encodedTextPos = word.indexOf("?=", encodingPos + 1);@b@ if (encodedTextPos == -1) {@b@ throw new ParseException("Missing encoded text in RFC 2047 encoded-word: " + word);@b@ }@b@@b@ String encodedText = word.substring(encodingPos + 1, encodedTextPos);@b@@b@ if (encodedText.length() == 0) {@b@ return "";@b@ }@b@@b@ try@b@ {@b@ ByteArrayOutputStream out = new ByteArrayOutputStream(encodedText.length());@b@@b@ byte[] encodedData = encodedText.getBytes("US-ASCII");@b@@b@ if (encoding.equals("B"))@b@ Base64Decoder.decode(encodedData, out);@b@ else if (encoding.equals("Q"))@b@ QuotedPrintableDecoder.decode(encodedData, out);@b@ else {@b@ throw new UnsupportedEncodingException("Unknown RFC 2047 encoding: " + encoding);@b@ }@b@@b@ byte[] decodedData = out.toByteArray();@b@ return new String(decodedData, javaCharset(charset));@b@ } catch (IOException e) {@b@ throw new UnsupportedEncodingException("Invalid RFC 2047 encoding");@b@ }@b@ }@b@@b@ private static String javaCharset(String charset)@b@ {@b@ if (charset == null) {@b@ return null;@b@ }@b@@b@ String mappedCharset = (String)MIME2JAVA.get(charset.toLowerCase(Locale.ENGLISH));@b@@b@ if (mappedCharset == null) {@b@ return charset;@b@ }@b@ return mappedCharset;@b@ }@b@@b@ static@b@ {@b@ MIME2JAVA.put("iso-2022-cn", "ISO2022CN");@b@ MIME2JAVA.put("iso-2022-kr", "ISO2022KR");@b@ MIME2JAVA.put("utf-8", "UTF8");@b@ MIME2JAVA.put("utf8", "UTF8");@b@ MIME2JAVA.put("ja_jp.iso2022-7", "ISO2022JP");@b@ MIME2JAVA.put("ja_jp.eucjp", "EUCJIS");@b@ MIME2JAVA.put("euc-kr", "KSC5601");@b@ MIME2JAVA.put("euckr", "KSC5601");@b@ MIME2JAVA.put("us-ascii", "ISO-8859-1");@b@ MIME2JAVA.put("x-us-ascii", "ISO-8859-1");@b@ }@b@}