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 ); } }