TypeCodeInputStream.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 2002, 2013, 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
26package com.sun.corba.se.impl.encoding;
27
28import java.util.HashMap;
29import java.util.Map;
30import java.util.Iterator;
31import java.util.List;
32import java.util.Collections;
33import java.util.ArrayList;
34import java.io.IOException;
35import java.io.PrintStream;
36import java.io.ByteArrayOutputStream;
37import java.math.BigDecimal;
38import java.math.BigInteger;
39import java.nio.ByteBuffer;
40
41import org.omg.CORBA.TypeCode ;
42import org.omg.CORBA.StructMember ;
43import org.omg.CORBA.UnionMember ;
44import org.omg.CORBA.ValueMember ;
45import org.omg.CORBA.TCKind ;
46import org.omg.CORBA.Any ;
47import org.omg.CORBA.Principal ;
48import org.omg.CORBA.BAD_TYPECODE ;
49import org.omg.CORBA.BAD_PARAM ;
50import org.omg.CORBA.BAD_OPERATION ;
51import org.omg.CORBA.INTERNAL ;
52import org.omg.CORBA.MARSHAL ;
53
54import org.omg.CORBA.TypeCodePackage.BadKind ;
55
56import org.omg.CORBA_2_3.portable.InputStream;
57import org.omg.CORBA_2_3.portable.OutputStream;
58
59import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
60import com.sun.corba.se.impl.corba.TypeCodeImpl;
61import com.sun.corba.se.spi.orb.ORB;
62import com.sun.corba.se.impl.encoding.CodeSetConversion;
63import com.sun.corba.se.impl.encoding.CDRInputStream;
64import com.sun.corba.se.impl.encoding.CDROutputStream;
65import com.sun.corba.se.impl.encoding.MarshalInputStream;
66
67import sun.corba.EncapsInputStreamFactory;
68
69public class TypeCodeInputStream extends EncapsInputStream implements TypeCodeReader
70{
71    private Map typeMap = null;
72    private InputStream enclosure = null;
73    private boolean isEncapsulation = false;
74
75    public TypeCodeInputStream(org.omg.CORBA.ORB orb, byte[] data, int size) {
76        super(orb, data, size);
77    }
78
79    public TypeCodeInputStream(org.omg.CORBA.ORB orb,
80                               byte[] data,
81                               int size,
82                               boolean littleEndian,
83                               GIOPVersion version) {
84        super(orb, data, size, littleEndian, version);
85    }
86
87    public TypeCodeInputStream(org.omg.CORBA.ORB orb,
88                               ByteBuffer byteBuffer,
89                               int size,
90                               boolean littleEndian,
91                               GIOPVersion version) {
92        super(orb, byteBuffer, size, littleEndian, version);
93    }
94
95    public void addTypeCodeAtPosition(TypeCodeImpl tc, int position) {
96        if (typeMap == null) {
97            //if (TypeCodeImpl.debug) System.out.println("Creating typeMap");
98            typeMap = new HashMap(16);
99        }
100        //if (TypeCodeImpl.debug) System.out.println(this + " adding tc " + tc + " at position " + position);
101        typeMap.put(new Integer(position), tc);
102    }
103
104    public TypeCodeImpl getTypeCodeAtPosition(int position) {
105        if (typeMap == null)
106            return null;
107        //if (TypeCodeImpl.debug) {
108            //System.out.println("Getting tc " + (TypeCode)typeMap.get(new Integer(position)) +
109                               //" at position " + position);
110        //}
111        return (TypeCodeImpl)typeMap.get(new Integer(position));
112    }
113
114    public void setEnclosingInputStream(InputStream enclosure) {
115        this.enclosure = enclosure;
116    }
117
118    public TypeCodeReader getTopLevelStream() {
119        if (enclosure == null)
120            return this;
121        if (enclosure instanceof TypeCodeReader)
122            return ((TypeCodeReader)enclosure).getTopLevelStream();
123        return this;
124    }
125
126    public int getTopLevelPosition() {
127        if (enclosure != null && enclosure instanceof TypeCodeReader) {
128            // The enclosed stream has to consider if the enclosing stream
129            // had to read the enclosed stream completely when creating it.
130            // This is why the size of the enclosed stream needs to be substracted.
131            int topPos = ((TypeCodeReader)enclosure).getTopLevelPosition();
132            // Substract getBufferLength from the parents pos because it read this stream
133            // from its own when creating it
134            int pos = topPos - getBufferLength() + getPosition();
135            //if (TypeCodeImpl.debug) {
136                //System.out.println("TypeCodeInputStream.getTopLevelPosition using getTopLevelPosition " + topPos +
137                    //(isEncapsulation ? " - encaps length 4" : "") +
138                    //" - getBufferLength() " + getBufferLength() +
139                    //" + getPosition() " + getPosition() + " = " + pos);
140            //}
141            return pos;
142        }
143        //if (TypeCodeImpl.debug) {
144            //System.out.println("TypeCodeInputStream.getTopLevelPosition returning getPosition() = " +
145                               //getPosition() + " because enclosure is " + enclosure);
146        //}
147        return getPosition();
148    }
149
150    public static TypeCodeInputStream readEncapsulation(InputStream is, org.omg.CORBA.ORB _orb) {
151        // _REVISIT_ Would be nice if we didn't have to copy the buffer!
152        TypeCodeInputStream encap;
153
154        int encapLength = is.read_long();
155
156        // read off part of the buffer corresponding to the encapsulation
157        byte[] encapBuffer = new byte[encapLength];
158        is.read_octet_array(encapBuffer, 0, encapBuffer.length);
159
160        // create an encapsulation using the marshal buffer
161        if (is instanceof CDRInputStream) {
162            encap = EncapsInputStreamFactory.newTypeCodeInputStream((ORB) _orb,
163                    encapBuffer, encapBuffer.length,
164                    ((CDRInputStream) is).isLittleEndian(),
165                    ((CDRInputStream) is).getGIOPVersion());
166        } else {
167            encap = EncapsInputStreamFactory.newTypeCodeInputStream((ORB) _orb,
168                    encapBuffer, encapBuffer.length);
169        }
170        encap.setEnclosingInputStream(is);
171        encap.makeEncapsulation();
172        //if (TypeCodeImpl.debug) {
173            //System.out.println("Created TypeCodeInputStream " + encap + " with parent " + is);
174            //encap.printBuffer();
175        //}
176        return encap;
177    }
178
179    protected void makeEncapsulation() {
180        // first entry in an encapsulation is the endianess
181        consumeEndian();
182        isEncapsulation = true;
183    }
184
185    public void printTypeMap() {
186        System.out.println("typeMap = {");
187        Iterator i = typeMap.keySet().iterator();
188        while (i.hasNext()) {
189            Integer pos = (Integer)i.next();
190            TypeCodeImpl tci = (TypeCodeImpl)typeMap.get(pos);
191            System.out.println("  key = " + pos.intValue() + ", value = " + tci.description());
192        }
193        System.out.println("}");
194    }
195}
196