package org.pentaho.reporting.libraries.formula.function.text;
import org.pentaho.reporting.libraries.formula.EvaluationException;
import org.pentaho.reporting.libraries.formula.FormulaContext;
import org.pentaho.reporting.libraries.formula.LibFormulaErrorValue;
import org.pentaho.reporting.libraries.formula.function.Function;
import org.pentaho.reporting.libraries.formula.function.ParameterCallback;
import org.pentaho.reporting.libraries.formula.lvalues.TypeValuePair;
import org.pentaho.reporting.libraries.formula.typing.Type;
import org.pentaho.reporting.libraries.formula.typing.TypeRegistry;
import org.pentaho.reporting.libraries.formula.typing.coretypes.TextType;
public class AscFunction implements Function
{
public AscFunction()
{
}
public String getCanonicalName()
{
return "ASC";
}
public TypeValuePair evaluate(final FormulaContext context,
final ParameterCallback parameters) throws EvaluationException
{
final int parameterCount = parameters.getParameterCount();
if (parameterCount != 1)
{
throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE);
}
final Type type1 = parameters.getType(0);
final Object value1 = parameters.getValue(0);
final TypeRegistry typeRegistry = context.getTypeRegistry();
final String result = typeRegistry.convertToText(type1, value1);
if (result == null)
{
throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
}
final char[] chars = result.toCharArray();
final StringBuffer b = new StringBuffer(chars.length);
for (int i = 0; i < chars.length; i++)
{
final char c = chars[i];
convert(c, b);
}
return new TypeValuePair(TextType.TYPE, b.toString());
}
private void convert(final char c, final StringBuffer b)
{
if (c >= 0x30a1 && c <= 0x30aa)
{
if ((c % 2) == 0)
{
// katakana a-o
b.append((char) ((c - 0x30a2) / 2 + 0xff71));
}
else
{
// katakana small a-o
b.append((char) ((c - 0x30a1) / 2 + 0xff67));
}
return;
}
if (c >= 0x30ab && c <= 0x30c2)
{
if ((c % 2) == 0)
{
// katakana ka-chi
b.append((char) ((c - 0x30ab) / 2 + 0xff76));
}
else
{
// katakana ga-dhi
b.append((char) ((c - 0x30ac) / 2 + 0xff76));
b.append((char) 0xff9e);
}
return;
}
if (c == 0x30c3)
{
// katakana small tsu
b.append((char) 0xff6f);
return;
}
if (c >= 0x30c4 && c <= 0x30c9)
{
if ((c % 2) == 0)
{
// katakana tsu-to
b.append((char) ((c - 0x30c4) / 2 + 0xff82));
}
else
{
// katakana du-do
b.append((char) ((c - 0x30c5) / 2 + 0xff82));
b.append((char) 0xff9e);
}
return;
}
if (c >= 0x30ca && c <= 0x30ce)
{
// katakana na-no
b.append((char) ((c - 0x30ca) + 0xff85));
return;
}
if (c >= 0x30cf && c <= 0x30dd)
{
switch (c % 3)
{
case 0:
// katakana ha-no
b.append((char) ((c - 0x30cf) / 3 + 0xff8a));
break;
case 1:
// katakana ba-bo
b.append((char) ((c - 0x30d0) / 3 + 0xff8a));
b.append((char) 0xff9e);
break;
case 2:
// katakana pa-po
b.append((char) ((c - 0x30d1) / 3 + 0xff8a));
b.append((char) 0xff9f);
break;
default:
throw new IllegalStateException();
}
return;
}
if (c>= 0x30de && c <= 0x30e2)
{
// katakana ma-mo
b.append((char) (c - 0x30de + 0xff8f));
return;
}
if (c >= 0x30e3 && c <= 0x30e8)
{
if (c % 2 == 0)
{
// katakana ya-yo
b.append((char)((c - 0x30e4) / 2 + 0xff94));
}
else
{
// katakana small ya-yo
b.append((char)((c - 0x30e3) / 2 + 0xff6c));
}
return;
}
if (c>= 0x30e9 && c <= 0x30ed)
{
// katakana ra-ro
b.append((char) (c - 0x30e9 + 0xff97));
return;
}
if (c == 0x30ef)
{
// katakana wa
b.append((char) 0xff9c);
return;
}
if (c == 0x30f2)
{
// katakana wo
b.append((char) 0xff66);
return;
}
if (c == 0x30f3)
{
// katakana nn
b.append((char) 0xff9d);
return;
}
if (c >= 0xff01 && c <= 0xff5e)
{
// ASCII characters
b.append((char)(c - 0xff01 + 0x0021));
return;
}
if (c == 0x2015)
{
// HORIZONTAL BAR => HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
b.append((char) 0xff70);
return;
}
if (c == 0x2018)
{
// LEFT SINGLE QUOTATION MARK => GRAVE ACCENT
b.append((char) 0x0060);
return;
}
if (c == 0x2019)
{
// RIGHT SINGLE QUOTATION MARK => APOSTROPHE
b.append((char) 0x0027);
return;
}
if (c == 0x201d)
{
// RIGHT DOUBLE QUOTATION MARK => QUOTATION MARK
b.append((char) 0x0022);
return;
}
if (c == 0x3001)
{
// IDEOGRAPHIC COMMA
b.append((char) 0xff64);
return;
}
if (c == 0x3002)
{
// IDEOGRAPHIC FULL STOP
b.append((char) 0xff61);
return;
}
if (c == 0x300c)
{
// LEFT CORNER BRACKET
b.append((char) 0xff61);
return;
}
if (c == 0x300d)
{
// RIGHT CORNER BRACKET
b.append((char) 0xff61);
return;
}
if (c == 0x309b)
{
// KATAKANA-HIRAGANA VOICED SOUND MARK
b.append((char) 0xff9e);
return;
}
if (c == 0x309c)
{
// KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
b.append((char) 0xff9f);
return;
}
if (c == 0x30fb)
{
// KATAKANA MIDDLE DOT
b.append((char) 0xff65);
return;
}
if (c == 0x30fc)
{
// KATAKANA-HIRAGANA PROLONGED SOUND MARK
b.append((char) 0xff70);
return;
}
if (c == 0xffe5)
{
// FULLWIDTH YEN SIGN => REVERSE SOLIDUS "\"
b.append((char) 0x005c);
return;
}
b.append(c);
}
}