xref: /AOO41X/main/jurt/com/sun/star/lib/uno/protocols/urp/Unmarshal.java (revision 2be432768a66cc90838f6a32e76ec156f587e741)
1*2be43276SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2be43276SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2be43276SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2be43276SAndrew Rist  * distributed with this work for additional information
6*2be43276SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2be43276SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2be43276SAndrew Rist  * "License"); you may not use this file except in compliance
9*2be43276SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*2be43276SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*2be43276SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2be43276SAndrew Rist  * software distributed under the License is distributed on an
15*2be43276SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2be43276SAndrew Rist  * KIND, either express or implied.  See the License for the
17*2be43276SAndrew Rist  * specific language governing permissions and limitations
18*2be43276SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*2be43276SAndrew Rist  *************************************************************/
21*2be43276SAndrew Rist 
22*2be43276SAndrew Rist 
23cdf0e10cSrcweir package com.sun.star.lib.uno.protocols.urp;
24cdf0e10cSrcweir 
25cdf0e10cSrcweir import com.sun.star.lib.uno.environments.remote.ThreadId;
26cdf0e10cSrcweir import com.sun.star.lib.uno.typedesc.TypeDescription;
27cdf0e10cSrcweir import com.sun.star.uno.Any;
28cdf0e10cSrcweir import com.sun.star.uno.Enum;
29cdf0e10cSrcweir import com.sun.star.uno.IBridge;
30cdf0e10cSrcweir import com.sun.star.uno.IFieldDescription;
31cdf0e10cSrcweir import com.sun.star.uno.Type;
32cdf0e10cSrcweir import com.sun.star.uno.TypeClass;
33cdf0e10cSrcweir import com.sun.star.uno.XInterface;
34cdf0e10cSrcweir import java.io.ByteArrayInputStream;
35cdf0e10cSrcweir import java.io.DataInputStream;
36cdf0e10cSrcweir import java.io.IOException;
37cdf0e10cSrcweir import java.io.UnsupportedEncodingException;
38cdf0e10cSrcweir import java.lang.reflect.Array;
39cdf0e10cSrcweir import java.lang.reflect.InvocationTargetException;
40cdf0e10cSrcweir 
41cdf0e10cSrcweir final class Unmarshal {
Unmarshal(IBridge bridge, int cacheSize)42cdf0e10cSrcweir     public Unmarshal(IBridge bridge, int cacheSize) {
43cdf0e10cSrcweir         this.bridge = bridge;
44cdf0e10cSrcweir         objectIdCache = new String[cacheSize];
45cdf0e10cSrcweir         threadIdCache = new ThreadId[cacheSize];
46cdf0e10cSrcweir         typeCache = new TypeDescription[cacheSize];
47cdf0e10cSrcweir         reset(new byte[0]);
48cdf0e10cSrcweir     }
49cdf0e10cSrcweir 
read8Bit()50cdf0e10cSrcweir     public int read8Bit() {
51cdf0e10cSrcweir         try {
52cdf0e10cSrcweir             return input.readUnsignedByte();
53cdf0e10cSrcweir         } catch (IOException e) {
54cdf0e10cSrcweir             throw new RuntimeException(e.toString());
55cdf0e10cSrcweir         }
56cdf0e10cSrcweir     }
57cdf0e10cSrcweir 
read16Bit()58cdf0e10cSrcweir     public int read16Bit() {
59cdf0e10cSrcweir         try {
60cdf0e10cSrcweir             return input.readUnsignedShort();
61cdf0e10cSrcweir         } catch (IOException e) {
62cdf0e10cSrcweir             throw new RuntimeException(e.toString());
63cdf0e10cSrcweir         }
64cdf0e10cSrcweir     }
65cdf0e10cSrcweir 
readObjectId()66cdf0e10cSrcweir     public String readObjectId() {
67cdf0e10cSrcweir         String id = readStringValue();
68cdf0e10cSrcweir         int index = read16Bit();
69cdf0e10cSrcweir         if (index == 0xFFFF) {
70cdf0e10cSrcweir             if (id.length() == 0) {
71cdf0e10cSrcweir                 id = null;
72cdf0e10cSrcweir             }
73cdf0e10cSrcweir         } else {
74cdf0e10cSrcweir             if (id.length() == 0) {
75cdf0e10cSrcweir                 id = objectIdCache[index];
76cdf0e10cSrcweir             } else {
77cdf0e10cSrcweir                 objectIdCache[index] = id;
78cdf0e10cSrcweir             }
79cdf0e10cSrcweir         }
80cdf0e10cSrcweir         return id;
81cdf0e10cSrcweir     }
82cdf0e10cSrcweir 
readInterface(Type type)83cdf0e10cSrcweir     public Object readInterface(Type type) {
84cdf0e10cSrcweir         String id = readObjectId();
85cdf0e10cSrcweir         return id == null ? null : bridge.mapInterfaceFrom(id, type);
86cdf0e10cSrcweir     }
87cdf0e10cSrcweir 
readThreadId()88cdf0e10cSrcweir     public ThreadId readThreadId() {
89cdf0e10cSrcweir         int len = readCompressedNumber();
90cdf0e10cSrcweir         byte[] data  ;
91cdf0e10cSrcweir         ThreadId id = null;
92cdf0e10cSrcweir         if (len != 0) {
93cdf0e10cSrcweir             data = new byte[len];
94cdf0e10cSrcweir             readBytes(data);
95cdf0e10cSrcweir             id = new ThreadId(data);
96cdf0e10cSrcweir         }
97cdf0e10cSrcweir         int index = read16Bit();
98cdf0e10cSrcweir         if (index != 0xFFFF) {
99cdf0e10cSrcweir             if (len == 0) {
100cdf0e10cSrcweir                 id = threadIdCache[index];
101cdf0e10cSrcweir             } else {
102cdf0e10cSrcweir                 threadIdCache[index] = id;
103cdf0e10cSrcweir             }
104cdf0e10cSrcweir         }
105cdf0e10cSrcweir         return id;
106cdf0e10cSrcweir     }
107cdf0e10cSrcweir 
readType()108cdf0e10cSrcweir     public TypeDescription readType() {
109cdf0e10cSrcweir         int b = read8Bit();
110cdf0e10cSrcweir         TypeClass typeClass = TypeClass.fromInt(b & 0x7F);
111cdf0e10cSrcweir         if (TypeDescription.isTypeClassSimple(typeClass)) {
112cdf0e10cSrcweir             return TypeDescription.getTypeDescription(typeClass);
113cdf0e10cSrcweir         } else {
114cdf0e10cSrcweir             int index = read16Bit();
115cdf0e10cSrcweir             TypeDescription type = null;
116cdf0e10cSrcweir             if ((b & 0x80) != 0) {
117cdf0e10cSrcweir                 try {
118cdf0e10cSrcweir                     type = TypeDescription.getTypeDescription(
119cdf0e10cSrcweir                         readStringValue());
120cdf0e10cSrcweir                 } catch (ClassNotFoundException e) {
121cdf0e10cSrcweir                     throw new RuntimeException(e.toString());
122cdf0e10cSrcweir                 }
123cdf0e10cSrcweir             }
124cdf0e10cSrcweir             if (index != 0xFFFF) {
125cdf0e10cSrcweir                 if ((b & 0x80) == 0) {
126cdf0e10cSrcweir                     type = typeCache[index];
127cdf0e10cSrcweir                 } else {
128cdf0e10cSrcweir                     typeCache[index] = type;
129cdf0e10cSrcweir                 }
130cdf0e10cSrcweir             }
131cdf0e10cSrcweir             return type;
132cdf0e10cSrcweir         }
133cdf0e10cSrcweir     }
134cdf0e10cSrcweir 
readValue(TypeDescription type)135cdf0e10cSrcweir     public Object readValue(TypeDescription type) {
136cdf0e10cSrcweir         switch (type.getTypeClass().getValue()) {
137cdf0e10cSrcweir         case TypeClass.VOID_value:
138cdf0e10cSrcweir             return null;
139cdf0e10cSrcweir 
140cdf0e10cSrcweir         case TypeClass.BOOLEAN_value:
141cdf0e10cSrcweir             return readBooleanValue();
142cdf0e10cSrcweir 
143cdf0e10cSrcweir         case TypeClass.BYTE_value:
144cdf0e10cSrcweir             return readByteValue();
145cdf0e10cSrcweir 
146cdf0e10cSrcweir         case TypeClass.SHORT_value:
147cdf0e10cSrcweir         case TypeClass.UNSIGNED_SHORT_value:
148cdf0e10cSrcweir             return readShortValue();
149cdf0e10cSrcweir 
150cdf0e10cSrcweir         case TypeClass.LONG_value:
151cdf0e10cSrcweir         case TypeClass.UNSIGNED_LONG_value:
152cdf0e10cSrcweir             return readLongValue();
153cdf0e10cSrcweir 
154cdf0e10cSrcweir         case TypeClass.HYPER_value:
155cdf0e10cSrcweir         case TypeClass.UNSIGNED_HYPER_value:
156cdf0e10cSrcweir             return readHyperValue();
157cdf0e10cSrcweir 
158cdf0e10cSrcweir         case TypeClass.FLOAT_value:
159cdf0e10cSrcweir             return readFloatValue();
160cdf0e10cSrcweir 
161cdf0e10cSrcweir         case TypeClass.DOUBLE_value:
162cdf0e10cSrcweir             return readDoubleValue();
163cdf0e10cSrcweir 
164cdf0e10cSrcweir         case TypeClass.CHAR_value:
165cdf0e10cSrcweir             return readCharValue();
166cdf0e10cSrcweir 
167cdf0e10cSrcweir         case TypeClass.STRING_value:
168cdf0e10cSrcweir             return readStringValue();
169cdf0e10cSrcweir 
170cdf0e10cSrcweir         case TypeClass.TYPE_value:
171cdf0e10cSrcweir             return readTypeValue();
172cdf0e10cSrcweir 
173cdf0e10cSrcweir         case TypeClass.ANY_value:
174cdf0e10cSrcweir             return readAnyValue();
175cdf0e10cSrcweir 
176cdf0e10cSrcweir         case TypeClass.SEQUENCE_value:
177cdf0e10cSrcweir             return readSequenceValue(type);
178cdf0e10cSrcweir 
179cdf0e10cSrcweir         case TypeClass.ENUM_value:
180cdf0e10cSrcweir             return readEnumValue(type);
181cdf0e10cSrcweir 
182cdf0e10cSrcweir         case TypeClass.STRUCT_value:
183cdf0e10cSrcweir             return readStructValue(type);
184cdf0e10cSrcweir 
185cdf0e10cSrcweir         case TypeClass.EXCEPTION_value:
186cdf0e10cSrcweir             return readExceptionValue(type);
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         case TypeClass.INTERFACE_value:
189cdf0e10cSrcweir             return readInterfaceValue(type);
190cdf0e10cSrcweir 
191cdf0e10cSrcweir         default:
192cdf0e10cSrcweir             throw new IllegalArgumentException("Bad type descriptor " + type);
193cdf0e10cSrcweir         }
194cdf0e10cSrcweir     }
195cdf0e10cSrcweir 
hasMore()196cdf0e10cSrcweir     public boolean hasMore() {
197cdf0e10cSrcweir         try {
198cdf0e10cSrcweir             return input.available() > 0;
199cdf0e10cSrcweir         } catch (IOException e) {
200cdf0e10cSrcweir             throw new RuntimeException(e.toString());
201cdf0e10cSrcweir         }
202cdf0e10cSrcweir     }
203cdf0e10cSrcweir 
reset(byte[] data)204cdf0e10cSrcweir     public void reset(byte[] data) {
205cdf0e10cSrcweir         input = new DataInputStream(new ByteArrayInputStream(data));
206cdf0e10cSrcweir     }
207cdf0e10cSrcweir 
readBooleanValue()208cdf0e10cSrcweir     private Boolean readBooleanValue() {
209cdf0e10cSrcweir         try {
210cdf0e10cSrcweir             return input.readBoolean() ? Boolean.TRUE : Boolean.FALSE;
211cdf0e10cSrcweir         } catch (IOException e) {
212cdf0e10cSrcweir             throw new RuntimeException(e.toString());
213cdf0e10cSrcweir         }
214cdf0e10cSrcweir     }
215cdf0e10cSrcweir 
readByteValue()216cdf0e10cSrcweir     private Byte readByteValue() {
217cdf0e10cSrcweir         try {
218cdf0e10cSrcweir             return new Byte(input.readByte());
219cdf0e10cSrcweir         } catch (IOException e) {
220cdf0e10cSrcweir             throw new RuntimeException(e.toString());
221cdf0e10cSrcweir         }
222cdf0e10cSrcweir     }
223cdf0e10cSrcweir 
readShortValue()224cdf0e10cSrcweir     private Short readShortValue() {
225cdf0e10cSrcweir         try {
226cdf0e10cSrcweir             return new Short(input.readShort());
227cdf0e10cSrcweir         } catch (IOException e) {
228cdf0e10cSrcweir             throw new RuntimeException(e.toString());
229cdf0e10cSrcweir         }
230cdf0e10cSrcweir     }
231cdf0e10cSrcweir 
readLongValue()232cdf0e10cSrcweir     private Integer readLongValue() {
233cdf0e10cSrcweir         try {
234cdf0e10cSrcweir             return new Integer(input.readInt());
235cdf0e10cSrcweir         } catch (IOException e) {
236cdf0e10cSrcweir             throw new RuntimeException(e.toString());
237cdf0e10cSrcweir         }
238cdf0e10cSrcweir     }
239cdf0e10cSrcweir 
readHyperValue()240cdf0e10cSrcweir     private Long readHyperValue() {
241cdf0e10cSrcweir         try {
242cdf0e10cSrcweir             return new Long(input.readLong());
243cdf0e10cSrcweir         } catch (IOException e) {
244cdf0e10cSrcweir             throw new RuntimeException(e.toString());
245cdf0e10cSrcweir         }
246cdf0e10cSrcweir     }
247cdf0e10cSrcweir 
readFloatValue()248cdf0e10cSrcweir     private Float readFloatValue() {
249cdf0e10cSrcweir         try {
250cdf0e10cSrcweir             return new Float(input.readFloat());
251cdf0e10cSrcweir         } catch (IOException e) {
252cdf0e10cSrcweir             throw new RuntimeException(e.toString());
253cdf0e10cSrcweir         }
254cdf0e10cSrcweir     }
255cdf0e10cSrcweir 
readDoubleValue()256cdf0e10cSrcweir     private Double readDoubleValue() {
257cdf0e10cSrcweir         try {
258cdf0e10cSrcweir             return new Double(input.readDouble());
259cdf0e10cSrcweir         } catch (IOException e) {
260cdf0e10cSrcweir             throw new RuntimeException(e.toString());
261cdf0e10cSrcweir         }
262cdf0e10cSrcweir     }
263cdf0e10cSrcweir 
readCharValue()264cdf0e10cSrcweir     private Character readCharValue() {
265cdf0e10cSrcweir         try {
266cdf0e10cSrcweir             return new Character(input.readChar());
267cdf0e10cSrcweir         } catch (IOException e) {
268cdf0e10cSrcweir             throw new RuntimeException(e.toString());
269cdf0e10cSrcweir         }
270cdf0e10cSrcweir     }
271cdf0e10cSrcweir 
readStringValue()272cdf0e10cSrcweir     private String readStringValue() {
273cdf0e10cSrcweir         int len = readCompressedNumber();
274cdf0e10cSrcweir         byte[] data = new byte[len];
275cdf0e10cSrcweir         readBytes(data);
276cdf0e10cSrcweir         try {
277cdf0e10cSrcweir             return new String(data, "UTF8");
278cdf0e10cSrcweir         } catch (UnsupportedEncodingException e) {
279cdf0e10cSrcweir             throw new RuntimeException(e.toString());
280cdf0e10cSrcweir         }
281cdf0e10cSrcweir     }
282cdf0e10cSrcweir 
readTypeValue()283cdf0e10cSrcweir     private Type readTypeValue() {
284cdf0e10cSrcweir         return new Type(readType());
285cdf0e10cSrcweir     }
286cdf0e10cSrcweir 
readAnyValue()287cdf0e10cSrcweir     private Object readAnyValue() {
288cdf0e10cSrcweir         TypeDescription type = readType();
289cdf0e10cSrcweir         switch (type.getTypeClass().getValue()) {
290cdf0e10cSrcweir         case TypeClass.VOID_value:
291cdf0e10cSrcweir             return Any.VOID;
292cdf0e10cSrcweir 
293cdf0e10cSrcweir         case TypeClass.BOOLEAN_value:
294cdf0e10cSrcweir             return readBooleanValue();
295cdf0e10cSrcweir 
296cdf0e10cSrcweir         case TypeClass.BYTE_value:
297cdf0e10cSrcweir             return readByteValue();
298cdf0e10cSrcweir 
299cdf0e10cSrcweir         case TypeClass.SHORT_value:
300cdf0e10cSrcweir             return readShortValue();
301cdf0e10cSrcweir 
302cdf0e10cSrcweir         case TypeClass.UNSIGNED_SHORT_value:
303cdf0e10cSrcweir             return new Any(Type.UNSIGNED_SHORT, readShortValue());
304cdf0e10cSrcweir 
305cdf0e10cSrcweir         case TypeClass.LONG_value:
306cdf0e10cSrcweir             return readLongValue();
307cdf0e10cSrcweir 
308cdf0e10cSrcweir         case TypeClass.UNSIGNED_LONG_value:
309cdf0e10cSrcweir             return new Any(Type.UNSIGNED_LONG, readLongValue());
310cdf0e10cSrcweir 
311cdf0e10cSrcweir         case TypeClass.HYPER_value:
312cdf0e10cSrcweir             return readHyperValue();
313cdf0e10cSrcweir 
314cdf0e10cSrcweir         case TypeClass.UNSIGNED_HYPER_value:
315cdf0e10cSrcweir             return new Any(Type.UNSIGNED_HYPER, readHyperValue());
316cdf0e10cSrcweir 
317cdf0e10cSrcweir         case TypeClass.FLOAT_value:
318cdf0e10cSrcweir             return readFloatValue();
319cdf0e10cSrcweir 
320cdf0e10cSrcweir         case TypeClass.DOUBLE_value:
321cdf0e10cSrcweir             return readDoubleValue();
322cdf0e10cSrcweir 
323cdf0e10cSrcweir         case TypeClass.CHAR_value:
324cdf0e10cSrcweir             return readCharValue();
325cdf0e10cSrcweir 
326cdf0e10cSrcweir         case TypeClass.STRING_value:
327cdf0e10cSrcweir             return readStringValue();
328cdf0e10cSrcweir 
329cdf0e10cSrcweir         case TypeClass.TYPE_value:
330cdf0e10cSrcweir             return readTypeValue();
331cdf0e10cSrcweir 
332cdf0e10cSrcweir         case TypeClass.SEQUENCE_value:
333cdf0e10cSrcweir             {
334cdf0e10cSrcweir                 Object value = readSequenceValue(type);
335cdf0e10cSrcweir                 TypeDescription ctype = (TypeDescription)
336cdf0e10cSrcweir                     type.getComponentType();
337cdf0e10cSrcweir                 while (ctype.getTypeClass() == TypeClass.SEQUENCE) {
338cdf0e10cSrcweir                     ctype = (TypeDescription) ctype.getComponentType();
339cdf0e10cSrcweir                 }
340cdf0e10cSrcweir                 switch (ctype.getTypeClass().getValue()) {
341cdf0e10cSrcweir                 case TypeClass.UNSIGNED_SHORT_value:
342cdf0e10cSrcweir                 case TypeClass.UNSIGNED_LONG_value:
343cdf0e10cSrcweir                 case TypeClass.UNSIGNED_HYPER_value:
344cdf0e10cSrcweir                     return new Any(new Type(type), value);
345cdf0e10cSrcweir 
346cdf0e10cSrcweir                 case TypeClass.STRUCT_value:
347cdf0e10cSrcweir                     if (ctype.hasTypeArguments()) {
348cdf0e10cSrcweir                         return new Any(new Type(type), value);
349cdf0e10cSrcweir                     }
350cdf0e10cSrcweir                 default:
351cdf0e10cSrcweir                     return value;
352cdf0e10cSrcweir                 }
353cdf0e10cSrcweir             }
354cdf0e10cSrcweir 
355cdf0e10cSrcweir         case TypeClass.ENUM_value:
356cdf0e10cSrcweir             return readEnumValue(type);
357cdf0e10cSrcweir 
358cdf0e10cSrcweir         case TypeClass.STRUCT_value:
359cdf0e10cSrcweir             {
360cdf0e10cSrcweir                 Object value = readStructValue(type);
361cdf0e10cSrcweir                 return type.hasTypeArguments()
362cdf0e10cSrcweir                     ? new Any(new Type(type), value) : value;
363cdf0e10cSrcweir             }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir         case TypeClass.EXCEPTION_value:
366cdf0e10cSrcweir             return readExceptionValue(type);
367cdf0e10cSrcweir 
368cdf0e10cSrcweir         case TypeClass.INTERFACE_value:
369cdf0e10cSrcweir             {
370cdf0e10cSrcweir                 Object value = readInterfaceValue(type);
371cdf0e10cSrcweir                 return type.getZClass() == XInterface.class
372cdf0e10cSrcweir                     ? value : new Any(new Type(type), value);
373cdf0e10cSrcweir             }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir         default:
376cdf0e10cSrcweir             throw new RuntimeException(
377cdf0e10cSrcweir                 "Reading ANY with bad type " + type.getTypeClass());
378cdf0e10cSrcweir         }
379cdf0e10cSrcweir     }
380cdf0e10cSrcweir 
readSequenceValue(TypeDescription type)381cdf0e10cSrcweir     private Object readSequenceValue(TypeDescription type) {
382cdf0e10cSrcweir         int len = readCompressedNumber();
383cdf0e10cSrcweir         TypeDescription ctype = (TypeDescription) type.getComponentType();
384cdf0e10cSrcweir         if (ctype.getTypeClass() == TypeClass.BYTE) {
385cdf0e10cSrcweir             byte[] data = new byte[len];
386cdf0e10cSrcweir             readBytes(data);
387cdf0e10cSrcweir             return data;
388cdf0e10cSrcweir         } else {
389cdf0e10cSrcweir             Object value = Array.newInstance(
390cdf0e10cSrcweir                 ctype.getTypeClass() == TypeClass.ANY
391cdf0e10cSrcweir                 ? Object.class : ctype.getZClass(), len);
392cdf0e10cSrcweir             for (int i = 0; i < len; ++i) {
393cdf0e10cSrcweir                 Array.set(value, i, readValue(ctype));
394cdf0e10cSrcweir             }
395cdf0e10cSrcweir             return value;
396cdf0e10cSrcweir         }
397cdf0e10cSrcweir     }
398cdf0e10cSrcweir 
readEnumValue(TypeDescription type)399cdf0e10cSrcweir     private Enum readEnumValue(TypeDescription type) {
400cdf0e10cSrcweir         try {
401cdf0e10cSrcweir             return (Enum)
402cdf0e10cSrcweir                 type.getZClass().getMethod(
403cdf0e10cSrcweir                     "fromInt", new Class[] { int.class }).
404cdf0e10cSrcweir                 invoke(null, new Object[] { readLongValue() });
405cdf0e10cSrcweir         } catch (IllegalAccessException e) {
406cdf0e10cSrcweir             throw new RuntimeException(e.toString());
407cdf0e10cSrcweir         } catch (InvocationTargetException e) {
408cdf0e10cSrcweir             throw new RuntimeException(e.toString());
409cdf0e10cSrcweir         } catch (NoSuchMethodException e) {
410cdf0e10cSrcweir             throw new RuntimeException(e.toString());
411cdf0e10cSrcweir         }
412cdf0e10cSrcweir     }
413cdf0e10cSrcweir 
readStructValue(TypeDescription type)414cdf0e10cSrcweir     private Object readStructValue(TypeDescription type) {
415cdf0e10cSrcweir         Object value;
416cdf0e10cSrcweir         try {
417cdf0e10cSrcweir             value = type.getZClass().newInstance();
418cdf0e10cSrcweir         } catch (IllegalAccessException e) {
419cdf0e10cSrcweir             throw new RuntimeException(e.toString());
420cdf0e10cSrcweir         } catch (InstantiationException e) {
421cdf0e10cSrcweir             throw new RuntimeException(e.toString());
422cdf0e10cSrcweir         }
423cdf0e10cSrcweir         readFields(type, value);
424cdf0e10cSrcweir         return value;
425cdf0e10cSrcweir     }
426cdf0e10cSrcweir 
readExceptionValue(TypeDescription type)427cdf0e10cSrcweir     private Exception readExceptionValue(TypeDescription type) {
428cdf0e10cSrcweir         Exception value;
429cdf0e10cSrcweir         try {
430cdf0e10cSrcweir             value = (Exception)
431cdf0e10cSrcweir                 type.getZClass().getConstructor(new Class[] { String.class }).
432cdf0e10cSrcweir                 newInstance(new Object[] { readStringValue() });
433cdf0e10cSrcweir         } catch (IllegalAccessException e) {
434cdf0e10cSrcweir             throw new RuntimeException(e.toString());
435cdf0e10cSrcweir         } catch (InstantiationException e) {
436cdf0e10cSrcweir             throw new RuntimeException(e.toString());
437cdf0e10cSrcweir         } catch (InvocationTargetException e) {
438cdf0e10cSrcweir             throw new RuntimeException(e.toString());
439cdf0e10cSrcweir         } catch (NoSuchMethodException e) {
440cdf0e10cSrcweir             throw new RuntimeException(e.toString());
441cdf0e10cSrcweir         }
442cdf0e10cSrcweir         readFields(type, value);
443cdf0e10cSrcweir         return value;
444cdf0e10cSrcweir     }
445cdf0e10cSrcweir 
readInterfaceValue(TypeDescription type)446cdf0e10cSrcweir     private Object readInterfaceValue(TypeDescription type) {
447cdf0e10cSrcweir         return readInterface(new Type(type));
448cdf0e10cSrcweir     }
449cdf0e10cSrcweir 
readCompressedNumber()450cdf0e10cSrcweir     private int readCompressedNumber() {
451cdf0e10cSrcweir         int number = read8Bit();
452cdf0e10cSrcweir         try {
453cdf0e10cSrcweir             return number < 0xFF ? number : input.readInt();
454cdf0e10cSrcweir         } catch (IOException e) {
455cdf0e10cSrcweir             throw new RuntimeException(e.toString());
456cdf0e10cSrcweir         }
457cdf0e10cSrcweir     }
458cdf0e10cSrcweir 
readBytes(byte[] data)459cdf0e10cSrcweir     private void readBytes(byte[] data) {
460cdf0e10cSrcweir         try {
461cdf0e10cSrcweir             input.readFully(data);
462cdf0e10cSrcweir         } catch (IOException e) {
463cdf0e10cSrcweir             throw new RuntimeException(e.toString());
464cdf0e10cSrcweir         }
465cdf0e10cSrcweir     }
466cdf0e10cSrcweir 
readFields(TypeDescription type, Object value)467cdf0e10cSrcweir     private void readFields(TypeDescription type, Object value) {
468cdf0e10cSrcweir         IFieldDescription[] fields = type.getFieldDescriptions();
469cdf0e10cSrcweir         for (int i = 0; i < fields.length; ++i) {
470cdf0e10cSrcweir             try {
471cdf0e10cSrcweir                 fields[i].getField().set(
472cdf0e10cSrcweir                     value,
473cdf0e10cSrcweir                     readValue(
474cdf0e10cSrcweir                         (TypeDescription) fields[i].getTypeDescription()));
475cdf0e10cSrcweir             } catch (IllegalAccessException e) {
476cdf0e10cSrcweir                 throw new RuntimeException(e.toString());
477cdf0e10cSrcweir             }
478cdf0e10cSrcweir         }
479cdf0e10cSrcweir     }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir     private final IBridge bridge;
482cdf0e10cSrcweir     private final String[] objectIdCache;
483cdf0e10cSrcweir     private final ThreadId[] threadIdCache;
484cdf0e10cSrcweir     private final TypeDescription[] typeCache;
485cdf0e10cSrcweir     private DataInputStream input;
486cdf0e10cSrcweir }
487