mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-30 05:02:26 -05:00
Replaced local version of jutf7 with a homebuilt jar from:
URL: https://jutf7.svn.sourceforge.net/svnroot/jutf7/trunk Repository Root: https://jutf7.svn.sourceforge.net/svnroot/jutf7 Repository UUID: 1064e9db-3825-0410-a553-84549dc1c2c0 Revision: 20 Last Changed Author: jtbeetstra Last Changed Rev: 20 Last Changed Date: 2010-04-22 11:31:16 -0400 (Thu, 22 Apr 2010)
This commit is contained in:
parent
2ce5b9ed03
commit
4cc114c568
@ -6,6 +6,7 @@
|
|||||||
<classpathentry exported="true" kind="lib" path="libs/apache-mime4j-core-0.7-SNAPSHOT.jar"/>
|
<classpathentry exported="true" kind="lib" path="libs/apache-mime4j-core-0.7-SNAPSHOT.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="libs/apache-mime4j-dom-0.7-SNAPSHOT.jar"/>
|
<classpathentry exported="true" kind="lib" path="libs/apache-mime4j-dom-0.7-SNAPSHOT.jar"/>
|
||||||
<classpathentry kind="lib" path="libs/commons-io-2.0.1.jar"/>
|
<classpathentry kind="lib" path="libs/commons-io-2.0.1.jar"/>
|
||||||
|
<classpathentry kind="lib" path="libs/jutf7-1.0.1-SNAPSHOT.jar"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/compile-only-libs"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/compile-only-libs"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
BIN
libs/jutf7-1.0.1-SNAPSHOT.jar
Normal file
BIN
libs/jutf7-1.0.1-SNAPSHOT.jar
Normal file
Binary file not shown.
@ -1,117 +0,0 @@
|
|||||||
/* ====================================================================
|
|
||||||
* Copyright (c) 2006 J.T. Beetstra
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.beetstra.jutf7;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Represent a base 64 mapping. The 64 characters used in the encoding can be
|
|
||||||
* specified, since modified-UTF-7 uses other characters than UTF-7 (',' instead
|
|
||||||
* of '/').
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* The exact type of the arguments and result values is adapted to the needs of
|
|
||||||
* the encoder and decoder, as opposed to following a strict interpretation of
|
|
||||||
* base 64.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Base 64, as specified in RFC 2045, is an encoding used to encode bytes as
|
|
||||||
* characters. In (modified-)UTF-7 however, it is used to encode characters as
|
|
||||||
* bytes, using some intermediate steps:
|
|
||||||
* </p>
|
|
||||||
* <ol>
|
|
||||||
* <li>Encode all characters as a 16-bit (UTF-16) integer value</li>
|
|
||||||
* <li>Write this as stream of bytes (most-significant first)</li>
|
|
||||||
* <li>Encode these bytes using (modified) base 64 encoding</li>
|
|
||||||
* <li>Write the thus formed stream of characters as a stream of bytes, using
|
|
||||||
* ASCII encoding</li>
|
|
||||||
* </ol>
|
|
||||||
*
|
|
||||||
* @author Jaap Beetstra
|
|
||||||
*/
|
|
||||||
class Base64Util {
|
|
||||||
private static final int ALPHABET_LENGTH = 64;
|
|
||||||
private final char[] alphabet;
|
|
||||||
private final int[] inverseAlphabet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the class with the specified encoding/decoding alphabet.
|
|
||||||
*
|
|
||||||
* @param alphabet
|
|
||||||
* @throws IllegalArgumentException if alphabet is not 64 characters long or
|
|
||||||
* contains characters which are not 7-bit ASCII
|
|
||||||
*/
|
|
||||||
Base64Util(final String alphabet) {
|
|
||||||
this.alphabet = alphabet.toCharArray();
|
|
||||||
if (alphabet.length() != ALPHABET_LENGTH)
|
|
||||||
throw new IllegalArgumentException("alphabet has incorrect length (should be 64, not "
|
|
||||||
+ alphabet.length() + ")");
|
|
||||||
inverseAlphabet = new int[128];
|
|
||||||
Arrays.fill(inverseAlphabet, -1);
|
|
||||||
for (int i = 0; i < this.alphabet.length; i++) {
|
|
||||||
final char ch = this.alphabet[i];
|
|
||||||
if (ch >= 128)
|
|
||||||
throw new IllegalArgumentException("invalid character in alphabet: " + ch);
|
|
||||||
inverseAlphabet[ch] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the integer value of the six bits represented by the specified
|
|
||||||
* character.
|
|
||||||
*
|
|
||||||
* @param ch The character, as a ASCII encoded byte
|
|
||||||
* @return The six bits, as an integer value, or -1 if the byte is not in
|
|
||||||
* the alphabet
|
|
||||||
*/
|
|
||||||
int getSextet(final byte ch) {
|
|
||||||
if (ch >= 128)
|
|
||||||
return -1;
|
|
||||||
return inverseAlphabet[ch];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tells whether the alphabet contains the specified character.
|
|
||||||
*
|
|
||||||
* @param ch The character
|
|
||||||
* @return true if the alphabet contains <code>ch</code>, false otherwise
|
|
||||||
*/
|
|
||||||
boolean contains(final char ch) {
|
|
||||||
if (ch >= 128)
|
|
||||||
return false;
|
|
||||||
return inverseAlphabet[ch] >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encodes the six bit group as a character.
|
|
||||||
*
|
|
||||||
* @param sextet The six bit group to be encoded
|
|
||||||
* @return The ASCII value of the character
|
|
||||||
*/
|
|
||||||
byte getChar(final int sextet) {
|
|
||||||
return (byte)alphabet[sextet];
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
/* ====================================================================
|
|
||||||
* Copyright (c) 2006 J.T. Beetstra
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.beetstra.jutf7;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Charset service-provider class used for both variants of the UTF-7 charset
|
|
||||||
* and the modified-UTF-7 charset.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author Jaap Beetstra
|
|
||||||
*/
|
|
||||||
public class CharsetProvider extends java.nio.charset.spi.CharsetProvider {
|
|
||||||
private static final String UTF7_NAME = "UTF-7";
|
|
||||||
private static final String UTF7_O_NAME = "X-UTF-7-OPTIONAL";
|
|
||||||
private static final String UTF7_M_NAME = "X-MODIFIED-UTF-7";
|
|
||||||
private static final String[] UTF7_ALIASES = new String[] {
|
|
||||||
"UNICODE-1-1-UTF-7", "CSUNICODE11UTF7", "X-RFC2152", "X-RFC-2152"
|
|
||||||
};
|
|
||||||
private static final String[] UTF7_O_ALIASES = new String[] {
|
|
||||||
"X-RFC2152-OPTIONAL", "X-RFC-2152-OPTIONAL"
|
|
||||||
};
|
|
||||||
private static final String[] UTF7_M_ALIASES = new String[] {
|
|
||||||
"X-IMAP-MODIFIED-UTF-7", "X-IMAP4-MODIFIED-UTF7", "X-IMAP4-MODIFIED-UTF-7",
|
|
||||||
"X-RFC3501", "X-RFC-3501"
|
|
||||||
};
|
|
||||||
private Charset utf7charset = new UTF7Charset(UTF7_NAME, UTF7_ALIASES, false);
|
|
||||||
private Charset utf7oCharset = new UTF7Charset(UTF7_O_NAME, UTF7_O_ALIASES, true);
|
|
||||||
private Charset imap4charset = new ModifiedUTF7Charset(UTF7_M_NAME, UTF7_M_ALIASES);
|
|
||||||
private List charsets;
|
|
||||||
|
|
||||||
public CharsetProvider() {
|
|
||||||
charsets = Arrays.asList(new Object[] {
|
|
||||||
utf7charset, imap4charset, utf7oCharset
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Charset charsetForName(String charsetName) {
|
|
||||||
charsetName = charsetName.toUpperCase();
|
|
||||||
for (Iterator iter = charsets.iterator(); iter.hasNext();) {
|
|
||||||
Charset charset = (Charset)iter.next();
|
|
||||||
if (charset.name().equals(charsetName))
|
|
||||||
return charset;
|
|
||||||
}
|
|
||||||
for (Iterator iter = charsets.iterator(); iter.hasNext();) {
|
|
||||||
Charset charset = (Charset)iter.next();
|
|
||||||
if (charset.aliases().contains(charsetName))
|
|
||||||
return charset;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Iterator charsets() {
|
|
||||||
return charsets.iterator();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
/* ====================================================================
|
|
||||||
* Copyright (c) 2006 J.T. Beetstra
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.beetstra.jutf7;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* The character set specified in RFC 3501 to use for IMAP4rev1 mailbox name
|
|
||||||
* encoding.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @see <a href="http://tools.ietf.org/html/rfc3501">RFC 3501< /a>
|
|
||||||
* @author Jaap Beetstra
|
|
||||||
*/
|
|
||||||
class ModifiedUTF7Charset extends UTF7StyleCharset {
|
|
||||||
private static final String MODIFIED_BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
+ "abcdefghijklmnopqrstuvwxyz" + "0123456789+,";
|
|
||||||
|
|
||||||
ModifiedUTF7Charset(String name, String[] aliases) {
|
|
||||||
super(name, aliases, MODIFIED_BASE64_ALPHABET, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean canEncodeDirectly(char ch) {
|
|
||||||
if (ch == shift())
|
|
||||||
return false;
|
|
||||||
return ch >= 0x20 && ch <= 0x7E;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte shift() {
|
|
||||||
return '&';
|
|
||||||
}
|
|
||||||
|
|
||||||
byte unshift() {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/* ====================================================================
|
|
||||||
* Copyright (c) 2006 J.T. Beetstra
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.beetstra.jutf7;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* The character set specified in RFC 2152. Two variants are supported using the
|
|
||||||
* encodeOptional constructor flag
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @see <a href="http://tools.ietf.org/html/rfc2152">RFC 2152< /a>
|
|
||||||
* @author Jaap Beetstra
|
|
||||||
*/
|
|
||||||
class UTF7Charset extends UTF7StyleCharset {
|
|
||||||
private static final String BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
+ "abcdefghijklmnopqrstuvwxyz" + "0123456789+/";
|
|
||||||
private static final String SET_D = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?";
|
|
||||||
private static final String SET_O = "!\"#$%&*;<=>@[]^_`{|}";
|
|
||||||
private static final String RULE_3 = " \t\r\n";
|
|
||||||
final String directlyEncoded;
|
|
||||||
|
|
||||||
UTF7Charset(String name, String[] aliases, boolean includeOptional) {
|
|
||||||
super(name, aliases, BASE64_ALPHABET, false);
|
|
||||||
if (includeOptional)
|
|
||||||
this.directlyEncoded = SET_D + SET_O + RULE_3;
|
|
||||||
else
|
|
||||||
this.directlyEncoded = SET_D + RULE_3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.beetstra.jutf7.UTF7StyleCharset#canEncodeDirectly(char)
|
|
||||||
*/
|
|
||||||
boolean canEncodeDirectly(char ch) {
|
|
||||||
return directlyEncoded.indexOf(ch) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.beetstra.jutf7.UTF7StyleCharset#shift()
|
|
||||||
*/
|
|
||||||
byte shift() {
|
|
||||||
return '+';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.beetstra.jutf7.UTF7StyleCharset#unshift()
|
|
||||||
*/
|
|
||||||
byte unshift() {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
/* ====================================================================
|
|
||||||
* Copyright (c) 2006 J.T. Beetstra
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.beetstra.jutf7;
|
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.charset.CharsetDecoder;
|
|
||||||
import java.nio.charset.CharsetEncoder;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Abstract base class for UTF-7 style encoding and decoding.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author Jaap Beetstra
|
|
||||||
*/
|
|
||||||
abstract class UTF7StyleCharset extends Charset {
|
|
||||||
private static final List CONTAINED = Arrays.asList(new String[] {
|
|
||||||
"US-ASCII", "ISO-8859-1", "UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE"
|
|
||||||
});
|
|
||||||
final boolean strict;
|
|
||||||
Base64Util base64;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Besides the name and aliases, two additional parameters are required.
|
|
||||||
* First the base 64 alphabet used; in modified UTF-7 a slightly different
|
|
||||||
* alphabet is used. Additionally, it should be specified if encoders and
|
|
||||||
* decoders should be strict about the interpretation of malformed encoded
|
|
||||||
* sequences. This is used since modified UTF-7 specifically disallows some
|
|
||||||
* constructs which are allowed (or not specifically disallowed) in UTF-7
|
|
||||||
* (RFC 2152).
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param canonicalName The name as defined in java.nio.charset.Charset
|
|
||||||
* @param aliases The aliases as defined in java.nio.charset.Charset
|
|
||||||
* @param alphabet The base 64 alphabet used
|
|
||||||
* @param strict True if strict handling of sequences is requested
|
|
||||||
*/
|
|
||||||
protected UTF7StyleCharset(String canonicalName, String[] aliases, String alphabet,
|
|
||||||
boolean strict) {
|
|
||||||
super(canonicalName, aliases);
|
|
||||||
this.base64 = new Base64Util(alphabet);
|
|
||||||
this.strict = strict;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see java.nio.charset.Charset#contains(java.nio.charset.Charset)
|
|
||||||
*/
|
|
||||||
public boolean contains(final Charset cs) {
|
|
||||||
return CONTAINED.contains(cs.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see java.nio.charset.Charset#newDecoder()
|
|
||||||
*/
|
|
||||||
public CharsetDecoder newDecoder() {
|
|
||||||
return new UTF7StyleCharsetDecoder(this, base64, strict);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see java.nio.charset.Charset#newEncoder()
|
|
||||||
*/
|
|
||||||
public CharsetEncoder newEncoder() {
|
|
||||||
return new UTF7StyleCharsetEncoder(this, base64, strict);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tells if a character can be encoded using simple (US-ASCII) encoding or
|
|
||||||
* requires base 64 encoding.
|
|
||||||
*
|
|
||||||
* @param ch The character
|
|
||||||
* @return True if the character can be encoded directly, false otherwise
|
|
||||||
*/
|
|
||||||
abstract boolean canEncodeDirectly(char ch);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns character used to switch to base 64 encoding.
|
|
||||||
*
|
|
||||||
* @return The shift character
|
|
||||||
*/
|
|
||||||
abstract byte shift();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns character used to switch from base 64 encoding to simple
|
|
||||||
* encoding.
|
|
||||||
*
|
|
||||||
* @return The unshift character
|
|
||||||
*/
|
|
||||||
abstract byte unshift();
|
|
||||||
}
|
|
@ -1,195 +0,0 @@
|
|||||||
/* ====================================================================
|
|
||||||
* Copyright (c) 2006 J.T. Beetstra
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.beetstra.jutf7;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.CharBuffer;
|
|
||||||
import java.nio.charset.CharsetDecoder;
|
|
||||||
import java.nio.charset.CoderResult;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* The CharsetDecoder used to decode both variants of the UTF-7 charset and the
|
|
||||||
* modified-UTF-7 charset.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author Jaap Beetstra
|
|
||||||
*/
|
|
||||||
class UTF7StyleCharsetDecoder extends CharsetDecoder {
|
|
||||||
private final Base64Util base64;
|
|
||||||
private final byte shift;
|
|
||||||
private final byte unshift;
|
|
||||||
private final boolean strict;
|
|
||||||
private boolean base64mode;
|
|
||||||
private int bitsRead;
|
|
||||||
private int tempChar;
|
|
||||||
private boolean justShifted;
|
|
||||||
private boolean justUnshifted;
|
|
||||||
|
|
||||||
UTF7StyleCharsetDecoder(UTF7StyleCharset cs, Base64Util base64, boolean strict) {
|
|
||||||
super(cs, 0.6f, 1.0f);
|
|
||||||
this.base64 = base64;
|
|
||||||
this.strict = strict;
|
|
||||||
this.shift = cs.shift();
|
|
||||||
this.unshift = cs.unshift();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see java.nio.charset.CharsetDecoder#decodeLoop(java.nio.ByteBuffer,
|
|
||||||
* java.nio.CharBuffer)
|
|
||||||
*/
|
|
||||||
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
|
|
||||||
while (in.hasRemaining()) {
|
|
||||||
byte b = in.get();
|
|
||||||
if (base64mode) {
|
|
||||||
if (b == unshift) {
|
|
||||||
if (base64bitsWaiting())
|
|
||||||
return malformed(in);
|
|
||||||
if (justShifted) {
|
|
||||||
if (!out.hasRemaining())
|
|
||||||
return overflow(in);
|
|
||||||
out.put((char)shift);
|
|
||||||
} else
|
|
||||||
justUnshifted = true;
|
|
||||||
setUnshifted();
|
|
||||||
} else {
|
|
||||||
if (!out.hasRemaining())
|
|
||||||
return overflow(in);
|
|
||||||
CoderResult result = handleBase64(in, out, b);
|
|
||||||
if (result != null)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
justShifted = false;
|
|
||||||
} else {
|
|
||||||
if (b == shift) {
|
|
||||||
base64mode = true;
|
|
||||||
if (justUnshifted && strict)
|
|
||||||
return malformed(in);
|
|
||||||
justShifted = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!out.hasRemaining())
|
|
||||||
return overflow(in);
|
|
||||||
out.put((char)b);
|
|
||||||
justUnshifted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CoderResult.UNDERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CoderResult overflow(ByteBuffer in) {
|
|
||||||
in.position(in.position() - 1);
|
|
||||||
return CoderResult.OVERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Decodes a byte in <i>base 64 mode</i>. Will directly write a character to
|
|
||||||
* the output buffer if completed.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param in The input buffer
|
|
||||||
* @param out The output buffer
|
|
||||||
* @param lastRead Last byte read from the input buffer
|
|
||||||
* @return CoderResult.malformed if a non-base 64 character was encountered
|
|
||||||
* in strict mode, null otherwise
|
|
||||||
*/
|
|
||||||
private CoderResult handleBase64(ByteBuffer in, CharBuffer out, byte lastRead) {
|
|
||||||
CoderResult result = null;
|
|
||||||
int sextet = base64.getSextet(lastRead);
|
|
||||||
if (sextet >= 0) {
|
|
||||||
bitsRead += 6;
|
|
||||||
if (bitsRead < 16) {
|
|
||||||
tempChar += sextet << (16 - bitsRead);
|
|
||||||
} else {
|
|
||||||
bitsRead -= 16;
|
|
||||||
tempChar += sextet >> (bitsRead);
|
|
||||||
out.put((char)tempChar);
|
|
||||||
tempChar = (sextet << (16 - bitsRead)) & 0xFFFF;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (strict)
|
|
||||||
return malformed(in);
|
|
||||||
out.put((char)lastRead);
|
|
||||||
if (base64bitsWaiting())
|
|
||||||
result = malformed(in);
|
|
||||||
setUnshifted();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see java.nio.charset.CharsetDecoder#implFlush(java.nio.CharBuffer)
|
|
||||||
*/
|
|
||||||
protected CoderResult implFlush(CharBuffer out) {
|
|
||||||
if ((base64mode && strict) || base64bitsWaiting())
|
|
||||||
return CoderResult.malformedForLength(1);
|
|
||||||
return CoderResult.UNDERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see java.nio.charset.CharsetDecoder#implReset()
|
|
||||||
*/
|
|
||||||
protected void implReset() {
|
|
||||||
setUnshifted();
|
|
||||||
justUnshifted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Resets the input buffer position to just before the last byte read, and
|
|
||||||
* returns a result indicating to skip the last byte.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param in The input buffer
|
|
||||||
* @return CoderResult.malformedForLength(1);
|
|
||||||
*/
|
|
||||||
private CoderResult malformed(ByteBuffer in) {
|
|
||||||
in.position(in.position() - 1);
|
|
||||||
return CoderResult.malformedForLength(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return True if there are base64 encoded characters waiting to be written
|
|
||||||
*/
|
|
||||||
private boolean base64bitsWaiting() {
|
|
||||||
return tempChar != 0 || bitsRead >= 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Updates internal state to reflect the decoder is no longer in <i>base 64
|
|
||||||
* mode</i>
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
private void setUnshifted() {
|
|
||||||
base64mode = false;
|
|
||||||
bitsRead = 0;
|
|
||||||
tempChar = 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,217 +0,0 @@
|
|||||||
/* ====================================================================
|
|
||||||
* Copyright (c) 2006 J.T. Beetstra
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.beetstra.jutf7;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.CharBuffer;
|
|
||||||
import java.nio.charset.CharsetEncoder;
|
|
||||||
import java.nio.charset.CoderResult;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* The CharsetEncoder used to encode both variants of the UTF-7 charset and the
|
|
||||||
* modified-UTF-7 charset.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <strong>Please note this class does not behave strictly according to the
|
|
||||||
* specification in Sun Java VMs before 1.6.</strong> This is done to get around
|
|
||||||
* a bug in the implementation of
|
|
||||||
* {@link java.nio.charset.CharsetEncoder#encode(CharBuffer)}. Unfortunately,
|
|
||||||
* that method cannot be overridden.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6221056">JDK
|
|
||||||
* bug 6221056< /a>
|
|
||||||
* @author Jaap Beetstra
|
|
||||||
*/
|
|
||||||
class UTF7StyleCharsetEncoder extends CharsetEncoder {
|
|
||||||
private static final float AVG_BYTES_PER_CHAR = 1.5f;
|
|
||||||
private static final float MAX_BYTES_PER_CHAR = 5.0f;
|
|
||||||
private final UTF7StyleCharset cs;
|
|
||||||
private final Base64Util base64;
|
|
||||||
private final byte shift;
|
|
||||||
private final byte unshift;
|
|
||||||
private final boolean strict;
|
|
||||||
private boolean base64mode;
|
|
||||||
private int bitsToOutput;
|
|
||||||
private int sextet;
|
|
||||||
static boolean useUglyHackToForceCallToFlushInJava5;
|
|
||||||
static {
|
|
||||||
String version = System.getProperty("java.specification.version");
|
|
||||||
String vendor = System.getProperty("java.vm.vendor");
|
|
||||||
useUglyHackToForceCallToFlushInJava5 = "1.4".equals(version) || "1.5".equals(version);
|
|
||||||
useUglyHackToForceCallToFlushInJava5 &= "Sun Microsystems Inc.".equals(vendor);
|
|
||||||
}
|
|
||||||
|
|
||||||
UTF7StyleCharsetEncoder(UTF7StyleCharset cs, Base64Util base64, boolean strict) {
|
|
||||||
super(cs, AVG_BYTES_PER_CHAR, MAX_BYTES_PER_CHAR);
|
|
||||||
this.cs = cs;
|
|
||||||
this.base64 = base64;
|
|
||||||
this.strict = strict;
|
|
||||||
this.shift = cs.shift();
|
|
||||||
this.unshift = cs.unshift();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see java.nio.charset.CharsetEncoder#implReset()
|
|
||||||
*/
|
|
||||||
protected void implReset() {
|
|
||||||
base64mode = false;
|
|
||||||
sextet = 0;
|
|
||||||
bitsToOutput = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
* <p>
|
|
||||||
* Note that this method might return <code>CoderResult.OVERFLOW</code> (as
|
|
||||||
* is required by the specification) if insufficient space is available in
|
|
||||||
* the output buffer. However, calling it again on JDKs before Java 6
|
|
||||||
* triggers a bug in
|
|
||||||
* {@link java.nio.charset.CharsetEncoder#flush(ByteBuffer)} causing it to
|
|
||||||
* throw an IllegalStateException (the buggy method is <code>final</code>,
|
|
||||||
* thus cannot be overridden).
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @see <a
|
|
||||||
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227608">
|
|
||||||
* JDK bug 6227608< /a>
|
|
||||||
* @param out The output byte buffer
|
|
||||||
* @return A coder-result object describing the reason for termination
|
|
||||||
*/
|
|
||||||
protected CoderResult implFlush(ByteBuffer out) {
|
|
||||||
if (base64mode) {
|
|
||||||
if (out.remaining() < 2)
|
|
||||||
return CoderResult.OVERFLOW;
|
|
||||||
if (bitsToOutput != 0)
|
|
||||||
out.put(base64.getChar(sextet));
|
|
||||||
out.put(unshift);
|
|
||||||
}
|
|
||||||
return CoderResult.UNDERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
* <p>
|
|
||||||
* Note that this method might return <code>CoderResult.OVERFLOW</code>,
|
|
||||||
* even though there is sufficient space available in the output buffer.
|
|
||||||
* This is done to force the broken implementation of
|
|
||||||
* {@link java.nio.charset.CharsetEncoder#encode(CharBuffer)} to call flush
|
|
||||||
* (the buggy method is <code>final</code>, thus cannot be overridden).
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* However, String.getBytes() fails if CoderResult.OVERFLOW is returned,
|
|
||||||
* since this assumes it always allocates sufficient bytes (maxBytesPerChar
|
|
||||||
* * nr_of_chars). Thus, as an extra check, the size of the input buffer is
|
|
||||||
* compared against the size of the output buffer. A static variable is used
|
|
||||||
* to indicate if a broken java version is used.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* It is not possible to directly write the last few bytes, since more bytes
|
|
||||||
* might be waiting to be encoded then those available in the input buffer.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @see <a
|
|
||||||
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6221056">
|
|
||||||
* JDK bug 6221056< /a>
|
|
||||||
* @param in The input character buffer
|
|
||||||
* @param out The output byte buffer
|
|
||||||
* @return A coder-result object describing the reason for termination
|
|
||||||
*/
|
|
||||||
protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
|
|
||||||
while (in.hasRemaining()) {
|
|
||||||
if (out.remaining() < 4)
|
|
||||||
return CoderResult.OVERFLOW;
|
|
||||||
char ch = in.get();
|
|
||||||
if (cs.canEncodeDirectly(ch)) {
|
|
||||||
unshift(out, ch);
|
|
||||||
out.put((byte)ch);
|
|
||||||
} else if (!base64mode && ch == shift) {
|
|
||||||
out.put(shift);
|
|
||||||
out.put(unshift);
|
|
||||||
} else
|
|
||||||
encodeBase64(ch, out);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* <HACK type="ugly"> These lines are required to trick JDK 1.5 and
|
|
||||||
* earlier into flushing when using Charset.encode(String),
|
|
||||||
* Charset.encode(CharBuffer) or CharsetEncoder.encode(CharBuffer)
|
|
||||||
* Without them, the last few bytes may be missing.
|
|
||||||
*/
|
|
||||||
if (base64mode && useUglyHackToForceCallToFlushInJava5
|
|
||||||
&& out.limit() != MAX_BYTES_PER_CHAR * in.limit())
|
|
||||||
return CoderResult.OVERFLOW;
|
|
||||||
/* </HACK> */
|
|
||||||
return CoderResult.UNDERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Writes the bytes necessary to leave <i>base 64 mode</i>. This might
|
|
||||||
* include an unshift character.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param out
|
|
||||||
* @param ch
|
|
||||||
*/
|
|
||||||
private void unshift(ByteBuffer out, char ch) {
|
|
||||||
if (!base64mode)
|
|
||||||
return;
|
|
||||||
if (bitsToOutput != 0)
|
|
||||||
out.put(base64.getChar(sextet));
|
|
||||||
if (base64.contains(ch) || ch == unshift || strict)
|
|
||||||
out.put(unshift);
|
|
||||||
base64mode = false;
|
|
||||||
sextet = 0;
|
|
||||||
bitsToOutput = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Writes the bytes necessary to encode a character in <i>base 64 mode</i>.
|
|
||||||
* All bytes which are fully determined will be written. The fields
|
|
||||||
* <code>bitsToOutput</code> and <code>sextet</code> are used to remember
|
|
||||||
* the bytes not yet fully determined.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param out
|
|
||||||
* @param ch
|
|
||||||
*/
|
|
||||||
private void encodeBase64(char ch, ByteBuffer out) {
|
|
||||||
if (!base64mode)
|
|
||||||
out.put(shift);
|
|
||||||
base64mode = true;
|
|
||||||
bitsToOutput += 16;
|
|
||||||
while (bitsToOutput >= 6) {
|
|
||||||
bitsToOutput -= 6;
|
|
||||||
sextet += (ch >> bitsToOutput);
|
|
||||||
sextet &= 0x3F;
|
|
||||||
out.put(base64.getChar(sextet));
|
|
||||||
sextet = 0;
|
|
||||||
}
|
|
||||||
sextet = (ch << (6 - bitsToOutput)) & 0x3F;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user