1 /* 2 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.corba.se.impl.dynamicany; 27 28 import org.omg.CORBA.TypeCode; 29 import org.omg.CORBA.Any; 30 import org.omg.CORBA.NO_IMPLEMENT; 31 import org.omg.DynamicAny.*; 32 import org.omg.DynamicAny.DynAnyPackage.*; 33 import java.math.BigDecimal; 34 import java.math.BigInteger; 35 import org.omg.CORBA.TypeCodePackage.BadKind; 36 37 import com.sun.corba.se.spi.orb.ORB ; 38 import com.sun.corba.se.spi.logging.CORBALogDomains ; 39 import com.sun.corba.se.impl.logging.ORBUtilSystemException ; 40 41 public class DynFixedImpl extends DynAnyBasicImpl implements DynFixed 42 { 43 // 44 // Constructors 45 // 46 47 private DynFixedImpl() { 48 this(null, (Any)null, false); 49 } 50 51 protected DynFixedImpl(ORB orb, Any any, boolean copyValue) { 52 super(orb, any, copyValue); 53 } 54 55 // Sets the current position to -1 and the value to zero. 56 protected DynFixedImpl(ORB orb, TypeCode typeCode) { 57 super(orb, typeCode); 58 index = NO_INDEX; 59 } 60 61 // 62 // DynAny interface methods 63 // 64 /* 65 public int component_count() { 66 return 0; 67 } 68 */ 69 // 70 // DynFixed interface methods 71 // 72 73 public String get_value () { 74 if (status == STATUS_DESTROYED) { 75 throw wrapper.dynAnyDestroyed() ; 76 } 77 return any.extract_fixed().toString(); 78 } 79 80 // Initializes the value of the DynFixed. 81 // The val string must contain a fixed string constant in the same format 82 // as used for IDL fixed-point literals. 83 // 84 // It may consist of an integer part, an optional decimal point, 85 // a fraction part and an optional letter d or D. 86 // The integer and fraction parts both must be sequences of decimal (base 10) digits. 87 // Either the integer part or the fraction part, but not both, may be missing. 88 // 89 // If val contains a value whose scale exceeds that of the DynFixed or is not initialized, 90 // the operation raises InvalidValue. 91 // The return value is true if val can be represented as the DynFixed without loss of precision. 92 // If val has more fractional digits than can be represented in the DynFixed, 93 // fractional digits are truncated and the return value is false. 94 // If val does not contain a valid fixed-point literal or contains extraneous characters 95 // other than leading or trailing white space, the operation raises TypeMismatch. 96 // 97 public boolean set_value (String val) 98 throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch, 99 org.omg.DynamicAny.DynAnyPackage.InvalidValue 100 { 101 if (status == STATUS_DESTROYED) { 102 throw wrapper.dynAnyDestroyed() ; 103 } 104 int digits = 0; 105 int scale = 0; 106 boolean preservedPrecision = true; 107 try { 108 digits = any.type().fixed_digits(); 109 scale = any.type().fixed_scale(); 110 } catch (BadKind ex) { // impossible 111 } 112 // First get rid of leading or trailing whitespace which is allowed 113 String string = val.trim(); 114 if (string.length() == 0) 115 throw new TypeMismatch(); 116 // Now scan for the sign 117 String sign = ""; 118 if (string.charAt(0) == '-') { 119 sign = "-"; 120 string = string.substring(1); 121 } else if (string.charAt(0) == '+') { 122 sign = "+"; 123 string = string.substring(1); 124 } 125 // Now get rid of the letter d or D. 126 int dIndex = string.indexOf('d'); 127 if (dIndex == -1) { 128 dIndex = string.indexOf('D'); 129 } 130 if (dIndex != -1) { 131 string = string.substring(0, dIndex); 132 } 133 // Just to be sure 134 if (string.length() == 0) 135 throw new TypeMismatch(); 136 // Now look for the dot to determine the integer part 137 String integerPart; 138 String fractionPart; 139 int currentScale; 140 int currentDigits; 141 int dotIndex = string.indexOf('.'); 142 if (dotIndex == -1) { 143 integerPart = string; 144 fractionPart = null; 145 currentScale = 0; 146 currentDigits = integerPart.length(); 147 } else if (dotIndex == 0 ) { 148 integerPart = null; 149 fractionPart = string; 150 currentScale = fractionPart.length(); 151 currentDigits = currentScale; 152 } else { 153 integerPart = string.substring(0, dotIndex); 154 fractionPart = string.substring(dotIndex + 1); 155 currentScale = fractionPart.length(); 156 currentDigits = integerPart.length() + currentScale; 157 } 158 // Let's see if we have to drop some precision 159 if (currentDigits > digits) { 160 preservedPrecision = false; 161 // truncate the fraction part 162 if (integerPart.length() < digits) { 163 fractionPart = fractionPart.substring(0, digits - integerPart.length()); 164 } else if (integerPart.length() == digits) { 165 // currentScale > 0 166 // drop the fraction completely 167 fractionPart = null; 168 } else { 169 // integerPart.length() > digits 170 // unable to truncate fraction part 171 throw new InvalidValue(); 172 } 173 } 174 // If val contains a value whose scale exceeds that of the DynFixed or is not initialized, 175 // the operation raises InvalidValue. 176 // Reinterpreted to mean raise InvalidValue only if the integer part exceeds precision, 177 // which is handled above (integerPart.length() > digits) 178 /* 179 if (currentScale > scale) { 180 throw new InvalidValue("Scale exceeds " + scale); 181 } 182 */ 183 // Now check whether both parts are valid numbers 184 BigDecimal result; 185 try { 186 new BigInteger(integerPart); 187 if (fractionPart == null) { 188 result = new BigDecimal(sign + integerPart); 189 } else { 190 new BigInteger(fractionPart); 191 result = new BigDecimal(sign + integerPart + "." + fractionPart); 192 } 193 } catch (NumberFormatException nfe) { 194 throw new TypeMismatch(); 195 } 196 any.insert_fixed(result, any.type()); 197 return preservedPrecision; 198 } 199 200 public String toString() { 201 int digits = 0; 202 int scale = 0; 203 try { 204 digits = any.type().fixed_digits(); 205 scale = any.type().fixed_scale(); 206 } catch (BadKind ex) { // impossible 207 } 208 return "DynFixed with value=" + this.get_value() + ", digits=" + digits + ", scale=" + scale; 209 } 210 }