/*
* 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" );
}
}