/* * JacORB - a free Java ORB * * Copyright (C) 1997-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.jacorb.idl; import java.io.File; import java.io.PrintWriter; import java.util.Set; /** * @author Gerald Brose */ public class FixedPointType extends TemplateTypeSpec { public ConstExpr digit_expr = null; public ConstExpr scale_expr = null; public int digits = 0; public int scale = 0; public FixedPointType(int num) { super(num); } public Object clone() { FixedPointType ft = new FixedPointType(new_num()); ft.name = this.name; ft.pack_name = this.pack_name; ft.digit_expr = this.digit_expr; ft.digits = this.digits; ft.scale_expr = this.scale_expr; ft.scale = this.scale; ft.included = this.included; ft.typedefd = this.typedefd; ft.set_token(this.get_token()); ft.setEnclosingSymbol(this.getEnclosingSymbol()); return ft; } public String helperName() { if (pack_name.length() > 0) { String s = ScopedName.unPseudoName(pack_name + "." + name); return getFullName(s); } else { return ScopedName.unPseudoName(name); } } public String typeName() { return "java.math.BigDecimal"; } public int getTCKind() { return org.omg.CORBA.TCKind._tk_fixed; } public TypeSpec typeSpec() { return this; } public void setEnclosingSymbol(IdlSymbol s) { if (enclosing_symbol != null && enclosing_symbol != s) throw new RuntimeException("Compiler Error: trying to reassign container for " + name); enclosing_symbol = s; } private void printHelperClass(String className, PrintWriter ps) { if (!pack_name.equals("")) ps.println("package " + pack_name + ";"); ps.println("public abstract class " + className + "Helper"); ps.println("{"); ps.println("\tprivate static org.omg.CORBA.TypeCode _type = " + getTypeCodeExpression() + ";"); ps.println("\tpublic static void insert(org.omg.CORBA.Any any, java.math.BigDecimal s)"); ps.println("\t{"); ps.println("\t\tany.insert_fixed(s, type());"); ps.println("\t}"); ps.println("\tpublic static java.math.BigDecimal extract(org.omg.CORBA.Any any)"); ps.println("\t{"); ps.println("\t\treturn any.extract_fixed();"); ps.println("\t}"); ps.println("\tpublic static org.omg.CORBA.TypeCode type()"); ps.println("\t{"); ps.println("\t\treturn _type;"); ps.println("\t}"); printIdMethod(ps); // from IdlSymbol /** read */ ps.println("\tpublic static java.math.BigDecimal read (final org.omg.CORBA.portable.InputStream in)"); ps.println("\t{"); ps.println("\t\tjava.math.BigDecimal result = in.read_fixed();"); ps.println("\t\treturn result.movePointLeft(" + scale + ");"); ps.println("\t}"); /** write */ ps.println("\tpublic static void write (final org.omg.CORBA.portable.OutputStream out, final java.math.BigDecimal s)"); ps.println("\t{"); StringBuffer mb = new StringBuffer("1"); for (int m = 0; m < digits - scale; m++) mb.append("0"); ps.println("\t\tif (s.scale() != " + scale + ")"); ps.println("\t\t\tthrow new org.omg.CORBA.DATA_CONVERSION();"); ps.println("\t\tjava.math.BigDecimal max = new java.math.BigDecimal(\"" + mb.toString() + "\");"); ps.println("\t\tif (s.compareTo(max) != -1)"); ps.println("\t\t\tthrow new org.omg.CORBA.DATA_CONVERSION();"); ps.println("\t\tout.write_fixed(s);"); ps.println("\t}"); ps.println("}"); } public void print(java.io.PrintWriter pw) { try { // write helper file String fullName = helperName(); String className; if (fullName.indexOf('.') > 0) { pack_name = fullName.substring(0, fullName.lastIndexOf('.')); className = fullName.substring(fullName.lastIndexOf('.') + 1); } else { pack_name = ""; className = fullName; } String path = parser.out_dir + fileSeparator + pack_name.replace('.', fileSeparator); File dir = new File(path); if (!dir.exists()) { if (!dir.mkdirs()) { org.jacorb.idl.parser.fatal_error("Unable to create " + path, null); } } String fname = className + "Helper.java"; File f = new File(dir, fname); if (GlobalInputStream.isMoreRecentThan(f)) { PrintWriter ps = new PrintWriter(new java.io.FileWriter(f)); printHelperClass(className, ps); ps.close(); } } catch(java.io.IOException i) { throw new RuntimeException("File IO error" + i); } } public void setPackage(String s) { s = parser.pack_replace(s); if (pack_name.length() > 0) pack_name = s + "." + pack_name; else pack_name = s; } public String toString() { return typeName(); } public String holderName() { return "org.omg.CORBA.FixedHolder"; } public String getTypeCodeExpression() { return "org.omg.CORBA.ORB.init().create_fixed_tc((short)" + digits + ",(short)" + scale + ")"; } public String getTypeCodeExpression(Set knownTypes) { return getTypeCodeExpression(); } public String printReadExpression(String strname) { return helperName() + "Helper.read(" + strname + ")"; } public String printReadStatement(String var_name, String strname) { String fixedName = null; if (hashCode() > 0) fixedName = "_fixed" + hashCode(); else fixedName = "_fixed" + (-1 * hashCode()); StringBuffer sb = new StringBuffer(); if (parser.generatedHelperPortability == parser.HELPER_DEPRECATED) { sb.append("\t\tjava.math.BigDecimal " + fixedName + "=" + strname + ".read_fixed();" + Environment.NL); sb.append("\t\t" + var_name + " = " + fixedName + ".movePointLeft(" + scale + ");" + Environment.NL); } else if (parser.generatedHelperPortability == parser.HELPER_PORTABLE) { sb.append("\t\t" + var_name + "=" + strname + ".read_fixed((short)" + digits + ", (short)" + scale+ ");" + Environment.NL); } else if (parser.generatedHelperPortability == parser.HELPER_JACORB) { sb.append("\t\t" + var_name + "=((org.jacorb.orb.CDRInputStream)" + strname + ").read_fixed((short)" + digits + ", (short)" + scale + ");" + Environment.NL); } else { assert false; } return sb.toString(); } public String printWriteStatement(String var_name, String strname) { StringBuffer mb = new StringBuffer("1"); for (int m = 0; m < digits - scale; m++) mb.append("0"); StringBuffer sb = new StringBuffer(); sb.append(Environment.NL); sb.append("\t\tif (" + var_name + ".scale() != " + scale + ")" + Environment.NL); sb.append("\t\t\tthrow new org.omg.CORBA.DATA_CONVERSION(\"wrong scale in fixed point value, expecting " + scale + ", got \" + " + var_name + ".scale());" + Environment.NL); String max = null; if (hashCode() > 0) max = "_max" + hashCode(); else max = "_max" + (-1 * hashCode()); sb.append("\t\tjava.math.BigDecimal " + max + "= new java.math.BigDecimal(\"" + mb.toString() + "\");" + Environment.NL); sb.append("\t\tif (" + var_name + ".compareTo(" + max + ") != -1)" + Environment.NL); sb.append("\t\t\tthrow new org.omg.CORBA.DATA_CONVERSION(\"more than " + digits + " digits in fixed point value\");" + Environment.NL); if (parser.generatedHelperPortability == parser.HELPER_DEPRECATED) { sb.append("\t\t" + strname + ".write_fixed(" + var_name + ");" + Environment.NL); } else if (parser.generatedHelperPortability == parser.HELPER_PORTABLE) { sb.append("\t\t" + strname + ".write_fixed(" + var_name + ", (short)" + digits + ", (short)" + scale + ");" + Environment.NL); } else if (parser.generatedHelperPortability == parser.HELPER_JACORB) { sb.append("\t\t((org.jacorb.orb.CDROutputStream)" + strname + ").write_fixed(" + var_name + ", (short)" + digits + ", (short)" + scale + ");" + Environment.NL); } else { assert false; } return sb.toString(); } public void parse() { digits = digit_expr.pos_int_const(); scale = scale_expr.pos_int_const(); if ((scale < 0) || (digits <= 0) || (scale > digits)) { parser.error("Error in fixed point type " + typeName() + ", invalid format: <" + digits + "," + scale + ">"); } } public void printInsertIntoAny(PrintWriter ps, String anyname, String varname) { String fullName = helperName(); String className; if (fullName.indexOf('.') > 0) { className = fullName.substring(fullName.lastIndexOf('.') + 1); } else { className = fullName; } String helpername = className + "Helper"; ps.println("\t\t" + helpername + ".insert("+anyname + ", "+ varname +" )"); } public void printExtractResult(PrintWriter ps, String resultname, String anyname, String resulttype) { throw new RuntimeException ( "DII-stubs not completely implemented for fixed-point types" ); } }