1 /* ArrayValueHelper.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.CDR; 40 41 import gnu.CORBA.ObjectCreator; 42 43 import org.omg.CORBA.BooleanSeqHelper; 44 import org.omg.CORBA.CharSeqHelper; 45 import org.omg.CORBA.DoubleSeqHelper; 46 import org.omg.CORBA.FloatSeqHelper; 47 import org.omg.CORBA.LongLongSeqHelper; 48 import org.omg.CORBA.LongSeqHelper; 49 import org.omg.CORBA.OctetSeqHelper; 50 import org.omg.CORBA.ShortSeqHelper; 51 import org.omg.CORBA.portable.BoxedValueHelper; 52 import org.omg.CORBA.portable.InputStream; 53 import org.omg.CORBA.portable.OutputStream; 54 55 import java.io.Serializable; 56 import java.lang.reflect.Array; 57 import java.rmi.Remote; 58 59 import javax.rmi.CORBA.Util; 60 import javax.rmi.CORBA.ValueHandler; 61 62 /** 63 * Writes arrays as a boxed value types. A single instance is used to write a 64 * single array. This class is only used with RMI/IIOP, to handle array boxed 65 * values. 66 * 67 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) 68 */ 69 class ArrayValueHelper 70 implements BoxedValueHelper 71 { 72 /** 73 * The value handler (one for all instances). 74 */ 75 static ValueHandler handler = Util.createValueHandler(); 76 77 /** 78 * A class of the array being written. 79 */ 80 Class arrayClass; 81 82 /** 83 * The array component class. 84 */ 85 Class component; 86 87 /** 88 * The array component repository Id. 89 */ 90 String componentId; 91 92 /** 93 * If true, the array members are written as objects rather than as values. 94 * True for Remotes and CORBA objects. 95 */ written_as_object()96 boolean written_as_object() 97 { 98 return org.omg.CORBA.Object.class.isAssignableFrom(component) 99 || Remote.class.isAssignableFrom(component); 100 } 101 102 /** 103 * Creates the instance of the helper to write this specific array class. 104 */ ArrayValueHelper(Class an_arrayClass)105 ArrayValueHelper(Class an_arrayClass) 106 { 107 arrayClass = an_arrayClass; 108 } 109 110 /** 111 * Get the array repository Id that will be the RMI repository id. 112 */ get_id()113 public String get_id() 114 { 115 return ObjectCreator.getRepositoryId(arrayClass); 116 } 117 118 /** 119 * Read the array from the input stream. 120 */ read_value(InputStream input)121 public Serializable read_value(InputStream input) 122 { 123 if (input instanceof HeadlessInput) 124 { 125 ((HeadlessInput) input).subsequentCalls = true; 126 } 127 128 component = arrayClass.getComponentType(); 129 130 if (component.equals(byte.class)) 131 return OctetSeqHelper.read(input); 132 else if (component.equals(String.class)) 133 { 134 // String array is optimized because this may be frequent. 135 String[] s = new String[input.read_long()]; 136 137 for (int i = 0; i < s.length; i++) 138 s[i] = (String) Vio.read(input, Vio.m_StringValueHelper); 139 return s; 140 } 141 else if (component.equals(int.class)) 142 return LongSeqHelper.read(input); 143 else if (component.equals(long.class)) 144 return LongLongSeqHelper.read(input); 145 else if (component.equals(double.class)) 146 return DoubleSeqHelper.read(input); 147 else if (component.equals(float.class)) 148 return FloatSeqHelper.read(input); 149 else if (component.equals(boolean.class)) 150 return BooleanSeqHelper.read(input); 151 else if (component.equals(short.class)) 152 return ShortSeqHelper.read(input); 153 else if (component.equals(char.class)) 154 return CharSeqHelper.read(input); 155 else 156 { 157 // Read others, use reflection. 158 int n = input.read_long(); 159 160 gnuValueStream s = null; 161 162 Serializable array = (Serializable) Array.newInstance(component, n); 163 if (written_as_object()) 164 for (int i = 0; i < n; i++) 165 { 166 gnuRuntime g; 167 int position; 168 if (input instanceof gnuValueStream) 169 { 170 s = (gnuValueStream) input; 171 g = s.getRunTime(); 172 position = s.getPosition(); 173 } 174 else 175 { 176 g = null; 177 position = -1; 178 } 179 180 if (input instanceof HeadlessInput) 181 ((HeadlessInput) input).subsequentCalls = true; 182 183 Object o = handler.readValue(input, position, component, null, g); 184 Array.set(array, i, o); 185 } 186 else 187 for (int i = 0; i < n; i++) 188 Array.set(array, i, Vio.read(input, component)); 189 return array; 190 } 191 } 192 193 /** 194 * Write the array to the input stream. 195 */ write_value(OutputStream output, Serializable value)196 public void write_value(OutputStream output, Serializable value) 197 { 198 if (output instanceof gnuValueStream) 199 { 200 gnuRuntime r = ((gnuValueStream) output).getRunTime(); 201 if (r != null) 202 r.target = null; 203 } 204 205 if (value instanceof byte[]) 206 OctetSeqHelper.write(output, (byte[]) value); 207 else if (value instanceof String[]) 208 { 209 String[] s = (String[]) value; 210 output.write_long(s.length); 211 for (int i = 0; i < s.length; i++) 212 Vio.write(output, s[i], Vio.m_StringValueHelper); 213 } 214 else if (value instanceof int[]) 215 LongSeqHelper.write(output, (int[]) value); 216 else if (value instanceof long[]) 217 LongLongSeqHelper.write(output, (long[]) value); 218 else if (value instanceof double[]) 219 DoubleSeqHelper.write(output, (double[]) value); 220 else if (value instanceof float[]) 221 FloatSeqHelper.write(output, (float[]) value); 222 else if (value instanceof boolean[]) 223 BooleanSeqHelper.write(output, (boolean[]) value); 224 else if (value instanceof short[]) 225 ShortSeqHelper.write(output, (short[]) value); 226 else if (value instanceof char[]) 227 CharSeqHelper.write(output, (char[]) value); 228 else 229 { 230 // Write others, use reflection. 231 component = arrayClass.getComponentType(); 232 233 int n = Array.getLength(value); 234 output.write_long(n); 235 if (written_as_object()) 236 for (int i = 0; i < n; i++) 237 { 238 Object o = Array.get(value, i); 239 if (o == null) 240 output.write_Object(null); 241 else 242 // CORBA objects have another notation. 243 handler.writeValue(output, (Serializable) o); 244 } 245 else 246 { 247 for (int i = 0; i < n; i++) 248 Vio.write(output, (Serializable) Array.get(value, i), 249 component); 250 } 251 252 } 253 } 254 } 255