~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/openjdk/java/io/InteropObjectInputStream.java

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
 
3
 * Copyright 2009 Jeroen Frijters
 
4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
5
 *
 
6
 * This code is free software; you can redistribute it and/or modify it
 
7
 * under the terms of the GNU General Public License version 2 only, as
 
8
 * published by the Free Software Foundation.  Oracle designates this
 
9
 * particular file as subject to the "Classpath" exception as provided
 
10
 * by Oracle in the LICENSE file that accompanied this code.
 
11
 *
 
12
 * This code is distributed in the hope that it will be useful, but WITHOUT
 
13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
14
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
15
 * version 2 for more details (a copy is included in the LICENSE file that
 
16
 * accompanied this code).
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License version
 
19
 * 2 along with this work; if not, write to the Free Software Foundation,
 
20
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 
21
 *
 
22
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 
23
 * or visit www.oracle.com if you need additional information or have any
 
24
 * questions.
 
25
 */
 
26
package java.io;
 
27
 
 
28
import cli.System.Runtime.Serialization.SerializationException;
 
29
import cli.System.Runtime.Serialization.SerializationInfo;
 
30
import java.util.concurrent.atomic.AtomicBoolean;
 
31
 
 
32
@ikvm.lang.Internal
 
33
public final class InteropObjectInputStream extends ObjectInputStream
 
34
{
 
35
    private ObjectDataInputStream dis;
 
36
    private CallbackContext curContext;
 
37
    
 
38
    public static void readObject(Object obj, SerializationInfo info)
 
39
    {
 
40
        try
 
41
        {
 
42
            new InteropObjectInputStream(obj, info);
 
43
        }
 
44
        catch (Exception x)
 
45
        {
 
46
            ikvm.runtime.Util.throwException(new SerializationException(x.getMessage(), x));
 
47
        }
 
48
    }
 
49
    
 
50
    private InteropObjectInputStream(Object obj, SerializationInfo info) throws IOException, ClassNotFoundException
 
51
    {
 
52
        dis = new ObjectDataInputStream(info);
 
53
        if (obj instanceof ObjectStreamClass)
 
54
        {
 
55
            switch (readByte())
 
56
            {
 
57
                case TC_PROXYCLASSDESC:
 
58
                    readProxyDesc((ObjectStreamClass)obj);
 
59
                    break;
 
60
                case TC_CLASSDESC:
 
61
                    readNonProxyDesc((ObjectStreamClass)obj);
 
62
                    break;
 
63
                default:
 
64
                    throw new StreamCorruptedException();
 
65
            }
 
66
        }
 
67
        else
 
68
        {
 
69
            readOrdinaryObject(obj);
 
70
        }
 
71
    }
 
72
    
 
73
    private ObjectStreamClass readClassDesc() throws IOException, ClassNotFoundException
 
74
    {
 
75
        return (ObjectStreamClass)readObject();
 
76
    }
 
77
    
 
78
    private void readProxyDesc(ObjectStreamClass desc) throws IOException, ClassNotFoundException
 
79
    {
 
80
        int numIfaces = readInt();
 
81
        Class[] ifaces = new Class[numIfaces];
 
82
        for (int i = 0; i < numIfaces; i++)
 
83
        {
 
84
            ifaces[i] = (Class)readObject();
 
85
        }
 
86
        Class cl = java.lang.reflect.Proxy.getProxyClass(Thread.currentThread().getContextClassLoader(), ifaces);
 
87
        desc.initProxy(cl, null, readClassDesc());
 
88
    }
 
89
    
 
90
    private void readNonProxyDesc(ObjectStreamClass desc) throws IOException, ClassNotFoundException
 
91
    {
 
92
        Class cl = (Class)readObject();
 
93
        ObjectStreamClass readDesc = new ObjectStreamClass();
 
94
        readDesc.readNonProxy(this);
 
95
        desc.initNonProxy(readDesc, cl, null, readClassDesc());
 
96
    }
 
97
    
 
98
    private void readOrdinaryObject(Object obj) throws IOException, ClassNotFoundException
 
99
    {
 
100
        ObjectStreamClass desc = readClassDesc();
 
101
        desc.checkDeserialize();
 
102
 
 
103
        if (obj instanceof InteropObjectOutputStream.DynamicProxy)
 
104
        {
 
105
            InteropObjectOutputStream.DynamicProxy pp = (InteropObjectOutputStream.DynamicProxy)obj;
 
106
            try
 
107
            {
 
108
                obj = desc.newInstance();
 
109
                pp.obj = obj;
 
110
            }
 
111
            catch (Exception ex)
 
112
            {
 
113
                throw (IOException) new InvalidClassException(
 
114
                    desc.forClass().getName(),
 
115
                    "unable to create instance").initCause(ex);
 
116
            }
 
117
        }
 
118
        
 
119
        if (desc.isExternalizable())
 
120
        {
 
121
            readExternalData((Externalizable)obj, desc);
 
122
        }
 
123
        else
 
124
        {
 
125
            readSerialData(obj, desc);
 
126
        }
 
127
    }
 
128
    
 
129
    private void readExternalData(Externalizable obj, ObjectStreamClass desc) throws IOException, ClassNotFoundException
 
130
    {
 
131
        CallbackContext oldContext = curContext;
 
132
        curContext = null;
 
133
        try {
 
134
            obj.readExternal(this);
 
135
            skipCustomData();
 
136
        } finally {
 
137
            curContext = oldContext;
 
138
        }
 
139
    }
 
140
 
 
141
    private void readSerialData(Object obj, ObjectStreamClass desc) throws IOException, ClassNotFoundException
 
142
    {
 
143
        ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
 
144
        for (int i = 0; i < slots.length; i++)
 
145
        {
 
146
            ObjectStreamClass slotDesc = slots[i].desc;
 
147
 
 
148
            if (slots[i].hasData)
 
149
            {
 
150
                if (slotDesc.hasReadObjectMethod())
 
151
                {
 
152
                    CallbackContext oldContext = curContext;
 
153
                    try
 
154
                    {
 
155
                        curContext = new CallbackContext(obj, slotDesc);
 
156
                        slotDesc.invokeReadObject(obj, this);
 
157
                    }
 
158
                    finally
 
159
                    {
 
160
                        curContext.setUsed();
 
161
                        curContext = oldContext;
 
162
                    }
 
163
                }
 
164
                else
 
165
                {
 
166
                    defaultReadFields(obj, slotDesc);
 
167
                }
 
168
                if (slotDesc.hasWriteObjectData())
 
169
                {
 
170
                    skipCustomData();
 
171
                }
 
172
            }
 
173
            else if (slotDesc.hasReadObjectNoDataMethod())
 
174
            {
 
175
                slotDesc.invokeReadObjectNoData(obj);
 
176
            }
 
177
        }
 
178
    }
 
179
    
 
180
    private void skipCustomData() throws IOException
 
181
    {
 
182
        dis.skipMarker();
 
183
    }
 
184
    
 
185
    private void defaultReadFields(Object obj, ObjectStreamClass desc) throws IOException, ClassNotFoundException
 
186
    {
 
187
        byte[] primVals = new byte[desc.getPrimDataSize()];
 
188
        readFully(primVals);
 
189
        desc.setPrimFieldValues(obj, primVals);
 
190
 
 
191
        Object[] objVals = new Object[desc.getNumObjFields()];
 
192
        for (int i = 0; i < objVals.length; i++)
 
193
        {
 
194
            objVals[i] = readObject();
 
195
        }
 
196
        desc.setObjFieldValues(obj, objVals);
 
197
    }
 
198
    
 
199
    @Override
 
200
    public void defaultReadObject() throws IOException, ClassNotFoundException
 
201
    {
 
202
        if (curContext == null) {
 
203
            throw new NotActiveException("not in call to readObject");
 
204
        }
 
205
        Object curObj = curContext.getObj();
 
206
        ObjectStreamClass curDesc = curContext.getDesc();
 
207
        defaultReadFields(curObj, curDesc);
 
208
    }
 
209
 
 
210
    @Override
 
211
    protected Object readObjectOverride() throws IOException
 
212
    {
 
213
        return dis.readObject();
 
214
    }
 
215
 
 
216
    @Override
 
217
    public Object readUnshared()
 
218
    {
 
219
        throw new UnsupportedOperationException();
 
220
    }
 
221
 
 
222
    @Override
 
223
    public ObjectInputStream.GetField readFields() throws IOException, ClassNotFoundException
 
224
    {
 
225
        if (curContext == null) {
 
226
            throw new NotActiveException("not in call to readObject");
 
227
        }
 
228
        Object curObj = curContext.getObj();
 
229
        ObjectStreamClass curDesc = curContext.getDesc();
 
230
        GetFieldImpl getField = new GetFieldImpl(curDesc);
 
231
        getField.readFields();
 
232
        return getField;
 
233
    }
 
234
 
 
235
    @Override
 
236
    public void registerValidation(ObjectInputValidation obj, int prio)
 
237
    {
 
238
        throw new UnsupportedOperationException();
 
239
    }
 
240
    
 
241
    @Override
 
242
    public int read() throws IOException
 
243
    {
 
244
        return dis.read();
 
245
    }
 
246
 
 
247
    @Override
 
248
    public int read(byte[] buf, int off, int len) throws IOException
 
249
    {
 
250
        return dis.read(buf, off, len);
 
251
    }
 
252
 
 
253
    @Override
 
254
    public int available() throws IOException
 
255
    {
 
256
        return dis.available();
 
257
    }
 
258
 
 
259
    @Override
 
260
    public void close() throws IOException
 
261
    {
 
262
        throw new UnsupportedOperationException();
 
263
    }
 
264
 
 
265
    @Override
 
266
    public boolean readBoolean() throws IOException
 
267
    {
 
268
        return dis.readBoolean();
 
269
    }
 
270
 
 
271
    @Override
 
272
    public byte readByte() throws IOException
 
273
    {
 
274
        return dis.readByte();
 
275
    }
 
276
 
 
277
    @Override
 
278
    public int readUnsignedByte() throws IOException
 
279
    {
 
280
        return dis.readUnsignedByte();
 
281
    }
 
282
 
 
283
    @Override
 
284
    public char readChar() throws IOException
 
285
    {
 
286
        return dis.readChar();
 
287
    }
 
288
 
 
289
    @Override
 
290
    public short readShort() throws IOException
 
291
    {
 
292
        return dis.readShort();
 
293
    }
 
294
 
 
295
    @Override
 
296
    public int readUnsignedShort() throws IOException
 
297
    {
 
298
        return dis.readUnsignedShort();
 
299
    }
 
300
 
 
301
    @Override
 
302
    public int readInt() throws IOException
 
303
    {
 
304
        return dis.readInt();
 
305
    }
 
306
 
 
307
    @Override
 
308
    public long readLong() throws IOException
 
309
    {
 
310
        return dis.readLong();
 
311
    }
 
312
 
 
313
    @Override
 
314
    public float readFloat() throws IOException
 
315
    {
 
316
        return dis.readFloat();
 
317
    }
 
318
 
 
319
    @Override
 
320
    public double readDouble() throws IOException
 
321
    {
 
322
        return dis.readDouble();
 
323
    }
 
324
 
 
325
    @Override
 
326
    public void readFully(byte[] buf) throws IOException
 
327
    {
 
328
        readFully(buf, 0, buf.length);
 
329
    }
 
330
 
 
331
    @Override
 
332
    public void readFully(byte[] buf, int off, int len) throws IOException
 
333
    {
 
334
        dis.readFully(buf, off, len);
 
335
    }
 
336
 
 
337
    @Override
 
338
    public int skipBytes(int len) throws IOException
 
339
    {
 
340
        return dis.skipBytes(len);
 
341
    }
 
342
 
 
343
    @Deprecated
 
344
    @Override
 
345
    public String readLine() throws IOException
 
346
    {
 
347
        return dis.readLine();
 
348
    }
 
349
 
 
350
    @Override
 
351
    public String readUTF() throws IOException
 
352
    {
 
353
        return dis.readUTF();
 
354
    }
 
355
    
 
356
    // private API used by ObjectStreamClass
 
357
    @Override    
 
358
    String readTypeString() throws IOException
 
359
    {
 
360
        return (String)readObjectOverride();
 
361
    }
 
362
 
 
363
    private final class GetFieldImpl extends GetField {
 
364
 
 
365
        /** class descriptor describing serializable fields */
 
366
        private final ObjectStreamClass desc;
 
367
        /** primitive field values */
 
368
        private final byte[] primVals;
 
369
        /** object field values */
 
370
        private final Object[] objVals;
 
371
        /** object field value handles */
 
372
        private final int[] objHandles;
 
373
 
 
374
        /**
 
375
         * Creates GetFieldImpl object for reading fields defined in given
 
376
         * class descriptor.
 
377
         */
 
378
        GetFieldImpl(ObjectStreamClass desc) {
 
379
            this.desc = desc;
 
380
            primVals = new byte[desc.getPrimDataSize()];
 
381
            objVals = new Object[desc.getNumObjFields()];
 
382
            objHandles = new int[objVals.length];
 
383
        }
 
384
 
 
385
        public ObjectStreamClass getObjectStreamClass() {
 
386
            return desc;
 
387
        }
 
388
 
 
389
        public boolean defaulted(String name) throws IOException {
 
390
            return (getFieldOffset(name, null) < 0);
 
391
        }
 
392
 
 
393
        public boolean get(String name, boolean val) throws IOException {
 
394
            int off = getFieldOffset(name, Boolean.TYPE);
 
395
            return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
 
396
        }
 
397
 
 
398
        public byte get(String name, byte val) throws IOException {
 
399
            int off = getFieldOffset(name, Byte.TYPE);
 
400
            return (off >= 0) ? primVals[off] : val;
 
401
        }
 
402
 
 
403
        public char get(String name, char val) throws IOException {
 
404
            int off = getFieldOffset(name, Character.TYPE);
 
405
            return (off >= 0) ? Bits.getChar(primVals, off) : val;
 
406
        }
 
407
 
 
408
        public short get(String name, short val) throws IOException {
 
409
            int off = getFieldOffset(name, Short.TYPE);
 
410
            return (off >= 0) ? Bits.getShort(primVals, off) : val;
 
411
        }
 
412
 
 
413
        public int get(String name, int val) throws IOException {
 
414
            int off = getFieldOffset(name, Integer.TYPE);
 
415
            return (off >= 0) ? Bits.getInt(primVals, off) : val;
 
416
        }
 
417
 
 
418
        public float get(String name, float val) throws IOException {
 
419
            int off = getFieldOffset(name, Float.TYPE);
 
420
            return (off >= 0) ? Bits.getFloat(primVals, off) : val;
 
421
        }
 
422
 
 
423
        public long get(String name, long val) throws IOException {
 
424
            int off = getFieldOffset(name, Long.TYPE);
 
425
            return (off >= 0) ? Bits.getLong(primVals, off) : val;
 
426
        }
 
427
 
 
428
        public double get(String name, double val) throws IOException {
 
429
            int off = getFieldOffset(name, Double.TYPE);
 
430
            return (off >= 0) ? Bits.getDouble(primVals, off) : val;
 
431
        }
 
432
 
 
433
        public Object get(String name, Object val) throws IOException {
 
434
            int off = getFieldOffset(name, Object.class);
 
435
            if (off >= 0) {
 
436
                return objVals[off];
 
437
            } else {
 
438
                return val;
 
439
            }
 
440
        }
 
441
 
 
442
        /**
 
443
         * Reads primitive and object field values from stream.
 
444
         */
 
445
        void readFields() throws IOException {
 
446
            readFully(primVals, 0, primVals.length);
 
447
 
 
448
            for (int i = 0; i < objVals.length; i++) {
 
449
                objVals[i] = readObjectOverride();
 
450
            }
 
451
        }
 
452
 
 
453
        /**
 
454
         * Returns offset of field with given name and type.  A specified type
 
455
         * of null matches all types, Object.class matches all non-primitive
 
456
         * types, and any other non-null type matches assignable types only.
 
457
         * If no matching field is found in the (incoming) class
 
458
         * descriptor but a matching field is present in the associated local
 
459
         * class descriptor, returns -1.  Throws IllegalArgumentException if
 
460
         * neither incoming nor local class descriptor contains a match.
 
461
         */
 
462
        private int getFieldOffset(String name, Class type) {
 
463
            ObjectStreamField field = desc.getField(name, type);
 
464
            if (field != null) {
 
465
                return field.getOffset();
 
466
            } else if (desc.getLocalDesc().getField(name, type) != null) {
 
467
                return -1;
 
468
            } else {
 
469
                throw new IllegalArgumentException("no such field " + name +
 
470
                                                   " with type " + type);
 
471
            }
 
472
        }
 
473
    }
 
474
 
 
475
    private final static class CallbackContext {
 
476
        private final Object obj;
 
477
        private final ObjectStreamClass desc;
 
478
        private final AtomicBoolean used = new AtomicBoolean();
 
479
 
 
480
        public CallbackContext(Object obj, ObjectStreamClass desc) {
 
481
            this.obj = obj;
 
482
            this.desc = desc;
 
483
        }
 
484
 
 
485
        public Object getObj() throws NotActiveException {
 
486
            checkAndSetUsed();
 
487
            return obj;
 
488
        }
 
489
 
 
490
        public ObjectStreamClass getDesc() {
 
491
            return desc;
 
492
        }
 
493
 
 
494
        private void checkAndSetUsed() throws NotActiveException {
 
495
            if (!used.compareAndSet(false, true)) {
 
496
                 throw new NotActiveException(
 
497
                      "not in readObject invocation or fields already read");
 
498
            }
 
499
        }
 
500
 
 
501
        public void setUsed() {
 
502
            used.set(true);
 
503
        }
 
504
    }
 
505
 
 
506
    private static final class ObjectDataInputStream extends DataInputStream
 
507
    {
 
508
        private final static class Inp extends FilterInputStream
 
509
        {
 
510
            private static final byte MARKER = 0;
 
511
            private static final byte OBJECTS = 10;
 
512
            private static final byte BYTES = 20;
 
513
            private final SerializationInfo info;
 
514
            private byte[] buf;
 
515
            private int pos;
 
516
            private int blockEnd = -1;
 
517
            private int objCount;
 
518
            private int objId;
 
519
 
 
520
            Inp(SerializationInfo info) throws IOException
 
521
            {
 
522
                super(null);
 
523
                this.info = info;
 
524
                buf = (byte[])info.GetValue("$data", ikvm.runtime.Util.getInstanceTypeFromClass(cli.System.Object.class));
 
525
                modeSwitch();
 
526
            }
 
527
            
 
528
            private void modeSwitch() throws IOException
 
529
            {
 
530
                if (pos == buf.length)
 
531
                {
 
532
                    // next read will report error
 
533
                    blockEnd = -1;
 
534
                    objCount = -1;
 
535
                }
 
536
                else if (buf[pos] == OBJECTS)
 
537
                {
 
538
                    pos++;
 
539
                    objCount = readPacked();
 
540
                    blockEnd = -1;
 
541
                }
 
542
                else if (buf[pos] == BYTES)
 
543
                {
 
544
                    pos++;
 
545
                    switchToData();
 
546
                }
 
547
                else if (buf[pos] == MARKER)
 
548
                {
 
549
                }
 
550
                else
 
551
                {
 
552
                    throw new StreamCorruptedException();
 
553
                }
 
554
            }
 
555
            
 
556
            private int packedLength(int val)
 
557
            {
 
558
                if (val < 0)
 
559
                {
 
560
                    // we only use packed integers for lengths or counts, so they can never be negative
 
561
                    throw new Error();
 
562
                }
 
563
                else if (val < 128)
 
564
                {
 
565
                    return 1;
 
566
                }
 
567
                else if (val < 16129)
 
568
                {
 
569
                    return 2;
 
570
                }
 
571
                else
 
572
                {
 
573
                    return 5;
 
574
                }
 
575
            }
 
576
            
 
577
            private int readPacked()
 
578
            {
 
579
                int b1 = buf[pos++] & 0xFF;
 
580
                if (b1 < 128)
 
581
                {
 
582
                    return b1;
 
583
                }
 
584
                else if (b1 != 128)
 
585
                {
 
586
                    return ((b1 & 127) << 7) + (buf[pos++] & 0xFF);
 
587
                }
 
588
                else
 
589
                {
 
590
                    int v = 0;
 
591
                    v |= (buf[pos++] & 0xFF) << 24;
 
592
                    v |= (buf[pos++] & 0xFF) << 16;
 
593
                    v |= (buf[pos++] & 0xFF) <<  8;
 
594
                    v |= (buf[pos++] & 0xFF) <<  0;
 
595
                    return v;
 
596
                }
 
597
            }
 
598
            
 
599
            private void switchToData() throws IOException
 
600
            {
 
601
                if (blockEnd != -1 || objCount != 0 || buf[pos] == MARKER)
 
602
                {
 
603
                    throw new StreamCorruptedException();
 
604
                }
 
605
                int len = readPacked();
 
606
                blockEnd = pos + len;
 
607
                if (blockEnd > buf.length)
 
608
                {
 
609
                    throw new StreamCorruptedException();
 
610
                }
 
611
            }
 
612
 
 
613
            public int read() throws IOException
 
614
            {
 
615
                if (blockEnd - pos < 1)
 
616
                {
 
617
                    switchToData();
 
618
                }
 
619
                return buf[pos++] & 0xFF;
 
620
            }
 
621
            
 
622
            public int read(byte b[], int off, int len) throws IOException
 
623
            {
 
624
                if (len == 0)
 
625
                {
 
626
                    return 0;
 
627
                }
 
628
                if (blockEnd - pos < len)
 
629
                {
 
630
                    switchToData();
 
631
                }
 
632
                System.arraycopy(buf, pos, b, off, len);
 
633
                pos += len;
 
634
                return len;
 
635
            }
 
636
            
 
637
            public long skip(long n) throws IOException
 
638
            {
 
639
                if (n == 0)
 
640
                {
 
641
                    return 0;
 
642
                }
 
643
                if (blockEnd - pos < n)
 
644
                {
 
645
                    switchToData();
 
646
                }
 
647
                pos += (int)n;
 
648
                return n;
 
649
            }
 
650
            
 
651
            public int available() throws IOException
 
652
            {
 
653
                return 0;
 
654
            }
 
655
            
 
656
            public void close() throws IOException
 
657
            {
 
658
            }
 
659
            
 
660
            public void mark(int readlimit)
 
661
            {
 
662
            }
 
663
            
 
664
            public void reset() throws IOException
 
665
            {
 
666
            }
 
667
            
 
668
            public boolean markSupported()
 
669
            {
 
670
                return false;
 
671
            }
 
672
            
 
673
            Object readObject() throws IOException
 
674
            {
 
675
                if (objCount <= 0)
 
676
                {
 
677
                    if (pos != blockEnd || buf[pos] == MARKER)
 
678
                    {
 
679
                        throw new StreamCorruptedException();
 
680
                    }
 
681
                    blockEnd = -1;
 
682
                    objCount = readPacked();
 
683
                }
 
684
                objCount--;
 
685
                return info.GetValue("$" + (objId++), ikvm.runtime.Util.getInstanceTypeFromClass(cli.System.Object.class));
 
686
            }
 
687
            
 
688
            void skipMarker() throws IOException
 
689
            {
 
690
                for (;;)
 
691
                {
 
692
                    if (objCount > 0)
 
693
                    {
 
694
                        objId += objCount;
 
695
                        objCount = 0;
 
696
                        if (buf[pos] == MARKER)
 
697
                        {
 
698
                            pos++;
 
699
                            modeSwitch();
 
700
                            break;
 
701
                        }
 
702
                        switchToData();
 
703
                    }
 
704
                    if (blockEnd != -1)
 
705
                    {
 
706
                        pos = blockEnd;
 
707
                        blockEnd = -1;
 
708
                    }
 
709
                    if (pos == buf.length)
 
710
                    {
 
711
                        throw new StreamCorruptedException();
 
712
                    }
 
713
                    if (buf[pos] == MARKER)
 
714
                    {
 
715
                        pos++;
 
716
                        modeSwitch();
 
717
                        break;
 
718
                    }
 
719
                    blockEnd = -1;
 
720
                    objCount = readPacked();
 
721
                }
 
722
            }
 
723
        }
 
724
 
 
725
        ObjectDataInputStream(SerializationInfo info) throws IOException
 
726
        {
 
727
            super(new Inp(info));
 
728
        }
 
729
        
 
730
        public Object readObject() throws IOException
 
731
        {
 
732
            return ((Inp)in).readObject();
 
733
        }
 
734
        
 
735
        public void skipMarker() throws IOException
 
736
        {
 
737
            ((Inp)in).skipMarker();
 
738
        }
 
739
    }
 
740
}