package gnu.inet.encoding;
public class IDNA
{
public final static String ACE_PREFIX = "xn--";
public static String toASCII(String input)
throws IDNAException
{
StringBuffer o = new StringBuffer();
StringBuffer h = new StringBuffer();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c == '.' || c == '\u3002' || c == '\uff0e' || c == '\uff61') {
o.append(toASCII(h.toString(), false, true));
o.append(c);
h = new StringBuffer();
} else {
h.append(c);
}
}
o.append(toASCII(h.toString(), false, true));
return o.toString();
}
public static String toASCII(String input, boolean allowUnassigned, boolean useSTD3ASCIIRules)
throws IDNAException
{
boolean nonASCII = false;
for (int i = 0; i < input.length(); i++) {
int c = input.charAt(i);
if (c > 0x7f) {
nonASCII = true;
break;
}
}
if (nonASCII) {
try {
input = Stringprep.nameprep(input, allowUnassigned);
} catch (StringprepException e) {
throw new IDNAException(e);
}
}
if (useSTD3ASCIIRules) {
for (int i = 0; i < input.length(); i++) {
int c = input.charAt(i);
if ((c <= 0x2c) ||
(c >= 0x2e && c <= 0x2f) ||
(c >= 0x3a && c <= 0x40) ||
(c >= 0x5b && c <= 0x60) ||
(c >= 0x7b && c <= 0x7f)) {
throw new IDNAException(IDNAException.CONTAINS_NON_LDH);
}
}
if (input.startsWith("-") || input.endsWith("-")) {
throw new IDNAException(IDNAException.CONTAINS_HYPHEN);
}
}
nonASCII = false;
for (int i = 0; i < input.length(); i++) {
int c = input.charAt(i);
if (c > 0x7f) {
nonASCII = true;
break;
}
}
String output = input;
if (nonASCII) {
if (input.startsWith(ACE_PREFIX)) {
throw new IDNAException(IDNAException.CONTAINS_ACE_PREFIX);
}
try {
output = Punycode.encode(input);
} catch (PunycodeException e) {
throw new IDNAException(e);
}
output = ACE_PREFIX + output;
}
if (output.length() < 1 || output.length() > 63) {
throw new IDNAException(IDNAException.TOO_LONG);
}
return output;
}
public static String toUnicode(String input)
{
StringBuffer o = new StringBuffer();
StringBuffer h = new StringBuffer();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c == '.' || c == '\u3002' || c == '\uff0e' || c == '\uff61') {
o.append(toUnicode(h.toString(), false, true));
o.append(c);
h = new StringBuffer();
} else {
h.append(c);
}
}
o.append(toUnicode(h.toString(), false, true));
return o.toString();
}
public static String toUnicode(String input, boolean allowUnassigned, boolean useSTD3ASCIIRules)
{
String original = input;
boolean nonASCII = false;
for (int i = 0; i < input.length(); i++) {
int c = input.charAt(i);
if (c > 0x7f) {
nonASCII = true;
break;
}
}
if (nonASCII) {
try {
input = Stringprep.nameprep(input, allowUnassigned);
} catch (StringprepException e) {
return original;
}
}
if (!input.startsWith(ACE_PREFIX)) {
return original;
}
String stored = input;
input = input.substring(ACE_PREFIX.length());
String output;
try {
output = Punycode.decode(input);
} catch (PunycodeException e) {
return original;
}
String ascii;
try {
ascii = toASCII(output, allowUnassigned, useSTD3ASCIIRules);
} catch (IDNAException e) {
return original;
}
if (!ascii.equalsIgnoreCase(stored)) {
return original;
}
return output;
}
}