1 /* gnuDynFixed.java -- 2 Copyright (C) 2005 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package gnu.CORBA.DynAn; 40 41 import org.omg.CORBA.Any; 42 import org.omg.CORBA.BAD_OPERATION; 43 import org.omg.CORBA.BAD_PARAM; 44 import org.omg.CORBA.ORB; 45 import org.omg.CORBA.TypeCode; 46 import org.omg.DynamicAny.DynAny; 47 import org.omg.DynamicAny.DynAnyPackage.InvalidValue; 48 import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; 49 import org.omg.DynamicAny.DynFixed; 50 import org.omg.DynamicAny.DynFixedOperations; 51 52 import java.math.BigDecimal; 53 54 /** 55 * Implements DynAny, holding CORBA <code>fixed</code>. This class is derived 56 * from gnuDynEnm to avoid repetetive inclusion of unused DynAny methods. 57 * 58 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) 59 */ 60 public class gnuDynFixed extends UndivideableAny implements DynFixed 61 { 62 /** 63 * Use serialVersionUID for interoperability. 64 */ 65 private static final long serialVersionUID = 1; 66 67 /** 68 * The default value, assigned in the new instance. 69 */ 70 static final BigDecimal ZERO = new BigDecimal("0.0"); 71 72 /** 73 * The content of the dyn fixed, wrapped in this DynAny. 74 */ 75 BigDecimal value; 76 77 /** 78 * The number of digits after the decimal point. 79 */ 80 final int scale; 81 82 /** 83 * The number of digits. 84 */ 85 final int digits; 86 87 /** 88 * Create a new instance of the dyn fixed. 89 */ gnuDynFixed(TypeCode oType, TypeCode aType, gnuDynAnyFactory aFactory, ORB anOrb )90 public gnuDynFixed(TypeCode oType, TypeCode aType, 91 gnuDynAnyFactory aFactory, ORB anOrb 92 ) 93 { 94 super(oType, aType, aFactory, anOrb); 95 try 96 { 97 digits = final_type.fixed_digits(); 98 scale = final_type.fixed_scale(); 99 } 100 catch (Exception e) 101 { 102 throw new BAD_PARAM("Not a fixed"); 103 } 104 value = ZERO; 105 } 106 107 /** 108 * Clone the current instance. 109 */ gnuDynFixed(gnuDynFixed from)110 public gnuDynFixed(gnuDynFixed from) 111 { 112 super(from.official_type, from.final_type, from.factory, from.orb); 113 digits = from.digits; 114 scale = from.scale; 115 value = from.value; 116 } 117 118 /** 119 * Get the value of the wrapped dyn fixed, as string. 120 */ get_value()121 public String get_value() 122 { 123 return value.toString(); 124 } 125 126 /** 127 * Set the value. 128 */ set_value(String fixed_value)129 public boolean set_value(String fixed_value) 130 throws TypeMismatch, InvalidValue 131 { 132 // Count the digits till decimal point. 133 int digs = 0; 134 char c; 135 boolean leading0 = true; 136 Digs: 137 for (int i = 0; i < fixed_value.length(); i++) 138 { 139 c = fixed_value.charAt(i); 140 if (Character.isDigit(c)) 141 { 142 if (!(c == '0' && leading0)) 143 digs++; 144 if (c != '0') 145 leading0 = false; 146 } 147 else if (c == '.') 148 break Digs; 149 } 150 if (digs > (digits - scale)) 151 throw new InvalidValue("Too many digits: " + digs + " for " + digits + 152 "." + scale 153 ); 154 155 try 156 { 157 value = new BigDecimal(fixed_value); 158 } 159 catch (NumberFormatException ex) 160 { 161 if (fixed_value.trim().length() == 0) 162 throw new InvalidValue("Empty string passed"); 163 164 TypeMismatch inva = 165 new TypeMismatch("Not a number: '" + fixed_value + "'"); 166 inva.initCause(ex); 167 throw inva; 168 } 169 170 valueChanged(); 171 return value.scale() <= scale; 172 } 173 174 /** 175 * Assign the value from another BigDecimal. 176 */ assign(DynAny from)177 public void assign(DynAny from) throws TypeMismatch 178 { 179 checkType(official_type, from.type()); 180 181 if (from instanceof gnuDynFixed) 182 { 183 gnuDynFixed other = (gnuDynFixed) from; 184 value = other.value; 185 } 186 else if (from instanceof DynFixedOperations) 187 { 188 value = new BigDecimal(((DynFixedOperations) from).get_value()); 189 } 190 else 191 throw new TypeMismatch("Not a DynFixed"); 192 valueChanged(); 193 } 194 195 /** 196 * Create a copy. 197 */ copy()198 public DynAny copy() 199 { 200 return new gnuDynFixed(this); 201 } 202 203 /** 204 * Compare for equality. 205 */ equal(DynAny other)206 public boolean equal(DynAny other) 207 { 208 if (other instanceof gnuDynFixed) 209 { 210 // Normally, this code would be executed. 211 return value.equals(((gnuDynFixed) other).value); 212 } 213 if (other instanceof DynFixedOperations) 214 { 215 // This may be involved when mixing implementations. 216 return ((DynFixedOperations) other).get_value().equals(get_value()); 217 } 218 else 219 return false; 220 } 221 222 /** 223 * Set the value from Any (must hold <code>fixed</code> with the matching 224 * typecode.). 225 */ from_any(Any an_any)226 public void from_any(Any an_any) throws TypeMismatch, InvalidValue 227 { 228 try 229 { 230 checkType(official_type, an_any.type()); 231 232 value = an_any.extract_fixed(); 233 valueChanged(); 234 } 235 catch (BAD_OPERATION e) 236 { 237 InvalidValue t = new InvalidValue(); 238 t.initCause(e); 239 throw t; 240 } 241 } 242 243 /** 244 * Create and return Any, holding this DynFixed value. 245 */ to_any()246 public Any to_any() 247 { 248 Any g = createAny(); 249 g.insert_fixed(value, official_type); 250 return g; 251 } 252 } 253