From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- .../thirdparty/org/json/simple/ItemList.java | 147 +++ .../thirdparty/org/json/simple/JSONArray.java | 107 ++ .../thirdparty/org/json/simple/JSONAware.java | 12 + .../thirdparty/org/json/simple/JSONObject.java | 129 +++ .../org/json/simple/JSONStreamAware.java | 15 + .../thirdparty/org/json/simple/JSONValue.java | 272 +++++ .../android/thirdparty/org/json/simple/LICENSE.txt | 202 ++++ .../org/json/simple/parser/ContainerFactory.java | 23 + .../org/json/simple/parser/ContentHandler.java | 110 ++ .../org/json/simple/parser/JSONParser.java | 533 ++++++++++ .../org/json/simple/parser/ParseException.java | 96 ++ .../thirdparty/org/json/simple/parser/Yylex.java | 688 ++++++++++++ .../thirdparty/org/json/simple/parser/Yytoken.java | 58 + .../thirdparty/org/lucasr/dspec/DesignSpec.java | 645 ++++++++++++ .../thirdparty/org/lucasr/dspec/RawResource.java | 60 ++ .../apache/commons/codec/BinaryDecoder.java | 43 + .../apache/commons/codec/BinaryEncoder.java | 43 + .../mozilla/apache/commons/codec/CharEncoding.java | 127 +++ .../org/mozilla/apache/commons/codec/Decoder.java | 56 + .../apache/commons/codec/DecoderException.java | 90 ++ .../org/mozilla/apache/commons/codec/Encoder.java | 47 + .../apache/commons/codec/EncoderException.java | 91 ++ .../apache/commons/codec/StringDecoder.java | 41 + .../apache/commons/codec/StringEncoder.java | 41 + .../commons/codec/StringEncoderComparator.java | 87 ++ .../apache/commons/codec/binary/Base32.java | 471 +++++++++ .../commons/codec/binary/Base32InputStream.java | 85 ++ .../commons/codec/binary/Base32OutputStream.java | 85 ++ .../apache/commons/codec/binary/Base64.java | 756 +++++++++++++ .../commons/codec/binary/Base64InputStream.java | 89 ++ .../commons/codec/binary/Base64OutputStream.java | 89 ++ .../apache/commons/codec/binary/BaseNCodec.java | 445 ++++++++ .../codec/binary/BaseNCodecInputStream.java | 132 +++ .../codec/binary/BaseNCodecOutputStream.java | 142 +++ .../apache/commons/codec/binary/BinaryCodec.java | 297 ++++++ .../mozilla/apache/commons/codec/binary/Hex.java | 302 ++++++ .../apache/commons/codec/binary/StringUtils.java | 287 +++++ .../apache/commons/codec/binary/package.html | 21 + .../apache/commons/codec/digest/DigestUtils.java | 583 +++++++++++ .../apache/commons/codec/digest/package.html | 21 + .../commons/codec/language/AbstractCaverphone.java | 78 ++ .../apache/commons/codec/language/Caverphone.java | 104 ++ .../apache/commons/codec/language/Caverphone1.java | 126 +++ .../apache/commons/codec/language/Caverphone2.java | 129 +++ .../commons/codec/language/ColognePhonetic.java | 417 ++++++++ .../commons/codec/language/DoubleMetaphone.java | 1106 ++++++++++++++++++++ .../apache/commons/codec/language/Metaphone.java | 408 ++++++++ .../commons/codec/language/RefinedSoundex.java | 203 ++++ .../apache/commons/codec/language/Soundex.java | 279 +++++ .../commons/codec/language/SoundexUtils.java | 124 +++ .../apache/commons/codec/language/package.html | 21 + .../mozilla/apache/commons/codec/net/BCodec.java | 209 ++++ .../mozilla/apache/commons/codec/net/QCodec.java | 312 ++++++ .../commons/codec/net/QuotedPrintableCodec.java | 388 +++++++ .../apache/commons/codec/net/RFC1522Codec.java | 179 ++++ .../mozilla/apache/commons/codec/net/URLCodec.java | 362 +++++++ .../mozilla/apache/commons/codec/net/Utils.java | 50 + .../mozilla/apache/commons/codec/net/package.html | 23 + .../org/mozilla/apache/commons/codec/overview.html | 29 + .../org/mozilla/apache/commons/codec/package.html | 100 ++ 60 files changed, 12215 insertions(+) create mode 100644 mobile/android/thirdparty/org/json/simple/ItemList.java create mode 100644 mobile/android/thirdparty/org/json/simple/JSONArray.java create mode 100644 mobile/android/thirdparty/org/json/simple/JSONAware.java create mode 100644 mobile/android/thirdparty/org/json/simple/JSONObject.java create mode 100644 mobile/android/thirdparty/org/json/simple/JSONStreamAware.java create mode 100644 mobile/android/thirdparty/org/json/simple/JSONValue.java create mode 100644 mobile/android/thirdparty/org/json/simple/LICENSE.txt create mode 100644 mobile/android/thirdparty/org/json/simple/parser/ContainerFactory.java create mode 100644 mobile/android/thirdparty/org/json/simple/parser/ContentHandler.java create mode 100644 mobile/android/thirdparty/org/json/simple/parser/JSONParser.java create mode 100644 mobile/android/thirdparty/org/json/simple/parser/ParseException.java create mode 100644 mobile/android/thirdparty/org/json/simple/parser/Yylex.java create mode 100644 mobile/android/thirdparty/org/json/simple/parser/Yytoken.java create mode 100644 mobile/android/thirdparty/org/lucasr/dspec/DesignSpec.java create mode 100644 mobile/android/thirdparty/org/lucasr/dspec/RawResource.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/BinaryDecoder.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/BinaryEncoder.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/CharEncoding.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/Decoder.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/DecoderException.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/Encoder.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/EncoderException.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringDecoder.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringEncoder.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringEncoderComparator.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32InputStream.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32OutputStream.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64InputStream.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64OutputStream.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodec.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodecInputStream.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodecOutputStream.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BinaryCodec.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Hex.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/StringUtils.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/package.html create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/digest/DigestUtils.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/digest/package.html create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/AbstractCaverphone.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone1.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone2.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/ColognePhonetic.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/DoubleMetaphone.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Metaphone.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/RefinedSoundex.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Soundex.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/SoundexUtils.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/package.html create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/BCodec.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/QCodec.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/QuotedPrintableCodec.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/RFC1522Codec.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/URLCodec.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/Utils.java create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/package.html create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/overview.html create mode 100644 mobile/android/thirdparty/org/mozilla/apache/commons/codec/package.html (limited to 'mobile/android/thirdparty/org') diff --git a/mobile/android/thirdparty/org/json/simple/ItemList.java b/mobile/android/thirdparty/org/json/simple/ItemList.java new file mode 100644 index 000000000..07231e673 --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/ItemList.java @@ -0,0 +1,147 @@ +/* + * $Id: ItemList.java,v 1.1 2006/04/15 14:10:48 platform Exp $ + * Created on 2006-3-24 + */ +package org.json.simple; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +/** + * |a:b:c| => |a|,|b|,|c| + * |:| => ||,|| + * |a:| => |a|,|| + * @author FangYidong + */ +public class ItemList { + private String sp=","; + List items=new ArrayList(); + + + public ItemList(){} + + + public ItemList(String s){ + this.split(s,sp,items); + } + + public ItemList(String s,String sp){ + this.sp=s; + this.split(s,sp,items); + } + + public ItemList(String s,String sp,boolean isMultiToken){ + split(s,sp,items,isMultiToken); + } + + public List getItems(){ + return this.items; + } + + public String[] getArray(){ + return (String[])this.items.toArray(); + } + + public void split(String s,String sp,List append,boolean isMultiToken){ + if(s==null || sp==null) + return; + if(isMultiToken){ + StringTokenizer tokens=new StringTokenizer(s,sp); + while(tokens.hasMoreTokens()){ + append.add(tokens.nextToken().trim()); + } + } + else{ + this.split(s,sp,append); + } + } + + public void split(String s,String sp,List append){ + if(s==null || sp==null) + return; + int pos=0; + int prevPos=0; + do{ + prevPos=pos; + pos=s.indexOf(sp,pos); + if(pos==-1) + break; + append.add(s.substring(prevPos,pos).trim()); + pos+=sp.length(); + }while(pos!=-1); + append.add(s.substring(prevPos).trim()); + } + + public void setSP(String sp){ + this.sp=sp; + } + + public void add(int i,String item){ + if(item==null) + return; + items.add(i,item.trim()); + } + + public void add(String item){ + if(item==null) + return; + items.add(item.trim()); + } + + public void addAll(ItemList list){ + items.addAll(list.items); + } + + public void addAll(String s){ + this.split(s,sp,items); + } + + public void addAll(String s,String sp){ + this.split(s,sp,items); + } + + public void addAll(String s,String sp,boolean isMultiToken){ + this.split(s,sp,items,isMultiToken); + } + + /** + * @param i 0-based + * @return + */ + public String get(int i){ + return (String)items.get(i); + } + + public int size(){ + return items.size(); + } + + public String toString(){ + return toString(sp); + } + + public String toString(String sp){ + StringBuffer sb=new StringBuffer(); + + for(int i=0;i + */ +public class JSONArray extends ArrayList implements List, JSONAware, JSONStreamAware { + private static final long serialVersionUID = 3957988303675231981L; + + /** + * Encode a list into JSON text and write it to out. + * If this list is also a JSONStreamAware or a JSONAware, JSONStreamAware and JSONAware specific behaviours will be ignored at this top level. + * + * @see org.json.simple.JSONValue#writeJSONString(Object, Writer) + * + * @param list + * @param out + */ + public static void writeJSONString(List list, Writer out) throws IOException{ + if(list == null){ + out.write("null"); + return; + } + + boolean first = true; + Iterator iter=list.iterator(); + + out.write('['); + while(iter.hasNext()){ + if(first) + first = false; + else + out.write(','); + + Object value=iter.next(); + if(value == null){ + out.write("null"); + continue; + } + + JSONValue.writeJSONString(value, out); + } + out.write(']'); + } + + public void writeJSONString(Writer out) throws IOException{ + writeJSONString(this, out); + } + + /** + * Convert a list to JSON text. The result is a JSON array. + * If this list is also a JSONAware, JSONAware specific behaviours will be omitted at this top level. + * + * @see org.json.simple.JSONValue#toJSONString(Object) + * + * @param list + * @return JSON text, or "null" if list is null. + */ + public static String toJSONString(List list){ + if(list == null) + return "null"; + + boolean first = true; + StringBuffer sb = new StringBuffer(); + Iterator iter=list.iterator(); + + sb.append('['); + while(iter.hasNext()){ + if(first) + first = false; + else + sb.append(','); + + Object value=iter.next(); + if(value == null){ + sb.append("null"); + continue; + } + sb.append(JSONValue.toJSONString(value)); + } + sb.append(']'); + return sb.toString(); + } + + public String toJSONString(){ + return toJSONString(this); + } + + public String toString() { + return toJSONString(); + } + + + +} diff --git a/mobile/android/thirdparty/org/json/simple/JSONAware.java b/mobile/android/thirdparty/org/json/simple/JSONAware.java new file mode 100644 index 000000000..89f152510 --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/JSONAware.java @@ -0,0 +1,12 @@ +package org.json.simple; + +/** + * Beans that support customized output of JSON text shall implement this interface. + * @author FangYidong + */ +public interface JSONAware { + /** + * @return JSON text + */ + String toJSONString(); +} diff --git a/mobile/android/thirdparty/org/json/simple/JSONObject.java b/mobile/android/thirdparty/org/json/simple/JSONObject.java new file mode 100644 index 000000000..d4401e114 --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/JSONObject.java @@ -0,0 +1,129 @@ +/* + * $Id: JSONObject.java,v 1.1 2006/04/15 14:10:48 platform Exp $ + * Created on 2006-4-10 + */ +package org.json.simple; + +import java.io.IOException; +import java.io.Writer; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * A JSON object. Key value pairs are unordered. JSONObject supports java.util.Map interface. + * + * @author FangYidong + */ +public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware{ + private static final long serialVersionUID = -503443796854799292L; + + /** + * Encode a map into JSON text and write it to out. + * If this map is also a JSONAware or JSONStreamAware, JSONAware or JSONStreamAware specific behaviours will be ignored at this top level. + * + * @see org.json.simple.JSONValue#writeJSONString(Object, Writer) + * + * @param map + * @param out + */ + public static void writeJSONString(Map map, Writer out) throws IOException { + if(map == null){ + out.write("null"); + return; + } + + boolean first = true; + Iterator iter=map.entrySet().iterator(); + + out.write('{'); + while(iter.hasNext()){ + if(first) + first = false; + else + out.write(','); + Map.Entry entry=(Map.Entry)iter.next(); + out.write('\"'); + out.write(escape(String.valueOf(entry.getKey()))); + out.write('\"'); + out.write(':'); + JSONValue.writeJSONString(entry.getValue(), out); + } + out.write('}'); + } + + public void writeJSONString(Writer out) throws IOException{ + writeJSONString(this, out); + } + + /** + * Convert a map to JSON text. The result is a JSON object. + * If this map is also a JSONAware, JSONAware specific behaviours will be omitted at this top level. + * + * @see org.json.simple.JSONValue#toJSONString(Object) + * + * @param map + * @return JSON text, or "null" if map is null. + */ + public static String toJSONString(Map map){ + if(map == null) + return "null"; + + StringBuffer sb = new StringBuffer(); + boolean first = true; + Iterator iter=map.entrySet().iterator(); + + sb.append('{'); + while(iter.hasNext()){ + if(first) + first = false; + else + sb.append(','); + + Map.Entry entry=(Map.Entry)iter.next(); + toJSONString(String.valueOf(entry.getKey()),entry.getValue(), sb); + } + sb.append('}'); + return sb.toString(); + } + + public String toJSONString(){ + return toJSONString(this); + } + + private static String toJSONString(String key,Object value, StringBuffer sb){ + sb.append('\"'); + if(key == null) + sb.append("null"); + else + JSONValue.escape(key, sb); + sb.append('\"').append(':'); + + sb.append(JSONValue.toJSONString(value)); + + return sb.toString(); + } + + public String toString(){ + return toJSONString(); + } + + public static String toString(String key,Object value){ + StringBuffer sb = new StringBuffer(); + toJSONString(key, value, sb); + return sb.toString(); + } + + /** + * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F). + * It's the same as JSONValue.escape() only for compatibility here. + * + * @see org.json.simple.JSONValue#escape(String) + * + * @param s + * @return + */ + public static String escape(String s){ + return JSONValue.escape(s); + } +} diff --git a/mobile/android/thirdparty/org/json/simple/JSONStreamAware.java b/mobile/android/thirdparty/org/json/simple/JSONStreamAware.java new file mode 100644 index 000000000..c2287c459 --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/JSONStreamAware.java @@ -0,0 +1,15 @@ +package org.json.simple; + +import java.io.IOException; +import java.io.Writer; + +/** + * Beans that support customized output of JSON text to a writer shall implement this interface. + * @author FangYidong + */ +public interface JSONStreamAware { + /** + * write JSON string to out. + */ + void writeJSONString(Writer out) throws IOException; +} diff --git a/mobile/android/thirdparty/org/json/simple/JSONValue.java b/mobile/android/thirdparty/org/json/simple/JSONValue.java new file mode 100644 index 000000000..aba3c40c2 --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/JSONValue.java @@ -0,0 +1,272 @@ +/* + * $Id: JSONValue.java,v 1.1 2006/04/15 14:37:04 platform Exp $ + * Created on 2006-4-15 + */ +package org.json.simple; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; +import java.util.List; +import java.util.Map; + +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + + +/** + * @author FangYidong + */ +public class JSONValue { + /** + * Parse JSON text into java object from the input source. + * Please use parseWithException() if you don't want to ignore the exception. + * + * @see org.json.simple.parser.JSONParser#parse(Reader) + * @see #parseWithException(Reader) + * + * @param in + * @return Instance of the following: + * org.json.simple.JSONObject, + * org.json.simple.JSONArray, + * java.lang.String, + * java.lang.Number, + * java.lang.Boolean, + * null + * + */ + public static Object parse(Reader in){ + try{ + JSONParser parser=new JSONParser(); + return parser.parse(in); + } + catch(Exception e){ + return null; + } + } + + public static Object parse(String s){ + StringReader in=new StringReader(s); + return parse(in); + } + + /** + * Parse JSON text into java object from the input source. + * + * @see org.json.simple.parser.JSONParser + * + * @param in + * @return Instance of the following: + * org.json.simple.JSONObject, + * org.json.simple.JSONArray, + * java.lang.String, + * java.lang.Number, + * java.lang.Boolean, + * null + * + * @throws IOException + * @throws ParseException + */ + public static Object parseWithException(Reader in) throws IOException, ParseException{ + JSONParser parser=new JSONParser(); + return parser.parse(in); + } + + public static Object parseWithException(String s) throws ParseException{ + JSONParser parser=new JSONParser(); + return parser.parse(s); + } + + /** + * Encode an object into JSON text and write it to out. + *

+ * If this object is a Map or a List, and it's also a JSONStreamAware or a JSONAware, JSONStreamAware or JSONAware will be considered firstly. + *

+ * DO NOT call this method from writeJSONString(Writer) of a class that implements both JSONStreamAware and (Map or List) with + * "this" as the first parameter, use JSONObject.writeJSONString(Map, Writer) or JSONArray.writeJSONString(List, Writer) instead. + * + * @see org.json.simple.JSONObject#writeJSONString(Map, Writer) + * @see org.json.simple.JSONArray#writeJSONString(List, Writer) + * + * @param value + * @param writer + */ + public static void writeJSONString(Object value, Writer out) throws IOException { + if(value == null){ + out.write("null"); + return; + } + + if(value instanceof String){ + out.write('\"'); + out.write(escape((String)value)); + out.write('\"'); + return; + } + + if(value instanceof Double){ + if(((Double)value).isInfinite() || ((Double)value).isNaN()) + out.write("null"); + else + out.write(value.toString()); + return; + } + + if(value instanceof Float){ + if(((Float)value).isInfinite() || ((Float)value).isNaN()) + out.write("null"); + else + out.write(value.toString()); + return; + } + + if(value instanceof Number){ + out.write(value.toString()); + return; + } + + if(value instanceof Boolean){ + out.write(value.toString()); + return; + } + + if((value instanceof JSONStreamAware)){ + ((JSONStreamAware)value).writeJSONString(out); + return; + } + + if((value instanceof JSONAware)){ + out.write(((JSONAware)value).toJSONString()); + return; + } + + if(value instanceof Map){ + JSONObject.writeJSONString((Map)value, out); + return; + } + + if(value instanceof List){ + JSONArray.writeJSONString((List)value, out); + return; + } + + out.write(value.toString()); + } + + /** + * Convert an object to JSON text. + *

+ * If this object is a Map or a List, and it's also a JSONAware, JSONAware will be considered firstly. + *

+ * DO NOT call this method from toJSONString() of a class that implements both JSONAware and Map or List with + * "this" as the parameter, use JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead. + * + * @see org.json.simple.JSONObject#toJSONString(Map) + * @see org.json.simple.JSONArray#toJSONString(List) + * + * @param value + * @return JSON text, or "null" if value is null or it's an NaN or an INF number. + */ + public static String toJSONString(Object value){ + if(value == null) + return "null"; + + if(value instanceof String) + return "\""+escape((String)value)+"\""; + + if(value instanceof Double){ + if(((Double)value).isInfinite() || ((Double)value).isNaN()) + return "null"; + else + return value.toString(); + } + + if(value instanceof Float){ + if(((Float)value).isInfinite() || ((Float)value).isNaN()) + return "null"; + else + return value.toString(); + } + + if(value instanceof Number) + return value.toString(); + + if(value instanceof Boolean) + return value.toString(); + + if((value instanceof JSONAware)) + return ((JSONAware)value).toJSONString(); + + if(value instanceof Map) + return JSONObject.toJSONString((Map)value); + + if(value instanceof List) + return JSONArray.toJSONString((List)value); + + return value.toString(); + } + + /** + * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F). + * @param s + * @return + */ + public static String escape(String s){ + if(s==null) + return null; + StringBuffer sb = new StringBuffer(); + escape(s, sb); + return sb.toString(); + } + + /** + * @param s - Must not be null. + * @param sb + */ + static void escape(String s, StringBuffer sb) { + for(int i=0;i='\u0000' && ch<='\u001F') || (ch>='\u007F' && ch<='\u009F') || (ch>='\u2000' && ch<='\u20FF')){ + String ss=Integer.toHexString(ch); + sb.append("\\u"); + for(int k=0;k<4-ss.length();k++){ + sb.append('0'); + } + sb.append(ss.toUpperCase()); + } + else{ + sb.append(ch); + } + } + }//for + } + +} diff --git a/mobile/android/thirdparty/org/json/simple/LICENSE.txt b/mobile/android/thirdparty/org/json/simple/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/mobile/android/thirdparty/org/json/simple/parser/ContainerFactory.java b/mobile/android/thirdparty/org/json/simple/parser/ContainerFactory.java new file mode 100644 index 000000000..366ac4dea --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/parser/ContainerFactory.java @@ -0,0 +1,23 @@ +package org.json.simple.parser; + +import java.util.List; +import java.util.Map; + +/** + * Container factory for creating containers for JSON object and JSON array. + * + * @see org.json.simple.parser.JSONParser#parse(java.io.Reader, ContainerFactory) + * + * @author FangYidong + */ +public interface ContainerFactory { + /** + * @return A Map instance to store JSON object, or null if you want to use org.json.simple.JSONObject. + */ + Map createObjectContainer(); + + /** + * @return A List instance to store JSON array, or null if you want to use org.json.simple.JSONArray. + */ + List creatArrayContainer(); +} diff --git a/mobile/android/thirdparty/org/json/simple/parser/ContentHandler.java b/mobile/android/thirdparty/org/json/simple/parser/ContentHandler.java new file mode 100644 index 000000000..ae8d06557 --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/parser/ContentHandler.java @@ -0,0 +1,110 @@ +package org.json.simple.parser; + +import java.io.IOException; + +/** + * A simplified and stoppable SAX-like content handler for stream processing of JSON text. + * + * @see org.xml.sax.ContentHandler + * @see org.json.simple.parser.JSONParser#parse(java.io.Reader, ContentHandler, boolean) + * + * @author FangYidong + */ +public interface ContentHandler { + /** + * Receive notification of the beginning of JSON processing. + * The parser will invoke this method only once. + * + * @throws ParseException + * - JSONParser will stop and throw the same exception to the caller when receiving this exception. + */ + void startJSON() throws ParseException, IOException; + + /** + * Receive notification of the end of JSON processing. + * + * @throws ParseException + */ + void endJSON() throws ParseException, IOException; + + /** + * Receive notification of the beginning of a JSON object. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * - JSONParser will stop and throw the same exception to the caller when receiving this exception. + * @see #endJSON + */ + boolean startObject() throws ParseException, IOException; + + /** + * Receive notification of the end of a JSON object. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #startObject + */ + boolean endObject() throws ParseException, IOException; + + /** + * Receive notification of the beginning of a JSON object entry. + * + * @param key - Key of a JSON object entry. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #endObjectEntry + */ + boolean startObjectEntry(String key) throws ParseException, IOException; + + /** + * Receive notification of the end of the value of previous object entry. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #startObjectEntry + */ + boolean endObjectEntry() throws ParseException, IOException; + + /** + * Receive notification of the beginning of a JSON array. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #endArray + */ + boolean startArray() throws ParseException, IOException; + + /** + * Receive notification of the end of a JSON array. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #startArray + */ + boolean endArray() throws ParseException, IOException; + + /** + * Receive notification of the JSON primitive values: + * java.lang.String, + * java.lang.Number, + * java.lang.Boolean + * null + * + * @param value - Instance of the following: + * java.lang.String, + * java.lang.Number, + * java.lang.Boolean + * null + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + */ + boolean primitive(Object value) throws ParseException, IOException; + +} diff --git a/mobile/android/thirdparty/org/json/simple/parser/JSONParser.java b/mobile/android/thirdparty/org/json/simple/parser/JSONParser.java new file mode 100644 index 000000000..9acaa377f --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/parser/JSONParser.java @@ -0,0 +1,533 @@ +/* + * $Id: JSONParser.java,v 1.1 2006/04/15 14:10:48 platform Exp $ + * Created on 2006-4-15 + */ +package org.json.simple.parser; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + + +/** + * Parser for JSON text. Please note that JSONParser is NOT thread-safe. + * + * @author FangYidong + */ +public class JSONParser { + public static final int S_INIT=0; + public static final int S_IN_FINISHED_VALUE=1;//string,number,boolean,null,object,array + public static final int S_IN_OBJECT=2; + public static final int S_IN_ARRAY=3; + public static final int S_PASSED_PAIR_KEY=4; + public static final int S_IN_PAIR_VALUE=5; + public static final int S_END=6; + public static final int S_IN_ERROR=-1; + + private LinkedList handlerStatusStack; + private Yylex lexer = new Yylex((Reader)null); + private Yytoken token = null; + private int status = S_INIT; + + private int peekStatus(LinkedList statusStack){ + if(statusStack.size()==0) + return -1; + Integer status=(Integer)statusStack.getFirst(); + return status.intValue(); + } + + /** + * Reset the parser to the initial state without resetting the underlying reader. + * + */ + public void reset(){ + token = null; + status = S_INIT; + handlerStatusStack = null; + } + + /** + * Reset the parser to the initial state with a new character reader. + * + * @param in - The new character reader. + * @throws IOException + * @throws ParseException + */ + public void reset(Reader in){ + lexer.yyreset(in); + reset(); + } + + /** + * @return The position of the beginning of the current token. + */ + public int getPosition(){ + return lexer.getPosition(); + } + + public Object parse(String s) throws ParseException{ + return parse(s, (ContainerFactory)null); + } + + public Object parse(String s, ContainerFactory containerFactory) throws ParseException{ + StringReader in=new StringReader(s); + try{ + return parse(in, containerFactory); + } + catch(IOException ie){ + /* + * Actually it will never happen. + */ + throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie); + } + } + + public Object parse(Reader in) throws IOException, ParseException{ + return parse(in, (ContainerFactory)null); + } + + /** + * Parse JSON text into java object from the input source. + * + * @param in + * @param containerFactory - Use this factory to createyour own JSON object and JSON array containers. + * @return Instance of the following: + * org.json.simple.JSONObject, + * org.json.simple.JSONArray, + * java.lang.String, + * java.lang.Number, + * java.lang.Boolean, + * null + * + * @throws IOException + * @throws ParseException + */ + public Object parse(Reader in, ContainerFactory containerFactory) throws IOException, ParseException{ + reset(in); + LinkedList statusStack = new LinkedList(); + LinkedList valueStack = new LinkedList(); + + try{ + do{ + nextToken(); + switch(status){ + case S_INIT: + switch(token.type){ + case Yytoken.TYPE_VALUE: + status=S_IN_FINISHED_VALUE; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(token.value); + break; + case Yytoken.TYPE_LEFT_BRACE: + status=S_IN_OBJECT; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(createObjectContainer(containerFactory)); + break; + case Yytoken.TYPE_LEFT_SQUARE: + status=S_IN_ARRAY; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(createArrayContainer(containerFactory)); + break; + default: + status=S_IN_ERROR; + }//inner switch + break; + + case S_IN_FINISHED_VALUE: + if(token.type==Yytoken.TYPE_EOF) + return valueStack.removeFirst(); + else + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); + + case S_IN_OBJECT: + switch(token.type){ + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + if(token.value instanceof String){ + String key=(String)token.value; + valueStack.addFirst(key); + status=S_PASSED_PAIR_KEY; + statusStack.addFirst(new Integer(status)); + } + else{ + status=S_IN_ERROR; + } + break; + case Yytoken.TYPE_RIGHT_BRACE: + if(valueStack.size()>1){ + statusStack.removeFirst(); + valueStack.removeFirst(); + status=peekStatus(statusStack); + } + else{ + status=S_IN_FINISHED_VALUE; + } + break; + default: + status=S_IN_ERROR; + break; + }//inner switch + break; + + case S_PASSED_PAIR_KEY: + switch(token.type){ + case Yytoken.TYPE_COLON: + break; + case Yytoken.TYPE_VALUE: + statusStack.removeFirst(); + String key=(String)valueStack.removeFirst(); + Map parent=(Map)valueStack.getFirst(); + parent.put(key,token.value); + status=peekStatus(statusStack); + break; + case Yytoken.TYPE_LEFT_SQUARE: + statusStack.removeFirst(); + key=(String)valueStack.removeFirst(); + parent=(Map)valueStack.getFirst(); + List newArray=createArrayContainer(containerFactory); + parent.put(key,newArray); + status=S_IN_ARRAY; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(newArray); + break; + case Yytoken.TYPE_LEFT_BRACE: + statusStack.removeFirst(); + key=(String)valueStack.removeFirst(); + parent=(Map)valueStack.getFirst(); + Map newObject=createObjectContainer(containerFactory); + parent.put(key,newObject); + status=S_IN_OBJECT; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(newObject); + break; + default: + status=S_IN_ERROR; + } + break; + + case S_IN_ARRAY: + switch(token.type){ + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + List val=(List)valueStack.getFirst(); + val.add(token.value); + break; + case Yytoken.TYPE_RIGHT_SQUARE: + if(valueStack.size()>1){ + statusStack.removeFirst(); + valueStack.removeFirst(); + status=peekStatus(statusStack); + } + else{ + status=S_IN_FINISHED_VALUE; + } + break; + case Yytoken.TYPE_LEFT_BRACE: + val=(List)valueStack.getFirst(); + Map newObject=createObjectContainer(containerFactory); + val.add(newObject); + status=S_IN_OBJECT; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(newObject); + break; + case Yytoken.TYPE_LEFT_SQUARE: + val=(List)valueStack.getFirst(); + List newArray=createArrayContainer(containerFactory); + val.add(newArray); + status=S_IN_ARRAY; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(newArray); + break; + default: + status=S_IN_ERROR; + }//inner switch + break; + case S_IN_ERROR: + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); + }//switch + if(status==S_IN_ERROR){ + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); + } + }while(token.type!=Yytoken.TYPE_EOF); + } + catch(IOException ie){ + throw ie; + } + + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); + } + + private void nextToken() throws ParseException, IOException{ + token = lexer.yylex(); + if(token == null) + token = new Yytoken(Yytoken.TYPE_EOF, null); + } + + private Map createObjectContainer(ContainerFactory containerFactory){ + if(containerFactory == null) + return new JSONObject(); + Map m = containerFactory.createObjectContainer(); + + if(m == null) + return new JSONObject(); + return m; + } + + private List createArrayContainer(ContainerFactory containerFactory){ + if(containerFactory == null) + return new JSONArray(); + List l = containerFactory.creatArrayContainer(); + + if(l == null) + return new JSONArray(); + return l; + } + + public void parse(String s, ContentHandler contentHandler) throws ParseException{ + parse(s, contentHandler, false); + } + + public void parse(String s, ContentHandler contentHandler, boolean isResume) throws ParseException{ + StringReader in=new StringReader(s); + try{ + parse(in, contentHandler, isResume); + } + catch(IOException ie){ + /* + * Actually it will never happen. + */ + throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie); + } + } + + public void parse(Reader in, ContentHandler contentHandler) throws IOException, ParseException{ + parse(in, contentHandler, false); + } + + /** + * Stream processing of JSON text. + * + * @see ContentHandler + * + * @param in + * @param contentHandler + * @param isResume - Indicates if it continues previous parsing operation. + * If set to true, resume parsing the old stream, and parameter 'in' will be ignored. + * If this method is called for the first time in this instance, isResume will be ignored. + * + * @throws IOException + * @throws ParseException + */ + public void parse(Reader in, ContentHandler contentHandler, boolean isResume) throws IOException, ParseException{ + if(!isResume){ + reset(in); + handlerStatusStack = new LinkedList(); + } + else{ + if(handlerStatusStack == null){ + isResume = false; + reset(in); + handlerStatusStack = new LinkedList(); + } + } + + LinkedList statusStack = handlerStatusStack; + + try{ + do{ + switch(status){ + case S_INIT: + contentHandler.startJSON(); + nextToken(); + switch(token.type){ + case Yytoken.TYPE_VALUE: + status=S_IN_FINISHED_VALUE; + statusStack.addFirst(new Integer(status)); + if(!contentHandler.primitive(token.value)) + return; + break; + case Yytoken.TYPE_LEFT_BRACE: + status=S_IN_OBJECT; + statusStack.addFirst(new Integer(status)); + if(!contentHandler.startObject()) + return; + break; + case Yytoken.TYPE_LEFT_SQUARE: + status=S_IN_ARRAY; + statusStack.addFirst(new Integer(status)); + if(!contentHandler.startArray()) + return; + break; + default: + status=S_IN_ERROR; + }//inner switch + break; + + case S_IN_FINISHED_VALUE: + nextToken(); + if(token.type==Yytoken.TYPE_EOF){ + contentHandler.endJSON(); + status = S_END; + return; + } + else{ + status = S_IN_ERROR; + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); + } + + case S_IN_OBJECT: + nextToken(); + switch(token.type){ + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + if(token.value instanceof String){ + String key=(String)token.value; + status=S_PASSED_PAIR_KEY; + statusStack.addFirst(new Integer(status)); + if(!contentHandler.startObjectEntry(key)) + return; + } + else{ + status=S_IN_ERROR; + } + break; + case Yytoken.TYPE_RIGHT_BRACE: + if(statusStack.size()>1){ + statusStack.removeFirst(); + status=peekStatus(statusStack); + } + else{ + status=S_IN_FINISHED_VALUE; + } + if(!contentHandler.endObject()) + return; + break; + default: + status=S_IN_ERROR; + break; + }//inner switch + break; + + case S_PASSED_PAIR_KEY: + nextToken(); + switch(token.type){ + case Yytoken.TYPE_COLON: + break; + case Yytoken.TYPE_VALUE: + statusStack.removeFirst(); + status=peekStatus(statusStack); + if(!contentHandler.primitive(token.value)) + return; + if(!contentHandler.endObjectEntry()) + return; + break; + case Yytoken.TYPE_LEFT_SQUARE: + statusStack.removeFirst(); + statusStack.addFirst(new Integer(S_IN_PAIR_VALUE)); + status=S_IN_ARRAY; + statusStack.addFirst(new Integer(status)); + if(!contentHandler.startArray()) + return; + break; + case Yytoken.TYPE_LEFT_BRACE: + statusStack.removeFirst(); + statusStack.addFirst(new Integer(S_IN_PAIR_VALUE)); + status=S_IN_OBJECT; + statusStack.addFirst(new Integer(status)); + if(!contentHandler.startObject()) + return; + break; + default: + status=S_IN_ERROR; + } + break; + + case S_IN_PAIR_VALUE: + /* + * S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token, + * therefore delay consuming token until next round. + */ + statusStack.removeFirst(); + status = peekStatus(statusStack); + if(!contentHandler.endObjectEntry()) + return; + break; + + case S_IN_ARRAY: + nextToken(); + switch(token.type){ + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + if(!contentHandler.primitive(token.value)) + return; + break; + case Yytoken.TYPE_RIGHT_SQUARE: + if(statusStack.size()>1){ + statusStack.removeFirst(); + status=peekStatus(statusStack); + } + else{ + status=S_IN_FINISHED_VALUE; + } + if(!contentHandler.endArray()) + return; + break; + case Yytoken.TYPE_LEFT_BRACE: + status=S_IN_OBJECT; + statusStack.addFirst(new Integer(status)); + if(!contentHandler.startObject()) + return; + break; + case Yytoken.TYPE_LEFT_SQUARE: + status=S_IN_ARRAY; + statusStack.addFirst(new Integer(status)); + if(!contentHandler.startArray()) + return; + break; + default: + status=S_IN_ERROR; + }//inner switch + break; + + case S_END: + return; + + case S_IN_ERROR: + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); + }//switch + if(status==S_IN_ERROR){ + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); + } + }while(token.type!=Yytoken.TYPE_EOF); + } + catch(IOException ie){ + status = S_IN_ERROR; + throw ie; + } + catch(ParseException pe){ + status = S_IN_ERROR; + throw pe; + } + catch(RuntimeException re){ + status = S_IN_ERROR; + throw re; + } + catch(Error e){ + status = S_IN_ERROR; + throw e; + } + + status = S_IN_ERROR; + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); + } +} diff --git a/mobile/android/thirdparty/org/json/simple/parser/ParseException.java b/mobile/android/thirdparty/org/json/simple/parser/ParseException.java new file mode 100644 index 000000000..a5a5407f9 --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/parser/ParseException.java @@ -0,0 +1,96 @@ +package org.json.simple.parser; + +/** + * ParseException explains why and where the error occurs in source JSON text. + * + * @author FangYidong + * + */ +public class ParseException extends Exception { + private static final long serialVersionUID = -7880698968187728548L; + + public static final int ERROR_UNEXPECTED_CHAR = 0; + public static final int ERROR_UNEXPECTED_TOKEN = 1; + public static final int ERROR_UNEXPECTED_EXCEPTION = 2; + + private int errorType; + private Object unexpectedObject; + private int position; + + public ParseException(int errorType, Throwable throwable) { + this(-1, errorType, null, throwable); + } + + public ParseException(int errorType, Object unexpectedObject) { + this(-1, errorType, unexpectedObject); + } + + public ParseException(int position, int errorType, Object unexpectedObject) { + this(-1, errorType, unexpectedObject, null); + } + + public ParseException(int position, int errorType, Object unexpectedObject, Throwable throwable) { + super(throwable); + this.position = position; + this.errorType = errorType; + this.unexpectedObject = unexpectedObject; + } + + public int getErrorType() { + return errorType; + } + + public void setErrorType(int errorType) { + this.errorType = errorType; + } + + /** + * @see org.json.simple.parser.JSONParser#getPosition() + * + * @return The character position (starting with 0) of the input where the error occurs. + */ + public int getPosition() { + return position; + } + + public void setPosition(int position) { + this.position = position; + } + + /** + * @see org.json.simple.parser.Yytoken + * + * @return One of the following base on the value of errorType: + * ERROR_UNEXPECTED_CHAR java.lang.Character + * ERROR_UNEXPECTED_TOKEN org.json.simple.parser.Yytoken + * ERROR_UNEXPECTED_EXCEPTION java.lang.Exception + */ + public Object getUnexpectedObject() { + return unexpectedObject; + } + + public void setUnexpectedObject(Object unexpectedObject) { + this.unexpectedObject = unexpectedObject; + } + + @Override + public String toString(){ + StringBuffer sb = new StringBuffer(); + + switch(errorType){ + case ERROR_UNEXPECTED_CHAR: + sb.append("Unexpected character (").append(unexpectedObject).append(") at position ").append(position).append("."); + break; + case ERROR_UNEXPECTED_TOKEN: + sb.append("Unexpected token ").append(unexpectedObject).append(" at position ").append(position).append("."); + break; + case ERROR_UNEXPECTED_EXCEPTION: + sb.append("Unexpected exception at position ").append(position).append(": ").append(unexpectedObject); + break; + default: + sb.append("Unkown error at position ").append(position).append("."); + break; + } + return sb.toString(); + } +} diff --git a/mobile/android/thirdparty/org/json/simple/parser/Yylex.java b/mobile/android/thirdparty/org/json/simple/parser/Yylex.java new file mode 100644 index 000000000..42ce508eb --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/parser/Yylex.java @@ -0,0 +1,688 @@ +/* The following code was generated by JFlex 1.4.2 */ + +package org.json.simple.parser; + +class Yylex { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int YYINITIAL = 0; + public static final int STRING_BEGIN = 2; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1 + }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\11\0\1\7\1\7\2\0\1\7\22\0\1\7\1\0\1\11\10\0"+ + "\1\6\1\31\1\2\1\4\1\12\12\3\1\32\6\0\4\1\1\5"+ + "\1\1\24\0\1\27\1\10\1\30\3\0\1\22\1\13\2\1\1\21"+ + "\1\14\5\0\1\23\1\0\1\15\3\0\1\16\1\24\1\17\1\20"+ + "\5\0\1\25\1\0\1\26\uff82\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\2\0\2\1\1\2\1\3\1\4\3\1\1\5\1\6"+ + "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\5\0"+ + "\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24"+ + "\1\0\1\25\1\0\1\25\4\0\1\26\1\27\2\0"+ + "\1\30"; + + private static int [] zzUnpackAction() { + int [] result = new int[45]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\33\0\66\0\121\0\154\0\207\0\66\0\242"+ + "\0\275\0\330\0\66\0\66\0\66\0\66\0\66\0\66"+ + "\0\363\0\u010e\0\66\0\u0129\0\u0144\0\u015f\0\u017a\0\u0195"+ + "\0\66\0\66\0\66\0\66\0\66\0\66\0\66\0\66"+ + "\0\u01b0\0\u01cb\0\u01e6\0\u01e6\0\u0201\0\u021c\0\u0237\0\u0252"+ + "\0\66\0\66\0\u026d\0\u0288\0\66"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[45]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int ZZ_TRANS [] = { + 2, 2, 3, 4, 2, 2, 2, 5, 2, 6, + 2, 2, 7, 8, 2, 9, 2, 2, 2, 2, + 2, 10, 11, 12, 13, 14, 15, 16, 16, 16, + 16, 16, 16, 16, 16, 17, 18, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4, 19, 20, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 23, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 16, 16, 16, 16, 16, 16, 16, + 16, -1, -1, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + -1, -1, -1, -1, -1, -1, -1, -1, 24, 25, + 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 34, 35, -1, -1, + 34, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 37, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 38, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 39, -1, 39, -1, 39, -1, -1, + -1, -1, -1, 39, 39, -1, -1, -1, -1, 39, + 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 33, -1, 20, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 38, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 42, -1, 42, -1, 42, + -1, -1, -1, -1, -1, 42, 42, -1, -1, -1, + -1, 42, 42, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 43, -1, 43, -1, 43, -1, -1, -1, + -1, -1, 43, 43, -1, -1, -1, -1, 43, 43, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, + -1, 44, -1, 44, -1, -1, -1, -1, -1, 44, + 44, -1, -1, -1, -1, 44, 44, -1, -1, -1, + -1, -1, -1, -1, -1, + }; + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\2\0\1\11\3\1\1\11\3\1\6\11\2\1\1\11"+ + "\5\0\10\11\1\0\1\1\1\0\1\1\4\0\2\11"+ + "\2\0\1\11"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[45]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /* user code: */ +private StringBuffer sb=new StringBuffer(); + +int getPosition(){ + return yychar; +} + + + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ + Yylex(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + Yylex(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 90) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead > 0) { + zzEndRead+= numRead; + return false; + } + // unlikely but not impossible: read 0 characters, but not at end of stream + if (numRead == 0) { + int c = zzReader.read(); + if (c == -1) { + return true; + } else { + zzBuffer[zzEndRead++] = (char) c; + return false; + } + } + + // numRead < 0 + return true; + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public Yytoken yylex() throws java.io.IOException, ParseException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + yychar+= zzMarkedPosL-zzStartRead; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 11: + { sb.append(yytext()); + } + case 25: break; + case 4: + { sb.delete(0, sb.length());yybegin(STRING_BEGIN); + } + case 26: break; + case 16: + { sb.append('\b'); + } + case 27: break; + case 6: + { return new Yytoken(Yytoken.TYPE_RIGHT_BRACE,null); + } + case 28: break; + case 23: + { Boolean val=Boolean.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE, val); + } + case 29: break; + case 22: + { return new Yytoken(Yytoken.TYPE_VALUE, null); + } + case 30: break; + case 13: + { yybegin(YYINITIAL);return new Yytoken(Yytoken.TYPE_VALUE, sb.toString()); + } + case 31: break; + case 12: + { sb.append('\\'); + } + case 32: break; + case 21: + { Double val=Double.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE, val); + } + case 33: break; + case 1: + { throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_CHAR, new Character(yycharat(0))); + } + case 34: break; + case 8: + { return new Yytoken(Yytoken.TYPE_RIGHT_SQUARE,null); + } + case 35: break; + case 19: + { sb.append('\r'); + } + case 36: break; + case 15: + { sb.append('/'); + } + case 37: break; + case 10: + { return new Yytoken(Yytoken.TYPE_COLON,null); + } + case 38: break; + case 14: + { sb.append('"'); + } + case 39: break; + case 5: + { return new Yytoken(Yytoken.TYPE_LEFT_BRACE,null); + } + case 40: break; + case 17: + { sb.append('\f'); + } + case 41: break; + case 24: + { try{ + int ch=Integer.parseInt(yytext().substring(2),16); + sb.append((char)ch); + } + catch(Exception e){ + throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_EXCEPTION, e); + } + } + case 42: break; + case 20: + { sb.append('\t'); + } + case 43: break; + case 7: + { return new Yytoken(Yytoken.TYPE_LEFT_SQUARE,null); + } + case 44: break; + case 2: + { Long val=Long.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE, val); + } + case 45: break; + case 18: + { sb.append('\n'); + } + case 46: break; + case 9: + { return new Yytoken(Yytoken.TYPE_COMMA,null); + } + case 47: break; + case 3: + { + } + case 48: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + return null; + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/mobile/android/thirdparty/org/json/simple/parser/Yytoken.java b/mobile/android/thirdparty/org/json/simple/parser/Yytoken.java new file mode 100644 index 000000000..ff14e27c1 --- /dev/null +++ b/mobile/android/thirdparty/org/json/simple/parser/Yytoken.java @@ -0,0 +1,58 @@ +/* + * $Id: Yytoken.java,v 1.1 2006/04/15 14:10:48 platform Exp $ + * Created on 2006-4-15 + */ +package org.json.simple.parser; + +/** + * @author FangYidong + */ +public class Yytoken { + public static final int TYPE_VALUE=0;//JSON primitive value: string,number,boolean,null + public static final int TYPE_LEFT_BRACE=1; + public static final int TYPE_RIGHT_BRACE=2; + public static final int TYPE_LEFT_SQUARE=3; + public static final int TYPE_RIGHT_SQUARE=4; + public static final int TYPE_COMMA=5; + public static final int TYPE_COLON=6; + public static final int TYPE_EOF=-1;//end of file + + public int type=0; + public Object value=null; + + public Yytoken(int type,Object value){ + this.type=type; + this.value=value; + } + + public String toString(){ + StringBuffer sb = new StringBuffer(); + switch(type){ + case TYPE_VALUE: + sb.append("VALUE(").append(value).append(")"); + break; + case TYPE_LEFT_BRACE: + sb.append("LEFT BRACE({)"); + break; + case TYPE_RIGHT_BRACE: + sb.append("RIGHT BRACE(})"); + break; + case TYPE_LEFT_SQUARE: + sb.append("LEFT SQUARE([)"); + break; + case TYPE_RIGHT_SQUARE: + sb.append("RIGHT SQUARE(])"); + break; + case TYPE_COMMA: + sb.append("COMMA(,)"); + break; + case TYPE_COLON: + sb.append("COLON(:)"); + break; + case TYPE_EOF: + sb.append("END OF FILE"); + break; + } + return sb.toString(); + } +} diff --git a/mobile/android/thirdparty/org/lucasr/dspec/DesignSpec.java b/mobile/android/thirdparty/org/lucasr/dspec/DesignSpec.java new file mode 100644 index 000000000..43505be4e --- /dev/null +++ b/mobile/android/thirdparty/org/lucasr/dspec/DesignSpec.java @@ -0,0 +1,645 @@ +/* + * Copyright (C) 2014 Lucas Rocha + * + * Licensed 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.lucasr.dspec; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.view.View; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Draw a baseline grid, keylines, and spacing markers on top of a {@link View}. + * + * A {@link DesignSpec} can be configure programmatically as follows: + *

    + *
  1. Toggle baseline grid visibility with {@link #setBaselineGridVisible(boolean)}.
  2. + *
  3. Change baseline grid cell width with {@link #setBaselineGridCellSize(float)}. + *
  4. Change baseline grid color with {@link #setBaselineGridColor(int)}. + *
  5. Toggle keylines visibility with {@link #setKeylinesVisible(boolean)}. + *
  6. Change keylines color with {@link #setKeylinesColor(int)}. + *
  7. Add keylines with {@link #addKeyline(float, From)}. + *
  8. Toggle spacings visibility with {@link #setSpacingsVisible(boolean)}. + *
  9. Change spacings color with {@link #setSpacingsColor(int)}. + *
  10. Add spacing with {@link #addSpacing(float, float, From)}. + *
+ * + * You can also define a {@link DesignSpec} via a raw JSON resource as follows: + *
+ * {
+ *     "baselineGridVisible": true,
+ *     "baselineGridCellSize": 8,
+ *     "keylines": [
+ *         { "offset": 16,
+ *           "from": "LEFT" },
+ *         { "offset": 72,
+ *           "from": "LEFT" },
+ *         { "offset": 16,
+ *           "from": "RIGHT" }
+ *     ],
+ *     "spacings": [
+ *         { "offset": 0,
+ *           "size": 16,
+ *           "from": "LEFT" },
+ *         { "offset": 56,
+ *           "size": 16,
+ *           "from": "LEFT" },
+ *         { "offset": 0,
+ *           "size": 16,
+ *           "from": "RIGHT" }
+ *     ]
+ * }
+ * 
+ * + * The {@link From} arguments implicitly define the orientation of the given + * keyline or spacing i.e. {@link From#LEFT}, {@link From#RIGHT}, {@link From#HORIZONTAL_CENTER} + * are implicitly vertical; and {@link From#TOP}, {@link From#BOTTOM}, {@link From#VERTICAL_CENTER} + * are implicitly horizontal. + * + * The {@link From} arguments also define the 'direction' of the offsets and sizes in keylines and + * spacings. For example, a keyline using {@link From#RIGHT} will have its offset measured from + * right to left of the target {@link View}. + * + * The easiest way to use a {@link DesignSpec} is by enclosing your target {@link View} with + * a {@link DesignSpecFrameLayout} using the {@code designSpec} attribute as follows: + *
+ * 
+ *
+ *     ...
+ *
+ * 
+ * 
+ * + * Where {@code @raw/my_spec} is a raw JSON resource. Because the {@link DesignSpec} is + * defined in an Android resource, you can vary it according to the target form factor using + * well-known resource qualifiers making it easy to define different specs for phones and tablets. + * + * Because {@link DesignSpec} is a {@link Drawable}, you can simply add it to any + * {@link android.view.ViewOverlay} if you're running your app on API level >= 18: + * + *
+ * DesignSpec designSpec = DesignSpec.fromResource(someView, R.raw.some_spec);
+ * someView.getOverlay().add(designSpec);
+ * 
+ * + * @see DesignSpecFrameLayout + * @see #fromResource(View, int) + */ +public class DesignSpec extends Drawable { + private static final boolean DEFAULT_BASELINE_GRID_VISIBLE = false; + private static final boolean DEFAULT_KEYLINES_VISIBLE = true; + private static final boolean DEFAULT_SPACINGS_VISIBLE = true; + + private static final int DEFAULT_BASELINE_GRID_CELL_SIZE_DIP = 8; + + private static final String DEFAULT_BASELINE_GRID_COLOR = "#44C2185B"; + private static final String DEFAULT_KEYLINE_COLOR = "#CCC2185B"; + private static final String DEFAULT_SPACING_COLOR = "#CC89FDFD"; + + private static final float KEYLINE_STROKE_WIDTH_DIP = 1.1f; + + private static final String JSON_KEY_BASELINE_GRID_VISIBLE = "baselineGridVisible"; + private static final String JSON_KEY_BASELINE_GRID_CELL_SIZE = "baselineGridCellSize"; + private static final String JSON_KEY_BASELINE_GRID_COLOR = "baselineGridColor"; + + private static final String JSON_KEY_KEYLINES_VISIBLE = "keylinesVisible"; + private static final String JSON_KEY_KEYLINES_COLOR = "keylinesColor"; + private static final String JSON_KEY_KEYLINES = "keylines"; + + private static final String JSON_KEY_OFFSET = "offset"; + private static final String JSON_KEY_SIZE = "size"; + private static final String JSON_KEY_FROM = "from"; + + private static final String JSON_KEY_SPACINGS_VISIBLE = "spacingsVisible"; + private static final String JSON_KEY_SPACINGS_COLOR = "spacingsColor"; + private static final String JSON_KEY_SPACINGS = "spacings"; + + /** + * Defined the reference point from which keyline/spacing offsets and sizes + * will be calculated. + */ + public enum From { + LEFT, + RIGHT, + TOP, + BOTTOM, + VERTICAL_CENTER, + HORIZONTAL_CENTER + } + + private static class Keyline { + public final float position; + public final From from; + + public Keyline(float position, From from) { + this.position = position; + this.from = from; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Keyline)) { + return false; + } + + if (o == this) { + return true; + } + + final Keyline other = (Keyline) o; + return (this.position == other.position && this.from == other.from); + } + } + + private static class Spacing { + public final float offset; + public final float size; + public final From from; + + public Spacing(float offset, float size, From from) { + this.offset = offset; + this.size = size; + this.from = from; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Keyline)) { + return false; + } + + if (o == this) { + return true; + } + + final Spacing other = (Spacing) o; + return (this.offset == other.offset && + this.size == other.size && + this.from == other.from); + } + } + + private final View mHostView; + + private final float mDensity; + + private boolean mBaselineGridVisible = DEFAULT_BASELINE_GRID_VISIBLE; + private float mBaselineGridCellSize; + private final Paint mBaselineGridPaint; + + private boolean mKeylinesVisible = DEFAULT_KEYLINES_VISIBLE; + private final Paint mKeylinesPaint; + private final List mKeylines; + + private boolean mSpacingsVisible = DEFAULT_SPACINGS_VISIBLE; + private final Paint mSpacingsPaint; + private final List mSpacings; + + public DesignSpec(Resources resources, View hostView) { + mHostView = hostView; + mDensity = resources.getDisplayMetrics().density; + + mKeylines = new ArrayList(); + mSpacings = new ArrayList(); + + mBaselineGridPaint = new Paint(); + mBaselineGridPaint.setColor(Color.parseColor(DEFAULT_BASELINE_GRID_COLOR)); + + mKeylinesPaint = new Paint(); + mKeylinesPaint.setStrokeWidth(KEYLINE_STROKE_WIDTH_DIP * mDensity); + mKeylinesPaint.setColor(Color.parseColor(DEFAULT_KEYLINE_COLOR)); + + mSpacingsPaint = new Paint(); + mSpacingsPaint.setColor(Color.parseColor(DEFAULT_SPACING_COLOR)); + + mBaselineGridCellSize = mDensity * DEFAULT_BASELINE_GRID_CELL_SIZE_DIP; + } + + /** + * Whether or not the baseline grid should be drawn. + */ + public boolean isBaselineGridVisible() { + return mBaselineGridVisible; + } + + /** + * Sets the baseline grid visibility. + */ + public DesignSpec setBaselineGridVisible(boolean visible) { + if (mBaselineGridVisible == visible) { + return this; + } + + mBaselineGridVisible = visible; + invalidateSelf(); + + return this; + } + + /** + * Sets the size of the baseline grid cells. By default, it uses the + * material design 8dp cell size. + */ + public DesignSpec setBaselineGridCellSize(float cellSize) { + if (mBaselineGridCellSize == cellSize) { + return this; + } + + mBaselineGridCellSize = cellSize; + invalidateSelf(); + + return this; + } + + /** + * Sets the baseline grid color. + */ + public DesignSpec setBaselineGridColor(int color) { + if (mBaselineGridPaint.getColor() == color) { + return this; + } + + mBaselineGridPaint.setColor(color); + invalidateSelf(); + + return this; + } + + /** + * Whether or not the keylines should be drawn. + */ + public boolean areKeylinesVisible() { + return mKeylinesVisible; + } + + /** + * Sets the visibility of keylines. + */ + public DesignSpec setKeylinesVisible(boolean visible) { + if (mKeylinesVisible == visible) { + return this; + } + + mKeylinesVisible = visible; + invalidateSelf(); + + return this; + } + + /** + * Sets the keyline color. + */ + public DesignSpec setKeylinesColor(int color) { + if (mKeylinesPaint.getColor() == color) { + return this; + } + + mKeylinesPaint.setColor(color); + invalidateSelf(); + + return this; + } + + /** + * Adds a keyline to the {@link DesignSpec}. + */ + public DesignSpec addKeyline(float position, From from) { + final Keyline keyline = new Keyline(position * mDensity, from); + if (mKeylines.contains(keyline)) { + return this; + } + + mKeylines.add(keyline); + return this; + } + + /** + * Whether or not the spacing markers should be drawn. + */ + public boolean areSpacingsVisible() { + return mSpacingsVisible; + } + + /** + * Sets the visibility of spacing markers. + */ + public DesignSpec setSpacingsVisible(boolean visible) { + if (mSpacingsVisible == visible) { + return this; + } + + mSpacingsVisible = visible; + invalidateSelf(); + + return this; + } + + /** + * Sets the spacing mark color. + */ + public DesignSpec setSpacingsColor(int color) { + if (mSpacingsPaint.getColor() == color) { + return this; + } + + mSpacingsPaint.setColor(color); + invalidateSelf(); + + return this; + } + + /** + * Adds a spacing mark to the {@link DesignSpec}. + */ + public DesignSpec addSpacing(float position, float size, From from) { + final Spacing spacing = new Spacing(position * mDensity, size * mDensity, from); + if (mSpacings.contains(spacing)) { + return this; + } + + mSpacings.add(spacing); + return this; + } + + private void drawBaselineGrid(Canvas canvas) { + if (!mBaselineGridVisible) { + return; + } + + final int width = getIntrinsicWidth(); + final int height = getIntrinsicHeight(); + + float x = mBaselineGridCellSize; + while (x < width) { + canvas.drawLine(x, 0, x, height, mBaselineGridPaint); + x += mBaselineGridCellSize; + } + + float y = mBaselineGridCellSize; + while (y < height) { + canvas.drawLine(0, y, width, y, mBaselineGridPaint); + y += mBaselineGridCellSize; + } + } + + private void drawKeylines(Canvas canvas) { + if (!mKeylinesVisible) { + return; + } + + final int width = getIntrinsicWidth(); + final int height = getIntrinsicHeight(); + + final int count = mKeylines.size(); + for (int i = 0; i < count; i++) { + final Keyline keyline = mKeylines.get(i); + + final float position; + switch (keyline.from) { + case LEFT: + case TOP: + position = keyline.position; + break; + + case RIGHT: + position = width - keyline.position; + break; + + case BOTTOM: + position = height - keyline.position; + break; + + case VERTICAL_CENTER: + position = (height / 2) + keyline.position; + break; + + case HORIZONTAL_CENTER: + position = (width / 2) + keyline.position; + break; + + default: + throw new IllegalStateException("Invalid keyline offset"); + } + + switch (keyline.from) { + case LEFT: + case RIGHT: + case HORIZONTAL_CENTER: + canvas.drawLine(position, 0, position, height, mKeylinesPaint); + break; + + case TOP: + case BOTTOM: + case VERTICAL_CENTER: + canvas.drawLine(0, position, width, position, mKeylinesPaint); + break; + } + } + } + + private void drawSpacings(Canvas canvas) { + if (!mSpacingsVisible) { + return; + } + + final int width = getIntrinsicWidth(); + final int height = getIntrinsicHeight(); + + final int count = mSpacings.size(); + for (int i = 0; i < count; i++) { + final Spacing spacing = mSpacings.get(i); + + final float position1; + final float position2; + switch (spacing.from) { + case LEFT: + case TOP: + position1 = spacing.offset; + position2 = position1 + spacing.size; + break; + + case RIGHT: + position1 = width - spacing.offset + spacing.size; + position2 = width - spacing.offset; + break; + + case BOTTOM: + position1 = height - spacing.offset + spacing.size; + position2 = height - spacing.offset; + break; + + case VERTICAL_CENTER: + position1 = (height / 2) + spacing.offset; + position2 = position1 + spacing.size; + break; + + case HORIZONTAL_CENTER: + position1 = (width / 2) + spacing.offset; + position2 = position1 + spacing.size; + break; + + default: + throw new IllegalStateException("Invalid spacing offset"); + } + + switch (spacing.from) { + case LEFT: + case RIGHT: + case HORIZONTAL_CENTER: + canvas.drawRect(position1, 0, position2, height, mSpacingsPaint); + break; + + case TOP: + case BOTTOM: + case VERTICAL_CENTER: + canvas.drawRect(0, position1, width, position2, mSpacingsPaint); + break; + } + } + } + + /** + * Draws the {@link DesignSpec}. You should call this in your {@link View}'s + * {@link View#onDraw(Canvas)} method if you're not simply enclosing it with a + * {@link DesignSpecFrameLayout}. + */ + @Override + public void draw(Canvas canvas) { + drawSpacings(canvas); + drawBaselineGrid(canvas); + drawKeylines(canvas); + } + + @Override + public int getIntrinsicWidth() { + return mHostView.getWidth(); + } + + @Override + public int getIntrinsicHeight() { + return mHostView.getHeight(); + } + + @Override + public void setAlpha(int alpha) { + mBaselineGridPaint.setAlpha(alpha); + mKeylinesPaint.setAlpha(alpha); + mSpacingsPaint.setAlpha(alpha); + } + + @Override + public void setColorFilter(ColorFilter cf) { + mBaselineGridPaint.setColorFilter(cf); + mKeylinesPaint.setColorFilter(cf); + mSpacingsPaint.setColorFilter(cf); + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + /** + * Creates a new {@link DesignSpec} instance from a resource ID using a {@link View} + * that will provide the {@link DesignSpec}'s intrinsic dimensions. + * + * @param view The {@link View} who will own the new {@link DesignSpec} instance. + * @param resId The resource ID pointing to a raw JSON resource. + * @return The newly created {@link DesignSpec} instance. + */ + public static DesignSpec fromResource(View view, int resId) { + final Resources resources = view.getResources(); + final DesignSpec spec = new DesignSpec(resources, view); + if (resId == 0) { + return spec; + } + + final JSONObject json; + try { + json = RawResource.getAsJSON(resources, resId); + } catch (IOException e) { + throw new IllegalStateException("Could not read design spec resource", e); + } + + final float density = resources.getDisplayMetrics().density; + + spec.setBaselineGridCellSize(density * json.optInt(JSON_KEY_BASELINE_GRID_CELL_SIZE, + DEFAULT_BASELINE_GRID_CELL_SIZE_DIP)); + + spec.setBaselineGridVisible(json.optBoolean(JSON_KEY_BASELINE_GRID_VISIBLE, + DEFAULT_BASELINE_GRID_VISIBLE)); + spec.setKeylinesVisible(json.optBoolean(JSON_KEY_KEYLINES_VISIBLE, + DEFAULT_KEYLINES_VISIBLE)); + spec.setSpacingsVisible(json.optBoolean(JSON_KEY_SPACINGS_VISIBLE, + DEFAULT_SPACINGS_VISIBLE)); + + spec.setBaselineGridColor(Color.parseColor(json.optString(JSON_KEY_BASELINE_GRID_COLOR, + DEFAULT_BASELINE_GRID_COLOR))); + spec.setKeylinesColor(Color.parseColor(json.optString(JSON_KEY_KEYLINES_COLOR, + DEFAULT_KEYLINE_COLOR))); + spec.setSpacingsColor(Color.parseColor(json.optString(JSON_KEY_SPACINGS_COLOR, + DEFAULT_SPACING_COLOR))); + + final JSONArray keylines = json.optJSONArray(JSON_KEY_KEYLINES); + if (keylines != null) { + final int keylineCount = keylines.length(); + for (int i = 0; i < keylineCount; i++) { + try { + final JSONObject keyline = keylines.getJSONObject(i); + spec.addKeyline(keyline.getInt(JSON_KEY_OFFSET), + From.valueOf(keyline.getString(JSON_KEY_FROM).toUpperCase())); + } catch (JSONException e) { + continue; + } + } + } + + final JSONArray spacings = json.optJSONArray(JSON_KEY_SPACINGS); + if (spacings != null) { + final int spacingCount = spacings.length(); + for (int i = 0; i < spacingCount; i++) { + try { + final JSONObject spacing = spacings.getJSONObject(i); + spec.addSpacing(spacing.getInt(JSON_KEY_OFFSET), spacing.getInt(JSON_KEY_SIZE), + From.valueOf(spacing.getString(JSON_KEY_FROM).toUpperCase())); + } catch (JSONException e) { + continue; + } + } + } + + return spec; + } +} diff --git a/mobile/android/thirdparty/org/lucasr/dspec/RawResource.java b/mobile/android/thirdparty/org/lucasr/dspec/RawResource.java new file mode 100644 index 000000000..f2e743b11 --- /dev/null +++ b/mobile/android/thirdparty/org/lucasr/dspec/RawResource.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 Lucas Rocha + * + * Licensed 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.lucasr.dspec; + +import android.content.Context; +import android.content.res.Resources; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; + +class RawResource { + public static JSONObject getAsJSON(Resources resources, int id) throws IOException { + InputStreamReader reader = null; + + try { + final InputStream is = resources.openRawResource(id); + if (is == null) { + return null; + } + + reader = new InputStreamReader(is, "UTF-8"); + + final char[] buffer = new char[1024]; + final StringWriter s = new StringWriter(); + + int n; + while ((n = reader.read(buffer, 0, buffer.length)) != -1) { + s.write(buffer, 0, n); + } + + return new JSONObject(s.toString()); + } catch (JSONException e) { + throw new IllegalStateException("Invalid design spec JSON resource", e); + } finally { + if (reader != null) { + reader.close(); + } + } + } +} \ No newline at end of file diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/BinaryDecoder.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/BinaryDecoder.java new file mode 100644 index 000000000..82e77e009 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/BinaryDecoder.java @@ -0,0 +1,43 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +/** + * Defines common decoding methods for byte array decoders. + * + * @author Apache Software Foundation + * @version $Id: BinaryDecoder.java 1075406 2011-02-28 16:18:26Z ggregory $ + */ +public interface BinaryDecoder extends Decoder { + + /** + * Decodes a byte array and returns the results as a byte array. + * + * @param source A byte array which has been encoded with the + * appropriate encoder + * + * @return a byte array that contains decoded content + * + * @throws DecoderException A decoder exception is thrown + * if a Decoder encounters a failure condition during + * the decode process. + */ + byte[] decode(byte[] source) throws DecoderException; +} + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/BinaryEncoder.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/BinaryEncoder.java new file mode 100644 index 000000000..5b1be202c --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/BinaryEncoder.java @@ -0,0 +1,43 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +/** + * Defines common encoding methods for byte array encoders. + * + * @author Apache Software Foundation + * @version $Id: BinaryEncoder.java 1075406 2011-02-28 16:18:26Z ggregory $ + */ +public interface BinaryEncoder extends Encoder { + + /** + * Encodes a byte array and return the encoded data + * as a byte array. + * + * @param source Data to be encoded + * + * @return A byte array containing the encoded data + * + * @throws EncoderException thrown if the Encoder + * encounters a failure condition during the + * encoding process. + */ + byte[] encode(byte[] source) throws EncoderException; +} + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/CharEncoding.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/CharEncoding.java new file mode 100644 index 000000000..c4227fb0e --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/CharEncoding.java @@ -0,0 +1,127 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +/** + * Character encoding names required of every implementation of the Java platform. + * + * From the Java documentation Standard + * charsets: + *

+ * Every implementation of the Java platform is required to support the following character encodings. Consult the + * release documentation for your implementation to see if any other encodings are supported. Consult the release + * documentation for your implementation to see if any other encodings are supported. + *

+ * + *
    + *
  • US-ASCII
    + * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set.
  • + *
  • ISO-8859-1
    + * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1.
  • + *
  • UTF-8
    + * Eight-bit Unicode Transformation Format.
  • + *
  • UTF-16BE
    + * Sixteen-bit Unicode Transformation Format, big-endian byte order.
  • + *
  • UTF-16LE
    + * Sixteen-bit Unicode Transformation Format, little-endian byte order.
  • + *
  • UTF-16
    + * Sixteen-bit Unicode Transformation Format, byte order specified by a mandatory initial byte-order mark (either order + * accepted on input, big-endian used on output.)
  • + *
+ * + * This perhaps would best belong in the [lang] project. Even if a similar interface is defined in [lang], it is not + * forseen that [codec] would be made to depend on [lang]. + * + * @see Standard charsets + * @author Apache Software Foundation + * @since 1.4 + * @version $Id: CharEncoding.java 797857 2009-07-25 23:43:33Z ggregory $ + */ +public class CharEncoding { + /** + * CharEncodingISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1.

+ *

+ * Every implementation of the Java platform is required to support this character encoding. + *

+ * + * @see Standard charsets + */ + public static final String ISO_8859_1 = "ISO-8859-1"; + + /** + *

+ * Seven-bit ASCII, also known as ISO646-US, also known as the Basic Latin block of the Unicode character set. + *

+ *

+ * Every implementation of the Java platform is required to support this character encoding. + *

+ * + * @see Standard charsets + */ + public static final String US_ASCII = "US-ASCII"; + + /** + *

+ * Sixteen-bit Unicode Transformation Format, The byte order specified by a mandatory initial byte-order mark + * (either order accepted on input, big-endian used on output) + *

+ *

+ * Every implementation of the Java platform is required to support this character encoding. + *

+ * + * @see Standard charsets + */ + public static final String UTF_16 = "UTF-16"; + + /** + *

+ * Sixteen-bit Unicode Transformation Format, big-endian byte order. + *

+ *

+ * Every implementation of the Java platform is required to support this character encoding. + *

+ * + * @see Standard charsets + */ + public static final String UTF_16BE = "UTF-16BE"; + + /** + *

+ * Sixteen-bit Unicode Transformation Format, little-endian byte order. + *

+ *

+ * Every implementation of the Java platform is required to support this character encoding. + *

+ * + * @see Standard charsets + */ + public static final String UTF_16LE = "UTF-16LE"; + + /** + *

+ * Eight-bit Unicode Transformation Format. + *

+ *

+ * Every implementation of the Java platform is required to support this character encoding. + *

+ * + * @see Standard charsets + */ + public static final String UTF_8 = "UTF-8"; +} \ No newline at end of file diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/Decoder.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/Decoder.java new file mode 100644 index 000000000..5194feae2 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/Decoder.java @@ -0,0 +1,56 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +/** + *

Provides the highest level of abstraction for Decoders. + * This is the sister interface of {@link Encoder}. All + * Decoders implement this common generic interface.

+ * + *

Allows a user to pass a generic Object to any Decoder + * implementation in the codec package.

+ * + *

One of the two interfaces at the center of the codec package.

+ * + * @author Apache Software Foundation + * @version $Id: Decoder.java 1075404 2011-02-28 16:17:29Z ggregory $ + */ +public interface Decoder { + + /** + * Decodes an "encoded" Object and returns a "decoded" + * Object. Note that the implementation of this + * interface will try to cast the Object parameter + * to the specific type expected by a particular Decoder + * implementation. If a {@link ClassCastException} occurs + * this decode method will throw a DecoderException. + * + * @param source the object to decode + * + * @return a 'decoded" object + * + * @throws DecoderException a decoder exception can + * be thrown for any number of reasons. Some good + * candidates are that the parameter passed to this + * method is null, a param cannot be cast to the + * appropriate type for a specific encoder. + */ + Object decode(Object source) throws DecoderException; +} + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/DecoderException.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/DecoderException.java new file mode 100644 index 000000000..88108a548 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/DecoderException.java @@ -0,0 +1,90 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +/** + * Thrown when there is a failure condition during the decoding process. This exception is thrown when a {@link Decoder} + * encounters a decoding specific exception such as invalid data, or characters outside of the expected range. + * + * @author Apache Software Foundation + * @version $Id: DecoderException.java 1080701 2011-03-11 17:52:27Z ggregory $ + */ +public class DecoderException extends Exception { + + /** + * Declares the Serial Version Uid. + * + * @see Always Declare Serial Version Uid + */ + private static final long serialVersionUID = 1L; + + /** + * Constructs a new exception with null as its detail message. The cause is not initialized, and may + * subsequently be initialized by a call to {@link #initCause}. + * + * @since 1.4 + */ + public DecoderException() { + super(); + } + + /** + * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently + * be initialized by a call to {@link #initCause}. + * + * @param message + * The detail message which is saved for later retrieval by the {@link #getMessage()} method. + */ + public DecoderException(String message) { + super(message); + } + + /** + * Constructsa new exception with the specified detail message and cause. + * + *

+ * Note that the detail message associated with cause is not automatically incorporated into this + * exception's detail message. + *

+ * + * @param message + * The detail message which is saved for later retrieval by the {@link #getMessage()} method. + * @param cause + * The cause which is saved for later retrieval by the {@link #getCause()} method. A null + * value is permitted, and indicates that the cause is nonexistent or unknown. + * @since 1.4 + */ + public DecoderException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified cause and a detail message of (cause==null ? + * null : cause.toString()) (which typically contains the class and detail message of cause). + * This constructor is useful for exceptions that are little more than wrappers for other throwables. + * + * @param cause + * The cause which is saved for later retrieval by the {@link #getCause()} method. A null + * value is permitted, and indicates that the cause is nonexistent or unknown. + * @since 1.4 + */ + public DecoderException(Throwable cause) { + super(cause); + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/Encoder.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/Encoder.java new file mode 100644 index 000000000..1b81af9b2 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/Encoder.java @@ -0,0 +1,47 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +/** + *

Provides the highest level of abstraction for Encoders. + * This is the sister interface of {@link Decoder}. Every implementation of + * Encoder provides this common generic interface whic allows a user to pass a + * generic Object to any Encoder implementation in the codec package.

+ * + * @author Apache Software Foundation + * @version $Id: Encoder.java 1075406 2011-02-28 16:18:26Z ggregory $ + */ +public interface Encoder { + + /** + * Encodes an "Object" and returns the encoded content + * as an Object. The Objects here may just be byte[] + * or Strings depending on the implementation used. + * + * @param source An object ot encode + * + * @return An "encoded" Object + * + * @throws EncoderException an encoder exception is + * thrown if the encoder experiences a failure + * condition during the encoding process. + */ + Object encode(Object source) throws EncoderException; +} + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/EncoderException.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/EncoderException.java new file mode 100644 index 000000000..a858abccd --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/EncoderException.java @@ -0,0 +1,91 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +/** + * Thrown when there is a failure condition during the encoding process. This exception is thrown when an + * {@link Encoder} encounters a encoding specific exception such as invalid data, inability to calculate a checksum, + * characters outside of the expected range. + * + * @author Apache Software Foundation + * @version $Id: EncoderException.java 1080701 2011-03-11 17:52:27Z ggregory $ + */ +public class EncoderException extends Exception { + + /** + * Declares the Serial Version Uid. + * + * @see Always Declare Serial Version Uid + */ + private static final long serialVersionUID = 1L; + + /** + * Constructs a new exception with null as its detail message. The cause is not initialized, and may + * subsequently be initialized by a call to {@link #initCause}. + * + * @since 1.4 + */ + public EncoderException() { + super(); + } + + /** + * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently + * be initialized by a call to {@link #initCause}. + * + * @param message + * a useful message relating to the encoder specific error. + */ + public EncoderException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified detail message and cause. + * + *

+ * Note that the detail message associated with cause is not automatically incorporated into this + * exception's detail message. + *

+ * + * @param message + * The detail message which is saved for later retrieval by the {@link #getMessage()} method. + * @param cause + * The cause which is saved for later retrieval by the {@link #getCause()} method. A null + * value is permitted, and indicates that the cause is nonexistent or unknown. + * @since 1.4 + */ + public EncoderException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified cause and a detail message of (cause==null ? + * null : cause.toString()) (which typically contains the class and detail message of cause). + * This constructor is useful for exceptions that are little more than wrappers for other throwables. + * + * @param cause + * The cause which is saved for later retrieval by the {@link #getCause()} method. A null + * value is permitted, and indicates that the cause is nonexistent or unknown. + * @since 1.4 + */ + public EncoderException(Throwable cause) { + super(cause); + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringDecoder.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringDecoder.java new file mode 100644 index 000000000..a112485b3 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringDecoder.java @@ -0,0 +1,41 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +/** + * Defines common decoding methods for String decoders. + * + * @author Apache Software Foundation + * @version $Id: StringDecoder.java 1080701 2011-03-11 17:52:27Z ggregory $ + */ +public interface StringDecoder extends Decoder { + + /** + * Decodes a String and returns a String. + * + * @param source the String to decode + * + * @return the encoded String + * + * @throws DecoderException thrown if there is + * an error condition during the Encoding process. + */ + String decode(String source) throws DecoderException; +} + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringEncoder.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringEncoder.java new file mode 100644 index 000000000..2bcc5165d --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringEncoder.java @@ -0,0 +1,41 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +/** + * Defines common encoding methods for String encoders. + * + * @author Apache Software Foundation + * @version $Id: StringEncoder.java 1080701 2011-03-11 17:52:27Z ggregory $ + */ +public interface StringEncoder extends Encoder { + + /** + * Encodes a String and returns a String. + * + * @param source the String to encode + * + * @return the encoded String + * + * @throws EncoderException thrown if there is + * an error conidition during the Encoding process. + */ + String encode(String source) throws EncoderException; +} + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringEncoderComparator.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringEncoderComparator.java new file mode 100644 index 000000000..8923df571 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/StringEncoderComparator.java @@ -0,0 +1,87 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec; + +import java.util.Comparator; + +/** + * Compares Strings using a {@link StringEncoder}. This comparator is used to sort Strings by an encoding scheme such as + * Soundex, Metaphone, etc. This class can come in handy if one need to sort Strings by an encoded form of a name such + * as Soundex. + * + * @author Apache Software Foundation + * @version $Id: StringEncoderComparator.java 1080701 2011-03-11 17:52:27Z ggregory $ + */ +@SuppressWarnings("rawtypes") +public class StringEncoderComparator implements Comparator { + + /** + * Internal encoder instance. + */ + private final StringEncoder stringEncoder; + + /** + * Constructs a new instance. + * + * @deprecated Creating an instance without a {@link StringEncoder} leads to a {@link NullPointerException}. Will be + * removed in 2.0. + */ + public StringEncoderComparator() { + this.stringEncoder = null; // Trying to use this will cause things to break + } + + /** + * Constructs a new instance with the given algorithm. + * + * @param stringEncoder + * the StringEncoder used for comparisons. + */ + public StringEncoderComparator(StringEncoder stringEncoder) { + this.stringEncoder = stringEncoder; + } + + /** + * Compares two strings based not on the strings themselves, but on an encoding of the two strings using the + * StringEncoder this Comparator was created with. + * + * If an {@link EncoderException} is encountered, return 0. + * + * @param o1 + * the object to compare + * @param o2 + * the object to compare to + * @return the Comparable.compareTo() return code or 0 if an encoding error was caught. + * @see Comparable + */ + @SuppressWarnings("unchecked") + public int compare(Object o1, Object o2) { + + int compareCode = 0; + + try { + Comparable s1 = (Comparable) this.stringEncoder.encode(o1); + Comparable s2 = (Comparable) this.stringEncoder.encode(o2); + compareCode = s1.compareTo(s2); + } catch (EncoderException ee) { + compareCode = 0; + } + return compareCode; + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32.java new file mode 100644 index 000000000..d0d923e62 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32.java @@ -0,0 +1,471 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +/** + * Provides Base32 encoding and decoding as defined by RFC 4648. + * + *

+ * The class can be parameterized in the following manner with various constructors: + *

    + *
  • Whether to use the "base32hex" variant instead of the default "base32"
  • + *
  • Line length: Default 76. Line length that aren't multiples of 8 will still essentially end up being multiples of + * 8 in the encoded data. + *
  • Line separator: Default is CRLF ("\r\n")
  • + *
+ *

+ *

+ * This class operates directly on byte streams, and not character streams. + *

+ *

+ * This class is not thread-safe. Each thread should use its own instance. + *

+ * + * @see RFC 4648 + * + * @since 1.5 + * @version $Revision: 1080712 $ + */ +public class Base32 extends BaseNCodec { + + /** + * BASE32 characters are 5 bits in length. + * They are formed by taking a block of five octets to form a 40-bit string, + * which is converted into eight BASE32 characters. + */ + private static final int BITS_PER_ENCODED_BYTE = 5; + private static final int BYTES_PER_ENCODED_BLOCK = 8; + private static final int BYTES_PER_UNENCODED_BLOCK = 5; + + /** + * Chunk separator per RFC 2045 section 2.1. + * + * @see RFC 2045 section 2.1 + */ + private static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; + + /** + * This array is a lookup table that translates Unicode characters drawn from the "Base32 Alphabet" (as specified in + * Table 3 of RFC 2045) into their 5-bit positive integer equivalents. Characters that are not in the Base32 + * alphabet but fall within the bounds of the array are translated to -1. + * + */ + private static final byte[] DECODE_TABLE = { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 63, // 20-2f + -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, // 30-3f 2-7 + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 40-4f A-N + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 50-5a O-Z + }; + + /** + * This array is a lookup table that translates 5-bit positive integer index values into their "Base32 Alphabet" + * equivalents as specified in Table 3 of RFC 2045. + */ + private static final byte[] ENCODE_TABLE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '2', '3', '4', '5', '6', '7', + }; + + /** + * This array is a lookup table that translates Unicode characters drawn from the "Base32 |Hex Alphabet" (as specified in + * Table 3 of RFC 2045) into their 5-bit positive integer equivalents. Characters that are not in the Base32 Hex + * alphabet but fall within the bounds of the array are translated to -1. + * + */ + private static final byte[] HEX_DECODE_TABLE = { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 63, // 20-2f + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 30-3f 2-7 + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 40-4f A-N + 25, 26, 27, 28, 29, 30, 31, 32, // 50-57 O-V + }; + + /** + * This array is a lookup table that translates 5-bit positive integer index values into their "Base32 Hex Alphabet" + * equivalents as specified in Table 3 of RFC 2045. + */ + private static final byte[] HEX_ENCODE_TABLE = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + }; + + /** Mask used to extract 5 bits, used when encoding Base32 bytes */ + private static final int MASK_5BITS = 0x1f; + + // The static final fields above are used for the original static byte[] methods on Base32. + // The private member fields below are used with the new streaming approach, which requires + // some state be preserved between calls of encode() and decode(). + + /** + * Place holder for the bytes we're dealing with for our based logic. + * Bitwise operations store and extract the encoding or decoding from this variable. + */ + private long bitWorkArea; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * decodeSize = {@link BYTES_PER_ENCODED_BLOCK} - 1 + lineSeparator.length; + */ + private final int decodeSize; + + /** + * Decode table to use. + */ + private final byte[] decodeTable; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * encodeSize = {@link BYTES_PER_ENCODED_BLOCK} + lineSeparator.length; + */ + private final int encodeSize; + + /** + * Encode table to use. + */ + private final byte[] encodeTable; + + /** + * Line separator for encoding. Not used when decoding. Only used if lineLength > 0. + */ + private final byte[] lineSeparator; + + /** + * Creates a Base32 codec used for decoding and encoding. + *

+ * When encoding the line length is 0 (no chunking). + *

+ * + */ + public Base32() { + this(false); + } + + /** + * Creates a Base32 codec used for decoding and encoding. + *

+ * When encoding the line length is 0 (no chunking). + *

+ * @param useHex if true then use Base32 Hex alphabet + */ + public Base32(boolean useHex) { + this(0, null, useHex); + } + + /** + * Creates a Base32 codec used for decoding and encoding. + *

+ * When encoding the line length is given in the constructor, the line separator is CRLF. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 8). + * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding. + */ + public Base32(int lineLength) { + this(lineLength, CHUNK_SEPARATOR); + } + + /** + * Creates a Base32 codec used for decoding and encoding. + *

+ * When encoding the line length and line separator are given in the constructor. + *

+ *

+ * Line lengths that aren't multiples of 8 will still essentially end up being multiples of 8 in the encoded data. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 8). + * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @throws IllegalArgumentException + * The provided lineSeparator included some Base32 characters. That's not going to work! + */ + public Base32(int lineLength, byte[] lineSeparator) { + this(lineLength, lineSeparator, false); + } + + /** + * Creates a Base32 / Base32 Hex codec used for decoding and encoding. + *

+ * When encoding the line length and line separator are given in the constructor. + *

+ *

+ * Line lengths that aren't multiples of 8 will still essentially end up being multiples of 8 in the encoded data. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 8). + * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @param useHex if true, then use Base32 Hex alphabet, otherwise use Base32 alphabet + * @throws IllegalArgumentException + * The provided lineSeparator included some Base32 characters. That's not going to work! + * Or the lineLength > 0 and lineSeparator is null. + */ + public Base32(int lineLength, byte[] lineSeparator, boolean useHex) { + super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, + lineLength, + lineSeparator == null ? 0 : lineSeparator.length); + if (useHex){ + this.encodeTable = HEX_ENCODE_TABLE; + this.decodeTable = HEX_DECODE_TABLE; + } else { + this.encodeTable = ENCODE_TABLE; + this.decodeTable = DECODE_TABLE; + } + if (lineLength > 0) { + if (lineSeparator == null) { + throw new IllegalArgumentException("lineLength "+lineLength+" > 0, but lineSeparator is null"); + } + // Must be done after initializing the tables + if (containsAlphabetOrPad(lineSeparator)) { + String sep = StringUtils.newStringUtf8(lineSeparator); + throw new IllegalArgumentException("lineSeparator must not contain Base32 characters: [" + sep + "]"); + } + this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length; + this.lineSeparator = new byte[lineSeparator.length]; + System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length); + } else { + this.encodeSize = BYTES_PER_ENCODED_BLOCK; + this.lineSeparator = null; + } + this.decodeSize = this.encodeSize - 1; + } + + /** + *

+ * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once + * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1" + * call is not necessary when decoding, but it doesn't hurt, either. + *

+ *

+ * Ignores all non-Base32 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are + * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in, + * garbage-out philosophy: it will not check the provided data for validity. + *

+ * + * @param in + * byte[] array of ascii data to Base32 decode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for encoding. + * + * Output is written to {@link #buffer} as 8-bit octets, using {@link pos} as the buffer position + */ + void decode(byte[] in, int inPos, int inAvail) { // package protected for access from I/O streams + if (eof) { + return; + } + if (inAvail < 0) { + eof = true; + } + for (int i = 0; i < inAvail; i++) { + byte b = in[inPos++]; + if (b == PAD) { + // We're done. + eof = true; + break; + } else { + ensureBufferSize(decodeSize); + if (b >= 0 && b < this.decodeTable.length) { + int result = this.decodeTable[b]; + if (result >= 0) { + modulus = (modulus+1) % BYTES_PER_ENCODED_BLOCK; + bitWorkArea = (bitWorkArea << BITS_PER_ENCODED_BYTE) + result; // collect decoded bytes + if (modulus == 0) { // we can output the 5 bytes + buffer[pos++] = (byte) ((bitWorkArea >> 32) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea >> 24) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea >> 16) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS); + buffer[pos++] = (byte) (bitWorkArea & MASK_8BITS); + } + } + } + } + } + + // Two forms of EOF as far as Base32 decoder is concerned: actual + // EOF (-1) and first time '=' character is encountered in stream. + // This approach makes the '=' padding characters completely optional. + if (eof && modulus >= 2) { // if modulus < 2, nothing to do + ensureBufferSize(decodeSize); + + // we ignore partial bytes, i.e. only multiples of 8 count + switch (modulus) { + case 2 : // 10 bits, drop 2 and output one byte + buffer[pos++] = (byte) ((bitWorkArea >> 2) & MASK_8BITS); + break; + case 3 : // 15 bits, drop 7 and output 1 byte + buffer[pos++] = (byte) ((bitWorkArea >> 7) & MASK_8BITS); + break; + case 4 : // 20 bits = 2*8 + 4 + bitWorkArea = bitWorkArea >> 4; // drop 4 bits + buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS); + break; + case 5 : // 25bits = 3*8 + 1 + bitWorkArea = bitWorkArea >> 1; + buffer[pos++] = (byte) ((bitWorkArea >> 16) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS); + break; + case 6 : // 30bits = 3*8 + 6 + bitWorkArea = bitWorkArea >> 6; + buffer[pos++] = (byte) ((bitWorkArea >> 16) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS); + break; + case 7 : // 35 = 4*8 +3 + bitWorkArea = bitWorkArea >> 3; + buffer[pos++] = (byte) ((bitWorkArea >> 24) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea >> 16) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS); + break; + } + } + } + + /** + *

+ * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with + * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush last + * remaining bytes (if not multiple of 5). + *

+ * + * @param in + * byte[] array of binary data to Base32 encode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for encoding. + */ + void encode(byte[] in, int inPos, int inAvail) { // package protected for access from I/O streams + if (eof) { + return; + } + // inAvail < 0 is how we're informed of EOF in the underlying data we're + // encoding. + if (inAvail < 0) { + eof = true; + if (0 == modulus && lineLength == 0) { + return; // no leftovers to process and not using chunking + } + ensureBufferSize(encodeSize); + int savedPos = pos; + switch (modulus) { // % 5 + case 1 : // Only 1 octet; take top 5 bits then remainder + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 3) & MASK_5BITS]; // 8-1*5 = 3 + buffer[pos++] = encodeTable[(int)(bitWorkArea << 2) & MASK_5BITS]; // 5-3=2 + buffer[pos++] = PAD; + buffer[pos++] = PAD; + buffer[pos++] = PAD; + buffer[pos++] = PAD; + buffer[pos++] = PAD; + buffer[pos++] = PAD; + break; + + case 2 : // 2 octets = 16 bits to use + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 11) & MASK_5BITS]; // 16-1*5 = 11 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 6) & MASK_5BITS]; // 16-2*5 = 6 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 1) & MASK_5BITS]; // 16-3*5 = 1 + buffer[pos++] = encodeTable[(int)(bitWorkArea << 4) & MASK_5BITS]; // 5-1 = 4 + buffer[pos++] = PAD; + buffer[pos++] = PAD; + buffer[pos++] = PAD; + buffer[pos++] = PAD; + break; + case 3 : // 3 octets = 24 bits to use + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 19) & MASK_5BITS]; // 24-1*5 = 19 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 14) & MASK_5BITS]; // 24-2*5 = 14 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 9) & MASK_5BITS]; // 24-3*5 = 9 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 4) & MASK_5BITS]; // 24-4*5 = 4 + buffer[pos++] = encodeTable[(int)(bitWorkArea << 1) & MASK_5BITS]; // 5-4 = 1 + buffer[pos++] = PAD; + buffer[pos++] = PAD; + buffer[pos++] = PAD; + break; + case 4 : // 4 octets = 32 bits to use + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 27) & MASK_5BITS]; // 32-1*5 = 27 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 22) & MASK_5BITS]; // 32-2*5 = 22 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 17) & MASK_5BITS]; // 32-3*5 = 17 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 12) & MASK_5BITS]; // 32-4*5 = 12 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 7) & MASK_5BITS]; // 32-5*5 = 7 + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 2) & MASK_5BITS]; // 32-6*5 = 2 + buffer[pos++] = encodeTable[(int)(bitWorkArea << 3) & MASK_5BITS]; // 5-2 = 3 + buffer[pos++] = PAD; + break; + } + currentLinePos += pos - savedPos; // keep track of current line position + // if currentPos == 0 we are at the start of a line, so don't add CRLF + if (lineLength > 0 && currentLinePos > 0){ // add chunk separator if required + System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length); + pos += lineSeparator.length; + } + } else { + for (int i = 0; i < inAvail; i++) { + ensureBufferSize(encodeSize); + modulus = (modulus+1) % BYTES_PER_UNENCODED_BLOCK; + int b = in[inPos++]; + if (b < 0) { + b += 256; + } + bitWorkArea = (bitWorkArea << 8) + b; // BITS_PER_BYTE + if (0 == modulus) { // we have enough bytes to create our output + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 35) & MASK_5BITS]; + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 30) & MASK_5BITS]; + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 25) & MASK_5BITS]; + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 20) & MASK_5BITS]; + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 15) & MASK_5BITS]; + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 10) & MASK_5BITS]; + buffer[pos++] = encodeTable[(int)(bitWorkArea >> 5) & MASK_5BITS]; + buffer[pos++] = encodeTable[(int)bitWorkArea & MASK_5BITS]; + currentLinePos += BYTES_PER_ENCODED_BLOCK; + if (lineLength > 0 && lineLength <= currentLinePos) { + System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length); + pos += lineSeparator.length; + currentLinePos = 0; + } + } + } + } + } + + /** + * Returns whether or not the octet is in the Base32 alphabet. + * + * @param octet + * The value to test + * @return true if the value is defined in the the Base32 alphabet false otherwise. + */ + public boolean isInAlphabet(byte octet) { + return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1; + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32InputStream.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32InputStream.java new file mode 100644 index 000000000..acb284f9b --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32InputStream.java @@ -0,0 +1,85 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import java.io.InputStream; + +/** + * Provides Base32 encoding and decoding in a streaming fashion (unlimited size). When encoding the default lineLength + * is 76 characters and the default lineEnding is CRLF, but these can be overridden by using the appropriate + * constructor. + *

+ * The default behaviour of the Base32InputStream is to DECODE, whereas the default behaviour of the Base32OutputStream + * is to ENCODE, but this behaviour can be overridden by using a different constructor. + *

+ *

+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode + * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc). + *

+ * + * @version $Revision: 1063784 $ + * @see RFC 4648 + * @since 1.5 + */ +public class Base32InputStream extends BaseNCodecInputStream { + + /** + * Creates a Base32InputStream such that all data read is Base32-decoded from the original provided InputStream. + * + * @param in + * InputStream to wrap. + */ + public Base32InputStream(InputStream in) { + this(in, false); + } + + /** + * Creates a Base32InputStream such that all data read is either Base32-encoded or Base32-decoded from the original + * provided InputStream. + * + * @param in + * InputStream to wrap. + * @param doEncode + * true if we should encode all data read from us, false if we should decode. + */ + public Base32InputStream(InputStream in, boolean doEncode) { + super(in, new Base32(false), doEncode); + } + + /** + * Creates a Base32InputStream such that all data read is either Base32-encoded or Base32-decoded from the original + * provided InputStream. + * + * @param in + * InputStream to wrap. + * @param doEncode + * true if we should encode all data read from us, false if we should decode. + * @param lineLength + * If doEncode is true, each line of encoded data will contain lineLength characters (rounded down to + * nearest multiple of 4). If lineLength <=0, the encoded data is not divided into lines. If doEncode is + * false, lineLength is ignored. + * @param lineSeparator + * If doEncode is true, each line of encoded data will be terminated with this byte sequence (e.g. \r\n). + * If lineLength <= 0, the lineSeparator is not used. If doEncode is false lineSeparator is ignored. + */ + public Base32InputStream(InputStream in, boolean doEncode, int lineLength, byte[] lineSeparator) { + super(in, new Base32(lineLength, lineSeparator), doEncode); + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32OutputStream.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32OutputStream.java new file mode 100644 index 000000000..af2f4d718 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base32OutputStream.java @@ -0,0 +1,85 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import java.io.OutputStream; + +/** + * Provides Base32 encoding and decoding in a streaming fashion (unlimited size). When encoding the default lineLength + * is 76 characters and the default lineEnding is CRLF, but these can be overridden by using the appropriate + * constructor. + *

+ * The default behaviour of the Base32OutputStream is to ENCODE, whereas the default behaviour of the Base32InputStream + * is to DECODE. But this behaviour can be overridden by using a different constructor. + *

+ *

+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode + * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc). + *

+ * + * @version $Revision: 1064132 $ + * @see RFC 4648 + * @since 1.5 + */ +public class Base32OutputStream extends BaseNCodecOutputStream { + + /** + * Creates a Base32OutputStream such that all data written is Base32-encoded to the original provided OutputStream. + * + * @param out + * OutputStream to wrap. + */ + public Base32OutputStream(OutputStream out) { + this(out, true); + } + + /** + * Creates a Base32OutputStream such that all data written is either Base32-encoded or Base32-decoded to the + * original provided OutputStream. + * + * @param out + * OutputStream to wrap. + * @param doEncode + * true if we should encode all data written to us, false if we should decode. + */ + public Base32OutputStream(OutputStream out, boolean doEncode) { + super(out, new Base32(false), doEncode); + } + + /** + * Creates a Base32OutputStream such that all data written is either Base32-encoded or Base32-decoded to the + * original provided OutputStream. + * + * @param out + * OutputStream to wrap. + * @param doEncode + * true if we should encode all data written to us, false if we should decode. + * @param lineLength + * If doEncode is true, each line of encoded data will contain lineLength characters (rounded down to + * nearest multiple of 4). If lineLength <=0, the encoded data is not divided into lines. If doEncode is + * false, lineLength is ignored. + * @param lineSeparator + * If doEncode is true, each line of encoded data will be terminated with this byte sequence (e.g. \r\n). + * If lineLength <= 0, the lineSeparator is not used. If doEncode is false lineSeparator is ignored. + */ + public Base32OutputStream(OutputStream out, boolean doEncode, int lineLength, byte[] lineSeparator) { + super(out, new Base32(lineLength, lineSeparator), doEncode); + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64.java new file mode 100644 index 000000000..07ed1a4c4 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64.java @@ -0,0 +1,756 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import java.math.BigInteger; + +/** + * Provides Base64 encoding and decoding as defined by RFC 2045. + * + *

+ * This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose + * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein. + *

+ *

+ * The class can be parameterized in the following manner with various constructors: + *

    + *
  • URL-safe mode: Default off.
  • + *
  • Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of + * 4 in the encoded data. + *
  • Line separator: Default is CRLF ("\r\n")
  • + *
+ *

+ *

+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode + * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc). + *

+ *

+ * This class is not thread-safe. Each thread should use its own instance. + *

+ * + * @see RFC 2045 + * @author Apache Software Foundation + * @since 1.0 + * @version $Revision: 1080712 $ + */ +public class Base64 extends BaseNCodec { + + /** + * BASE32 characters are 6 bits in length. + * They are formed by taking a block of 3 octets to form a 24-bit string, + * which is converted into 4 BASE64 characters. + */ + private static final int BITS_PER_ENCODED_BYTE = 6; + private static final int BYTES_PER_UNENCODED_BLOCK = 3; + private static final int BYTES_PER_ENCODED_BLOCK = 4; + + /** + * Chunk separator per RFC 2045 section 2.1. + * + *

+ * N.B. The next major release may break compatibility and make this field private. + *

+ * + * @see RFC 2045 section 2.1 + */ + static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; + + /** + * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet" + * equivalents as specified in Table 1 of RFC 2045. + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] STANDARD_ENCODE_TABLE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' + }; + + /** + * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and / + * changed to - and _ to make the encoded Base64 results more URL-SAFE. + * This table is only used when the Base64's mode is set to URL-SAFE. + */ + private static final byte[] URL_SAFE_ENCODE_TABLE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' + }; + + /** + * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified in + * Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64 + * alphabet but fall within the bounds of the array are translated to -1. + * + * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both + * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit). + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] DECODE_TABLE = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 + }; + + /** + * Base64 uses 6-bit fields. + */ + /** Mask used to extract 6 bits, used when encoding */ + private static final int MASK_6BITS = 0x3f; + + // The static final fields above are used for the original static byte[] methods on Base64. + // The private member fields below are used with the new streaming approach, which requires + // some state be preserved between calls of encode() and decode(). + + /** + * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able + * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch + * between the two modes. + */ + private final byte[] encodeTable; + + // Only one decode table currently; keep for consistency with Base32 code + private final byte[] decodeTable = DECODE_TABLE; + + /** + * Line separator for encoding. Not used when decoding. Only used if lineLength > 0. + */ + private final byte[] lineSeparator; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * decodeSize = 3 + lineSeparator.length; + */ + private final int decodeSize; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * encodeSize = 4 + lineSeparator.length; + */ + private final int encodeSize; + + /** + * Place holder for the bytes we're dealing with for our based logic. + * Bitwise operations store and extract the encoding or decoding from this variable. + */ + private int bitWorkArea; + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length is 0 (no chunking), and the encoding table is STANDARD_ENCODE_TABLE. + *

+ * + *

+ * When decoding all variants are supported. + *

+ */ + public Base64() { + this(0); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in the given URL-safe mode. + *

+ * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE. + *

+ * + *

+ * When decoding all variants are supported. + *

+ * + * @param urlSafe + * if true, URL-safe encoding is used. In most cases this should be set to + * false. + * @since 1.4 + */ + public Base64(boolean urlSafe) { + this(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4). + * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding. + * @since 1.4 + */ + public Base64(int lineLength) { + this(lineLength, CHUNK_SEPARATOR); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4). + * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @throws IllegalArgumentException + * Thrown when the provided lineSeparator included some base64 characters. + * @since 1.4 + */ + public Base64(int lineLength, byte[] lineSeparator) { + this(lineLength, lineSeparator, false); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4). + * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @param urlSafe + * Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode + * operations. Decoding seamlessly handles both modes. + * @throws IllegalArgumentException + * The provided lineSeparator included some base64 characters. That's not going to work! + * @since 1.4 + */ + public Base64(int lineLength, byte[] lineSeparator, boolean urlSafe) { + super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, + lineLength, + lineSeparator == null ? 0 : lineSeparator.length); + // TODO could be simplified if there is no requirement to reject invalid line sep when length <=0 + // @see test case Base64Test.testConstructors() + if (lineSeparator != null) { + if (containsAlphabetOrPad(lineSeparator)) { + String sep = StringUtils.newStringUtf8(lineSeparator); + throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]"); + } + if (lineLength > 0){ // null line-sep forces no chunking rather than throwing IAE + this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length; + this.lineSeparator = new byte[lineSeparator.length]; + System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length); + } else { + this.encodeSize = BYTES_PER_ENCODED_BLOCK; + this.lineSeparator = null; + } + } else { + this.encodeSize = BYTES_PER_ENCODED_BLOCK; + this.lineSeparator = null; + } + this.decodeSize = this.encodeSize - 1; + this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE; + } + + /** + * Returns our current encode mode. True if we're URL-SAFE, false otherwise. + * + * @return true if we're in URL-SAFE mode, false otherwise. + * @since 1.4 + */ + public boolean isUrlSafe() { + return this.encodeTable == URL_SAFE_ENCODE_TABLE; + } + + /** + *

+ * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with + * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush last + * remaining bytes (if not multiple of 3). + *

+ *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ * + * @param in + * byte[] array of binary data to base64 encode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for encoding. + */ + void encode(byte[] in, int inPos, int inAvail) { + if (eof) { + return; + } + // inAvail < 0 is how we're informed of EOF in the underlying data we're + // encoding. + if (inAvail < 0) { + eof = true; + if (0 == modulus && lineLength == 0) { + return; // no leftovers to process and not using chunking + } + ensureBufferSize(encodeSize); + int savedPos = pos; + switch (modulus) { // 0-2 + case 1 : // 8 bits = 6 + 2 + buffer[pos++] = encodeTable[(bitWorkArea >> 2) & MASK_6BITS]; // top 6 bits + buffer[pos++] = encodeTable[(bitWorkArea << 4) & MASK_6BITS]; // remaining 2 + // URL-SAFE skips the padding to further reduce size. + if (encodeTable == STANDARD_ENCODE_TABLE) { + buffer[pos++] = PAD; + buffer[pos++] = PAD; + } + break; + + case 2 : // 16 bits = 6 + 6 + 4 + buffer[pos++] = encodeTable[(bitWorkArea >> 10) & MASK_6BITS]; + buffer[pos++] = encodeTable[(bitWorkArea >> 4) & MASK_6BITS]; + buffer[pos++] = encodeTable[(bitWorkArea << 2) & MASK_6BITS]; + // URL-SAFE skips the padding to further reduce size. + if (encodeTable == STANDARD_ENCODE_TABLE) { + buffer[pos++] = PAD; + } + break; + } + currentLinePos += pos - savedPos; // keep track of current line position + // if currentPos == 0 we are at the start of a line, so don't add CRLF + if (lineLength > 0 && currentLinePos > 0) { + System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length); + pos += lineSeparator.length; + } + } else { + for (int i = 0; i < inAvail; i++) { + ensureBufferSize(encodeSize); + modulus = (modulus+1) % BYTES_PER_UNENCODED_BLOCK; + int b = in[inPos++]; + if (b < 0) { + b += 256; + } + bitWorkArea = (bitWorkArea << 8) + b; // BITS_PER_BYTE + if (0 == modulus) { // 3 bytes = 24 bits = 4 * 6 bits to extract + buffer[pos++] = encodeTable[(bitWorkArea >> 18) & MASK_6BITS]; + buffer[pos++] = encodeTable[(bitWorkArea >> 12) & MASK_6BITS]; + buffer[pos++] = encodeTable[(bitWorkArea >> 6) & MASK_6BITS]; + buffer[pos++] = encodeTable[bitWorkArea & MASK_6BITS]; + currentLinePos += BYTES_PER_ENCODED_BLOCK; + if (lineLength > 0 && lineLength <= currentLinePos) { + System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length); + pos += lineSeparator.length; + currentLinePos = 0; + } + } + } + } + } + + /** + *

+ * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once + * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1" + * call is not necessary when decoding, but it doesn't hurt, either. + *

+ *

+ * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are + * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in, + * garbage-out philosophy: it will not check the provided data for validity. + *

+ *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ * + * @param in + * byte[] array of ascii data to base64 decode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for encoding. + */ + void decode(byte[] in, int inPos, int inAvail) { + if (eof) { + return; + } + if (inAvail < 0) { + eof = true; + } + for (int i = 0; i < inAvail; i++) { + ensureBufferSize(decodeSize); + byte b = in[inPos++]; + if (b == PAD) { + // We're done. + eof = true; + break; + } else { + if (b >= 0 && b < DECODE_TABLE.length) { + int result = DECODE_TABLE[b]; + if (result >= 0) { + modulus = (modulus+1) % BYTES_PER_ENCODED_BLOCK; + bitWorkArea = (bitWorkArea << BITS_PER_ENCODED_BYTE) + result; + if (modulus == 0) { + buffer[pos++] = (byte) ((bitWorkArea >> 16) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS); + buffer[pos++] = (byte) (bitWorkArea & MASK_8BITS); + } + } + } + } + } + + // Two forms of EOF as far as base64 decoder is concerned: actual + // EOF (-1) and first time '=' character is encountered in stream. + // This approach makes the '=' padding characters completely optional. + if (eof && modulus != 0) { + ensureBufferSize(decodeSize); + + // We have some spare bits remaining + // Output all whole multiples of 8 bits and ignore the rest + switch (modulus) { + // case 1: // 6 bits - ignore entirely + // break; + case 2 : // 12 bits = 8 + 4 + bitWorkArea = bitWorkArea >> 4; // dump the extra 4 bits + buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS); + break; + case 3 : // 18 bits = 8 + 8 + 2 + bitWorkArea = bitWorkArea >> 2; // dump 2 bits + buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS); + buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS); + break; + } + } + } + + /** + * Returns whether or not the octet is in the base 64 alphabet. + * + * @param octet + * The value to test + * @return true if the value is defined in the the base 64 alphabet, false otherwise. + * @since 1.4 + */ + public static boolean isBase64(byte octet) { + return octet == PAD_DEFAULT || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1); + } + + /** + * Tests a given String to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param base64 + * String to test + * @return true if all characters in the String are valid characters in the Base64 alphabet or if + * the String is empty; false, otherwise + * @since 1.5 + */ + public static boolean isBase64(String base64) { + return isBase64(StringUtils.getBytesUtf8(base64)); + } + + /** + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param arrayOctet + * byte array to test + * @return true if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; + * false, otherwise + * @deprecated 1.5 Use {@link #isBase64(byte[])}, will be removed in 2.0. + */ + public static boolean isArrayByteBase64(byte[] arrayOctet) { + return isBase64(arrayOctet); + } + + /** + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param arrayOctet + * byte array to test + * @return true if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; + * false, otherwise + * @since 1.5 + */ + public static boolean isBase64(byte[] arrayOctet) { + for (int i = 0; i < arrayOctet.length; i++) { + if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) { + return false; + } + } + return true; + } + + /** + * Encodes binary data using the base64 algorithm but does not chunk the output. + * + * @param binaryData + * binary data to encode + * @return byte[] containing Base64 characters in their UTF-8 representation. + */ + public static byte[] encodeBase64(byte[] binaryData) { + return encodeBase64(binaryData, false); + } + + /** + * Encodes binary data using the base64 algorithm but does not chunk the output. + * + * NOTE: We changed the behaviour of this method from multi-line chunking (commons-codec-1.4) to + * single-line non-chunking (commons-codec-1.5). + * + * @param binaryData + * binary data to encode + * @return String containing Base64 characters. + * @since 1.4 (NOTE: 1.4 chunked the output, whereas 1.5 does not). + */ + public static String encodeBase64String(byte[] binaryData) { + return StringUtils.newStringUtf8(encodeBase64(binaryData, false)); + } + + /** + * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The + * url-safe variation emits - and _ instead of + and / characters. + * + * @param binaryData + * binary data to encode + * @return byte[] containing Base64 characters in their UTF-8 representation. + * @since 1.4 + */ + public static byte[] encodeBase64URLSafe(byte[] binaryData) { + return encodeBase64(binaryData, false, true); + } + + /** + * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The + * url-safe variation emits - and _ instead of + and / characters. + * + * @param binaryData + * binary data to encode + * @return String containing Base64 characters + * @since 1.4 + */ + public static String encodeBase64URLSafeString(byte[] binaryData) { + return StringUtils.newStringUtf8(encodeBase64(binaryData, false, true)); + } + + /** + * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks + * + * @param binaryData + * binary data to encode + * @return Base64 characters chunked in 76 character blocks + */ + public static byte[] encodeBase64Chunked(byte[] binaryData) { + return encodeBase64(binaryData, true); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if true this encoder will chunk the base64 output into 76 character blocks + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} + */ + public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) { + return encodeBase64(binaryData, isChunked, false); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if true this encoder will chunk the base64 output into 76 character blocks + * @param urlSafe + * if true this encoder will emit - and _ instead of the usual + and / characters. + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} + * @since 1.4 + */ + public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe) { + return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if true this encoder will chunk the base64 output into 76 character blocks + * @param urlSafe + * if true this encoder will emit - and _ instead of the usual + and / characters. + * @param maxResultSize + * The maximum result size to accept. + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than maxResultSize + * @since 1.4 + */ + public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe, int maxResultSize) { + if (binaryData == null || binaryData.length == 0) { + return binaryData; + } + + // Create this so can use the super-class method + // Also ensures that the same roundings are performed by the ctor and the code + Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe); + long len = b64.getEncodedLength(binaryData); + if (len > maxResultSize) { + throw new IllegalArgumentException("Input array too big, the output array would be bigger (" + + len + + ") than the specified maximum size of " + + maxResultSize); + } + + return b64.encode(binaryData); + } + + /** + * Decodes a Base64 String into octets + * + * @param base64String + * String containing Base64 data + * @return Array containing decoded data. + * @since 1.4 + */ + public static byte[] decodeBase64(String base64String) { + return new Base64().decode(base64String); + } + + /** + * Decodes Base64 data into octets + * + * @param base64Data + * Byte array containing Base64 data + * @return Array containing decoded data. + */ + public static byte[] decodeBase64(byte[] base64Data) { + return new Base64().decode(base64Data); + } + + // Implementation of the Encoder Interface + + // Implementation of integer encoding used for crypto + /** + * Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature + * + * @param pArray + * a byte array containing base64 character data + * @return A BigInteger + * @since 1.4 + */ + public static BigInteger decodeInteger(byte[] pArray) { + return new BigInteger(1, decodeBase64(pArray)); + } + + /** + * Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature + * + * @param bigInt + * a BigInteger + * @return A byte array containing base64 character data + * @throws NullPointerException + * if null is passed in + * @since 1.4 + */ + public static byte[] encodeInteger(BigInteger bigInt) { + if (bigInt == null) { + throw new NullPointerException("encodeInteger called with null parameter"); + } + return encodeBase64(toIntegerBytes(bigInt), false); + } + + /** + * Returns a byte-array representation of a BigInteger without sign bit. + * + * @param bigInt + * BigInteger to be converted + * @return a byte array representation of the BigInteger parameter + */ + static byte[] toIntegerBytes(BigInteger bigInt) { + int bitlen = bigInt.bitLength(); + // round bitlen + bitlen = ((bitlen + 7) >> 3) << 3; + byte[] bigBytes = bigInt.toByteArray(); + + if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) { + return bigBytes; + } + // set up params for copying everything but sign bit + int startSrc = 0; + int len = bigBytes.length; + + // if bigInt is exactly byte-aligned, just skip signbit in copy + if ((bigInt.bitLength() % 8) == 0) { + startSrc = 1; + len--; + } + int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec + byte[] resizedBytes = new byte[bitlen / 8]; + System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len); + return resizedBytes; + } + + /** + * Returns whether or not the octet is in the Base32 alphabet. + * + * @param octet + * The value to test + * @return true if the value is defined in the the Base32 alphabet false otherwise. + */ + protected boolean isInAlphabet(byte octet) { + return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1; + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64InputStream.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64InputStream.java new file mode 100644 index 000000000..cf99ceb91 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64InputStream.java @@ -0,0 +1,89 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import java.io.InputStream; + +/** + * Provides Base64 encoding and decoding in a streaming fashion (unlimited size). When encoding the default lineLength + * is 76 characters and the default lineEnding is CRLF, but these can be overridden by using the appropriate + * constructor. + *

+ * The default behaviour of the Base64InputStream is to DECODE, whereas the default behaviour of the Base64OutputStream + * is to ENCODE, but this behaviour can be overridden by using a different constructor. + *

+ *

+ * This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose + * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein. + *

+ *

+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode + * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc). + *

+ * + * @author Apache Software Foundation + * @version $Id: Base64InputStream.java 1064424 2011-01-28 02:02:46Z sebb $ + * @see RFC 2045 + * @since 1.4 + */ +public class Base64InputStream extends BaseNCodecInputStream { + + /** + * Creates a Base64InputStream such that all data read is Base64-decoded from the original provided InputStream. + * + * @param in + * InputStream to wrap. + */ + public Base64InputStream(InputStream in) { + this(in, false); + } + + /** + * Creates a Base64InputStream such that all data read is either Base64-encoded or Base64-decoded from the original + * provided InputStream. + * + * @param in + * InputStream to wrap. + * @param doEncode + * true if we should encode all data read from us, false if we should decode. + */ + public Base64InputStream(InputStream in, boolean doEncode) { + super(in, new Base64(false), doEncode); + } + + /** + * Creates a Base64InputStream such that all data read is either Base64-encoded or Base64-decoded from the original + * provided InputStream. + * + * @param in + * InputStream to wrap. + * @param doEncode + * true if we should encode all data read from us, false if we should decode. + * @param lineLength + * If doEncode is true, each line of encoded data will contain lineLength characters (rounded down to + * nearest multiple of 4). If lineLength <=0, the encoded data is not divided into lines. If doEncode is + * false, lineLength is ignored. + * @param lineSeparator + * If doEncode is true, each line of encoded data will be terminated with this byte sequence (e.g. \r\n). + * If lineLength <= 0, the lineSeparator is not used. If doEncode is false lineSeparator is ignored. + */ + public Base64InputStream(InputStream in, boolean doEncode, int lineLength, byte[] lineSeparator) { + super(in, new Base64(lineLength, lineSeparator), doEncode); + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64OutputStream.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64OutputStream.java new file mode 100644 index 000000000..df880c2b9 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Base64OutputStream.java @@ -0,0 +1,89 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import java.io.OutputStream; + +/** + * Provides Base64 encoding and decoding in a streaming fashion (unlimited size). When encoding the default lineLength + * is 76 characters and the default lineEnding is CRLF, but these can be overridden by using the appropriate + * constructor. + *

+ * The default behaviour of the Base64OutputStream is to ENCODE, whereas the default behaviour of the Base64InputStream + * is to DECODE. But this behaviour can be overridden by using a different constructor. + *

+ *

+ * This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose + * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein. + *

+ *

+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode + * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc). + *

+ * + * @author Apache Software Foundation + * @version $Id: Base64OutputStream.java 1064424 2011-01-28 02:02:46Z sebb $ + * @see RFC 2045 + * @since 1.4 + */ +public class Base64OutputStream extends BaseNCodecOutputStream { + + /** + * Creates a Base64OutputStream such that all data written is Base64-encoded to the original provided OutputStream. + * + * @param out + * OutputStream to wrap. + */ + public Base64OutputStream(OutputStream out) { + this(out, true); + } + + /** + * Creates a Base64OutputStream such that all data written is either Base64-encoded or Base64-decoded to the + * original provided OutputStream. + * + * @param out + * OutputStream to wrap. + * @param doEncode + * true if we should encode all data written to us, false if we should decode. + */ + public Base64OutputStream(OutputStream out, boolean doEncode) { + super(out,new Base64(false), doEncode); + } + + /** + * Creates a Base64OutputStream such that all data written is either Base64-encoded or Base64-decoded to the + * original provided OutputStream. + * + * @param out + * OutputStream to wrap. + * @param doEncode + * true if we should encode all data written to us, false if we should decode. + * @param lineLength + * If doEncode is true, each line of encoded data will contain lineLength characters (rounded down to + * nearest multiple of 4). If lineLength <=0, the encoded data is not divided into lines. If doEncode is + * false, lineLength is ignored. + * @param lineSeparator + * If doEncode is true, each line of encoded data will be terminated with this byte sequence (e.g. \r\n). + * If lineLength <= 0, the lineSeparator is not used. If doEncode is false lineSeparator is ignored. + */ + public Base64OutputStream(OutputStream out, boolean doEncode, int lineLength, byte[] lineSeparator) { + super(out, new Base64(lineLength, lineSeparator), doEncode); + } +} \ No newline at end of file diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodec.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodec.java new file mode 100644 index 000000000..c2ed4efef --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodec.java @@ -0,0 +1,445 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import org.mozilla.apache.commons.codec.BinaryDecoder; +import org.mozilla.apache.commons.codec.BinaryEncoder; +import org.mozilla.apache.commons.codec.DecoderException; +import org.mozilla.apache.commons.codec.EncoderException; + +/** + * Abstract superclass for Base-N encoders and decoders. + * + *

+ * This class is not thread-safe. + * Each thread should use its own instance. + *

+ */ +public abstract class BaseNCodec implements BinaryEncoder, BinaryDecoder { + + /** + * MIME chunk size per RFC 2045 section 6.8. + * + *

+ * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any + * equal signs. + *

+ * + * @see RFC 2045 section 6.8 + */ + public static final int MIME_CHUNK_SIZE = 76; + + /** + * PEM chunk size per RFC 1421 section 4.3.2.4. + * + *

+ * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any + * equal signs. + *

+ * + * @see RFC 1421 section 4.3.2.4 + */ + public static final int PEM_CHUNK_SIZE = 64; + + private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2; + + /** + * Defines the default buffer size - currently {@value} + * - must be large enough for at least one encoded block+separator + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** Mask used to extract 8 bits, used in decoding bytes */ + protected static final int MASK_8BITS = 0xff; + + /** + * Byte used to pad output. + */ + protected static final byte PAD_DEFAULT = '='; // Allow static access to default + + protected final byte PAD = PAD_DEFAULT; // instance variable just in case it needs to vary later + + /** Number of bytes in each full block of unencoded data, e.g. 4 for Base64 and 5 for Base32 */ + private final int unencodedBlockSize; + + /** Number of bytes in each full block of encoded data, e.g. 3 for Base64 and 8 for Base32 */ + private final int encodedBlockSize; + + /** + * Chunksize for encoding. Not used when decoding. + * A value of zero or less implies no chunking of the encoded data. + * Rounded down to nearest multiple of encodedBlockSize. + */ + protected final int lineLength; + + /** + * Size of chunk separator. Not used unless {@link #lineLength} > 0. + */ + private final int chunkSeparatorLength; + + /** + * Buffer for streaming. + */ + protected byte[] buffer; + + /** + * Position where next character should be written in the buffer. + */ + protected int pos; + + /** + * Position where next character should be read from the buffer. + */ + private int readPos; + + /** + * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this object becomes useless, + * and must be thrown away. + */ + protected boolean eof; + + /** + * Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to + * make sure each encoded line never goes beyond lineLength (if lineLength > 0). + */ + protected int currentLinePos; + + /** + * Writes to the buffer only occur after every 3/5 reads when encoding, and every 4/8 reads when decoding. + * This variable helps track that. + */ + protected int modulus; + + /** + * Note lineLength is rounded down to the nearest multiple of {@link #encodedBlockSize} + * If chunkSeparatorLength is zero, then chunking is disabled. + * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3) + * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4) + * @param lineLength if > 0, use chunking with a length lineLength + * @param chunkSeparatorLength the chunk separator length, if relevant + */ + protected BaseNCodec(int unencodedBlockSize, int encodedBlockSize, int lineLength, int chunkSeparatorLength){ + this.unencodedBlockSize = unencodedBlockSize; + this.encodedBlockSize = encodedBlockSize; + this.lineLength = (lineLength > 0 && chunkSeparatorLength > 0) ? (lineLength / encodedBlockSize) * encodedBlockSize : 0; + this.chunkSeparatorLength = chunkSeparatorLength; + } + + /** + * Returns true if this object has buffered data for reading. + * + * @return true if there is data still available for reading. + */ + boolean hasData() { // package protected for access from I/O streams + return this.buffer != null; + } + + /** + * Returns the amount of buffered data available for reading. + * + * @return The amount of buffered data available for reading. + */ + int available() { // package protected for access from I/O streams + return buffer != null ? pos - readPos : 0; + } + + /** + * Get the default buffer size. Can be overridden. + * + * @return {@link #DEFAULT_BUFFER_SIZE} + */ + protected int getDefaultBufferSize() { + return DEFAULT_BUFFER_SIZE; + } + + /** Increases our buffer by the {@link #DEFAULT_BUFFER_RESIZE_FACTOR}. */ + private void resizeBuffer() { + if (buffer == null) { + buffer = new byte[getDefaultBufferSize()]; + pos = 0; + readPos = 0; + } else { + byte[] b = new byte[buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR]; + System.arraycopy(buffer, 0, b, 0, buffer.length); + buffer = b; + } + } + + /** + * Ensure that the buffer has room for size bytes + * + * @param size minimum spare space required + */ + protected void ensureBufferSize(int size){ + if ((buffer == null) || (buffer.length < pos + size)){ + resizeBuffer(); + } + } + + /** + * Extracts buffered data into the provided byte[] array, starting at position bPos, + * up to a maximum of bAvail bytes. Returns how many bytes were actually extracted. + * + * @param b + * byte[] array to extract the buffered data into. + * @param bPos + * position in byte[] array to start extraction at. + * @param bAvail + * amount of bytes we're allowed to extract. We may extract fewer (if fewer are available). + * @return The number of bytes successfully extracted into the provided byte[] array. + */ + int readResults(byte[] b, int bPos, int bAvail) { // package protected for access from I/O streams + if (buffer != null) { + int len = Math.min(available(), bAvail); + System.arraycopy(buffer, readPos, b, bPos, len); + readPos += len; + if (readPos >= pos) { + buffer = null; // so hasData() will return false, and this method can return -1 + } + return len; + } + return eof ? -1 : 0; + } + + /** + * Checks if a byte value is whitespace or not. + * Whitespace is taken to mean: space, tab, CR, LF + * @param byteToCheck + * the byte to check + * @return true if byte is whitespace, false otherwise + */ + protected static boolean isWhiteSpace(byte byteToCheck) { + switch (byteToCheck) { + case ' ' : + case '\n' : + case '\r' : + case '\t' : + return true; + default : + return false; + } + } + + /** + * Resets this object to its initial newly constructed state. + */ + private void reset() { + buffer = null; + pos = 0; + readPos = 0; + currentLinePos = 0; + modulus = 0; + eof = false; + } + + /** + * Encodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of the + * Encoder interface, and will throw an EncoderException if the supplied object is not of type byte[]. + * + * @param pObject + * Object to encode + * @return An object (of type byte[]) containing the Base-N encoded data which corresponds to the byte[] supplied. + * @throws EncoderException + * if the parameter supplied is not of type byte[] + */ + public Object encode(Object pObject) throws EncoderException { + if (!(pObject instanceof byte[])) { + throw new EncoderException("Parameter supplied to Base-N encode is not a byte[]"); + } + return encode((byte[]) pObject); + } + + /** + * Encodes a byte[] containing binary data, into a String containing characters in the Base-N alphabet. + * + * @param pArray + * a byte array containing binary data + * @return A String containing only Base-N character data + */ + public String encodeToString(byte[] pArray) { + return StringUtils.newStringUtf8(encode(pArray)); + } + + /** + * Decodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of the + * Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String. + * + * @param pObject + * Object to decode + * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String supplied. + * @throws DecoderException + * if the parameter supplied is not of type byte[] + */ + public Object decode(Object pObject) throws DecoderException { + if (pObject instanceof byte[]) { + return decode((byte[]) pObject); + } else if (pObject instanceof String) { + return decode((String) pObject); + } else { + throw new DecoderException("Parameter supplied to Base-N decode is not a byte[] or a String"); + } + } + + /** + * Decodes a String containing characters in the Base-N alphabet. + * + * @param pArray + * A String containing Base-N character data + * @return a byte array containing binary data + */ + public byte[] decode(String pArray) { + return decode(StringUtils.getBytesUtf8(pArray)); + } + + /** + * Decodes a byte[] containing characters in the Base-N alphabet. + * + * @param pArray + * A byte array containing Base-N character data + * @return a byte array containing binary data + */ + public byte[] decode(byte[] pArray) { + reset(); + if (pArray == null || pArray.length == 0) { + return pArray; + } + decode(pArray, 0, pArray.length); + decode(pArray, 0, -1); // Notify decoder of EOF. + byte[] result = new byte[pos]; + readResults(result, 0, result.length); + return result; + } + + /** + * Encodes a byte[] containing binary data, into a byte[] containing characters in the alphabet. + * + * @param pArray + * a byte array containing binary data + * @return A byte array containing only the basen alphabetic character data + */ + public byte[] encode(byte[] pArray) { + reset(); + if (pArray == null || pArray.length == 0) { + return pArray; + } + encode(pArray, 0, pArray.length); + encode(pArray, 0, -1); // Notify encoder of EOF. + byte[] buf = new byte[pos - readPos]; + readResults(buf, 0, buf.length); + return buf; + } + + /** + * Encodes a byte[] containing binary data, into a String containing characters in the appropriate alphabet. + * Uses UTF8 encoding. + * + * @param pArray a byte array containing binary data + * @return String containing only character data in the appropriate alphabet. + */ + public String encodeAsString(byte[] pArray){ + return StringUtils.newStringUtf8(encode(pArray)); + } + + abstract void encode(byte[] pArray, int i, int length); // package protected for access from I/O streams + + abstract void decode(byte[] pArray, int i, int length); // package protected for access from I/O streams + + /** + * Returns whether or not the octet is in the current alphabet. + * Does not allow whitespace or pad. + * + * @param value The value to test + * + * @return true if the value is defined in the current alphabet, false otherwise. + */ + protected abstract boolean isInAlphabet(byte value); + + /** + * Tests a given byte array to see if it contains only valid characters within the alphabet. + * The method optionally treats whitespace and pad as valid. + * + * @param arrayOctet byte array to test + * @param allowWSPad if true, then whitespace and PAD are also allowed + * + * @return true if all bytes are valid characters in the alphabet or if the byte array is empty; + * false, otherwise + */ + public boolean isInAlphabet(byte[] arrayOctet, boolean allowWSPad) { + for (int i = 0; i < arrayOctet.length; i++) { + if (!isInAlphabet(arrayOctet[i]) && + (!allowWSPad || (arrayOctet[i] != PAD) && !isWhiteSpace(arrayOctet[i]))) { + return false; + } + } + return true; + } + + /** + * Tests a given String to see if it contains only valid characters within the alphabet. + * The method treats whitespace and PAD as valid. + * + * @param basen String to test + * @return true if all characters in the String are valid characters in the alphabet or if + * the String is empty; false, otherwise + * @see #isInAlphabet(byte[], boolean) + */ + public boolean isInAlphabet(String basen) { + return isInAlphabet(StringUtils.getBytesUtf8(basen), true); + } + + /** + * Tests a given byte array to see if it contains any characters within the alphabet or PAD. + * + * Intended for use in checking line-ending arrays + * + * @param arrayOctet + * byte array to test + * @return true if any byte is a valid character in the alphabet or PAD; false otherwise + */ + protected boolean containsAlphabetOrPad(byte[] arrayOctet) { + if (arrayOctet == null) { + return false; + } + for (int i = 0; i < arrayOctet.length; i++) { + if (PAD == arrayOctet[i] || isInAlphabet(arrayOctet[i])) { + return true; + } + } + return false; + } + + /** + * Calculates the amount of space needed to encode the supplied array. + * + * @param pArray byte[] array which will later be encoded + * + * @return amount of space needed to encoded the supplied array. + * Returns a long since a max-len array will require > Integer.MAX_VALUE + */ + public long getEncodedLength(byte[] pArray) { + // Calculate non-chunked size - rounded up to allow for padding + // cast to long is needed to avoid possibility of overflow + long len = ((pArray.length + unencodedBlockSize-1) / unencodedBlockSize) * (long) encodedBlockSize; + if (lineLength > 0) { // We're using chunking + // Round up to nearest multiple + len += ((len + lineLength-1) / lineLength) * chunkSeparatorLength; + } + return len; + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodecInputStream.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodecInputStream.java new file mode 100644 index 000000000..0aa879b15 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodecInputStream.java @@ -0,0 +1,132 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Abstract superclass for Base-N input streams. + * + * @since 1.5 + */ +public class BaseNCodecInputStream extends FilterInputStream { + + private final boolean doEncode; + + private final BaseNCodec baseNCodec; + + private final byte[] singleByte = new byte[1]; + + protected BaseNCodecInputStream(InputStream in, BaseNCodec baseNCodec, boolean doEncode) { + super(in); + this.doEncode = doEncode; + this.baseNCodec = baseNCodec; + } + + /** + * Reads one byte from this input stream. + * + * @return the byte as an integer in the range 0 to 255. Returns -1 if EOF has been reached. + * @throws IOException + * if an I/O error occurs. + */ + public int read() throws IOException { + int r = read(singleByte, 0, 1); + while (r == 0) { + r = read(singleByte, 0, 1); + } + if (r > 0) { + return singleByte[0] < 0 ? 256 + singleByte[0] : singleByte[0]; + } + return -1; + } + + /** + * Attempts to read len bytes into the specified b array starting at offset + * from this InputStream. + * + * @param b + * destination byte array + * @param offset + * where to start writing the bytes + * @param len + * maximum number of bytes to read + * + * @return number of bytes read + * @throws IOException + * if an I/O error occurs. + * @throws NullPointerException + * if the byte array parameter is null + * @throws IndexOutOfBoundsException + * if offset, len or buffer size are invalid + */ + public int read(byte b[], int offset, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (offset < 0 || len < 0) { + throw new IndexOutOfBoundsException(); + } else if (offset > b.length || offset + len > b.length) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } else { + int readLen = 0; + /* + Rationale for while-loop on (readLen == 0): + ----- + Base32.readResults() usually returns > 0 or EOF (-1). In the + rare case where it returns 0, we just keep trying. + + This is essentially an undocumented contract for InputStream + implementors that want their code to work properly with + java.io.InputStreamReader, since the latter hates it when + InputStream.read(byte[]) returns a zero. Unfortunately our + readResults() call must return 0 if a large amount of the data + being decoded was non-base32, so this while-loop enables proper + interop with InputStreamReader for that scenario. + ----- + This is a fix for CODEC-101 + */ + while (readLen == 0) { + if (!baseNCodec.hasData()) { + byte[] buf = new byte[doEncode ? 4096 : 8192]; + int c = in.read(buf); + if (doEncode) { + baseNCodec.encode(buf, 0, c); + } else { + baseNCodec.decode(buf, 0, c); + } + } + readLen = baseNCodec.readResults(b, offset, len); + } + return readLen; + } + } + /** + * {@inheritDoc} + * + * @return false + */ + public boolean markSupported() { + return false; // not an easy job to support marks + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodecOutputStream.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodecOutputStream.java new file mode 100644 index 000000000..bdcbd4d34 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BaseNCodecOutputStream.java @@ -0,0 +1,142 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Abstract superclass for Base-N output streams. + * + * @since 1.5 + */ +public class BaseNCodecOutputStream extends FilterOutputStream { + + private final boolean doEncode; + + private final BaseNCodec baseNCodec; + + private final byte[] singleByte = new byte[1]; + + public BaseNCodecOutputStream(OutputStream out, BaseNCodec basedCodec, boolean doEncode) { + super(out); + this.baseNCodec = basedCodec; + this.doEncode = doEncode; + } + + /** + * Writes the specified byte to this output stream. + * + * @param i + * source byte + * @throws IOException + * if an I/O error occurs. + */ + public void write(int i) throws IOException { + singleByte[0] = (byte) i; + write(singleByte, 0, 1); + } + + /** + * Writes len bytes from the specified b array starting at offset to this + * output stream. + * + * @param b + * source byte array + * @param offset + * where to start reading the bytes + * @param len + * maximum number of bytes to write + * + * @throws IOException + * if an I/O error occurs. + * @throws NullPointerException + * if the byte array parameter is null + * @throws IndexOutOfBoundsException + * if offset, len or buffer size are invalid + */ + public void write(byte b[], int offset, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (offset < 0 || len < 0) { + throw new IndexOutOfBoundsException(); + } else if (offset > b.length || offset + len > b.length) { + throw new IndexOutOfBoundsException(); + } else if (len > 0) { + if (doEncode) { + baseNCodec.encode(b, offset, len); + } else { + baseNCodec.decode(b, offset, len); + } + flush(false); + } + } + + /** + * Flushes this output stream and forces any buffered output bytes to be written out to the stream. If propogate is + * true, the wrapped stream will also be flushed. + * + * @param propogate + * boolean flag to indicate whether the wrapped OutputStream should also be flushed. + * @throws IOException + * if an I/O error occurs. + */ + private void flush(boolean propogate) throws IOException { + int avail = baseNCodec.available(); + if (avail > 0) { + byte[] buf = new byte[avail]; + int c = baseNCodec.readResults(buf, 0, avail); + if (c > 0) { + out.write(buf, 0, c); + } + } + if (propogate) { + out.flush(); + } + } + + /** + * Flushes this output stream and forces any buffered output bytes to be written out to the stream. + * + * @throws IOException + * if an I/O error occurs. + */ + public void flush() throws IOException { + flush(true); + } + + /** + * Closes this output stream and releases any system resources associated with the stream. + * + * @throws IOException + * if an I/O error occurs. + */ + public void close() throws IOException { + // Notify encoder of EOF (-1). + if (doEncode) { + baseNCodec.encode(singleByte, 0, -1); + } else { + baseNCodec.decode(singleByte, 0, -1); + } + flush(); + out.close(); + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BinaryCodec.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BinaryCodec.java new file mode 100644 index 000000000..141474151 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/BinaryCodec.java @@ -0,0 +1,297 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import org.mozilla.apache.commons.codec.BinaryDecoder; +import org.mozilla.apache.commons.codec.BinaryEncoder; +import org.mozilla.apache.commons.codec.DecoderException; +import org.mozilla.apache.commons.codec.EncoderException; + +/** + * Converts between byte arrays and strings of "0"s and "1"s. + * + * TODO: may want to add more bit vector functions like and/or/xor/nand + * TODO: also might be good to generate boolean[] from byte[] et cetera. + * + * @author Apache Software Foundation + * @since 1.3 + * @version $Id: BinaryCodec.java 1080701 2011-03-11 17:52:27Z ggregory $ + */ +public class BinaryCodec implements BinaryDecoder, BinaryEncoder { + /* + * tried to avoid using ArrayUtils to minimize dependencies while using these empty arrays - dep is just not worth + * it. + */ + /** Empty char array. */ + private static final char[] EMPTY_CHAR_ARRAY = new char[0]; + + /** Empty byte array. */ + private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + + /** Mask for bit 0 of a byte. */ + private static final int BIT_0 = 1; + + /** Mask for bit 1 of a byte. */ + private static final int BIT_1 = 0x02; + + /** Mask for bit 2 of a byte. */ + private static final int BIT_2 = 0x04; + + /** Mask for bit 3 of a byte. */ + private static final int BIT_3 = 0x08; + + /** Mask for bit 4 of a byte. */ + private static final int BIT_4 = 0x10; + + /** Mask for bit 5 of a byte. */ + private static final int BIT_5 = 0x20; + + /** Mask for bit 6 of a byte. */ + private static final int BIT_6 = 0x40; + + /** Mask for bit 7 of a byte. */ + private static final int BIT_7 = 0x80; + + private static final int[] BITS = {BIT_0, BIT_1, BIT_2, BIT_3, BIT_4, BIT_5, BIT_6, BIT_7}; + + /** + * Converts an array of raw binary data into an array of ASCII 0 and 1 characters. + * + * @param raw + * the raw binary data to convert + * @return 0 and 1 ASCII character bytes one for each bit of the argument + * @see org.mozilla.apache.commons.codec.BinaryEncoder#encode(byte[]) + */ + public byte[] encode(byte[] raw) { + return toAsciiBytes(raw); + } + + /** + * Converts an array of raw binary data into an array of ASCII 0 and 1 chars. + * + * @param raw + * the raw binary data to convert + * @return 0 and 1 ASCII character chars one for each bit of the argument + * @throws EncoderException + * if the argument is not a byte[] + * @see org.mozilla.apache.commons.codec.Encoder#encode(Object) + */ + public Object encode(Object raw) throws EncoderException { + if (!(raw instanceof byte[])) { + throw new EncoderException("argument not a byte array"); + } + return toAsciiChars((byte[]) raw); + } + + /** + * Decodes a byte array where each byte represents an ASCII '0' or '1'. + * + * @param ascii + * each byte represents an ASCII '0' or '1' + * @return the raw encoded binary where each bit corresponds to a byte in the byte array argument + * @throws DecoderException + * if argument is not a byte[], char[] or String + * @see org.mozilla.apache.commons.codec.Decoder#decode(Object) + */ + public Object decode(Object ascii) throws DecoderException { + if (ascii == null) { + return EMPTY_BYTE_ARRAY; + } + if (ascii instanceof byte[]) { + return fromAscii((byte[]) ascii); + } + if (ascii instanceof char[]) { + return fromAscii((char[]) ascii); + } + if (ascii instanceof String) { + return fromAscii(((String) ascii).toCharArray()); + } + throw new DecoderException("argument not a byte array"); + } + + /** + * Decodes a byte array where each byte represents an ASCII '0' or '1'. + * + * @param ascii + * each byte represents an ASCII '0' or '1' + * @return the raw encoded binary where each bit corresponds to a byte in the byte array argument + * @see org.mozilla.apache.commons.codec.Decoder#decode(Object) + */ + public byte[] decode(byte[] ascii) { + return fromAscii(ascii); + } + + /** + * Decodes a String where each char of the String represents an ASCII '0' or '1'. + * + * @param ascii + * String of '0' and '1' characters + * @return the raw encoded binary where each bit corresponds to a byte in the byte array argument + * @see org.mozilla.apache.commons.codec.Decoder#decode(Object) + */ + public byte[] toByteArray(String ascii) { + if (ascii == null) { + return EMPTY_BYTE_ARRAY; + } + return fromAscii(ascii.toCharArray()); + } + + // ------------------------------------------------------------------------ + // + // static codec operations + // + // ------------------------------------------------------------------------ + /** + * Decodes a char array where each char represents an ASCII '0' or '1'. + * + * @param ascii + * each char represents an ASCII '0' or '1' + * @return the raw encoded binary where each bit corresponds to a char in the char array argument + */ + public static byte[] fromAscii(char[] ascii) { + if (ascii == null || ascii.length == 0) { + return EMPTY_BYTE_ARRAY; + } + // get length/8 times bytes with 3 bit shifts to the right of the length + byte[] l_raw = new byte[ascii.length >> 3]; + /* + * We decr index jj by 8 as we go along to not recompute indices using multiplication every time inside the + * loop. + */ + for (int ii = 0, jj = ascii.length - 1; ii < l_raw.length; ii++, jj -= 8) { + for (int bits = 0; bits < BITS.length; ++bits) { + if (ascii[jj - bits] == '1') { + l_raw[ii] |= BITS[bits]; + } + } + } + return l_raw; + } + + /** + * Decodes a byte array where each byte represents an ASCII '0' or '1'. + * + * @param ascii + * each byte represents an ASCII '0' or '1' + * @return the raw encoded binary where each bit corresponds to a byte in the byte array argument + */ + public static byte[] fromAscii(byte[] ascii) { + if (isEmpty(ascii)) { + return EMPTY_BYTE_ARRAY; + } + // get length/8 times bytes with 3 bit shifts to the right of the length + byte[] l_raw = new byte[ascii.length >> 3]; + /* + * We decr index jj by 8 as we go along to not recompute indices using multiplication every time inside the + * loop. + */ + for (int ii = 0, jj = ascii.length - 1; ii < l_raw.length; ii++, jj -= 8) { + for (int bits = 0; bits < BITS.length; ++bits) { + if (ascii[jj - bits] == '1') { + l_raw[ii] |= BITS[bits]; + } + } + } + return l_raw; + } + + /** + * Returns true if the given array is null or empty (size 0.) + * + * @param array + * the source array + * @return true if the given array is null or empty (size 0.) + */ + private static boolean isEmpty(byte[] array) { + return array == null || array.length == 0; + } + + /** + * Converts an array of raw binary data into an array of ASCII 0 and 1 character bytes - each byte is a truncated + * char. + * + * @param raw + * the raw binary data to convert + * @return an array of 0 and 1 character bytes for each bit of the argument + * @see org.mozilla.apache.commons.codec.BinaryEncoder#encode(byte[]) + */ + public static byte[] toAsciiBytes(byte[] raw) { + if (isEmpty(raw)) { + return EMPTY_BYTE_ARRAY; + } + // get 8 times the bytes with 3 bit shifts to the left of the length + byte[] l_ascii = new byte[raw.length << 3]; + /* + * We decr index jj by 8 as we go along to not recompute indices using multiplication every time inside the + * loop. + */ + for (int ii = 0, jj = l_ascii.length - 1; ii < raw.length; ii++, jj -= 8) { + for (int bits = 0; bits < BITS.length; ++bits) { + if ((raw[ii] & BITS[bits]) == 0) { + l_ascii[jj - bits] = '0'; + } else { + l_ascii[jj - bits] = '1'; + } + } + } + return l_ascii; + } + + /** + * Converts an array of raw binary data into an array of ASCII 0 and 1 characters. + * + * @param raw + * the raw binary data to convert + * @return an array of 0 and 1 characters for each bit of the argument + * @see org.mozilla.apache.commons.codec.BinaryEncoder#encode(byte[]) + */ + public static char[] toAsciiChars(byte[] raw) { + if (isEmpty(raw)) { + return EMPTY_CHAR_ARRAY; + } + // get 8 times the bytes with 3 bit shifts to the left of the length + char[] l_ascii = new char[raw.length << 3]; + /* + * We decr index jj by 8 as we go along to not recompute indices using multiplication every time inside the + * loop. + */ + for (int ii = 0, jj = l_ascii.length - 1; ii < raw.length; ii++, jj -= 8) { + for (int bits = 0; bits < BITS.length; ++bits) { + if ((raw[ii] & BITS[bits]) == 0) { + l_ascii[jj - bits] = '0'; + } else { + l_ascii[jj - bits] = '1'; + } + } + } + return l_ascii; + } + + /** + * Converts an array of raw binary data into a String of ASCII 0 and 1 characters. + * + * @param raw + * the raw binary data to convert + * @return a String of 0 and 1 characters representing the binary data + * @see org.mozilla.apache.commons.codec.BinaryEncoder#encode(byte[]) + */ + public static String toAsciiString(byte[] raw) { + return new String(toAsciiChars(raw)); + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Hex.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Hex.java new file mode 100644 index 000000000..a2e34fe34 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/Hex.java @@ -0,0 +1,302 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import java.io.UnsupportedEncodingException; + +import org.mozilla.apache.commons.codec.BinaryDecoder; +import org.mozilla.apache.commons.codec.BinaryEncoder; +import org.mozilla.apache.commons.codec.CharEncoding; +import org.mozilla.apache.commons.codec.DecoderException; +import org.mozilla.apache.commons.codec.EncoderException; + +/** + * Converts hexadecimal Strings. The charset used for certain operation can be set, the default is set in + * {@link #DEFAULT_CHARSET_NAME} + * + * @since 1.1 + * @author Apache Software Foundation + * @version $Id: Hex.java 1080701 2011-03-11 17:52:27Z ggregory $ + */ +public class Hex implements BinaryEncoder, BinaryDecoder { + + /** + * Default charset name is {@link CharEncoding#UTF_8} + * + * @since 1.4 + */ + public static final String DEFAULT_CHARSET_NAME = CharEncoding.UTF_8; + + /** + * Used to build output as Hex + */ + private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + /** + * Used to build output as Hex + */ + private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + /** + * Converts an array of characters representing hexadecimal values into an array of bytes of those same values. The + * returned array will be half the length of the passed array, as it takes two characters to represent any given + * byte. An exception is thrown if the passed char array has an odd number of elements. + * + * @param data + * An array of characters containing hexadecimal digits + * @return A byte array containing binary data decoded from the supplied char array. + * @throws DecoderException + * Thrown if an odd number or illegal of characters is supplied + */ + public static byte[] decodeHex(char[] data) throws DecoderException { + + int len = data.length; + + if ((len & 0x01) != 0) { + throw new DecoderException("Odd number of characters."); + } + + byte[] out = new byte[len >> 1]; + + // two characters form the hex value. + for (int i = 0, j = 0; j < len; i++) { + int f = toDigit(data[j], j) << 4; + j++; + f = f | toDigit(data[j], j); + j++; + out[i] = (byte) (f & 0xFF); + } + + return out; + } + + /** + * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order. + * The returned array will be double the length of the passed array, as it takes two characters to represent any + * given byte. + * + * @param data + * a byte[] to convert to Hex characters + * @return A char[] containing hexadecimal characters + */ + public static char[] encodeHex(byte[] data) { + return encodeHex(data, true); + } + + /** + * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order. + * The returned array will be double the length of the passed array, as it takes two characters to represent any + * given byte. + * + * @param data + * a byte[] to convert to Hex characters + * @param toLowerCase + * true converts to lowercase, false to uppercase + * @return A char[] containing hexadecimal characters + * @since 1.4 + */ + public static char[] encodeHex(byte[] data, boolean toLowerCase) { + return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); + } + + /** + * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order. + * The returned array will be double the length of the passed array, as it takes two characters to represent any + * given byte. + * + * @param data + * a byte[] to convert to Hex characters + * @param toDigits + * the output alphabet + * @return A char[] containing hexadecimal characters + * @since 1.4 + */ + protected static char[] encodeHex(byte[] data, char[] toDigits) { + int l = data.length; + char[] out = new char[l << 1]; + // two characters form the hex value. + for (int i = 0, j = 0; i < l; i++) { + out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; + out[j++] = toDigits[0x0F & data[i]]; + } + return out; + } + + /** + * Converts an array of bytes into a String representing the hexadecimal values of each byte in order. The returned + * String will be double the length of the passed array, as it takes two characters to represent any given byte. + * + * @param data + * a byte[] to convert to Hex characters + * @return A String containing hexadecimal characters + * @since 1.4 + */ + public static String encodeHexString(byte[] data) { + return new String(encodeHex(data)); + } + + /** + * Converts a hexadecimal character to an integer. + * + * @param ch + * A character to convert to an integer digit + * @param index + * The index of the character in the source + * @return An integer + * @throws DecoderException + * Thrown if ch is an illegal hex character + */ + protected static int toDigit(char ch, int index) throws DecoderException { + int digit = Character.digit(ch, 16); + if (digit == -1) { + throw new DecoderException("Illegal hexadecimal character " + ch + " at index " + index); + } + return digit; + } + + private final String charsetName; + + /** + * Creates a new codec with the default charset name {@link #DEFAULT_CHARSET_NAME} + */ + public Hex() { + // use default encoding + this.charsetName = DEFAULT_CHARSET_NAME; + } + + /** + * Creates a new codec with the given charset name. + * + * @param csName + * the charset name. + * @since 1.4 + */ + public Hex(String csName) { + this.charsetName = csName; + } + + /** + * Converts an array of character bytes representing hexadecimal values into an array of bytes of those same values. + * The returned array will be half the length of the passed array, as it takes two characters to represent any given + * byte. An exception is thrown if the passed char array has an odd number of elements. + * + * @param array + * An array of character bytes containing hexadecimal digits + * @return A byte array containing binary data decoded from the supplied byte array (representing characters). + * @throws DecoderException + * Thrown if an odd number of characters is supplied to this function + * @see #decodeHex(char[]) + */ + public byte[] decode(byte[] array) throws DecoderException { + try { + return decodeHex(new String(array, getCharsetName()).toCharArray()); + } catch (UnsupportedEncodingException e) { + throw new DecoderException(e.getMessage(), e); + } + } + + /** + * Converts a String or an array of character bytes representing hexadecimal values into an array of bytes of those + * same values. The returned array will be half the length of the passed String or array, as it takes two characters + * to represent any given byte. An exception is thrown if the passed char array has an odd number of elements. + * + * @param object + * A String or, an array of character bytes containing hexadecimal digits + * @return A byte array containing binary data decoded from the supplied byte array (representing characters). + * @throws DecoderException + * Thrown if an odd number of characters is supplied to this function or the object is not a String or + * char[] + * @see #decodeHex(char[]) + */ + public Object decode(Object object) throws DecoderException { + try { + char[] charArray = object instanceof String ? ((String) object).toCharArray() : (char[]) object; + return decodeHex(charArray); + } catch (ClassCastException e) { + throw new DecoderException(e.getMessage(), e); + } + } + + /** + * Converts an array of bytes into an array of bytes for the characters representing the hexadecimal values of each + * byte in order. The returned array will be double the length of the passed array, as it takes two characters to + * represent any given byte. + *

+ * The conversion from hexadecimal characters to the returned bytes is performed with the charset named by + * {@link #getCharsetName()}. + *

+ * + * @param array + * a byte[] to convert to Hex characters + * @return A byte[] containing the bytes of the hexadecimal characters + * @throws IllegalStateException + * if the charsetName is invalid. This API throws {@link IllegalStateException} instead of + * {@link UnsupportedEncodingException} for backward compatibility. + * @see #encodeHex(byte[]) + */ + public byte[] encode(byte[] array) { + return StringUtils.getBytesUnchecked(encodeHexString(array), getCharsetName()); + } + + /** + * Converts a String or an array of bytes into an array of characters representing the hexadecimal values of each + * byte in order. The returned array will be double the length of the passed String or array, as it takes two + * characters to represent any given byte. + *

+ * The conversion from hexadecimal characters to bytes to be encoded to performed with the charset named by + * {@link #getCharsetName()}. + *

+ * + * @param object + * a String, or byte[] to convert to Hex characters + * @return A char[] containing hexadecimal characters + * @throws EncoderException + * Thrown if the given object is not a String or byte[] + * @see #encodeHex(byte[]) + */ + public Object encode(Object object) throws EncoderException { + try { + byte[] byteArray = object instanceof String ? ((String) object).getBytes(getCharsetName()) : (byte[]) object; + return encodeHex(byteArray); + } catch (ClassCastException e) { + throw new EncoderException(e.getMessage(), e); + } catch (UnsupportedEncodingException e) { + throw new EncoderException(e.getMessage(), e); + } + } + + /** + * Gets the charset name. + * + * @return the charset name. + * @since 1.4 + */ + public String getCharsetName() { + return this.charsetName; + } + + /** + * Returns a string representation of the object, which includes the charset name. + * + * @return a string representation of the object. + */ + public String toString() { + return super.toString() + "[charsetName=" + this.charsetName + "]"; + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/StringUtils.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/StringUtils.java new file mode 100644 index 000000000..7bf960124 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/StringUtils.java @@ -0,0 +1,287 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.binary; + +import java.io.UnsupportedEncodingException; + +import org.mozilla.apache.commons.codec.CharEncoding; + +/** + * Converts String to and from bytes using the encodings required by the Java specification. These encodings are specified in Standard charsets + * + * @see CharEncoding + * @see Standard charsets + * @author Gary Gregory + * @version $Id: StringUtils.java 950460 2010-06-02 09:43:02Z sebb $ + * @since 1.4 + */ +public class StringUtils { + + /** + * Encodes the given string into a sequence of bytes using the ISO-8859-1 charset, storing the result into a new + * byte array. + * + * @param string + * the String to encode, may be null + * @return encoded bytes, or null if the input string was null + * @throws IllegalStateException + * Thrown when the charset is missing, which should be never according the the Java specification. + * @see Standard charsets + * @see #getBytesUnchecked(String, String) + */ + public static byte[] getBytesIso8859_1(String string) { + return StringUtils.getBytesUnchecked(string, CharEncoding.ISO_8859_1); + } + + /** + * Encodes the given string into a sequence of bytes using the US-ASCII charset, storing the result into a new byte + * array. + * + * @param string + * the String to encode, may be null + * @return encoded bytes, or null if the input string was null + * @throws IllegalStateException + * Thrown when the charset is missing, which should be never according the the Java specification. + * @see Standard charsets + * @see #getBytesUnchecked(String, String) + */ + public static byte[] getBytesUsAscii(String string) { + return StringUtils.getBytesUnchecked(string, CharEncoding.US_ASCII); + } + + /** + * Encodes the given string into a sequence of bytes using the UTF-16 charset, storing the result into a new byte + * array. + * + * @param string + * the String to encode, may be null + * @return encoded bytes, or null if the input string was null + * @throws IllegalStateException + * Thrown when the charset is missing, which should be never according the the Java specification. + * @see Standard charsets + * @see #getBytesUnchecked(String, String) + */ + public static byte[] getBytesUtf16(String string) { + return StringUtils.getBytesUnchecked(string, CharEncoding.UTF_16); + } + + /** + * Encodes the given string into a sequence of bytes using the UTF-16BE charset, storing the result into a new byte + * array. + * + * @param string + * the String to encode, may be null + * @return encoded bytes, or null if the input string was null + * @throws IllegalStateException + * Thrown when the charset is missing, which should be never according the the Java specification. + * @see Standard charsets + * @see #getBytesUnchecked(String, String) + */ + public static byte[] getBytesUtf16Be(String string) { + return StringUtils.getBytesUnchecked(string, CharEncoding.UTF_16BE); + } + + /** + * Encodes the given string into a sequence of bytes using the UTF-16LE charset, storing the result into a new byte + * array. + * + * @param string + * the String to encode, may be null + * @return encoded bytes, or null if the input string was null + * @throws IllegalStateException + * Thrown when the charset is missing, which should be never according the the Java specification. + * @see Standard charsets + * @see #getBytesUnchecked(String, String) + */ + public static byte[] getBytesUtf16Le(String string) { + return StringUtils.getBytesUnchecked(string, CharEncoding.UTF_16LE); + } + + /** + * Encodes the given string into a sequence of bytes using the UTF-8 charset, storing the result into a new byte + * array. + * + * @param string + * the String to encode, may be null + * @return encoded bytes, or null if the input string was null + * @throws IllegalStateException + * Thrown when the charset is missing, which should be never according the the Java specification. + * @see Standard charsets + * @see #getBytesUnchecked(String, String) + */ + public static byte[] getBytesUtf8(String string) { + return StringUtils.getBytesUnchecked(string, CharEncoding.UTF_8); + } + + /** + * Encodes the given string into a sequence of bytes using the named charset, storing the result into a new byte + * array. + *

+ * This method catches {@link UnsupportedEncodingException} and rethrows it as {@link IllegalStateException}, which + * should never happen for a required charset name. Use this method when the encoding is required to be in the JRE. + *

+ * + * @param string + * the String to encode, may be null + * @param charsetName + * The name of a required {@link java.nio.charset.Charset} + * @return encoded bytes, or null if the input string was null + * @throws IllegalStateException + * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen for a + * required charset name. + * @see CharEncoding + * @see String#getBytes(String) + */ + public static byte[] getBytesUnchecked(String string, String charsetName) { + if (string == null) { + return null; + } + try { + return string.getBytes(charsetName); + } catch (UnsupportedEncodingException e) { + throw StringUtils.newIllegalStateException(charsetName, e); + } + } + + private static IllegalStateException newIllegalStateException(String charsetName, UnsupportedEncodingException e) { + return new IllegalStateException(charsetName + ": " + e); + } + + /** + * Constructs a new String by decoding the specified array of bytes using the given charset. + *

+ * This method catches {@link UnsupportedEncodingException} and re-throws it as {@link IllegalStateException}, which + * should never happen for a required charset name. Use this method when the encoding is required to be in the JRE. + *

+ * + * @param bytes + * The bytes to be decoded into characters, may be null + * @param charsetName + * The name of a required {@link java.nio.charset.Charset} + * @return A new String decoded from the specified array of bytes using the given charset, + * or null if the input byte arrray was null. + * @throws IllegalStateException + * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen for a + * required charset name. + * @see CharEncoding + * @see String#String(byte[], String) + */ + public static String newString(byte[] bytes, String charsetName) { + if (bytes == null) { + return null; + } + try { + return new String(bytes, charsetName); + } catch (UnsupportedEncodingException e) { + throw StringUtils.newIllegalStateException(charsetName, e); + } + } + + /** + * Constructs a new String by decoding the specified array of bytes using the ISO-8859-1 charset. + * + * @param bytes + * The bytes to be decoded into characters, may be null + * @return A new String decoded from the specified array of bytes using the ISO-8859-1 charset, + * or null if the input byte array was null. + * @throws IllegalStateException + * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the + * charset is required. + */ + public static String newStringIso8859_1(byte[] bytes) { + return StringUtils.newString(bytes, CharEncoding.ISO_8859_1); + } + + /** + * Constructs a new String by decoding the specified array of bytes using the US-ASCII charset. + * + * @param bytes + * The bytes to be decoded into characters + * @return A new String decoded from the specified array of bytes using the US-ASCII charset, + * or null if the input byte array was null. + * @throws IllegalStateException + * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the + * charset is required. + */ + public static String newStringUsAscii(byte[] bytes) { + return StringUtils.newString(bytes, CharEncoding.US_ASCII); + } + + /** + * Constructs a new String by decoding the specified array of bytes using the UTF-16 charset. + * + * @param bytes + * The bytes to be decoded into characters + * @return A new String decoded from the specified array of bytes using the UTF-16 charset + * or null if the input byte array was null. + * @throws IllegalStateException + * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the + * charset is required. + */ + public static String newStringUtf16(byte[] bytes) { + return StringUtils.newString(bytes, CharEncoding.UTF_16); + } + + /** + * Constructs a new String by decoding the specified array of bytes using the UTF-16BE charset. + * + * @param bytes + * The bytes to be decoded into characters + * @return A new String decoded from the specified array of bytes using the UTF-16BE charset, + * or null if the input byte array was null. + * @throws IllegalStateException + * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the + * charset is required. + */ + public static String newStringUtf16Be(byte[] bytes) { + return StringUtils.newString(bytes, CharEncoding.UTF_16BE); + } + + /** + * Constructs a new String by decoding the specified array of bytes using the UTF-16LE charset. + * + * @param bytes + * The bytes to be decoded into characters + * @return A new String decoded from the specified array of bytes using the UTF-16LE charset, + * or null if the input byte array was null. + * @throws IllegalStateException + * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the + * charset is required. + */ + public static String newStringUtf16Le(byte[] bytes) { + return StringUtils.newString(bytes, CharEncoding.UTF_16LE); + } + + /** + * Constructs a new String by decoding the specified array of bytes using the UTF-8 charset. + * + * @param bytes + * The bytes to be decoded into characters + * @return A new String decoded from the specified array of bytes using the UTF-8 charset, + * or null if the input byte array was null. + * @throws IllegalStateException + * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the + * charset is required. + */ + public static String newStringUtf8(byte[] bytes) { + return StringUtils.newString(bytes, CharEncoding.UTF_8); + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/package.html b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/package.html new file mode 100644 index 000000000..13345ece4 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/binary/package.html @@ -0,0 +1,21 @@ + + + + Base64, Base32, Binary, and Hexadecimal String encoding and decoding. + + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/digest/DigestUtils.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/digest/DigestUtils.java new file mode 100644 index 000000000..2421bb0fe --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/digest/DigestUtils.java @@ -0,0 +1,583 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.digest; + +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.mozilla.apache.commons.codec.binary.Hex; +import org.mozilla.apache.commons.codec.binary.StringUtils; + +/** + * Operations to simplify common {@link java.security.MessageDigest} tasks. This class is thread safe. + * + * @author Apache Software Foundation + * @version $Id: DigestUtils.java 1064793 2011-01-28 17:42:55Z ggregory $ + */ +public class DigestUtils { + + private static final int STREAM_BUFFER_LENGTH = 1024; + + /** + * Read through an InputStream and returns the digest for the data + * + * @param digest + * The MessageDigest to use (e.g. MD5) + * @param data + * Data to digest + * @return MD5 digest + * @throws IOException + * On error reading from the stream + */ + private static byte[] digest(MessageDigest digest, InputStream data) throws IOException { + byte[] buffer = new byte[STREAM_BUFFER_LENGTH]; + int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH); + + while (read > -1) { + digest.update(buffer, 0, read); + read = data.read(buffer, 0, STREAM_BUFFER_LENGTH); + } + + return digest.digest(); + } + + /** + * Calls {@link StringUtils#getBytesUtf8(String)} + * + * @param data + * the String to encode + * @return encoded bytes + */ + private static byte[] getBytesUtf8(String data) { + return StringUtils.getBytesUtf8(data); + } + + /** + * Returns a MessageDigest for the given algorithm. + * + * @param algorithm + * the name of the algorithm requested. See Appendix A in the Java + * Cryptography Architecture API Specification & Reference for information about standard algorithm + * names. + * @return An MD5 digest instance. + * @see MessageDigest#getInstance(String) + * @throws RuntimeException + * when a {@link java.security.NoSuchAlgorithmException} is caught. + */ + static MessageDigest getDigest(String algorithm) { + try { + return MessageDigest.getInstance(algorithm); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e.getMessage()); + } + } + + /** + * Returns an MD5 MessageDigest. + * + * @return An MD5 digest instance. + * @throws RuntimeException + * when a {@link java.security.NoSuchAlgorithmException} is caught. + */ + private static MessageDigest getMd5Digest() { + return getDigest("MD5"); + } + + /** + * Returns an SHA-256 digest. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @return An SHA-256 digest instance. + * @throws RuntimeException + * when a {@link java.security.NoSuchAlgorithmException} is caught. + */ + private static MessageDigest getSha256Digest() { + return getDigest("SHA-256"); + } + + /** + * Returns an SHA-384 digest. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @return An SHA-384 digest instance. + * @throws RuntimeException + * when a {@link java.security.NoSuchAlgorithmException} is caught. + */ + private static MessageDigest getSha384Digest() { + return getDigest("SHA-384"); + } + + /** + * Returns an SHA-512 digest. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @return An SHA-512 digest instance. + * @throws RuntimeException + * when a {@link java.security.NoSuchAlgorithmException} is caught. + */ + private static MessageDigest getSha512Digest() { + return getDigest("SHA-512"); + } + + /** + * Returns an SHA-1 digest. + * + * @return An SHA-1 digest instance. + * @throws RuntimeException + * when a {@link java.security.NoSuchAlgorithmException} is caught. + */ + private static MessageDigest getShaDigest() { + return getDigest("SHA"); + } + + /** + * Calculates the MD5 digest and returns the value as a 16 element byte[]. + * + * @param data + * Data to digest + * @return MD5 digest + */ + public static byte[] md5(byte[] data) { + return getMd5Digest().digest(data); + } + + /** + * Calculates the MD5 digest and returns the value as a 16 element byte[]. + * + * @param data + * Data to digest + * @return MD5 digest + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static byte[] md5(InputStream data) throws IOException { + return digest(getMd5Digest(), data); + } + + /** + * Calculates the MD5 digest and returns the value as a 16 element byte[]. + * + * @param data + * Data to digest + * @return MD5 digest + */ + public static byte[] md5(String data) { + return md5(getBytesUtf8(data)); + } + + /** + * Calculates the MD5 digest and returns the value as a 32 character hex string. + * + * @param data + * Data to digest + * @return MD5 digest as a hex string + */ + public static String md5Hex(byte[] data) { + return Hex.encodeHexString(md5(data)); + } + + /** + * Calculates the MD5 digest and returns the value as a 32 character hex string. + * + * @param data + * Data to digest + * @return MD5 digest as a hex string + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static String md5Hex(InputStream data) throws IOException { + return Hex.encodeHexString(md5(data)); + } + + /** + * Calculates the MD5 digest and returns the value as a 32 character hex string. + * + * @param data + * Data to digest + * @return MD5 digest as a hex string + */ + public static String md5Hex(String data) { + return Hex.encodeHexString(md5(data)); + } + + /** + * Calculates the SHA-1 digest and returns the value as a byte[]. + * + * @param data + * Data to digest + * @return SHA-1 digest + */ + public static byte[] sha(byte[] data) { + return getShaDigest().digest(data); + } + + /** + * Calculates the SHA-1 digest and returns the value as a byte[]. + * + * @param data + * Data to digest + * @return SHA-1 digest + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static byte[] sha(InputStream data) throws IOException { + return digest(getShaDigest(), data); + } + + /** + * Calculates the SHA-1 digest and returns the value as a byte[]. + * + * @param data + * Data to digest + * @return SHA-1 digest + */ + public static byte[] sha(String data) { + return sha(getBytesUtf8(data)); + } + + /** + * Calculates the SHA-256 digest and returns the value as a byte[]. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-256 digest + * @since 1.4 + */ + public static byte[] sha256(byte[] data) { + return getSha256Digest().digest(data); + } + + /** + * Calculates the SHA-256 digest and returns the value as a byte[]. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-256 digest + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static byte[] sha256(InputStream data) throws IOException { + return digest(getSha256Digest(), data); + } + + /** + * Calculates the SHA-256 digest and returns the value as a byte[]. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-256 digest + * @since 1.4 + */ + public static byte[] sha256(String data) { + return sha256(getBytesUtf8(data)); + } + + /** + * Calculates the SHA-256 digest and returns the value as a hex string. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-256 digest as a hex string + * @since 1.4 + */ + public static String sha256Hex(byte[] data) { + return Hex.encodeHexString(sha256(data)); + } + + /** + * Calculates the SHA-256 digest and returns the value as a hex string. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-256 digest as a hex string + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static String sha256Hex(InputStream data) throws IOException { + return Hex.encodeHexString(sha256(data)); + } + + /** + * Calculates the SHA-256 digest and returns the value as a hex string. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-256 digest as a hex string + * @since 1.4 + */ + public static String sha256Hex(String data) { + return Hex.encodeHexString(sha256(data)); + } + + /** + * Calculates the SHA-384 digest and returns the value as a byte[]. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-384 digest + * @since 1.4 + */ + public static byte[] sha384(byte[] data) { + return getSha384Digest().digest(data); + } + + /** + * Calculates the SHA-384 digest and returns the value as a byte[]. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-384 digest + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static byte[] sha384(InputStream data) throws IOException { + return digest(getSha384Digest(), data); + } + + /** + * Calculates the SHA-384 digest and returns the value as a byte[]. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-384 digest + * @since 1.4 + */ + public static byte[] sha384(String data) { + return sha384(getBytesUtf8(data)); + } + + /** + * Calculates the SHA-384 digest and returns the value as a hex string. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-384 digest as a hex string + * @since 1.4 + */ + public static String sha384Hex(byte[] data) { + return Hex.encodeHexString(sha384(data)); + } + + /** + * Calculates the SHA-384 digest and returns the value as a hex string. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-384 digest as a hex string + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static String sha384Hex(InputStream data) throws IOException { + return Hex.encodeHexString(sha384(data)); + } + + /** + * Calculates the SHA-384 digest and returns the value as a hex string. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-384 digest as a hex string + * @since 1.4 + */ + public static String sha384Hex(String data) { + return Hex.encodeHexString(sha384(data)); + } + + /** + * Calculates the SHA-512 digest and returns the value as a byte[]. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-512 digest + * @since 1.4 + */ + public static byte[] sha512(byte[] data) { + return getSha512Digest().digest(data); + } + + /** + * Calculates the SHA-512 digest and returns the value as a byte[]. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-512 digest + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static byte[] sha512(InputStream data) throws IOException { + return digest(getSha512Digest(), data); + } + + /** + * Calculates the SHA-512 digest and returns the value as a byte[]. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-512 digest + * @since 1.4 + */ + public static byte[] sha512(String data) { + return sha512(getBytesUtf8(data)); + } + + /** + * Calculates the SHA-512 digest and returns the value as a hex string. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-512 digest as a hex string + * @since 1.4 + */ + public static String sha512Hex(byte[] data) { + return Hex.encodeHexString(sha512(data)); + } + + /** + * Calculates the SHA-512 digest and returns the value as a hex string. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-512 digest as a hex string + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static String sha512Hex(InputStream data) throws IOException { + return Hex.encodeHexString(sha512(data)); + } + + /** + * Calculates the SHA-512 digest and returns the value as a hex string. + *

+ * Throws a RuntimeException on JRE versions prior to 1.4.0. + *

+ * + * @param data + * Data to digest + * @return SHA-512 digest as a hex string + * @since 1.4 + */ + public static String sha512Hex(String data) { + return Hex.encodeHexString(sha512(data)); + } + + /** + * Calculates the SHA-1 digest and returns the value as a hex string. + * + * @param data + * Data to digest + * @return SHA-1 digest as a hex string + */ + public static String shaHex(byte[] data) { + return Hex.encodeHexString(sha(data)); + } + + /** + * Calculates the SHA-1 digest and returns the value as a hex string. + * + * @param data + * Data to digest + * @return SHA-1 digest as a hex string + * @throws IOException + * On error reading from the stream + * @since 1.4 + */ + public static String shaHex(InputStream data) throws IOException { + return Hex.encodeHexString(sha(data)); + } + + /** + * Calculates the SHA-1 digest and returns the value as a hex string. + * + * @param data + * Data to digest + * @return SHA-1 digest as a hex string + */ + public static String shaHex(String data) { + return Hex.encodeHexString(sha(data)); + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/digest/package.html b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/digest/package.html new file mode 100644 index 000000000..1da976276 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/digest/package.html @@ -0,0 +1,21 @@ + + + + Simplifies common {@link java.security.MessageDigest} tasks. + + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/AbstractCaverphone.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/AbstractCaverphone.java new file mode 100644 index 000000000..fbcc75943 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/AbstractCaverphone.java @@ -0,0 +1,78 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.StringEncoder; + +/** + * Encodes a string into a Caverphone value. + * + * This is an algorithm created by the Caversham Project at the University of Otago. It implements the Caverphone 2.0 + * algorithm: + * + * @author Apache Software Foundation + * @version $Id: Caverphone.java 1075947 2011-03-01 17:56:14Z ggregory $ + * @see Wikipedia - Caverphone + * @since 1.5 + */ +public abstract class AbstractCaverphone implements StringEncoder { + + /** + * Creates an instance of the Caverphone encoder + */ + public AbstractCaverphone() { + super(); + } + + /** + * Encodes an Object using the caverphone algorithm. This method is provided in order to satisfy the requirements of + * the Encoder interface, and will throw an EncoderException if the supplied object is not of type java.lang.String. + * + * @param source + * Object to encode + * @return An object (or type java.lang.String) containing the caverphone code which corresponds to the String + * supplied. + * @throws EncoderException + * if the parameter supplied is not of type java.lang.String + */ + public Object encode(Object source) throws EncoderException { + if (!(source instanceof String)) { + throw new EncoderException("Parameter supplied to Caverphone encode is not of type java.lang.String"); + } + return this.encode((String) source); + } + + /** + * Tests if the encodings of two strings are equal. + * + * This method might be promoted to a new AbstractStringEncoder superclass. + * + * @param str1 + * First of two strings to compare + * @param str2 + * Second of two strings to compare + * @return true if the encodings of these strings are identical, false otherwise. + * @throws EncoderException + */ + public boolean isEncodeEqual(String str1, String str2) throws EncoderException { + return this.encode(str1).equals(this.encode(str2)); + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone.java new file mode 100644 index 000000000..062fa4135 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone.java @@ -0,0 +1,104 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.StringEncoder; + +/** + * Encodes a string into a Caverphone 2.0 value. Delegate to a {@link Caverphone2} instance. + * + * This is an algorithm created by the Caversham Project at the University of Otago. It implements the Caverphone 2.0 + * algorithm: + * + * @author Apache Software Foundation + * @version $Id: Caverphone.java 1079535 2011-03-08 20:54:37Z ggregory $ + * @see Wikipedia - Caverphone + * @see Caverphone 2.0 specification + * @since 1.4 + * @deprecated 1.5 Replaced by {@link Caverphone2}, will be removed in 2.0. + */ +public class Caverphone implements StringEncoder { + + /** + * Delegate to a {@link Caverphone2} instance to avoid code duplication. + */ + final private Caverphone2 encoder = new Caverphone2(); + + /** + * Creates an instance of the Caverphone encoder + */ + public Caverphone() { + super(); + } + + /** + * Encodes the given String into a Caverphone value. + * + * @param source + * String the source string + * @return A caverphone code for the given String + */ + public String caverphone(String source) { + return this.encoder.encode(source); + } + + /** + * Encodes an Object using the caverphone algorithm. This method is provided in order to satisfy the requirements of + * the Encoder interface, and will throw an EncoderException if the supplied object is not of type java.lang.String. + * + * @param pObject + * Object to encode + * @return An object (or type java.lang.String) containing the caverphone code which corresponds to the String + * supplied. + * @throws EncoderException + * if the parameter supplied is not of type java.lang.String + */ + public Object encode(Object pObject) throws EncoderException { + if (!(pObject instanceof String)) { + throw new EncoderException("Parameter supplied to Caverphone encode is not of type java.lang.String"); + } + return this.caverphone((String) pObject); + } + + /** + * Encodes a String using the Caverphone algorithm. + * + * @param pString + * String object to encode + * @return The caverphone code corresponding to the String supplied + */ + public String encode(String pString) { + return this.caverphone(pString); + } + + /** + * Tests if the caverphones of two strings are identical. + * + * @param str1 + * First of two strings to compare + * @param str2 + * Second of two strings to compare + * @return true if the caverphones of these strings are identical, false otherwise. + */ + public boolean isCaverphoneEqual(String str1, String str2) { + return this.caverphone(str1).equals(this.caverphone(str2)); + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone1.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone1.java new file mode 100644 index 000000000..e0d2e1de3 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone1.java @@ -0,0 +1,126 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +/** + * Encodes a string into a Caverphone 1.0 value. + * + * This is an algorithm created by the Caversham Project at the University of Otago. It implements the Caverphone 1.0 + * algorithm: + * + * @author Apache Software Foundation + * @version $Id: Caverphone.java 1075947 2011-03-01 17:56:14Z ggregory $ + * @see Wikipedia - Caverphone + * @see Caverphone 1.0 specification + * @since 1.5 + */ +public class Caverphone1 extends AbstractCaverphone { + + private static final String SIX_1 = "111111"; + + /** + * Encodes the given String into a Caverphone value. + * + * @param source + * String the source string + * @return A caverphone code for the given String + */ + public String encode(String source) { + String txt = source; + if (txt == null || txt.length() == 0) { + return SIX_1; + } + + // 1. Convert to lowercase + txt = txt.toLowerCase(java.util.Locale.ENGLISH); + + // 2. Remove anything not A-Z + txt = txt.replaceAll("[^a-z]", ""); + + // 3. Handle various start options + // 2 is a temporary placeholder to indicate a consonant which we are no longer interested in. + txt = txt.replaceAll("^cough", "cou2f"); + txt = txt.replaceAll("^rough", "rou2f"); + txt = txt.replaceAll("^tough", "tou2f"); + txt = txt.replaceAll("^enough", "enou2f"); + txt = txt.replaceAll("^gn", "2n"); + + // End + txt = txt.replaceAll("mb$", "m2"); + + // 4. Handle replacements + txt = txt.replaceAll("cq", "2q"); + txt = txt.replaceAll("ci", "si"); + txt = txt.replaceAll("ce", "se"); + txt = txt.replaceAll("cy", "sy"); + txt = txt.replaceAll("tch", "2ch"); + txt = txt.replaceAll("c", "k"); + txt = txt.replaceAll("q", "k"); + txt = txt.replaceAll("x", "k"); + txt = txt.replaceAll("v", "f"); + txt = txt.replaceAll("dg", "2g"); + txt = txt.replaceAll("tio", "sio"); + txt = txt.replaceAll("tia", "sia"); + txt = txt.replaceAll("d", "t"); + txt = txt.replaceAll("ph", "fh"); + txt = txt.replaceAll("b", "p"); + txt = txt.replaceAll("sh", "s2"); + txt = txt.replaceAll("z", "s"); + txt = txt.replaceAll("^[aeiou]", "A"); + // 3 is a temporary placeholder marking a vowel + txt = txt.replaceAll("[aeiou]", "3"); + txt = txt.replaceAll("3gh3", "3kh3"); + txt = txt.replaceAll("gh", "22"); + txt = txt.replaceAll("g", "k"); + txt = txt.replaceAll("s+", "S"); + txt = txt.replaceAll("t+", "T"); + txt = txt.replaceAll("p+", "P"); + txt = txt.replaceAll("k+", "K"); + txt = txt.replaceAll("f+", "F"); + txt = txt.replaceAll("m+", "M"); + txt = txt.replaceAll("n+", "N"); + txt = txt.replaceAll("w3", "W3"); + txt = txt.replaceAll("wy", "Wy"); // 1.0 only + txt = txt.replaceAll("wh3", "Wh3"); + txt = txt.replaceAll("why", "Why"); // 1.0 only + txt = txt.replaceAll("w", "2"); + txt = txt.replaceAll("^h", "A"); + txt = txt.replaceAll("h", "2"); + txt = txt.replaceAll("r3", "R3"); + txt = txt.replaceAll("ry", "Ry"); // 1.0 only + txt = txt.replaceAll("r", "2"); + txt = txt.replaceAll("l3", "L3"); + txt = txt.replaceAll("ly", "Ly"); // 1.0 only + txt = txt.replaceAll("l", "2"); + txt = txt.replaceAll("j", "y"); // 1.0 only + txt = txt.replaceAll("y3", "Y3"); // 1.0 only + txt = txt.replaceAll("y", "2"); // 1.0 only + + // 5. Handle removals + txt = txt.replaceAll("2", ""); + txt = txt.replaceAll("3", ""); + + // 6. put ten 1s on the end + txt = txt + SIX_1; + + // 7. take the first six characters as the code + return txt.substring(0, SIX_1.length()); + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone2.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone2.java new file mode 100644 index 000000000..a05b560e7 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Caverphone2.java @@ -0,0 +1,129 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +/** + * Encodes a string into a Caverphone 2.0 value. + * + * This is an algorithm created by the Caversham Project at the University of Otago. It implements the Caverphone 2.0 + * algorithm: + * + * @author Apache Software Foundation + * @version $Id: Caverphone.java 1075947 2011-03-01 17:56:14Z ggregory $ + * @see Wikipedia - Caverphone + * @see Caverphone 2.0 specification + * @since 1.5 + */ +public class Caverphone2 extends AbstractCaverphone { + + private static final String TEN_1 = "1111111111"; + + /** + * Encodes the given String into a Caverphone 2.0 value. + * + * @param source + * String the source string + * @return A caverphone code for the given String + */ + public String encode(String source) { + String txt = source; + if (txt == null || txt.length() == 0) { + return TEN_1; + } + + // 1. Convert to lowercase + txt = txt.toLowerCase(java.util.Locale.ENGLISH); + + // 2. Remove anything not A-Z + txt = txt.replaceAll("[^a-z]", ""); + + // 2.5. Remove final e + txt = txt.replaceAll("e$", ""); // 2.0 only + + // 3. Handle various start options + txt = txt.replaceAll("^cough", "cou2f"); + txt = txt.replaceAll("^rough", "rou2f"); + txt = txt.replaceAll("^tough", "tou2f"); + txt = txt.replaceAll("^enough", "enou2f"); // 2.0 only + txt = txt.replaceAll("^trough", "trou2f"); // 2.0 only - note the spec says ^enough here again, c+p error I assume + txt = txt.replaceAll("^gn", "2n"); + + // End + txt = txt.replaceAll("mb$", "m2"); + + // 4. Handle replacements + txt = txt.replaceAll("cq", "2q"); + txt = txt.replaceAll("ci", "si"); + txt = txt.replaceAll("ce", "se"); + txt = txt.replaceAll("cy", "sy"); + txt = txt.replaceAll("tch", "2ch"); + txt = txt.replaceAll("c", "k"); + txt = txt.replaceAll("q", "k"); + txt = txt.replaceAll("x", "k"); + txt = txt.replaceAll("v", "f"); + txt = txt.replaceAll("dg", "2g"); + txt = txt.replaceAll("tio", "sio"); + txt = txt.replaceAll("tia", "sia"); + txt = txt.replaceAll("d", "t"); + txt = txt.replaceAll("ph", "fh"); + txt = txt.replaceAll("b", "p"); + txt = txt.replaceAll("sh", "s2"); + txt = txt.replaceAll("z", "s"); + txt = txt.replaceAll("^[aeiou]", "A"); + txt = txt.replaceAll("[aeiou]", "3"); + txt = txt.replaceAll("j", "y"); // 2.0 only + txt = txt.replaceAll("^y3", "Y3"); // 2.0 only + txt = txt.replaceAll("^y", "A"); // 2.0 only + txt = txt.replaceAll("y", "3"); // 2.0 only + txt = txt.replaceAll("3gh3", "3kh3"); + txt = txt.replaceAll("gh", "22"); + txt = txt.replaceAll("g", "k"); + txt = txt.replaceAll("s+", "S"); + txt = txt.replaceAll("t+", "T"); + txt = txt.replaceAll("p+", "P"); + txt = txt.replaceAll("k+", "K"); + txt = txt.replaceAll("f+", "F"); + txt = txt.replaceAll("m+", "M"); + txt = txt.replaceAll("n+", "N"); + txt = txt.replaceAll("w3", "W3"); + txt = txt.replaceAll("wh3", "Wh3"); + txt = txt.replaceAll("w$", "3"); // 2.0 only + txt = txt.replaceAll("w", "2"); + txt = txt.replaceAll("^h", "A"); + txt = txt.replaceAll("h", "2"); + txt = txt.replaceAll("r3", "R3"); + txt = txt.replaceAll("r$", "3"); // 2.0 only + txt = txt.replaceAll("r", "2"); + txt = txt.replaceAll("l3", "L3"); + txt = txt.replaceAll("l$", "3"); // 2.0 only + txt = txt.replaceAll("l", "2"); + + // 5. Handle removals + txt = txt.replaceAll("2", ""); + txt = txt.replaceAll("3$", "A"); // 2.0 only + txt = txt.replaceAll("3", ""); + + // 6. put ten 1s on the end + txt = txt + TEN_1; + + // 7. take the first ten characters as the code + return txt.substring(0, TEN_1.length()); + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/ColognePhonetic.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/ColognePhonetic.java new file mode 100644 index 000000000..ae6285790 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/ColognePhonetic.java @@ -0,0 +1,417 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +import java.util.Locale; + +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.StringEncoder; + +/** + *

+ * Encodes a string into a Cologne Phonetic value. + *

+ *

+ * Implements the “Kölner Phonetic” (Cologne Phonetic) + * algorithm issued by Hans Joachim Postel in 1969. + *

+ * + *

+ * The Kölner Phonetik is a phonetic algorithm which is optimized for the German language. It is related to the + * well-known soundex algorithm. + *

+ * + *

Algorithm

+ * + *
    + * + *
  • + *

    Step 1:

    + * After preprocessing (convertion to upper case, transcription of germanic umlauts, removal of non alphabetical characters) the + * letters of the supplied text are replaced by their phonetic code according to the folowing table. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    LetterContextCode
    A, E, I, J, O, U, Y0
    H-
    B1
    Pnot before H
    D, Tnot before C, S, Z2
    F, V, W3
    Pbefore H
    G, K, Q4
    Cat onset before A, H, K, L, O, Q, R, U, X
    before A, H, K, O, Q, U, X except after S, Z
    Xnot after C, K, Q48
    L5
    M, N6
    R7
    S, Z8
    Cafter S, Z
    at onset except before A, H, K, L, O, Q, R, U, X
    not before A, H, K, O, Q, U, X
    D, Tbefore C, S, Z
    Xafter C, K, Q
    + *

    + * (Source: Wikipedia (de): + * Kölner Phonetik – Buchstabencodes) + *

    + * + *

    Example:

    + * + * {@code "Müller-Lüdenscheidt" => "MULLERLUDENSCHEIDT" => "6005507500206880022"} + * + *
  • + * + *
  • + *

    Step 2:

    + * Collapse of all multiple consecutive code digits. + *

    Example:

    + * {@code "6005507500206880022" => "6050750206802"}
  • + * + *
  • + *

    Step 3:

    + * Removal of all codes “0” except at the beginning. This means that two or more identical consecutive digits can occur + * if they occur after removing the "0" digits. + * + *

    Example:

    + * {@code "6050750206802" => "65752682"}
  • + * + *
+ * + * @see Wikipedia (de): Kölner Phonetik (in German) + * @author Apache Software Foundation + * @since 1.5 + */ +public class ColognePhonetic implements StringEncoder { + + private abstract class CologneBuffer { + + protected final char[] data; + + protected int length = 0; + + public CologneBuffer(char[] data) { + this.data = data; + this.length = data.length; + } + + public CologneBuffer(int buffSize) { + this.data = new char[buffSize]; + this.length = 0; + } + + protected abstract char[] copyData(int start, final int length); + + public int length() { + return length; + } + + public String toString() { + return new String(copyData(0, length)); + } + } + + private class CologneOutputBuffer extends CologneBuffer { + + public CologneOutputBuffer(int buffSize) { + super(buffSize); + } + + public void addRight(char chr) { + data[length] = chr; + length++; + } + + protected char[] copyData(int start, final int length) { + char[] newData = new char[length]; + System.arraycopy(data, start, newData, 0, length); + return newData; + } + } + + private class CologneInputBuffer extends CologneBuffer { + + public CologneInputBuffer(char[] data) { + super(data); + } + + public void addLeft(char ch) { + length++; + data[getNextPos()] = ch; + } + + protected char[] copyData(int start, final int length) { + char[] newData = new char[length]; + System.arraycopy(data, data.length - this.length + start, newData, 0, length); + return newData; + } + + public char getNextChar() { + return data[getNextPos()]; + } + + protected int getNextPos() { + return data.length - length; + } + + public char removeNext() { + char ch = getNextChar(); + length--; + return ch; + } + } + + private static final char[][] PREPROCESS_MAP = new char[][]{{'\u00C4', 'A'}, // Ä + {'\u00DC', 'U'}, // Ü + {'\u00D6', 'O'}, // Ö + {'\u00DF', 'S'} // ß + }; + + /* + * Returns whether the array contains the key, or not. + */ + private static boolean arrayContains(char[] arr, char key) { + for (int i = 0; i < arr.length; i++) { + if (arr[i] == key) { + return true; + } + } + return false; + } + + /** + *

+ * colognePhonetic() is the actual implementations of the Kölner Phonetik algorithm. + *

+ *

+ * In contrast to the initial description of the algorithm, this implementation does the encoding in one pass. + *

+ * + * @param text + * @return the corresponding encoding according to the Kölner Phonetik algorithm + */ + public String colognePhonetic(String text) { + if (text == null) { + return null; + } + + text = preprocess(text); + + CologneOutputBuffer output = new CologneOutputBuffer(text.length() * 2); + CologneInputBuffer input = new CologneInputBuffer(text.toCharArray()); + + char nextChar; + + char lastChar = '-'; + char lastCode = '/'; + char code; + char chr; + + int rightLength = input.length(); + + while (rightLength > 0) { + chr = input.removeNext(); + + if ((rightLength = input.length()) > 0) { + nextChar = input.getNextChar(); + } else { + nextChar = '-'; + } + + if (arrayContains(new char[]{'A', 'E', 'I', 'J', 'O', 'U', 'Y'}, chr)) { + code = '0'; + } else if (chr == 'H' || chr < 'A' || chr > 'Z') { + if (lastCode == '/') { + continue; + } + code = '-'; + } else if (chr == 'B' || (chr == 'P' && nextChar != 'H')) { + code = '1'; + } else if ((chr == 'D' || chr == 'T') && !arrayContains(new char[]{'S', 'C', 'Z'}, nextChar)) { + code = '2'; + } else if (arrayContains(new char[]{'W', 'F', 'P', 'V'}, chr)) { + code = '3'; + } else if (arrayContains(new char[]{'G', 'K', 'Q'}, chr)) { + code = '4'; + } else if (chr == 'X' && !arrayContains(new char[]{'C', 'K', 'Q'}, lastChar)) { + code = '4'; + input.addLeft('S'); + rightLength++; + } else if (chr == 'S' || chr == 'Z') { + code = '8'; + } else if (chr == 'C') { + if (lastCode == '/') { + if (arrayContains(new char[]{'A', 'H', 'K', 'L', 'O', 'Q', 'R', 'U', 'X'}, nextChar)) { + code = '4'; + } else { + code = '8'; + } + } else { + if (arrayContains(new char[]{'S', 'Z'}, lastChar) || + !arrayContains(new char[]{'A', 'H', 'O', 'U', 'K', 'Q', 'X'}, nextChar)) { + code = '8'; + } else { + code = '4'; + } + } + } else if (arrayContains(new char[]{'T', 'D', 'X'}, chr)) { + code = '8'; + } else if (chr == 'R') { + code = '7'; + } else if (chr == 'L') { + code = '5'; + } else if (chr == 'M' || chr == 'N') { + code = '6'; + } else { + code = chr; + } + + if (code != '-' && (lastCode != code && (code != '0' || lastCode == '/') || code < '0' || code > '8')) { + output.addRight(code); + } + + lastChar = chr; + lastCode = code; + } + return output.toString(); + } + + public Object encode(Object object) throws EncoderException { + if (!(object instanceof String)) { + throw new EncoderException("This method’s parameter was expected to be of the type " + + String.class.getName() + + ". But actually it was of the type " + + object.getClass().getName() + + "."); + } + return encode((String) object); + } + + public String encode(String text) { + return colognePhonetic(text); + } + + public boolean isEncodeEqual(String text1, String text2) { + return colognePhonetic(text1).equals(colognePhonetic(text2)); + } + + /* + * Converts the string to upper case and replaces germanic umlauts, and the “ß”. + */ + private String preprocess(String text) { + text = text.toUpperCase(Locale.GERMAN); + + char[] chrs = text.toCharArray(); + + for (int index = 0; index < chrs.length; index++) { + if (chrs[index] > 'Z') { + for (int replacement = 0; replacement < PREPROCESS_MAP.length; replacement++) { + if (chrs[index] == PREPROCESS_MAP[replacement][0]) { + chrs[index] = PREPROCESS_MAP[replacement][1]; + break; + } + } + } + } + return new String(chrs); + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/DoubleMetaphone.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/DoubleMetaphone.java new file mode 100644 index 000000000..5069ade72 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/DoubleMetaphone.java @@ -0,0 +1,1106 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.StringEncoder; + +/** + * Encodes a string into a double metaphone value. + * This Implementation is based on the algorithm by Lawrence Philips. + * + * + * @author Apache Software Foundation + * @version $Id: DoubleMetaphone.java 1072742 2011-02-20 21:39:03Z ggregory $ + */ +public class DoubleMetaphone implements StringEncoder { + + /** + * "Vowels" to test for + */ + private static final String VOWELS = "AEIOUY"; + + /** + * Prefixes when present which are not pronounced + */ + private static final String[] SILENT_START = + { "GN", "KN", "PN", "WR", "PS" }; + private static final String[] L_R_N_M_B_H_F_V_W_SPACE = + { "L", "R", "N", "M", "B", "H", "F", "V", "W", " " }; + private static final String[] ES_EP_EB_EL_EY_IB_IL_IN_IE_EI_ER = + { "ES", "EP", "EB", "EL", "EY", "IB", "IL", "IN", "IE", "EI", "ER" }; + private static final String[] L_T_K_S_N_M_B_Z = + { "L", "T", "K", "S", "N", "M", "B", "Z" }; + + /** + * Maximum length of an encoding, default is 4 + */ + private int maxCodeLen = 4; + + /** + * Creates an instance of this DoubleMetaphone encoder + */ + public DoubleMetaphone() { + super(); + } + + /** + * Encode a value with Double Metaphone + * + * @param value String to encode + * @return an encoded string + */ + public String doubleMetaphone(String value) { + return doubleMetaphone(value, false); + } + + /** + * Encode a value with Double Metaphone, optionally using the alternate + * encoding. + * + * @param value String to encode + * @param alternate use alternate encode + * @return an encoded string + */ + public String doubleMetaphone(String value, boolean alternate) { + value = cleanInput(value); + if (value == null) { + return null; + } + + boolean slavoGermanic = isSlavoGermanic(value); + int index = isSilentStart(value) ? 1 : 0; + + DoubleMetaphoneResult result = new DoubleMetaphoneResult(this.getMaxCodeLen()); + + while (!result.isComplete() && index <= value.length() - 1) { + switch (value.charAt(index)) { + case 'A': + case 'E': + case 'I': + case 'O': + case 'U': + case 'Y': + index = handleAEIOUY(result, index); + break; + case 'B': + result.append('P'); + index = charAt(value, index + 1) == 'B' ? index + 2 : index + 1; + break; + case '\u00C7': + // A C with a Cedilla + result.append('S'); + index++; + break; + case 'C': + index = handleC(value, result, index); + break; + case 'D': + index = handleD(value, result, index); + break; + case 'F': + result.append('F'); + index = charAt(value, index + 1) == 'F' ? index + 2 : index + 1; + break; + case 'G': + index = handleG(value, result, index, slavoGermanic); + break; + case 'H': + index = handleH(value, result, index); + break; + case 'J': + index = handleJ(value, result, index, slavoGermanic); + break; + case 'K': + result.append('K'); + index = charAt(value, index + 1) == 'K' ? index + 2 : index + 1; + break; + case 'L': + index = handleL(value, result, index); + break; + case 'M': + result.append('M'); + index = conditionM0(value, index) ? index + 2 : index + 1; + break; + case 'N': + result.append('N'); + index = charAt(value, index + 1) == 'N' ? index + 2 : index + 1; + break; + case '\u00D1': + // N with a tilde (spanish ene) + result.append('N'); + index++; + break; + case 'P': + index = handleP(value, result, index); + break; + case 'Q': + result.append('K'); + index = charAt(value, index + 1) == 'Q' ? index + 2 : index + 1; + break; + case 'R': + index = handleR(value, result, index, slavoGermanic); + break; + case 'S': + index = handleS(value, result, index, slavoGermanic); + break; + case 'T': + index = handleT(value, result, index); + break; + case 'V': + result.append('F'); + index = charAt(value, index + 1) == 'V' ? index + 2 : index + 1; + break; + case 'W': + index = handleW(value, result, index); + break; + case 'X': + index = handleX(value, result, index); + break; + case 'Z': + index = handleZ(value, result, index, slavoGermanic); + break; + default: + index++; + break; + } + } + + return alternate ? result.getAlternate() : result.getPrimary(); + } + + /** + * Encode the value using DoubleMetaphone. It will only work if + * obj is a String (like Metaphone). + * + * @param obj Object to encode (should be of type String) + * @return An encoded Object (will be of type String) + * @throws EncoderException encode parameter is not of type String + */ + public Object encode(Object obj) throws EncoderException { + if (!(obj instanceof String)) { + throw new EncoderException("DoubleMetaphone encode parameter is not of type String"); + } + return doubleMetaphone((String) obj); + } + + /** + * Encode the value using DoubleMetaphone. + * + * @param value String to encode + * @return An encoded String + */ + public String encode(String value) { + return doubleMetaphone(value); + } + + /** + * Check if the Double Metaphone values of two String values + * are equal. + * + * @param value1 The left-hand side of the encoded {@link String#equals(Object)}. + * @param value2 The right-hand side of the encoded {@link String#equals(Object)}. + * @return true if the encoded Strings are equal; + * false otherwise. + * @see #isDoubleMetaphoneEqual(String,String,boolean) + */ + public boolean isDoubleMetaphoneEqual(String value1, String value2) { + return isDoubleMetaphoneEqual(value1, value2, false); + } + + /** + * Check if the Double Metaphone values of two String values + * are equal, optionally using the alternate value. + * + * @param value1 The left-hand side of the encoded {@link String#equals(Object)}. + * @param value2 The right-hand side of the encoded {@link String#equals(Object)}. + * @param alternate use the alternate value if true. + * @return true if the encoded Strings are equal; + * false otherwise. + */ + public boolean isDoubleMetaphoneEqual(String value1, + String value2, + boolean alternate) { + return doubleMetaphone(value1, alternate).equals(doubleMetaphone + (value2, alternate)); + } + + /** + * Returns the maxCodeLen. + * @return int + */ + public int getMaxCodeLen() { + return this.maxCodeLen; + } + + /** + * Sets the maxCodeLen. + * @param maxCodeLen The maxCodeLen to set + */ + public void setMaxCodeLen(int maxCodeLen) { + this.maxCodeLen = maxCodeLen; + } + + //-- BEGIN HANDLERS --// + + /** + * Handles 'A', 'E', 'I', 'O', 'U', and 'Y' cases + */ + private int handleAEIOUY(DoubleMetaphoneResult result, int + index) { + if (index == 0) { + result.append('A'); + } + return index + 1; + } + + /** + * Handles 'C' cases + */ + private int handleC(String value, + DoubleMetaphoneResult result, + int index) { + if (conditionC0(value, index)) { // very confusing, moved out + result.append('K'); + index += 2; + } else if (index == 0 && contains(value, index, 6, "CAESAR")) { + result.append('S'); + index += 2; + } else if (contains(value, index, 2, "CH")) { + index = handleCH(value, result, index); + } else if (contains(value, index, 2, "CZ") && + !contains(value, index - 2, 4, "WICZ")) { + //-- "Czerny" --// + result.append('S', 'X'); + index += 2; + } else if (contains(value, index + 1, 3, "CIA")) { + //-- "focaccia" --// + result.append('X'); + index += 3; + } else if (contains(value, index, 2, "CC") && + !(index == 1 && charAt(value, 0) == 'M')) { + //-- double "cc" but not "McClelland" --// + return handleCC(value, result, index); + } else if (contains(value, index, 2, "CK", "CG", "CQ")) { + result.append('K'); + index += 2; + } else if (contains(value, index, 2, "CI", "CE", "CY")) { + //-- Italian vs. English --// + if (contains(value, index, 3, "CIO", "CIE", "CIA")) { + result.append('S', 'X'); + } else { + result.append('S'); + } + index += 2; + } else { + result.append('K'); + if (contains(value, index + 1, 2, " C", " Q", " G")) { + //-- Mac Caffrey, Mac Gregor --// + index += 3; + } else if (contains(value, index + 1, 1, "C", "K", "Q") && + !contains(value, index + 1, 2, "CE", "CI")) { + index += 2; + } else { + index++; + } + } + + return index; + } + + /** + * Handles 'CC' cases + */ + private int handleCC(String value, + DoubleMetaphoneResult result, + int index) { + if (contains(value, index + 2, 1, "I", "E", "H") && + !contains(value, index + 2, 2, "HU")) { + //-- "bellocchio" but not "bacchus" --// + if ((index == 1 && charAt(value, index - 1) == 'A') || + contains(value, index - 1, 5, "UCCEE", "UCCES")) { + //-- "accident", "accede", "succeed" --// + result.append("KS"); + } else { + //-- "bacci", "bertucci", other Italian --// + result.append('X'); + } + index += 3; + } else { // Pierce's rule + result.append('K'); + index += 2; + } + + return index; + } + + /** + * Handles 'CH' cases + */ + private int handleCH(String value, + DoubleMetaphoneResult result, + int index) { + if (index > 0 && contains(value, index, 4, "CHAE")) { // Michael + result.append('K', 'X'); + return index + 2; + } else if (conditionCH0(value, index)) { + //-- Greek roots ("chemistry", "chorus", etc.) --// + result.append('K'); + return index + 2; + } else if (conditionCH1(value, index)) { + //-- Germanic, Greek, or otherwise 'ch' for 'kh' sound --// + result.append('K'); + return index + 2; + } else { + if (index > 0) { + if (contains(value, 0, 2, "MC")) { + result.append('K'); + } else { + result.append('X', 'K'); + } + } else { + result.append('X'); + } + return index + 2; + } + } + + /** + * Handles 'D' cases + */ + private int handleD(String value, + DoubleMetaphoneResult result, + int index) { + if (contains(value, index, 2, "DG")) { + //-- "Edge" --// + if (contains(value, index + 2, 1, "I", "E", "Y")) { + result.append('J'); + index += 3; + //-- "Edgar" --// + } else { + result.append("TK"); + index += 2; + } + } else if (contains(value, index, 2, "DT", "DD")) { + result.append('T'); + index += 2; + } else { + result.append('T'); + index++; + } + return index; + } + + /** + * Handles 'G' cases + */ + private int handleG(String value, + DoubleMetaphoneResult result, + int index, + boolean slavoGermanic) { + if (charAt(value, index + 1) == 'H') { + index = handleGH(value, result, index); + } else if (charAt(value, index + 1) == 'N') { + if (index == 1 && isVowel(charAt(value, 0)) && !slavoGermanic) { + result.append("KN", "N"); + } else if (!contains(value, index + 2, 2, "EY") && + charAt(value, index + 1) != 'Y' && !slavoGermanic) { + result.append("N", "KN"); + } else { + result.append("KN"); + } + index = index + 2; + } else if (contains(value, index + 1, 2, "LI") && !slavoGermanic) { + result.append("KL", "L"); + index += 2; + } else if (index == 0 && (charAt(value, index + 1) == 'Y' || contains(value, index + 1, 2, ES_EP_EB_EL_EY_IB_IL_IN_IE_EI_ER))) { + //-- -ges-, -gep-, -gel-, -gie- at beginning --// + result.append('K', 'J'); + index += 2; + } else if ((contains(value, index + 1, 2, "ER") || + charAt(value, index + 1) == 'Y') && + !contains(value, 0, 6, "DANGER", "RANGER", "MANGER") && + !contains(value, index - 1, 1, "E", "I") && + !contains(value, index - 1, 3, "RGY", "OGY")) { + //-- -ger-, -gy- --// + result.append('K', 'J'); + index += 2; + } else if (contains(value, index + 1, 1, "E", "I", "Y") || + contains(value, index - 1, 4, "AGGI", "OGGI")) { + //-- Italian "biaggi" --// + if ((contains(value, 0 ,4, "VAN ", "VON ") || contains(value, 0, 3, "SCH")) || contains(value, index + 1, 2, "ET")) { + //-- obvious germanic --// + result.append('K'); + } else if (contains(value, index + 1, 3, "IER")) { + result.append('J'); + } else { + result.append('J', 'K'); + } + index += 2; + } else if (charAt(value, index + 1) == 'G') { + index += 2; + result.append('K'); + } else { + index++; + result.append('K'); + } + return index; + } + + /** + * Handles 'GH' cases + */ + private int handleGH(String value, + DoubleMetaphoneResult result, + int index) { + if (index > 0 && !isVowel(charAt(value, index - 1))) { + result.append('K'); + index += 2; + } else if (index == 0) { + if (charAt(value, index + 2) == 'I') { + result.append('J'); + } else { + result.append('K'); + } + index += 2; + } else if ((index > 1 && contains(value, index - 2, 1, "B", "H", "D")) || + (index > 2 && contains(value, index - 3, 1, "B", "H", "D")) || + (index > 3 && contains(value, index - 4, 1, "B", "H"))) { + //-- Parker's rule (with some further refinements) - "hugh" + index += 2; + } else { + if (index > 2 && charAt(value, index - 1) == 'U' && + contains(value, index - 3, 1, "C", "G", "L", "R", "T")) { + //-- "laugh", "McLaughlin", "cough", "gough", "rough", "tough" + result.append('F'); + } else if (index > 0 && charAt(value, index - 1) != 'I') { + result.append('K'); + } + index += 2; + } + return index; + } + + /** + * Handles 'H' cases + */ + private int handleH(String value, + DoubleMetaphoneResult result, + int index) { + //-- only keep if first & before vowel or between 2 vowels --// + if ((index == 0 || isVowel(charAt(value, index - 1))) && + isVowel(charAt(value, index + 1))) { + result.append('H'); + index += 2; + //-- also takes car of "HH" --// + } else { + index++; + } + return index; + } + + /** + * Handles 'J' cases + */ + private int handleJ(String value, DoubleMetaphoneResult result, int index, + boolean slavoGermanic) { + if (contains(value, index, 4, "JOSE") || contains(value, 0, 4, "SAN ")) { + //-- obvious Spanish, "Jose", "San Jacinto" --// + if ((index == 0 && (charAt(value, index + 4) == ' ') || + value.length() == 4) || contains(value, 0, 4, "SAN ")) { + result.append('H'); + } else { + result.append('J', 'H'); + } + index++; + } else { + if (index == 0 && !contains(value, index, 4, "JOSE")) { + result.append('J', 'A'); + } else if (isVowel(charAt(value, index - 1)) && !slavoGermanic && + (charAt(value, index + 1) == 'A' || charAt(value, index + 1) == 'O')) { + result.append('J', 'H'); + } else if (index == value.length() - 1) { + result.append('J', ' '); + } else if (!contains(value, index + 1, 1, L_T_K_S_N_M_B_Z) && !contains(value, index - 1, 1, "S", "K", "L")) { + result.append('J'); + } + + if (charAt(value, index + 1) == 'J') { + index += 2; + } else { + index++; + } + } + return index; + } + + /** + * Handles 'L' cases + */ + private int handleL(String value, + DoubleMetaphoneResult result, + int index) { + if (charAt(value, index + 1) == 'L') { + if (conditionL0(value, index)) { + result.appendPrimary('L'); + } else { + result.append('L'); + } + index += 2; + } else { + index++; + result.append('L'); + } + return index; + } + + /** + * Handles 'P' cases + */ + private int handleP(String value, + DoubleMetaphoneResult result, + int index) { + if (charAt(value, index + 1) == 'H') { + result.append('F'); + index += 2; + } else { + result.append('P'); + index = contains(value, index + 1, 1, "P", "B") ? index + 2 : index + 1; + } + return index; + } + + /** + * Handles 'R' cases + */ + private int handleR(String value, + DoubleMetaphoneResult result, + int index, + boolean slavoGermanic) { + if (index == value.length() - 1 && !slavoGermanic && + contains(value, index - 2, 2, "IE") && + !contains(value, index - 4, 2, "ME", "MA")) { + result.appendAlternate('R'); + } else { + result.append('R'); + } + return charAt(value, index + 1) == 'R' ? index + 2 : index + 1; + } + + /** + * Handles 'S' cases + */ + private int handleS(String value, + DoubleMetaphoneResult result, + int index, + boolean slavoGermanic) { + if (contains(value, index - 1, 3, "ISL", "YSL")) { + //-- special cases "island", "isle", "carlisle", "carlysle" --// + index++; + } else if (index == 0 && contains(value, index, 5, "SUGAR")) { + //-- special case "sugar-" --// + result.append('X', 'S'); + index++; + } else if (contains(value, index, 2, "SH")) { + if (contains(value, index + 1, 4, + "HEIM", "HOEK", "HOLM", "HOLZ")) { + //-- germanic --// + result.append('S'); + } else { + result.append('X'); + } + index += 2; + } else if (contains(value, index, 3, "SIO", "SIA") || contains(value, index, 4, "SIAN")) { + //-- Italian and Armenian --// + if (slavoGermanic) { + result.append('S'); + } else { + result.append('S', 'X'); + } + index += 3; + } else if ((index == 0 && contains(value, index + 1, 1, "M", "N", "L", "W")) || contains(value, index + 1, 1, "Z")) { + //-- german & anglicisations, e.g. "smith" match "schmidt" // + // "snider" match "schneider" --// + //-- also, -sz- in slavic language altho in hungarian it // + // is pronounced "s" --// + result.append('S', 'X'); + index = contains(value, index + 1, 1, "Z") ? index + 2 : index + 1; + } else if (contains(value, index, 2, "SC")) { + index = handleSC(value, result, index); + } else { + if (index == value.length() - 1 && contains(value, index - 2, + 2, "AI", "OI")){ + //-- french e.g. "resnais", "artois" --// + result.appendAlternate('S'); + } else { + result.append('S'); + } + index = contains(value, index + 1, 1, "S", "Z") ? index + 2 : index + 1; + } + return index; + } + + /** + * Handles 'SC' cases + */ + private int handleSC(String value, + DoubleMetaphoneResult result, + int index) { + if (charAt(value, index + 2) == 'H') { + //-- Schlesinger's rule --// + if (contains(value, index + 3, + 2, "OO", "ER", "EN", "UY", "ED", "EM")) { + //-- Dutch origin, e.g. "school", "schooner" --// + if (contains(value, index + 3, 2, "ER", "EN")) { + //-- "schermerhorn", "schenker" --// + result.append("X", "SK"); + } else { + result.append("SK"); + } + } else { + if (index == 0 && !isVowel(charAt(value, 3)) && charAt(value, 3) != 'W') { + result.append('X', 'S'); + } else { + result.append('X'); + } + } + } else if (contains(value, index + 2, 1, "I", "E", "Y")) { + result.append('S'); + } else { + result.append("SK"); + } + return index + 3; + } + + /** + * Handles 'T' cases + */ + private int handleT(String value, + DoubleMetaphoneResult result, + int index) { + if (contains(value, index, 4, "TION")) { + result.append('X'); + index += 3; + } else if (contains(value, index, 3, "TIA", "TCH")) { + result.append('X'); + index += 3; + } else if (contains(value, index, 2, "TH") || contains(value, index, + 3, "TTH")) { + if (contains(value, index + 2, 2, "OM", "AM") || + //-- special case "thomas", "thames" or germanic --// + contains(value, 0, 4, "VAN ", "VON ") || + contains(value, 0, 3, "SCH")) { + result.append('T'); + } else { + result.append('0', 'T'); + } + index += 2; + } else { + result.append('T'); + index = contains(value, index + 1, 1, "T", "D") ? index + 2 : index + 1; + } + return index; + } + + /** + * Handles 'W' cases + */ + private int handleW(String value, + DoubleMetaphoneResult result, + int index) { + if (contains(value, index, 2, "WR")) { + //-- can also be in middle of word --// + result.append('R'); + index += 2; + } else { + if (index == 0 && (isVowel(charAt(value, index + 1)) || + contains(value, index, 2, "WH"))) { + if (isVowel(charAt(value, index + 1))) { + //-- Wasserman should match Vasserman --// + result.append('A', 'F'); + } else { + //-- need Uomo to match Womo --// + result.append('A'); + } + index++; + } else if ((index == value.length() - 1 && isVowel(charAt(value, index - 1))) || + contains(value, index - 1, + 5, "EWSKI", "EWSKY", "OWSKI", "OWSKY") || + contains(value, 0, 3, "SCH")) { + //-- Arnow should match Arnoff --// + result.appendAlternate('F'); + index++; + } else if (contains(value, index, 4, "WICZ", "WITZ")) { + //-- Polish e.g. "filipowicz" --// + result.append("TS", "FX"); + index += 4; + } else { + index++; + } + } + return index; + } + + /** + * Handles 'X' cases + */ + private int handleX(String value, + DoubleMetaphoneResult result, + int index) { + if (index == 0) { + result.append('S'); + index++; + } else { + if (!((index == value.length() - 1) && + (contains(value, index - 3, 3, "IAU", "EAU") || + contains(value, index - 2, 2, "AU", "OU")))) { + //-- French e.g. breaux --// + result.append("KS"); + } + index = contains(value, index + 1, 1, "C", "X") ? index + 2 : index + 1; + } + return index; + } + + /** + * Handles 'Z' cases + */ + private int handleZ(String value, DoubleMetaphoneResult result, int index, + boolean slavoGermanic) { + if (charAt(value, index + 1) == 'H') { + //-- Chinese pinyin e.g. "zhao" or Angelina "Zhang" --// + result.append('J'); + index += 2; + } else { + if (contains(value, index + 1, 2, "ZO", "ZI", "ZA") || (slavoGermanic && (index > 0 && charAt(value, index - 1) != 'T'))) { + result.append("S", "TS"); + } else { + result.append('S'); + } + index = charAt(value, index + 1) == 'Z' ? index + 2 : index + 1; + } + return index; + } + + //-- BEGIN CONDITIONS --// + + /** + * Complex condition 0 for 'C' + */ + private boolean conditionC0(String value, int index) { + if (contains(value, index, 4, "CHIA")) { + return true; + } else if (index <= 1) { + return false; + } else if (isVowel(charAt(value, index - 2))) { + return false; + } else if (!contains(value, index - 1, 3, "ACH")) { + return false; + } else { + char c = charAt(value, index + 2); + return (c != 'I' && c != 'E') || + contains(value, index - 2, 6, "BACHER", "MACHER"); + } + } + + /** + * Complex condition 0 for 'CH' + */ + private boolean conditionCH0(String value, int index) { + if (index != 0) { + return false; + } else if (!contains(value, index + 1, 5, "HARAC", "HARIS") && + !contains(value, index + 1, 3, "HOR", "HYM", "HIA", "HEM")) { + return false; + } else if (contains(value, 0, 5, "CHORE")) { + return false; + } else { + return true; + } + } + + /** + * Complex condition 1 for 'CH' + */ + private boolean conditionCH1(String value, int index) { + return ((contains(value, 0, 4, "VAN ", "VON ") || contains(value, 0, + 3, "SCH")) || + contains(value, index - 2, 6, "ORCHES", "ARCHIT", "ORCHID") || + contains(value, index + 2, 1, "T", "S") || + ((contains(value, index - 1, 1, "A", "O", "U", "E") || index == 0) && + (contains(value, index + 2, 1, L_R_N_M_B_H_F_V_W_SPACE) || index + 1 == value.length() - 1))); + } + + /** + * Complex condition 0 for 'L' + */ + private boolean conditionL0(String value, int index) { + if (index == value.length() - 3 && + contains(value, index - 1, 4, "ILLO", "ILLA", "ALLE")) { + return true; + } else if ((contains(value, value.length() - 2, 2, "AS", "OS") || + contains(value, value.length() - 1, 1, "A", "O")) && + contains(value, index - 1, 4, "ALLE")) { + return true; + } else { + return false; + } + } + + /** + * Complex condition 0 for 'M' + */ + private boolean conditionM0(String value, int index) { + if (charAt(value, index + 1) == 'M') { + return true; + } + return contains(value, index - 1, 3, "UMB") && + ((index + 1) == value.length() - 1 || contains(value, + index + 2, 2, "ER")); + } + + //-- BEGIN HELPER FUNCTIONS --// + + /** + * Determines whether or not a value is of slavo-germanic orgin. A value is + * of slavo-germanic origin if it contians any of 'W', 'K', 'CZ', or 'WITZ'. + */ + private boolean isSlavoGermanic(String value) { + return value.indexOf('W') > -1 || value.indexOf('K') > -1 || + value.indexOf("CZ") > -1 || value.indexOf("WITZ") > -1; + } + + /** + * Determines whether or not a character is a vowel or not + */ + private boolean isVowel(char ch) { + return VOWELS.indexOf(ch) != -1; + } + + /** + * Determines whether or not the value starts with a silent letter. It will + * return true if the value starts with any of 'GN', 'KN', + * 'PN', 'WR' or 'PS'. + */ + private boolean isSilentStart(String value) { + boolean result = false; + for (int i = 0; i < SILENT_START.length; i++) { + if (value.startsWith(SILENT_START[i])) { + result = true; + break; + } + } + return result; + } + + /** + * Cleans the input + */ + private String cleanInput(String input) { + if (input == null) { + return null; + } + input = input.trim(); + if (input.length() == 0) { + return null; + } + return input.toUpperCase(java.util.Locale.ENGLISH); + } + + /** + * Gets the character at index index if available, otherwise + * it returns Character.MIN_VALUE so that there is some sort + * of a default + */ + protected char charAt(String value, int index) { + if (index < 0 || index >= value.length()) { + return Character.MIN_VALUE; + } + return value.charAt(index); + } + + /** + * Shortcut method with 1 criteria + */ + private static boolean contains(String value, int start, int length, + String criteria) { + return contains(value, start, length, + new String[] { criteria }); + } + + /** + * Shortcut method with 2 criteria + */ + private static boolean contains(String value, int start, int length, + String criteria1, String criteria2) { + return contains(value, start, length, + new String[] { criteria1, criteria2 }); + } + + /** + * Shortcut method with 3 criteria + */ + private static boolean contains(String value, int start, int length, + String criteria1, String criteria2, + String criteria3) { + return contains(value, start, length, + new String[] { criteria1, criteria2, criteria3 }); + } + + /** + * Shortcut method with 4 criteria + */ + private static boolean contains(String value, int start, int length, + String criteria1, String criteria2, + String criteria3, String criteria4) { + return contains(value, start, length, + new String[] { criteria1, criteria2, criteria3, + criteria4 }); + } + + /** + * Shortcut method with 5 criteria + */ + private static boolean contains(String value, int start, int length, + String criteria1, String criteria2, + String criteria3, String criteria4, + String criteria5) { + return contains(value, start, length, + new String[] { criteria1, criteria2, criteria3, + criteria4, criteria5 }); + } + + /** + * Shortcut method with 6 criteria + */ + private static boolean contains(String value, int start, int length, + String criteria1, String criteria2, + String criteria3, String criteria4, + String criteria5, String criteria6) { + return contains(value, start, length, + new String[] { criteria1, criteria2, criteria3, + criteria4, criteria5, criteria6 }); + } + + /** + * Determines whether value contains any of the criteria starting at index start and + * matching up to length length + */ + protected static boolean contains(String value, int start, int length, + String[] criteria) { + boolean result = false; + if (start >= 0 && start + length <= value.length()) { + String target = value.substring(start, start + length); + + for (int i = 0; i < criteria.length; i++) { + if (target.equals(criteria[i])) { + result = true; + break; + } + } + } + return result; + } + + //-- BEGIN INNER CLASSES --// + + /** + * Inner class for storing results, since there is the optional alternate + * encoding. + */ + public class DoubleMetaphoneResult { + + private StringBuffer primary = new StringBuffer(getMaxCodeLen()); + private StringBuffer alternate = new StringBuffer(getMaxCodeLen()); + private int maxLength; + + public DoubleMetaphoneResult(int maxLength) { + this.maxLength = maxLength; + } + + public void append(char value) { + appendPrimary(value); + appendAlternate(value); + } + + public void append(char primary, char alternate) { + appendPrimary(primary); + appendAlternate(alternate); + } + + public void appendPrimary(char value) { + if (this.primary.length() < this.maxLength) { + this.primary.append(value); + } + } + + public void appendAlternate(char value) { + if (this.alternate.length() < this.maxLength) { + this.alternate.append(value); + } + } + + public void append(String value) { + appendPrimary(value); + appendAlternate(value); + } + + public void append(String primary, String alternate) { + appendPrimary(primary); + appendAlternate(alternate); + } + + public void appendPrimary(String value) { + int addChars = this.maxLength - this.primary.length(); + if (value.length() <= addChars) { + this.primary.append(value); + } else { + this.primary.append(value.substring(0, addChars)); + } + } + + public void appendAlternate(String value) { + int addChars = this.maxLength - this.alternate.length(); + if (value.length() <= addChars) { + this.alternate.append(value); + } else { + this.alternate.append(value.substring(0, addChars)); + } + } + + public String getPrimary() { + return this.primary.toString(); + } + + public String getAlternate() { + return this.alternate.toString(); + } + + public boolean isComplete() { + return this.primary.length() >= this.maxLength && + this.alternate.length() >= this.maxLength; + } + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Metaphone.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Metaphone.java new file mode 100644 index 000000000..ec7cd3813 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Metaphone.java @@ -0,0 +1,408 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.StringEncoder; + +/** + * Encodes a string into a Metaphone value. + *

+ * Initial Java implementation by William B. Brogden. December, 1997. + * Permission given by wbrogden for code to be used anywhere. + *

+ *

+ * Hanging on the Metaphone by Lawrence Philips in Computer Language of Dec. 1990, p + * 39. + *

+ *

+ * Note, that this does not match the algorithm that ships with PHP, or the algorithm + * found in the Perl Text:Metaphone-1.96. + * They have had undocumented changes from the originally published algorithm. + * For more information, see CODEC-57. + *

+ * + * @author Apache Software Foundation + * @version $Id: Metaphone.java 1080867 2011-03-12 06:06:46Z ggregory $ + */ +public class Metaphone implements StringEncoder { + + /** + * Five values in the English language + */ + private static final String VOWELS = "AEIOU" ; + + /** + * Variable used in Metaphone algorithm + */ + private static final String FRONTV = "EIY" ; + + /** + * Variable used in Metaphone algorithm + */ + private static final String VARSON = "CSPTG" ; + + /** + * The max code length for metaphone is 4 + */ + private int maxCodeLen = 4 ; + + /** + * Creates an instance of the Metaphone encoder + */ + public Metaphone() { + super(); + } + + /** + * Find the metaphone value of a String. This is similar to the + * soundex algorithm, but better at finding similar sounding words. + * All input is converted to upper case. + * Limitations: Input format is expected to be a single ASCII word + * with only characters in the A - Z range, no punctuation or numbers. + * + * @param txt String to find the metaphone code for + * @return A metaphone code corresponding to the String supplied + */ + public String metaphone(String txt) { + boolean hard = false ; + if ((txt == null) || (txt.length() == 0)) { + return "" ; + } + // single character is itself + if (txt.length() == 1) { + return txt.toUpperCase(java.util.Locale.ENGLISH) ; + } + + char[] inwd = txt.toUpperCase(java.util.Locale.ENGLISH).toCharArray() ; + + StringBuffer local = new StringBuffer(40); // manipulate + StringBuffer code = new StringBuffer(10) ; // output + // handle initial 2 characters exceptions + switch(inwd[0]) { + case 'K' : + case 'G' : + case 'P' : /* looking for KN, etc*/ + if (inwd[1] == 'N') { + local.append(inwd, 1, inwd.length - 1); + } else { + local.append(inwd); + } + break; + case 'A': /* looking for AE */ + if (inwd[1] == 'E') { + local.append(inwd, 1, inwd.length - 1); + } else { + local.append(inwd); + } + break; + case 'W' : /* looking for WR or WH */ + if (inwd[1] == 'R') { // WR -> R + local.append(inwd, 1, inwd.length - 1); + break ; + } + if (inwd[1] == 'H') { + local.append(inwd, 1, inwd.length - 1); + local.setCharAt(0, 'W'); // WH -> W + } else { + local.append(inwd); + } + break; + case 'X' : /* initial X becomes S */ + inwd[0] = 'S'; + local.append(inwd); + break ; + default : + local.append(inwd); + } // now local has working string with initials fixed + + int wdsz = local.length(); + int n = 0 ; + + while ((code.length() < this.getMaxCodeLen()) && + (n < wdsz) ) { // max code size of 4 works well + char symb = local.charAt(n) ; + // remove duplicate letters except C + if ((symb != 'C') && (isPreviousChar( local, n, symb )) ) { + n++ ; + } else { // not dup + switch(symb) { + case 'A' : case 'E' : case 'I' : case 'O' : case 'U' : + if (n == 0) { + code.append(symb); + } + break ; // only use vowel if leading char + case 'B' : + if ( isPreviousChar(local, n, 'M') && + isLastChar(wdsz, n) ) { // B is silent if word ends in MB + break; + } + code.append(symb); + break; + case 'C' : // lots of C special cases + /* discard if SCI, SCE or SCY */ + if ( isPreviousChar(local, n, 'S') && + !isLastChar(wdsz, n) && + (FRONTV.indexOf(local.charAt(n + 1)) >= 0) ) { + break; + } + if (regionMatch(local, n, "CIA")) { // "CIA" -> X + code.append('X'); + break; + } + if (!isLastChar(wdsz, n) && + (FRONTV.indexOf(local.charAt(n + 1)) >= 0)) { + code.append('S'); + break; // CI,CE,CY -> S + } + if (isPreviousChar(local, n, 'S') && + isNextChar(local, n, 'H') ) { // SCH->sk + code.append('K') ; + break ; + } + if (isNextChar(local, n, 'H')) { // detect CH + if ((n == 0) && + (wdsz >= 3) && + isVowel(local,2) ) { // CH consonant -> K consonant + code.append('K'); + } else { + code.append('X'); // CHvowel -> X + } + } else { + code.append('K'); + } + break ; + case 'D' : + if (!isLastChar(wdsz, n + 1) && + isNextChar(local, n, 'G') && + (FRONTV.indexOf(local.charAt(n + 2)) >= 0)) { // DGE DGI DGY -> J + code.append('J'); n += 2 ; + } else { + code.append('T'); + } + break ; + case 'G' : // GH silent at end or before consonant + if (isLastChar(wdsz, n + 1) && + isNextChar(local, n, 'H')) { + break; + } + if (!isLastChar(wdsz, n + 1) && + isNextChar(local,n,'H') && + !isVowel(local,n+2)) { + break; + } + if ((n > 0) && + ( regionMatch(local, n, "GN") || + regionMatch(local, n, "GNED") ) ) { + break; // silent G + } + if (isPreviousChar(local, n, 'G')) { + // NOTE: Given that duplicated chars are removed, I don't see how this can ever be true + hard = true ; + } else { + hard = false ; + } + if (!isLastChar(wdsz, n) && + (FRONTV.indexOf(local.charAt(n + 1)) >= 0) && + (!hard)) { + code.append('J'); + } else { + code.append('K'); + } + break ; + case 'H': + if (isLastChar(wdsz, n)) { + break ; // terminal H + } + if ((n > 0) && + (VARSON.indexOf(local.charAt(n - 1)) >= 0)) { + break; + } + if (isVowel(local,n+1)) { + code.append('H'); // Hvowel + } + break; + case 'F': + case 'J' : + case 'L' : + case 'M': + case 'N' : + case 'R' : + code.append(symb); + break; + case 'K' : + if (n > 0) { // not initial + if (!isPreviousChar(local, n, 'C')) { + code.append(symb); + } + } else { + code.append(symb); // initial K + } + break ; + case 'P' : + if (isNextChar(local,n,'H')) { + // PH -> F + code.append('F'); + } else { + code.append(symb); + } + break ; + case 'Q' : + code.append('K'); + break; + case 'S' : + if (regionMatch(local,n,"SH") || + regionMatch(local,n,"SIO") || + regionMatch(local,n,"SIA")) { + code.append('X'); + } else { + code.append('S'); + } + break; + case 'T' : + if (regionMatch(local,n,"TIA") || + regionMatch(local,n,"TIO")) { + code.append('X'); + break; + } + if (regionMatch(local,n,"TCH")) { + // Silent if in "TCH" + break; + } + // substitute numeral 0 for TH (resembles theta after all) + if (regionMatch(local,n,"TH")) { + code.append('0'); + } else { + code.append('T'); + } + break ; + case 'V' : + code.append('F'); break ; + case 'W' : case 'Y' : // silent if not followed by vowel + if (!isLastChar(wdsz,n) && + isVowel(local,n+1)) { + code.append(symb); + } + break ; + case 'X' : + code.append('K'); code.append('S'); + break ; + case 'Z' : + code.append('S'); break ; + } // end switch + n++ ; + } // end else from symb != 'C' + if (code.length() > this.getMaxCodeLen()) { + code.setLength(this.getMaxCodeLen()); + } + } + return code.toString(); + } + + private boolean isVowel(StringBuffer string, int index) { + return VOWELS.indexOf(string.charAt(index)) >= 0; + } + + private boolean isPreviousChar(StringBuffer string, int index, char c) { + boolean matches = false; + if( index > 0 && + index < string.length() ) { + matches = string.charAt(index - 1) == c; + } + return matches; + } + + private boolean isNextChar(StringBuffer string, int index, char c) { + boolean matches = false; + if( index >= 0 && + index < string.length() - 1 ) { + matches = string.charAt(index + 1) == c; + } + return matches; + } + + private boolean regionMatch(StringBuffer string, int index, String test) { + boolean matches = false; + if( index >= 0 && + (index + test.length() - 1) < string.length() ) { + String substring = string.substring( index, index + test.length()); + matches = substring.equals( test ); + } + return matches; + } + + private boolean isLastChar(int wdsz, int n) { + return n + 1 == wdsz; + } + + + /** + * Encodes an Object using the metaphone algorithm. This method + * is provided in order to satisfy the requirements of the + * Encoder interface, and will throw an EncoderException if the + * supplied object is not of type java.lang.String. + * + * @param pObject Object to encode + * @return An object (or type java.lang.String) containing the + * metaphone code which corresponds to the String supplied. + * @throws EncoderException if the parameter supplied is not + * of type java.lang.String + */ + public Object encode(Object pObject) throws EncoderException { + if (!(pObject instanceof String)) { + throw new EncoderException("Parameter supplied to Metaphone encode is not of type java.lang.String"); + } + return metaphone((String) pObject); + } + + /** + * Encodes a String using the Metaphone algorithm. + * + * @param pString String object to encode + * @return The metaphone code corresponding to the String supplied + */ + public String encode(String pString) { + return metaphone(pString); + } + + /** + * Tests is the metaphones of two strings are identical. + * + * @param str1 First of two strings to compare + * @param str2 Second of two strings to compare + * @return true if the metaphones of these strings are identical, + * false otherwise. + */ + public boolean isMetaphoneEqual(String str1, String str2) { + return metaphone(str1).equals(metaphone(str2)); + } + + /** + * Returns the maxCodeLen. + * @return int + */ + public int getMaxCodeLen() { return this.maxCodeLen; } + + /** + * Sets the maxCodeLen. + * @param maxCodeLen The maxCodeLen to set + */ + public void setMaxCodeLen(int maxCodeLen) { this.maxCodeLen = maxCodeLen; } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/RefinedSoundex.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/RefinedSoundex.java new file mode 100644 index 000000000..7fb730cea --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/RefinedSoundex.java @@ -0,0 +1,203 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.StringEncoder; + +/** + * Encodes a string into a Refined Soundex value. A refined soundex code is + * optimized for spell checking words. Soundex method originally developed by + * Margaret Odell and Robert Russell. + * + * @author Apache Software Foundation + * @version $Id: RefinedSoundex.java 1064455 2011-01-28 04:40:27Z ggregory $ + */ +public class RefinedSoundex implements StringEncoder { + + /** + * @since 1.4 + */ + public static final String US_ENGLISH_MAPPING_STRING = "01360240043788015936020505"; + + /** + * RefinedSoundex is *refined* for a number of reasons one being that the + * mappings have been altered. This implementation contains default + * mappings for US English. + */ + private static final char[] US_ENGLISH_MAPPING = US_ENGLISH_MAPPING_STRING.toCharArray(); + + /** + * Every letter of the alphabet is "mapped" to a numerical value. This char + * array holds the values to which each letter is mapped. This + * implementation contains a default map for US_ENGLISH + */ + private final char[] soundexMapping; + + /** + * This static variable contains an instance of the RefinedSoundex using + * the US_ENGLISH mapping. + */ + public static final RefinedSoundex US_ENGLISH = new RefinedSoundex(); + + /** + * Creates an instance of the RefinedSoundex object using the default US + * English mapping. + */ + public RefinedSoundex() { + this.soundexMapping = US_ENGLISH_MAPPING; + } + + /** + * Creates a refined soundex instance using a custom mapping. This + * constructor can be used to customize the mapping, and/or possibly + * provide an internationalized mapping for a non-Western character set. + * + * @param mapping + * Mapping array to use when finding the corresponding code for + * a given character + */ + public RefinedSoundex(char[] mapping) { + this.soundexMapping = new char[mapping.length]; + System.arraycopy(mapping, 0, this.soundexMapping, 0, mapping.length); + } + + /** + * Creates a refined Soundex instance using a custom mapping. This constructor can be used to customize the mapping, + * and/or possibly provide an internationalized mapping for a non-Western character set. + * + * @param mapping + * Mapping string to use when finding the corresponding code for a given character + * @since 1.4 + */ + public RefinedSoundex(String mapping) { + this.soundexMapping = mapping.toCharArray(); + } + + /** + * Returns the number of characters in the two encoded Strings that are the + * same. This return value ranges from 0 to the length of the shortest + * encoded String: 0 indicates little or no similarity, and 4 out of 4 (for + * example) indicates strong similarity or identical values. For refined + * Soundex, the return value can be greater than 4. + * + * @param s1 + * A String that will be encoded and compared. + * @param s2 + * A String that will be encoded and compared. + * @return The number of characters in the two encoded Strings that are the + * same from 0 to to the length of the shortest encoded String. + * + * @see SoundexUtils#difference(StringEncoder,String,String) + * @see + * MS T-SQL DIFFERENCE + * + * @throws EncoderException + * if an error occurs encoding one of the strings + * @since 1.3 + */ + public int difference(String s1, String s2) throws EncoderException { + return SoundexUtils.difference(this, s1, s2); + } + + /** + * Encodes an Object using the refined soundex algorithm. This method is + * provided in order to satisfy the requirements of the Encoder interface, + * and will throw an EncoderException if the supplied object is not of type + * java.lang.String. + * + * @param pObject + * Object to encode + * @return An object (or type java.lang.String) containing the refined + * soundex code which corresponds to the String supplied. + * @throws EncoderException + * if the parameter supplied is not of type java.lang.String + */ + public Object encode(Object pObject) throws EncoderException { + if (!(pObject instanceof String)) { + throw new EncoderException("Parameter supplied to RefinedSoundex encode is not of type java.lang.String"); + } + return soundex((String) pObject); + } + + /** + * Encodes a String using the refined soundex algorithm. + * + * @param pString + * A String object to encode + * @return A Soundex code corresponding to the String supplied + */ + public String encode(String pString) { + return soundex(pString); + } + + /** + * Returns the mapping code for a given character. The mapping codes are + * maintained in an internal char array named soundexMapping, and the + * default values of these mappings are US English. + * + * @param c + * char to get mapping for + * @return A character (really a numeral) to return for the given char + */ + char getMappingCode(char c) { + if (!Character.isLetter(c)) { + return 0; + } + return this.soundexMapping[Character.toUpperCase(c) - 'A']; + } + + /** + * Retreives the Refined Soundex code for a given String object. + * + * @param str + * String to encode using the Refined Soundex algorithm + * @return A soundex code for the String supplied + */ + public String soundex(String str) { + if (str == null) { + return null; + } + str = SoundexUtils.clean(str); + if (str.length() == 0) { + return str; + } + + StringBuffer sBuf = new StringBuffer(); + sBuf.append(str.charAt(0)); + + char last, current; + last = '*'; + + for (int i = 0; i < str.length(); i++) { + + current = getMappingCode(str.charAt(i)); + if (current == last) { + continue; + } else if (current != 0) { + sBuf.append(current); + } + + last = current; + + } + + return sBuf.toString(); + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Soundex.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Soundex.java new file mode 100644 index 000000000..76805bca3 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/Soundex.java @@ -0,0 +1,279 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.StringEncoder; + +/** + * Encodes a string into a Soundex value. Soundex is an encoding used to relate similar names, but can also be used as a + * general purpose scheme to find word with similar phonemes. + * + * @author Apache Software Foundation + * @version $Id: Soundex.java 1064454 2011-01-28 04:40:02Z ggregory $ + */ +public class Soundex implements StringEncoder { + + /** + * This is a default mapping of the 26 letters used in US English. A value of 0 for a letter position + * means do not encode. + *

+ * (This constant is provided as both an implementation convenience and to allow Javadoc to pick + * up the value for the constant values page.) + *

+ * + * @see #US_ENGLISH_MAPPING + */ + public static final String US_ENGLISH_MAPPING_STRING = "01230120022455012623010202"; + + /** + * This is a default mapping of the 26 letters used in US English. A value of 0 for a letter position + * means do not encode. + * + * @see Soundex#Soundex(char[]) + */ + private static final char[] US_ENGLISH_MAPPING = US_ENGLISH_MAPPING_STRING.toCharArray(); + + /** + * An instance of Soundex using the US_ENGLISH_MAPPING mapping. + * + * @see #US_ENGLISH_MAPPING + */ + public static final Soundex US_ENGLISH = new Soundex(); + + + /** + * Encodes the Strings and returns the number of characters in the two encoded Strings that are the same. This + * return value ranges from 0 through 4: 0 indicates little or no similarity, and 4 indicates strong similarity or + * identical values. + * + * @param s1 + * A String that will be encoded and compared. + * @param s2 + * A String that will be encoded and compared. + * @return The number of characters in the two encoded Strings that are the same from 0 to 4. + * + * @see SoundexUtils#difference(StringEncoder,String,String) + * @see MS + * T-SQL DIFFERENCE + * + * @throws EncoderException + * if an error occurs encoding one of the strings + * @since 1.3 + */ + public int difference(String s1, String s2) throws EncoderException { + return SoundexUtils.difference(this, s1, s2); + } + + /** + * The maximum length of a Soundex code - Soundex codes are only four characters by definition. + * + * @deprecated This feature is not needed since the encoding size must be constant. Will be removed in 2.0. + */ + private int maxLength = 4; + + /** + * Every letter of the alphabet is "mapped" to a numerical value. This char array holds the values to which each + * letter is mapped. This implementation contains a default map for US_ENGLISH + */ + private final char[] soundexMapping; + + /** + * Creates an instance using US_ENGLISH_MAPPING + * + * @see Soundex#Soundex(char[]) + * @see Soundex#US_ENGLISH_MAPPING + */ + public Soundex() { + this.soundexMapping = US_ENGLISH_MAPPING; + } + + /** + * Creates a soundex instance using the given mapping. This constructor can be used to provide an internationalized + * mapping for a non-Western character set. + * + * Every letter of the alphabet is "mapped" to a numerical value. This char array holds the values to which each + * letter is mapped. This implementation contains a default map for US_ENGLISH + * + * @param mapping + * Mapping array to use when finding the corresponding code for a given character + */ + public Soundex(char[] mapping) { + this.soundexMapping = new char[mapping.length]; + System.arraycopy(mapping, 0, this.soundexMapping, 0, mapping.length); + } + + /** + * Creates a refined soundex instance using a custom mapping. This constructor can be used to customize the mapping, + * and/or possibly provide an internationalized mapping for a non-Western character set. + * + * @param mapping + * Mapping string to use when finding the corresponding code for a given character + * @since 1.4 + */ + public Soundex(String mapping) { + this.soundexMapping = mapping.toCharArray(); + } + + /** + * Encodes an Object using the soundex algorithm. This method is provided in order to satisfy the requirements of + * the Encoder interface, and will throw an EncoderException if the supplied object is not of type java.lang.String. + * + * @param pObject + * Object to encode + * @return An object (or type java.lang.String) containing the soundex code which corresponds to the String + * supplied. + * @throws EncoderException + * if the parameter supplied is not of type java.lang.String + * @throws IllegalArgumentException + * if a character is not mapped + */ + public Object encode(Object pObject) throws EncoderException { + if (!(pObject instanceof String)) { + throw new EncoderException("Parameter supplied to Soundex encode is not of type java.lang.String"); + } + return soundex((String) pObject); + } + + /** + * Encodes a String using the soundex algorithm. + * + * @param pString + * A String object to encode + * @return A Soundex code corresponding to the String supplied + * @throws IllegalArgumentException + * if a character is not mapped + */ + public String encode(String pString) { + return soundex(pString); + } + + /** + * Used internally by the SoundEx algorithm. + * + * Consonants from the same code group separated by W or H are treated as one. + * + * @param str + * the cleaned working string to encode (in upper case). + * @param index + * the character position to encode + * @return Mapping code for a particular character + * @throws IllegalArgumentException + * if the character is not mapped + */ + private char getMappingCode(String str, int index) { + // map() throws IllegalArgumentException + char mappedChar = this.map(str.charAt(index)); + // HW rule check + if (index > 1 && mappedChar != '0') { + char hwChar = str.charAt(index - 1); + if ('H' == hwChar || 'W' == hwChar) { + char preHWChar = str.charAt(index - 2); + char firstCode = this.map(preHWChar); + if (firstCode == mappedChar || 'H' == preHWChar || 'W' == preHWChar) { + return 0; + } + } + } + return mappedChar; + } + + /** + * Returns the maxLength. Standard Soundex + * + * @deprecated This feature is not needed since the encoding size must be constant. Will be removed in 2.0. + * @return int + */ + public int getMaxLength() { + return this.maxLength; + } + + /** + * Returns the soundex mapping. + * + * @return soundexMapping. + */ + private char[] getSoundexMapping() { + return this.soundexMapping; + } + + /** + * Maps the given upper-case character to its Soundex code. + * + * @param ch + * An upper-case character. + * @return A Soundex code. + * @throws IllegalArgumentException + * Thrown if ch is not mapped. + */ + private char map(char ch) { + int index = ch - 'A'; + if (index < 0 || index >= this.getSoundexMapping().length) { + throw new IllegalArgumentException("The character is not mapped: " + ch); + } + return this.getSoundexMapping()[index]; + } + + /** + * Sets the maxLength. + * + * @deprecated This feature is not needed since the encoding size must be constant. Will be removed in 2.0. + * @param maxLength + * The maxLength to set + */ + public void setMaxLength(int maxLength) { + this.maxLength = maxLength; + } + + /** + * Retrieves the Soundex code for a given String object. + * + * @param str + * String to encode using the Soundex algorithm + * @return A soundex code for the String supplied + * @throws IllegalArgumentException + * if a character is not mapped + */ + public String soundex(String str) { + if (str == null) { + return null; + } + str = SoundexUtils.clean(str); + if (str.length() == 0) { + return str; + } + char out[] = {'0', '0', '0', '0'}; + char last, mapped; + int incount = 1, count = 1; + out[0] = str.charAt(0); + // getMappingCode() throws IllegalArgumentException + last = getMappingCode(str, 0); + while ((incount < str.length()) && (count < out.length)) { + mapped = getMappingCode(str, incount++); + if (mapped != 0) { + if ((mapped != '0') && (mapped != last)) { + out[count++] = mapped; + } + last = mapped; + } + } + return new String(out); + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/SoundexUtils.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/SoundexUtils.java new file mode 100644 index 000000000..3e5a16a5a --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/SoundexUtils.java @@ -0,0 +1,124 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.language; + +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.StringEncoder; + +/** + * Utility methods for {@link Soundex} and {@link RefinedSoundex} classes. + * + * @author Apache Software Foundation + * @version $Id: SoundexUtils.java 658834 2008-05-21 19:57:51Z niallp $ + * @since 1.3 + */ +final class SoundexUtils { + + /** + * Cleans up the input string before Soundex processing by only returning + * upper case letters. + * + * @param str + * The String to clean. + * @return A clean String. + */ + static String clean(String str) { + if (str == null || str.length() == 0) { + return str; + } + int len = str.length(); + char[] chars = new char[len]; + int count = 0; + for (int i = 0; i < len; i++) { + if (Character.isLetter(str.charAt(i))) { + chars[count++] = str.charAt(i); + } + } + if (count == len) { + return str.toUpperCase(java.util.Locale.ENGLISH); + } + return new String(chars, 0, count).toUpperCase(java.util.Locale.ENGLISH); + } + + /** + * Encodes the Strings and returns the number of characters in the two + * encoded Strings that are the same. + *
    + *
  • For Soundex, this return value ranges from 0 through 4: 0 indicates + * little or no similarity, and 4 indicates strong similarity or identical + * values.
  • + *
  • For refined Soundex, the return value can be greater than 4.
  • + *
+ * + * @param encoder + * The encoder to use to encode the Strings. + * @param s1 + * A String that will be encoded and compared. + * @param s2 + * A String that will be encoded and compared. + * @return The number of characters in the two Soundex encoded Strings that + * are the same. + * + * @see #differenceEncoded(String,String) + * @see + * MS T-SQL DIFFERENCE + * + * @throws EncoderException + * if an error occurs encoding one of the strings + */ + static int difference(StringEncoder encoder, String s1, String s2) throws EncoderException { + return differenceEncoded(encoder.encode(s1), encoder.encode(s2)); + } + + /** + * Returns the number of characters in the two Soundex encoded Strings that + * are the same. + *
    + *
  • For Soundex, this return value ranges from 0 through 4: 0 indicates + * little or no similarity, and 4 indicates strong similarity or identical + * values.
  • + *
  • For refined Soundex, the return value can be greater than 4.
  • + *
+ * + * @param es1 + * An encoded String. + * @param es2 + * An encoded String. + * @return The number of characters in the two Soundex encoded Strings that + * are the same. + * + * @see + * MS T-SQL DIFFERENCE + */ + static int differenceEncoded(String es1, String es2) { + + if (es1 == null || es2 == null) { + return 0; + } + int lengthToMatch = Math.min(es1.length(), es2.length()); + int diff = 0; + for (int i = 0; i < lengthToMatch; i++) { + if (es1.charAt(i) == es2.charAt(i)) { + diff++; + } + } + return diff; + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/package.html b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/package.html new file mode 100644 index 000000000..6e3376689 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/language/package.html @@ -0,0 +1,21 @@ + + + + Language and phonetic encoders. + + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/BCodec.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/BCodec.java new file mode 100644 index 000000000..b694888eb --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/BCodec.java @@ -0,0 +1,209 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.net; + +import java.io.UnsupportedEncodingException; + +import org.mozilla.apache.commons.codec.DecoderException; +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.CharEncoding; +import org.mozilla.apache.commons.codec.StringDecoder; +import org.mozilla.apache.commons.codec.StringEncoder; +import org.mozilla.apache.commons.codec.binary.Base64; + +/** + *

+ * Identical to the Base64 encoding defined by RFC + * 1521 and allows a character set to be specified. + *

+ * + *

+ * RFC 1522 describes techniques to allow the encoding of non-ASCII + * text in various portions of a RFC 822 [2] message header, in a manner which is unlikely to confuse existing message + * handling software. + *

+ * + * @see MIME (Multipurpose Internet Mail Extensions) Part Two: Message + * Header Extensions for Non-ASCII Text + * + * @author Apache Software Foundation + * @since 1.3 + * @version $Id: BCodec.java 797857 2009-07-25 23:43:33Z ggregory $ + */ +public class BCodec extends RFC1522Codec implements StringEncoder, StringDecoder { + /** + * The default charset used for string decoding and encoding. + */ + private final String charset; + + /** + * Default constructor. + */ + public BCodec() { + this(CharEncoding.UTF_8); + } + + /** + * Constructor which allows for the selection of a default charset + * + * @param charset + * the default string charset to use. + * + * @see Standard charsets + */ + public BCodec(final String charset) { + super(); + this.charset = charset; + } + + protected String getEncoding() { + return "B"; + } + + protected byte[] doEncoding(byte[] bytes) { + if (bytes == null) { + return null; + } + return Base64.encodeBase64(bytes); + } + + protected byte[] doDecoding(byte[] bytes) { + if (bytes == null) { + return null; + } + return Base64.decodeBase64(bytes); + } + + /** + * Encodes a string into its Base64 form using the specified charset. Unsafe characters are escaped. + * + * @param value + * string to convert to Base64 form + * @param charset + * the charset for value + * @return Base64 string + * + * @throws EncoderException + * thrown if a failure condition is encountered during the encoding process. + */ + public String encode(final String value, final String charset) throws EncoderException { + if (value == null) { + return null; + } + try { + return encodeText(value, charset); + } catch (UnsupportedEncodingException e) { + throw new EncoderException(e.getMessage(), e); + } + } + + /** + * Encodes a string into its Base64 form using the default charset. Unsafe characters are escaped. + * + * @param value + * string to convert to Base64 form + * @return Base64 string + * + * @throws EncoderException + * thrown if a failure condition is encountered during the encoding process. + */ + public String encode(String value) throws EncoderException { + if (value == null) { + return null; + } + return encode(value, getDefaultCharset()); + } + + /** + * Decodes a Base64 string into its original form. Escaped characters are converted back to their original + * representation. + * + * @param value + * Base64 string to convert into its original form + * @return original string + * @throws DecoderException + * A decoder exception is thrown if a failure condition is encountered during the decode process. + */ + public String decode(String value) throws DecoderException { + if (value == null) { + return null; + } + try { + return decodeText(value); + } catch (UnsupportedEncodingException e) { + throw new DecoderException(e.getMessage(), e); + } + } + + /** + * Encodes an object into its Base64 form using the default charset. Unsafe characters are escaped. + * + * @param value + * object to convert to Base64 form + * @return Base64 object + * + * @throws EncoderException + * thrown if a failure condition is encountered during the encoding process. + */ + public Object encode(Object value) throws EncoderException { + if (value == null) { + return null; + } else if (value instanceof String) { + return encode((String) value); + } else { + throw new EncoderException("Objects of type " + + value.getClass().getName() + + " cannot be encoded using BCodec"); + } + } + + /** + * Decodes a Base64 object into its original form. Escaped characters are converted back to their original + * representation. + * + * @param value + * Base64 object to convert into its original form + * + * @return original object + * + * @throws DecoderException + * Thrown if the argument is not a String. Thrown if a failure condition is + * encountered during the decode process. + */ + public Object decode(Object value) throws DecoderException { + if (value == null) { + return null; + } else if (value instanceof String) { + return decode((String) value); + } else { + throw new DecoderException("Objects of type " + + value.getClass().getName() + + " cannot be decoded using BCodec"); + } + } + + /** + * The default charset used for string decoding and encoding. + * + * @return the default string charset. + */ + public String getDefaultCharset() { + return this.charset; + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/QCodec.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/QCodec.java new file mode 100644 index 000000000..d174bcdff --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/QCodec.java @@ -0,0 +1,312 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.net; + +import java.io.UnsupportedEncodingException; +import java.util.BitSet; + +import org.mozilla.apache.commons.codec.DecoderException; +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.CharEncoding; +import org.mozilla.apache.commons.codec.StringDecoder; +import org.mozilla.apache.commons.codec.StringEncoder; + +/** + *

+ * Similar to the Quoted-Printable content-transfer-encoding defined in RFC 1521 and designed to allow text containing mostly ASCII + * characters to be decipherable on an ASCII terminal without decoding. + *

+ * + *

+ * RFC 1522 describes techniques to allow the encoding of non-ASCII + * text in various portions of a RFC 822 [2] message header, in a manner which is unlikely to confuse existing message + * handling software. + *

+ * + * @see MIME (Multipurpose Internet Mail Extensions) Part Two: Message + * Header Extensions for Non-ASCII Text + * + * @author Apache Software Foundation + * @since 1.3 + * @version $Id: QCodec.java 797857 2009-07-25 23:43:33Z ggregory $ + */ +public class QCodec extends RFC1522Codec implements StringEncoder, StringDecoder { + /** + * The default charset used for string decoding and encoding. + */ + private final String charset; + + /** + * BitSet of printable characters as defined in RFC 1522. + */ + private static final BitSet PRINTABLE_CHARS = new BitSet(256); + // Static initializer for printable chars collection + static { + // alpha characters + PRINTABLE_CHARS.set(' '); + PRINTABLE_CHARS.set('!'); + PRINTABLE_CHARS.set('"'); + PRINTABLE_CHARS.set('#'); + PRINTABLE_CHARS.set('$'); + PRINTABLE_CHARS.set('%'); + PRINTABLE_CHARS.set('&'); + PRINTABLE_CHARS.set('\''); + PRINTABLE_CHARS.set('('); + PRINTABLE_CHARS.set(')'); + PRINTABLE_CHARS.set('*'); + PRINTABLE_CHARS.set('+'); + PRINTABLE_CHARS.set(','); + PRINTABLE_CHARS.set('-'); + PRINTABLE_CHARS.set('.'); + PRINTABLE_CHARS.set('/'); + for (int i = '0'; i <= '9'; i++) { + PRINTABLE_CHARS.set(i); + } + PRINTABLE_CHARS.set(':'); + PRINTABLE_CHARS.set(';'); + PRINTABLE_CHARS.set('<'); + PRINTABLE_CHARS.set('>'); + PRINTABLE_CHARS.set('@'); + for (int i = 'A'; i <= 'Z'; i++) { + PRINTABLE_CHARS.set(i); + } + PRINTABLE_CHARS.set('['); + PRINTABLE_CHARS.set('\\'); + PRINTABLE_CHARS.set(']'); + PRINTABLE_CHARS.set('^'); + PRINTABLE_CHARS.set('`'); + for (int i = 'a'; i <= 'z'; i++) { + PRINTABLE_CHARS.set(i); + } + PRINTABLE_CHARS.set('{'); + PRINTABLE_CHARS.set('|'); + PRINTABLE_CHARS.set('}'); + PRINTABLE_CHARS.set('~'); + } + + private static final byte BLANK = 32; + + private static final byte UNDERSCORE = 95; + + private boolean encodeBlanks = false; + + /** + * Default constructor. + */ + public QCodec() { + this(CharEncoding.UTF_8); + } + + /** + * Constructor which allows for the selection of a default charset + * + * @param charset + * the default string charset to use. + * + * @see Standard charsets + */ + public QCodec(final String charset) { + super(); + this.charset = charset; + } + + protected String getEncoding() { + return "Q"; + } + + protected byte[] doEncoding(byte[] bytes) { + if (bytes == null) { + return null; + } + byte[] data = QuotedPrintableCodec.encodeQuotedPrintable(PRINTABLE_CHARS, bytes); + if (this.encodeBlanks) { + for (int i = 0; i < data.length; i++) { + if (data[i] == BLANK) { + data[i] = UNDERSCORE; + } + } + } + return data; + } + + protected byte[] doDecoding(byte[] bytes) throws DecoderException { + if (bytes == null) { + return null; + } + boolean hasUnderscores = false; + for (int i = 0; i < bytes.length; i++) { + if (bytes[i] == UNDERSCORE) { + hasUnderscores = true; + break; + } + } + if (hasUnderscores) { + byte[] tmp = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + byte b = bytes[i]; + if (b != UNDERSCORE) { + tmp[i] = b; + } else { + tmp[i] = BLANK; + } + } + return QuotedPrintableCodec.decodeQuotedPrintable(tmp); + } + return QuotedPrintableCodec.decodeQuotedPrintable(bytes); + } + + /** + * Encodes a string into its quoted-printable form using the specified charset. Unsafe characters are escaped. + * + * @param pString + * string to convert to quoted-printable form + * @param charset + * the charset for pString + * @return quoted-printable string + * + * @throws EncoderException + * thrown if a failure condition is encountered during the encoding process. + */ + public String encode(final String pString, final String charset) throws EncoderException { + if (pString == null) { + return null; + } + try { + return encodeText(pString, charset); + } catch (UnsupportedEncodingException e) { + throw new EncoderException(e.getMessage(), e); + } + } + + /** + * Encodes a string into its quoted-printable form using the default charset. Unsafe characters are escaped. + * + * @param pString + * string to convert to quoted-printable form + * @return quoted-printable string + * + * @throws EncoderException + * thrown if a failure condition is encountered during the encoding process. + */ + public String encode(String pString) throws EncoderException { + if (pString == null) { + return null; + } + return encode(pString, getDefaultCharset()); + } + + /** + * Decodes a quoted-printable string into its original form. Escaped characters are converted back to their original + * representation. + * + * @param pString + * quoted-printable string to convert into its original form + * + * @return original string + * + * @throws DecoderException + * A decoder exception is thrown if a failure condition is encountered during the decode process. + */ + public String decode(String pString) throws DecoderException { + if (pString == null) { + return null; + } + try { + return decodeText(pString); + } catch (UnsupportedEncodingException e) { + throw new DecoderException(e.getMessage(), e); + } + } + + /** + * Encodes an object into its quoted-printable form using the default charset. Unsafe characters are escaped. + * + * @param pObject + * object to convert to quoted-printable form + * @return quoted-printable object + * + * @throws EncoderException + * thrown if a failure condition is encountered during the encoding process. + */ + public Object encode(Object pObject) throws EncoderException { + if (pObject == null) { + return null; + } else if (pObject instanceof String) { + return encode((String) pObject); + } else { + throw new EncoderException("Objects of type " + + pObject.getClass().getName() + + " cannot be encoded using Q codec"); + } + } + + /** + * Decodes a quoted-printable object into its original form. Escaped characters are converted back to their original + * representation. + * + * @param pObject + * quoted-printable object to convert into its original form + * + * @return original object + * + * @throws DecoderException + * Thrown if the argument is not a String. Thrown if a failure condition is + * encountered during the decode process. + */ + public Object decode(Object pObject) throws DecoderException { + if (pObject == null) { + return null; + } else if (pObject instanceof String) { + return decode((String) pObject); + } else { + throw new DecoderException("Objects of type " + + pObject.getClass().getName() + + " cannot be decoded using Q codec"); + } + } + + /** + * The default charset used for string decoding and encoding. + * + * @return the default string charset. + */ + public String getDefaultCharset() { + return this.charset; + } + + /** + * Tests if optional tranformation of SPACE characters is to be used + * + * @return true if SPACE characters are to be transformed, false otherwise + */ + public boolean isEncodeBlanks() { + return this.encodeBlanks; + } + + /** + * Defines whether optional tranformation of SPACE characters is to be used + * + * @param b + * true if SPACE characters are to be transformed, false otherwise + */ + public void setEncodeBlanks(boolean b) { + this.encodeBlanks = b; + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/QuotedPrintableCodec.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/QuotedPrintableCodec.java new file mode 100644 index 000000000..c9b5e6172 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/QuotedPrintableCodec.java @@ -0,0 +1,388 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.net; + +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.util.BitSet; + +import org.mozilla.apache.commons.codec.BinaryDecoder; +import org.mozilla.apache.commons.codec.BinaryEncoder; +import org.mozilla.apache.commons.codec.DecoderException; +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.CharEncoding; +import org.mozilla.apache.commons.codec.StringDecoder; +import org.mozilla.apache.commons.codec.StringEncoder; +import org.mozilla.apache.commons.codec.binary.StringUtils; + +/** + *

+ * Codec for the Quoted-Printable section of RFC 1521. + *

+ *

+ * The Quoted-Printable encoding is intended to represent data that largely consists of octets that correspond to + * printable characters in the ASCII character set. It encodes the data in such a way that the resulting octets are + * unlikely to be modified by mail transport. If the data being encoded are mostly ASCII text, the encoded form of the + * data remains largely recognizable by humans. A body which is entirely ASCII may also be encoded in Quoted-Printable + * to ensure the integrity of the data should the message pass through a character- translating, and/or line-wrapping + * gateway. + *

+ * + *

+ * Note: + *

+ *

+ * Rules #3, #4, and #5 of the quoted-printable spec are not implemented yet because the complete quoted-printable spec + * does not lend itself well into the byte[] oriented codec framework. Complete the codec once the steamable codec + * framework is ready. The motivation behind providing the codec in a partial form is that it can already come in handy + * for those applications that do not require quoted-printable line formatting (rules #3, #4, #5), for instance Q codec. + *

+ * + * @see RFC 1521 MIME (Multipurpose Internet Mail Extensions) Part One: + * Mechanisms for Specifying and Describing the Format of Internet Message Bodies + * + * @author Apache Software Foundation + * @since 1.3 + * @version $Id: QuotedPrintableCodec.java 1080712 2011-03-11 18:26:59Z ggregory $ + */ +public class QuotedPrintableCodec implements BinaryEncoder, BinaryDecoder, StringEncoder, StringDecoder { + /** + * The default charset used for string decoding and encoding. + */ + private final String charset; + + /** + * BitSet of printable characters as defined in RFC 1521. + */ + private static final BitSet PRINTABLE_CHARS = new BitSet(256); + + private static final byte ESCAPE_CHAR = '='; + + private static final byte TAB = 9; + + private static final byte SPACE = 32; + // Static initializer for printable chars collection + static { + // alpha characters + for (int i = 33; i <= 60; i++) { + PRINTABLE_CHARS.set(i); + } + for (int i = 62; i <= 126; i++) { + PRINTABLE_CHARS.set(i); + } + PRINTABLE_CHARS.set(TAB); + PRINTABLE_CHARS.set(SPACE); + } + + /** + * Default constructor. + */ + public QuotedPrintableCodec() { + this(CharEncoding.UTF_8); + } + + /** + * Constructor which allows for the selection of a default charset + * + * @param charset + * the default string charset to use. + */ + public QuotedPrintableCodec(String charset) { + super(); + this.charset = charset; + } + + /** + * Encodes byte into its quoted-printable representation. + * + * @param b + * byte to encode + * @param buffer + * the buffer to write to + */ + private static final void encodeQuotedPrintable(int b, ByteArrayOutputStream buffer) { + buffer.write(ESCAPE_CHAR); + char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, 16)); + char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, 16)); + buffer.write(hex1); + buffer.write(hex2); + } + + /** + * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters are escaped. + * + *

+ * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in + * RFC 1521 and is suitable for encoding binary data and unformatted text. + *

+ * + * @param printable + * bitset of characters deemed quoted-printable + * @param bytes + * array of bytes to be encoded + * @return array of bytes containing quoted-printable data + */ + public static final byte[] encodeQuotedPrintable(BitSet printable, byte[] bytes) { + if (bytes == null) { + return null; + } + if (printable == null) { + printable = PRINTABLE_CHARS; + } + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + for (int i = 0; i < bytes.length; i++) { + int b = bytes[i]; + if (b < 0) { + b = 256 + b; + } + if (printable.get(b)) { + buffer.write(b); + } else { + encodeQuotedPrintable(b, buffer); + } + } + return buffer.toByteArray(); + } + + /** + * Decodes an array quoted-printable characters into an array of original bytes. Escaped characters are converted + * back to their original representation. + * + *

+ * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in + * RFC 1521. + *

+ * + * @param bytes + * array of quoted-printable characters + * @return array of original bytes + * @throws DecoderException + * Thrown if quoted-printable decoding is unsuccessful + */ + public static final byte[] decodeQuotedPrintable(byte[] bytes) throws DecoderException { + if (bytes == null) { + return null; + } + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + for (int i = 0; i < bytes.length; i++) { + int b = bytes[i]; + if (b == ESCAPE_CHAR) { + try { + int u = Utils.digit16(bytes[++i]); + int l = Utils.digit16(bytes[++i]); + buffer.write((char) ((u << 4) + l)); + } catch (ArrayIndexOutOfBoundsException e) { + throw new DecoderException("Invalid quoted-printable encoding", e); + } + } else { + buffer.write(b); + } + } + return buffer.toByteArray(); + } + + /** + * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters are escaped. + * + *

+ * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in + * RFC 1521 and is suitable for encoding binary data and unformatted text. + *

+ * + * @param bytes + * array of bytes to be encoded + * @return array of bytes containing quoted-printable data + */ + public byte[] encode(byte[] bytes) { + return encodeQuotedPrintable(PRINTABLE_CHARS, bytes); + } + + /** + * Decodes an array of quoted-printable characters into an array of original bytes. Escaped characters are converted + * back to their original representation. + * + *

+ * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in + * RFC 1521. + *

+ * + * @param bytes + * array of quoted-printable characters + * @return array of original bytes + * @throws DecoderException + * Thrown if quoted-printable decoding is unsuccessful + */ + public byte[] decode(byte[] bytes) throws DecoderException { + return decodeQuotedPrintable(bytes); + } + + /** + * Encodes a string into its quoted-printable form using the default string charset. Unsafe characters are escaped. + * + *

+ * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in + * RFC 1521 and is suitable for encoding binary data. + *

+ * + * @param pString + * string to convert to quoted-printable form + * @return quoted-printable string + * + * @throws EncoderException + * Thrown if quoted-printable encoding is unsuccessful + * + * @see #getDefaultCharset() + */ + public String encode(String pString) throws EncoderException { + if (pString == null) { + return null; + } + try { + return encode(pString, getDefaultCharset()); + } catch (UnsupportedEncodingException e) { + throw new EncoderException(e.getMessage(), e); + } + } + + /** + * Decodes a quoted-printable string into its original form using the specified string charset. Escaped characters + * are converted back to their original representation. + * + * @param pString + * quoted-printable string to convert into its original form + * @param charset + * the original string charset + * @return original string + * @throws DecoderException + * Thrown if quoted-printable decoding is unsuccessful + * @throws UnsupportedEncodingException + * Thrown if charset is not supported + */ + public String decode(String pString, String charset) throws DecoderException, UnsupportedEncodingException { + if (pString == null) { + return null; + } + return new String(decode(StringUtils.getBytesUsAscii(pString)), charset); + } + + /** + * Decodes a quoted-printable string into its original form using the default string charset. Escaped characters are + * converted back to their original representation. + * + * @param pString + * quoted-printable string to convert into its original form + * @return original string + * @throws DecoderException + * Thrown if quoted-printable decoding is unsuccessful. + * Thrown if charset is not supported. + * @see #getDefaultCharset() + */ + public String decode(String pString) throws DecoderException { + if (pString == null) { + return null; + } + try { + return decode(pString, getDefaultCharset()); + } catch (UnsupportedEncodingException e) { + throw new DecoderException(e.getMessage(), e); + } + } + + /** + * Encodes an object into its quoted-printable safe form. Unsafe characters are escaped. + * + * @param pObject + * string to convert to a quoted-printable form + * @return quoted-printable object + * @throws EncoderException + * Thrown if quoted-printable encoding is not applicable to objects of this type or if encoding is + * unsuccessful + */ + public Object encode(Object pObject) throws EncoderException { + if (pObject == null) { + return null; + } else if (pObject instanceof byte[]) { + return encode((byte[]) pObject); + } else if (pObject instanceof String) { + return encode((String) pObject); + } else { + throw new EncoderException("Objects of type " + + pObject.getClass().getName() + + " cannot be quoted-printable encoded"); + } + } + + /** + * Decodes a quoted-printable object into its original form. Escaped characters are converted back to their original + * representation. + * + * @param pObject + * quoted-printable object to convert into its original form + * @return original object + * @throws DecoderException + * Thrown if the argument is not a String or byte[]. Thrown if a failure condition is + * encountered during the decode process. + */ + public Object decode(Object pObject) throws DecoderException { + if (pObject == null) { + return null; + } else if (pObject instanceof byte[]) { + return decode((byte[]) pObject); + } else if (pObject instanceof String) { + return decode((String) pObject); + } else { + throw new DecoderException("Objects of type " + + pObject.getClass().getName() + + " cannot be quoted-printable decoded"); + } + } + + /** + * Returns the default charset used for string decoding and encoding. + * + * @return the default string charset. + */ + public String getDefaultCharset() { + return this.charset; + } + + /** + * Encodes a string into its quoted-printable form using the specified charset. Unsafe characters are escaped. + * + *

+ * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in + * RFC 1521 and is suitable for encoding binary data and unformatted text. + *

+ * + * @param pString + * string to convert to quoted-printable form + * @param charset + * the charset for pString + * @return quoted-printable string + * + * @throws UnsupportedEncodingException + * Thrown if the charset is not supported + */ + public String encode(String pString, String charset) throws UnsupportedEncodingException { + if (pString == null) { + return null; + } + return StringUtils.newStringUsAscii(encode(pString.getBytes(charset))); + } +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/RFC1522Codec.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/RFC1522Codec.java new file mode 100644 index 000000000..f11a450cb --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/RFC1522Codec.java @@ -0,0 +1,179 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.net; + +import java.io.UnsupportedEncodingException; + +import org.mozilla.apache.commons.codec.DecoderException; +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.binary.StringUtils; + +/** + *

+ * Implements methods common to all codecs defined in RFC 1522. + *

+ * + *

+ * RFC 1522 + * describes techniques to allow the encoding of non-ASCII text in + * various portions of a RFC 822 [2] message header, in a manner which + * is unlikely to confuse existing message handling software. + *

+ + * @see + * MIME (Multipurpose Internet Mail Extensions) Part Two: + * Message Header Extensions for Non-ASCII Text + *

+ * + * @author Apache Software Foundation + * @since 1.3 + * @version $Id: RFC1522Codec.java 798428 2009-07-28 07:32:49Z ggregory $ + */ +abstract class RFC1522Codec { + + /** + * Separator. + */ + protected static final char SEP = '?'; + + /** + * Prefix + */ + protected static final String POSTFIX = "?="; + + /** + * Postfix + */ + protected static final String PREFIX = "=?"; + + /** + * Applies an RFC 1522 compliant encoding scheme to the given string of text with the + * given charset. This method constructs the "encoded-word" header common to all the + * RFC 1522 codecs and then invokes {@link #doEncoding(byte [])} method of a concrete + * class to perform the specific enconding. + * + * @param text a string to encode + * @param charset a charset to be used + * + * @return RFC 1522 compliant "encoded-word" + * + * @throws EncoderException thrown if there is an error conidition during the Encoding + * process. + * @throws UnsupportedEncodingException thrown if charset is not supported + * + * @see Standard charsets + */ + protected String encodeText(final String text, final String charset) + throws EncoderException, UnsupportedEncodingException + { + if (text == null) { + return null; + } + StringBuffer buffer = new StringBuffer(); + buffer.append(PREFIX); + buffer.append(charset); + buffer.append(SEP); + buffer.append(getEncoding()); + buffer.append(SEP); + byte [] rawdata = doEncoding(text.getBytes(charset)); + buffer.append(StringUtils.newStringUsAscii(rawdata)); + buffer.append(POSTFIX); + return buffer.toString(); + } + + /** + * Applies an RFC 1522 compliant decoding scheme to the given string of text. This method + * processes the "encoded-word" header common to all the RFC 1522 codecs and then invokes + * {@link #doEncoding(byte [])} method of a concrete class to perform the specific deconding. + * + * @param text a string to decode + * @return A new decoded String or null if the input is null. + * + * @throws DecoderException thrown if there is an error conidition during the Decoding + * process. + * @throws UnsupportedEncodingException thrown if charset specified in the "encoded-word" + * header is not supported + */ + protected String decodeText(final String text) + throws DecoderException, UnsupportedEncodingException + { + if (text == null) { + return null; + } + if ((!text.startsWith(PREFIX)) || (!text.endsWith(POSTFIX))) { + throw new DecoderException("RFC 1522 violation: malformed encoded content"); + } + int terminator = text.length() - 2; + int from = 2; + int to = text.indexOf(SEP, from); + if (to == terminator) { + throw new DecoderException("RFC 1522 violation: charset token not found"); + } + String charset = text.substring(from, to); + if (charset.equals("")) { + throw new DecoderException("RFC 1522 violation: charset not specified"); + } + from = to + 1; + to = text.indexOf(SEP, from); + if (to == terminator) { + throw new DecoderException("RFC 1522 violation: encoding token not found"); + } + String encoding = text.substring(from, to); + if (!getEncoding().equalsIgnoreCase(encoding)) { + throw new DecoderException("This codec cannot decode " + + encoding + " encoded content"); + } + from = to + 1; + to = text.indexOf(SEP, from); + byte[] data = StringUtils.getBytesUsAscii(text.substring(from, to)); + data = doDecoding(data); + return new String(data, charset); + } + + /** + * Returns the codec name (referred to as encoding in the RFC 1522) + * + * @return name of the codec + */ + protected abstract String getEncoding(); + + /** + * Encodes an array of bytes using the defined encoding scheme + * + * @param bytes Data to be encoded + * + * @return A byte array containing the encoded data + * + * @throws EncoderException thrown if the Encoder encounters a failure condition + * during the encoding process. + */ + protected abstract byte[] doEncoding(byte[] bytes) throws EncoderException; + + /** + * Decodes an array of bytes using the defined encoding scheme + * + * @param bytes Data to be decoded + * + * @return a byte array that contains decoded data + * + * @throws DecoderException A decoder exception is thrown if a Decoder encounters a + * failure condition during the decode process. + */ + protected abstract byte[] doDecoding(byte[] bytes) throws DecoderException; +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/URLCodec.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/URLCodec.java new file mode 100644 index 000000000..74699310f --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/URLCodec.java @@ -0,0 +1,362 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.net; + +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.util.BitSet; + +import org.mozilla.apache.commons.codec.BinaryDecoder; +import org.mozilla.apache.commons.codec.BinaryEncoder; +import org.mozilla.apache.commons.codec.DecoderException; +import org.mozilla.apache.commons.codec.EncoderException; +import org.mozilla.apache.commons.codec.CharEncoding; +import org.mozilla.apache.commons.codec.StringDecoder; +import org.mozilla.apache.commons.codec.StringEncoder; +import org.mozilla.apache.commons.codec.binary.StringUtils; + +/** + *

Implements the 'www-form-urlencoded' encoding scheme, + * also misleadingly known as URL encoding.

+ * + *

For more detailed information please refer to + * + * Chapter 17.13.4 'Form content types' of the + * HTML 4.01 Specification

+ * + *

+ * This codec is meant to be a replacement for standard Java classes + * {@link java.net.URLEncoder} and {@link java.net.URLDecoder} + * on older Java platforms, as these classes in Java versions below + * 1.4 rely on the platform's default charset encoding. + *

+ * + * @author Apache Software Foundation + * @since 1.2 + * @version $Id: URLCodec.java 1079537 2011-03-08 20:56:19Z ggregory $ + */ +public class URLCodec implements BinaryEncoder, BinaryDecoder, StringEncoder, StringDecoder { + + /** + * Radix used in encoding and decoding. + */ + static final int RADIX = 16; + + /** + * The default charset used for string decoding and encoding. Consider this field final. The next major release may + * break compatibility and make this field be final. + */ + protected String charset; + + /** + * Release 1.5 made this field final. + */ + protected static final byte ESCAPE_CHAR = '%'; + /** + * BitSet of www-form-url safe characters. + */ + protected static final BitSet WWW_FORM_URL = new BitSet(256); + + // Static initializer for www_form_url + static { + // alpha characters + for (int i = 'a'; i <= 'z'; i++) { + WWW_FORM_URL.set(i); + } + for (int i = 'A'; i <= 'Z'; i++) { + WWW_FORM_URL.set(i); + } + // numeric characters + for (int i = '0'; i <= '9'; i++) { + WWW_FORM_URL.set(i); + } + // special chars + WWW_FORM_URL.set('-'); + WWW_FORM_URL.set('_'); + WWW_FORM_URL.set('.'); + WWW_FORM_URL.set('*'); + // blank to be replaced with + + WWW_FORM_URL.set(' '); + } + + + /** + * Default constructor. + */ + public URLCodec() { + this(CharEncoding.UTF_8); + } + + /** + * Constructor which allows for the selection of a default charset + * + * @param charset the default string charset to use. + */ + public URLCodec(String charset) { + super(); + this.charset = charset; + } + + /** + * Encodes an array of bytes into an array of URL safe 7-bit characters. Unsafe characters are escaped. + * + * @param urlsafe + * bitset of characters deemed URL safe + * @param bytes + * array of bytes to convert to URL safe characters + * @return array of bytes containing URL safe characters + */ + public static final byte[] encodeUrl(BitSet urlsafe, byte[] bytes) { + if (bytes == null) { + return null; + } + if (urlsafe == null) { + urlsafe = WWW_FORM_URL; + } + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + for (int i = 0; i < bytes.length; i++) { + int b = bytes[i]; + if (b < 0) { + b = 256 + b; + } + if (urlsafe.get(b)) { + if (b == ' ') { + b = '+'; + } + buffer.write(b); + } else { + buffer.write(ESCAPE_CHAR); + char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, RADIX)); + char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, RADIX)); + buffer.write(hex1); + buffer.write(hex2); + } + } + return buffer.toByteArray(); + } + + /** + * Decodes an array of URL safe 7-bit characters into an array of + * original bytes. Escaped characters are converted back to their + * original representation. + * + * @param bytes array of URL safe characters + * @return array of original bytes + * @throws DecoderException Thrown if URL decoding is unsuccessful + */ + public static final byte[] decodeUrl(byte[] bytes) throws DecoderException { + if (bytes == null) { + return null; + } + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + for (int i = 0; i < bytes.length; i++) { + int b = bytes[i]; + if (b == '+') { + buffer.write(' '); + } else if (b == ESCAPE_CHAR) { + try { + int u = Utils.digit16(bytes[++i]); + int l = Utils.digit16(bytes[++i]); + buffer.write((char) ((u << 4) + l)); + } catch (ArrayIndexOutOfBoundsException e) { + throw new DecoderException("Invalid URL encoding: ", e); + } + } else { + buffer.write(b); + } + } + return buffer.toByteArray(); + } + + /** + * Encodes an array of bytes into an array of URL safe 7-bit + * characters. Unsafe characters are escaped. + * + * @param bytes array of bytes to convert to URL safe characters + * @return array of bytes containing URL safe characters + */ + public byte[] encode(byte[] bytes) { + return encodeUrl(WWW_FORM_URL, bytes); + } + + + /** + * Decodes an array of URL safe 7-bit characters into an array of + * original bytes. Escaped characters are converted back to their + * original representation. + * + * @param bytes array of URL safe characters + * @return array of original bytes + * @throws DecoderException Thrown if URL decoding is unsuccessful + */ + public byte[] decode(byte[] bytes) throws DecoderException { + return decodeUrl(bytes); + } + + /** + * Encodes a string into its URL safe form using the specified string charset. Unsafe characters are escaped. + * + * @param pString + * string to convert to a URL safe form + * @param charset + * the charset for pString + * @return URL safe string + * @throws UnsupportedEncodingException + * Thrown if charset is not supported + */ + public String encode(String pString, String charset) throws UnsupportedEncodingException { + if (pString == null) { + return null; + } + return StringUtils.newStringUsAscii(encode(pString.getBytes(charset))); + } + + /** + * Encodes a string into its URL safe form using the default string + * charset. Unsafe characters are escaped. + * + * @param pString string to convert to a URL safe form + * @return URL safe string + * @throws EncoderException Thrown if URL encoding is unsuccessful + * + * @see #getDefaultCharset() + */ + public String encode(String pString) throws EncoderException { + if (pString == null) { + return null; + } + try { + return encode(pString, getDefaultCharset()); + } catch (UnsupportedEncodingException e) { + throw new EncoderException(e.getMessage(), e); + } + } + + + /** + * Decodes a URL safe string into its original form using the + * specified encoding. Escaped characters are converted back + * to their original representation. + * + * @param pString URL safe string to convert into its original form + * @param charset the original string charset + * @return original string + * @throws DecoderException Thrown if URL decoding is unsuccessful + * @throws UnsupportedEncodingException Thrown if charset is not + * supported + */ + public String decode(String pString, String charset) throws DecoderException, UnsupportedEncodingException { + if (pString == null) { + return null; + } + return new String(decode(StringUtils.getBytesUsAscii(pString)), charset); + } + + /** + * Decodes a URL safe string into its original form using the default + * string charset. Escaped characters are converted back to their + * original representation. + * + * @param pString URL safe string to convert into its original form + * @return original string + * @throws DecoderException Thrown if URL decoding is unsuccessful + * + * @see #getDefaultCharset() + */ + public String decode(String pString) throws DecoderException { + if (pString == null) { + return null; + } + try { + return decode(pString, getDefaultCharset()); + } catch (UnsupportedEncodingException e) { + throw new DecoderException(e.getMessage(), e); + } + } + + /** + * Encodes an object into its URL safe form. Unsafe characters are + * escaped. + * + * @param pObject string to convert to a URL safe form + * @return URL safe object + * @throws EncoderException Thrown if URL encoding is not + * applicable to objects of this type or + * if encoding is unsuccessful + */ + public Object encode(Object pObject) throws EncoderException { + if (pObject == null) { + return null; + } else if (pObject instanceof byte[]) { + return encode((byte[])pObject); + } else if (pObject instanceof String) { + return encode((String)pObject); + } else { + throw new EncoderException("Objects of type " + + pObject.getClass().getName() + " cannot be URL encoded"); + + } + } + + /** + * Decodes a URL safe object into its original form. Escaped characters are converted back to their original + * representation. + * + * @param pObject + * URL safe object to convert into its original form + * @return original object + * @throws DecoderException + * Thrown if the argument is not a String or byte[]. Thrown if a failure condition is + * encountered during the decode process. + */ + public Object decode(Object pObject) throws DecoderException { + if (pObject == null) { + return null; + } else if (pObject instanceof byte[]) { + return decode((byte[]) pObject); + } else if (pObject instanceof String) { + return decode((String) pObject); + } else { + throw new DecoderException("Objects of type " + pObject.getClass().getName() + " cannot be URL decoded"); + + } + } + + /** + * The String encoding used for decoding and encoding. + * + * @return Returns the encoding. + * + * @deprecated Use {@link #getDefaultCharset()}, will be removed in 2.0. + */ + public String getEncoding() { + return this.charset; + } + + /** + * The default charset used for string decoding and encoding. + * + * @return the default string charset. + */ + public String getDefaultCharset() { + return this.charset; + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/Utils.java b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/Utils.java new file mode 100644 index 000000000..adfe84513 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/Utils.java @@ -0,0 +1,50 @@ +// Mozilla has modified this file - see http://hg.mozilla.org/ for details. +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.mozilla.apache.commons.codec.net; + +import org.mozilla.apache.commons.codec.DecoderException; + +/** + * Utility methods for this package. + * + * @author
Gary Gregory + * @version $Id: Utils.java 798611 2009-07-28 17:10:44Z ggregory $ + * @since 1.4 + */ +class Utils { + + /** + * Returns the numeric value of the character b in radix 16. + * + * @param b + * The byte to be converted. + * @return The numeric value represented by the character in radix 16. + * + * @throws DecoderException + * Thrown when the byte is not valid per {@link Character#digit(char,int)} + */ + static int digit16(byte b) throws DecoderException { + int i = Character.digit((char) b, 16); + if (i == -1) { + throw new DecoderException("Invalid URL encoding: not a valid digit (radix " + URLCodec.RADIX + "): " + b); + } + return i; + } + +} diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/package.html b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/package.html new file mode 100644 index 000000000..2b8ceab2e --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/net/package.html @@ -0,0 +1,23 @@ + + + +

+ Network related encoding and decoding. +

+ + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/overview.html b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/overview.html new file mode 100644 index 000000000..29939dba5 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/overview.html @@ -0,0 +1,29 @@ + + + + +

+This document is the API specification for the Apache Commons Codec Library, version 1.3. +

+

+This library requires a JRE version of 1.2.2 or greater. +The hypertext links originating from this document point to Sun's version 1.3 API as the 1.2.2 API documentation +is no longer on-line. +

+ + diff --git a/mobile/android/thirdparty/org/mozilla/apache/commons/codec/package.html b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/package.html new file mode 100644 index 000000000..da4a3ea52 --- /dev/null +++ b/mobile/android/thirdparty/org/mozilla/apache/commons/codec/package.html @@ -0,0 +1,100 @@ + + + + + + +

Interfaces and classes used by + the various implementations in the sub-packages.

+ +

Definitive implementations of commonly used encoders and decoders.

+ +

Codec is currently comprised of a modest set of utilities and a + simple framework for String encoding and decoding in three categories: + Binary Encoders, Language Encoders, and Network Encoders.

+ +

Binary Encoders

+ + + + + + + + + + + + + + +
+ + org.apache.commons.codec.binary.Base64 + + Provides Base64 content-transfer-encoding as defined in + RFC 2045 + Production
+ + org.apache.commons.codec.binary.Hex + + Converts an array of bytes into an array of characters + representing the hexidecimal values of each byte in order + Production
+

+ Language Encoders +

+

+ Codec contains a number of commonly used language and phonetic + encoders +

+ + + + + + + + + + + + + +
+ org.apache.commons.codec.language.Soundex + Implementation of the Soundex algorithm.Production
+ org.apache.commons.codec.language.Metaphone + Implementation of the Metaphone algorithm.Production
+

Network Encoders

+

+

Codec contains network related encoders

+ + + + + + + + +
+ org.apache.commons.codec.net.URLCodec + Implements the 'www-form-urlencoded' encoding scheme.Production
+
+ + -- cgit v1.2.3