Package com.sun.star.lib.uno.protocols.iiop

Source Code of com.sun.star.lib.uno.protocols.iiop.Unmarshal$I2U

/*************************************************************************
*
*  $RCSfile: Unmarshal.java,v $
*
*  $Revision: 1.3 $
*
*  last change: $Author: kr $ $Date: 2001/01/16 18:01:30 $
*
*  The Contents of this file are made available subject to the terms of
*  either of the following licenses
*
*         - GNU Lesser General Public License Version 2.1
*         - Sun Industry Standards Source License Version 1.1
*
*  Sun Microsystems Inc., October, 2000
*
*  GNU Lesser General Public License Version 2.1
*  =============================================
*  Copyright 2000 by Sun Microsystems, Inc.
*  901 San Antonio Road, Palo Alto, CA 94303, USA
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License version 2.1, as published by the Free Software Foundation.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
*  MA  02111-1307  USA
*
*
*  Sun Industry Standards Source License Version 1.1
*  =================================================
*  The contents of this file are subject to the Sun Industry Standards
*  Source License Version 1.1 (the "License"); You may not use this file
*  except in compliance with the License. You may obtain a copy of the
*  License at http://www.openoffice.org/license.html.
*
*  Software provided under this License is provided on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
*  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
*  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
*  See the License for the specific provisions governing your rights and
*  obligations concerning the Software.
*
*  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
*  Copyright: 2000 by Sun Microsystems, Inc.
*
*  All Rights Reserved.
*
*  Contributor(s): _______________________________________
*
*
************************************************************************/

package com.sun.star.lib.uno.protocols.iiop;


import java.io.DataInputStream;
import java.io.IOException;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import java.util.Hashtable;


import com.sun.star.corba.CorbaString8;
import com.sun.star.corba.CorbaUnion;
import com.sun.star.corba.ObjectKey;
import com.sun.star.corba.TCKind;

import com.sun.star.uno.Any;
import com.sun.star.uno.Ascii;
import com.sun.star.uno.AsciiString;
import com.sun.star.uno.Enum;
import com.sun.star.uno.IBridge;
import com.sun.star.uno.Type;
import com.sun.star.uno.TypeClass;
import com.sun.star.uno.Union;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;

import com.sun.star.corba.iiop.ProfileBody_1_1;

import com.sun.star.corba.iop.IOR;


import com.sun.star.corba.giop.ReplyHeader_1_2;


import com.sun.star.lib.uno.environments.remote.IUnmarshal;
import com.sun.star.lib.uno.environments.remote.Protocol;
import com.sun.star.lib.uno.environments.remote.ThreadID;

import com.sun.star.lib.uno.typedesc.TypeDescription;

import com.sun.star.lib.uno.typeinfo.MemberTypeInfo;


final class Unmarshal extends CDRInputStream implements IUnmarshal {
  public static boolean DEBUG = false;


  static final TypeDescription __asciiTypeDescription       = TypeDescription.getTypeDescription(Ascii.class);
  static final TypeDescription __asciiStringTypeDescription = TypeDescription.getTypeDescription(AsciiString.class);

  static final TypeDescription __IORTypeDescription = TypeDescription.getTypeDescription(IOR.class);
  static final TypeDescription __ProfileBody_1_1TypeDescription = TypeDescription.getTypeDescription(ProfileBody_1_1.class);
  static final TypeDescription __ObjectKeyTypeDescription = TypeDescription.getTypeDescription(ObjectKey.class);
  static final TypeDescription __xInterfaceTypeDescription = TypeDescription.getTypeDescription(XInterface.class);

  static class I2U {
    TypeClass       _typeClass;
    TypeDescription _typeDescription;

    I2U(TypeClass typeClass, TypeDescription typeDescription) {
      _typeClass       = typeClass;
      _typeDescription = typeDescription;
    }
  }

//      new I2U(TypeClass.UNSIGNED_SHORT.getValue(), Short.TYPE,        Short.class,    null,),      //ushort -> ushort, 4 -> 5
//      new I2U(TypeClass.UNSIGNED_LONG.getValue(),  Integer.TYPE,      Integer.class),     //ulong -> ulong, 5 -> 7
//      new I2U(TypeClass.UNSIGNED_HYPER.getValue(), Long.TYPE,         Long.class),    //ulonglong -> uhyper, 24 -> 9
  final static I2U IIOP2UNOTypeClass[] = new I2U[]{
    new I2U(TypeClass.VOID,           TypeDescription.__void_TypeDescription),        //null -> void, 0 ->0
    new I2U(TypeClass.VOID,           TypeDescription.__void_TypeDescription),        //void -> void, 1 -> 0
    new I2U(TypeClass.SHORT,          TypeDescription.__short_TypeDescription),     //short -> short, 2 -> 4
    new I2U(TypeClass.LONG,           TypeDescription.__long_TypeDescription),     //long -> long, 3 -> 6
    new I2U(TypeClass.UNSIGNED_SHORT, null),                       // ushort, 4 -> 5, not supported
    new I2U(TypeClass.UNSIGNED_LONG,  null),                         //ulong -> ulong, 5 -> 7, not supported
    new I2U(TypeClass.FLOAT,          TypeDescription.__float_TypeDescription),     //float -> float, 6 -> 10
    new I2U(TypeClass.DOUBLE,         TypeDescription.__double_TypeDescription),       //double -> double, 7 -> 11
    new I2U(TypeClass.BOOLEAN,        TypeDescription.__boolean_TypeDescription),     //bool -> bool, 8 -> 2
    new I2U(TypeClass.UNKNOWN,        __asciiTypeDescription),       //ascii -> ???, 9 -> 27
    new I2U(TypeClass.BYTE,           TypeDescription.__byte_TypeDescription),     //octet -> byte, 10 -> 3
    new I2U(TypeClass.ANY,            TypeDescription.__any_TypeDescription),       //any -> any, 11 -> 14
    new I2U(TypeClass.TYPE,           TypeDescription.__type_TypeDescription),       //TypeCode -> type, 12 -> 13
    new I2U(TypeClass.UNKNOWN,        null),                   //Principal -> ???, 13 -> 27
    new I2U(TypeClass.INTERFACE,      null),                     //objref -> interface, 14 -> 22
    new I2U(TypeClass.STRUCT,         null),                   //struct -> struct, 15 -> 17
    new I2U(TypeClass.UNION,          null),                   //union -> union, 16 -> 18
    new I2U(TypeClass.ENUM,           null),                 //enum -> enum, 17 -> 15
    new I2U(TypeClass.UNKNOWN,        __asciiStringTypeDescription), //asciistring -> ???, 18 -> 27
    new I2U(TypeClass.SEQUENCE,       null),                   //sequence -> sequence, 19 -> 20
    new I2U(TypeClass.ARRAY,          null),                   //array -> array, 20 -> 21
    new I2U(TypeClass.TYPEDEF,        null),                   //alias -> typedef, 21 -> 16
    new I2U(TypeClass.EXCEPTION,      null),                     //exception -> exception, 22 -> 19
    new I2U(TypeClass.HYPER,          TypeDescription.__hyper_TypeDescription),     //longlong -> hyper, 23 -> 8
    new I2U(TypeClass.UNSIGNED_HYPER, null),                     //ulonglong -> uhyper, 24 -> 9, not supported
    new I2U(TypeClass.UNKNOWN,        null),                   //longdouble -> ???, 25 -> 27
    new I2U(TypeClass.CHAR,           TypeDescription.__char_TypeDescription),       //unicode -> unicode, 26 -> 1
    new I2U(TypeClass.STRING,         TypeDescription.__string_TypeDescription),       //unicodestring-> unicodestring, 27 -> 12
    new I2U(TypeClass.UNKNOWN,        null),                   //fixed -> ???, 28 -> 27
    new I2U(TypeClass.UNKNOWN,        null),                   //value -> ???, 29 -> 27
    new I2U(TypeClass.UNKNOWN,        null),                   //value_box -> ???, 30 -> 27
    new I2U(TypeClass.UNKNOWN,        null),                   //native -> ???, 31 -> 27
    new I2U(TypeClass.UNKNOWN,        null)                       //abstract_interface -> ???, 32 -> 27
      };
 
  // The last type kind read with the read_typeclass method. Only usefull for spead up.
  private int LastIIOPTypeKind;

  private void todo() throws Exception {
    throw new Exception(getClass().getName() + " - todo: not implemented");
  }

  protected IBridge _bridge;

  Unmarshal(byte [] Buffer, int size, boolean littleEndian, IBridge bridge)  {
    super(Buffer, size, littleEndian);
    _bridge = bridge;
  }

  /** Return the proper type kind of a class
   */
  static int classToIIOPTypeKind(TypeDescription typeDescription){
      int nLen = IIOP2UNOTypeClass.length;
    int result = TCKind.tk_struct_value;

      //strat with 0, so no unsigned types occure
    int i;
    for(i = 0; i != nLen; ++i)
      if( typeDescription.equals(IIOP2UNOTypeClass[i]._typeDescription) ) {
        result = i;
        break;
      }

    if(i >= nLen) {
      // workaround for: isAssignableFrom bug with jdk blackdown 118 under linux
//        __getDeclaredFields(type);

      /*if(JavaClass == com.sun.star.corba.CorbaString8.class)  //////////////////////////////////////////////////
        result = TCKind.tk_string.getValue();
        else */
      if(typeDescription.getTypeClass() == TypeClass.SEQUENCE)
        result = TCKind.tk_sequence.getValue();
      else if(typeDescription.getTypeClass() == TypeClass.EXCEPTION)
        result = TCKind.tk_except.getValue();
      else if(typeDescription.getTypeClass() == TypeClass.ENUM)
        result = TCKind.tk_enum.getValue();
      else if(typeDescription.getTypeClass() == TypeClass.UNION)
        result = TCKind.tk_union.getValue();
      // this is (like write_union) only temporaer
      else if(com.sun.star.corba.CorbaUnion.class.isAssignableFrom(typeDescription.getZClass()))
        result = TCKind.tk_union.getValue();
      // any ?
      else if(Object.class == typeDescription.getZClass()
                 || Number.class.isAssignableFrom(typeDescription.getZClass())
         || Character.class == typeDescription.getZClass()
                 || Boolean.class == typeDescription.getZClass()) {
        result =  TCKind.tk_any.getValue();
      }
      else if(typeDescription.getTypeClass() == TypeClass.INTERFACE)
        result = TCKind.tk_objref.getValue();
    }

//        if(DEBUG) System.err.println("##### Unmarshal.classToIIOPTypeKind:" + type + " " + result);

    return result;
  }


  private TypeDescription readTypeDescription() throws Exception {
    TypeDescription result = null;

    //Class return = null;
    String TypeName = null;
    int kind = read_long();

    int nCount = 0;
    int nBound = 0;

    switch(kind) {
    case TCKind.tk_Principal_value:  todo()break;
    case TCKind.tk_objref_value:
      TypeName = read_asciistring();
      read_asciistring()// dummy
      break;

    case TCKind.tk_struct_value:
      TypeName = read_asciistring();
      read_asciistring();// dummy
      nCount = read_long();
      for(int i = 0; i < nCount; ++ i) {
        read_asciistring()// member name
        readTypeDescription();
      }
      break;

    case TCKind.tk_union_value:
      TypeName = read_asciistring();
      read_asciistring()// dummy

      TypeDescription descreminator = readTypeDescription();// Descriminator type code
      int nDefault = read_long()// index of default
      nCount = read_long();// count of members

      for(int i = 0; i < nCount; ++ i) {// add members of the unions
        // value of descriminator
        todo();
        // member name
        read_asciistring();
        //typecode of the member
        readTypeDescription();
      }
      break;

    case TCKind.tk_enum_value:
      TypeName = read_asciistring();
      read_asciistring()// dummy
      nCount = read_long();// all enum names
      for(int i = 0; i < nCount; ++ i)
        read_asciistring()// member name

      break;

    case TCKind.tk_string_value:
      // read the bounds of an string
      nBound = read_long();
      break;

    case TCKind.tk_sequence_value:
      TypeDescription elementType = readTypeDescription();
      TypeName = "[]" + elementType.getTypeName();

      nBound = read_long();
      if(nBound != 0)
        todo();
     
      result = TypeDescription.getTypeDescription(TypeName);
      break;

    case TCKind.tk_except_value:
      TypeName = read_asciistring();
      // dummy
      read_asciistring();
      nCount = read_long();
      for(int i = 0;i < nCount; ++ i){
        read_asciistring()// member name
        readTypeDescription();
      }
      break;

    case TCKind.tk_wstring_value:
      // read the bounds of an string
      nBound = read_long();
      break;
    }
    LastIIOPTypeKind = kind;

    if(IIOP2UNOTypeClass[kind]._typeDescription != null)
      result = IIOP2UNOTypeClass[kind]._typeDescription;

    else
      result = TypeDescription.getTypeDescription(TypeName);
//        result = TypeDescription.getType(IIOP2UNOTypeClass[kind]._typeClass, TypeName);
   
    if(DEBUG); System.err.println("##### " + getClass().getName() + " - read_type - kind:" + result + " " + kind);

    return result;
  }

  Boolean readBoolean() throws Exception {
    Boolean result =  new Boolean(read_boolean());

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readBoolean:" + result);

    return result;
  }

  Byte readByte() throws Exception {
    Byte result = new Byte(read_octet());

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readByte:" + result);

    return result;
  }


  Character readCharacter() throws Exception {
    Character result = new Character(read_ascii());

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readChar:" + result);

    return result;
  }

  Short readShort() throws Exception {
    Short result = new Short(read_short());

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readShort:" + result);
   
    return result;
  }

  Integer readInteger() throws Exception {
    Integer result = new Integer(read_long());

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readInteger:" + result);

    return result;
  }

  Double readDouble() throws Exception {
    Double result = new Double(read_double());

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readDouble:" + result);

    return result;
  }


  Float readFloat() throws Exception {
    Float result = new Float(read_float());

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readFloat:" + result);

    return result;
  }

  Long readLong() throws Exception {
    Long result = new Long(read_longlong());

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readLong:" + result);

    return result;
  }


  Throwable readThrowable() throws Exception {
    String typeName = read_asciistring();
    TypeDescription typeDescription = TypeDescription.getTypeDescription(typeName);

    String message = read_unicodestring();

    Constructor constructor = typeDescription.getZClass().getConstructor(new Class[]{String.class});
    Throwable throwable = (Throwable)constructor.newInstance(new Object[]{message});

    readStruct(typeDescription, throwable);

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readThrowable:" + throwable);

    return throwable;
  }

  void readStruct(TypeDescription typeDescription, Object object) throws Exception {
    Field fields[] = typeDescription.getFields();

    for(int i = 0; i < fields.length; ++ i) {
      if((fields[i].getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) == 0) { // neither static nor transient ?
        MemberTypeInfo memberTypeInfo = typeDescription.getMemberTypeInfo(fields[i].getName());
       
        // default the member type to the declared type
        Class zInterface = fields[i].getType();
       
        if(memberTypeInfo != null) {
          if(memberTypeInfo.isAny()) // is the member an any?
            if(zInterface.isArray())
              zInterface = Class.forName("[Lcom.sun.star.uno.Any;");
            else
              zInterface = Any.class;
         
          else if(memberTypeInfo.isInterface()) { // is the member an interface ?
            Class xInterface = zInterface;

            if(!XInterface.class.isAssignableFrom(fields[i].getType())) // is the member type not derived of XInterface ?
              xInterface = XInterface.class; // ensure that we get at least an XInterface

            if(zInterface.isArray())
              zInterface = Class.forName("[L" + xInterface.getName() + ";");
            else
              zInterface = xInterface;
          }
        }

        fields[i].set(object, readObject(TypeDescription.getTypeDescription(zInterface)));
      }
    }

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readStruct:" + object);
  }

  Object readStruct(TypeDescription typeDescription) throws Exception {
    Object object = null;

    if(typeDescription.getZClass() == CorbaString8.class) { // special treatement for CorbaString8
      String string = read_asciistring();
      if(DEBUG) System.err.println("##### Unmarshal.read_struct - CorbaString8:" + string);
      object = new CorbaString8(string);
    }
    else {
      object = typeDescription.getZClass().newInstance();

      readStruct(typeDescription, object);
    }

    return object;
  }


  public ThreadID readThreadID() throws Exception {
    throw new com.sun.star.uno.RuntimeException("Unmarshal.readThreadID - not implemented!!!");
  }

  public Object readObject(TypeDescription typeDescription) throws Exception {
    Object result = null;

    switch(typeDescription.getTypeClass().getValue()) {
    case TypeClass.ANY_value:       result = readAny();                       break; // read an any?
    case TypeClass.SEQUENCE_value:     
    case TypeClass.ARRAY_value:      result = readSequence(typeDescription);   break// read a sequence ?
    case TypeClass.VOID_value:                                                break; // nop  // read nothing ?
    case TypeClass.ENUM_value:       result = readEnum(typeDescription);       break// read an enum ?
    case TypeClass.UNION_value:      result = readUnion(typeDescription);      break// read a union ?
    case TypeClass.TYPE_value:      result = new Type(readTypeDescription()); break// read a type ?
    case TypeClass.INTERFACE_value:  result = read_objref(typeDescription);    break// read an interface ?
    case TypeClass.BOOLEAN_value:   result = readBoolean();                   break// is it a boolean
    case TypeClass.CHAR_value:      result = readCharacter();                 break// is it a character ?)
    case TypeClass.BYTE_value:       result = readByte();                      break; // is it a byte ?
    case TypeClass.SHORT_value:      result = readShort();                     break// is it a short ?
    case TypeClass.LONG_value:      result = readInteger();                   break// is it an integer ?
    case TypeClass.HYPER_value:     result = readLong();                      break// is it a long ?
    case TypeClass.FLOAT_value:     result = readFloat();                     break// is it a float ?
    case TypeClass.DOUBLE_value:    result = readDouble();                    break// is it a double ?
    case TypeClass.STRING_value:    result = read_unicodestring();            break// is it a String ?
    case TypeClass.EXCEPTION_value:  result = readThrowable();                 break// is it an exception?
    case TypeClass.STRUCT_value:   
      if(typeDescription.getZClass() == ThreadID.class) // read a thread id ?
        result = readThreadID();

      else if(CorbaUnion.class.isAssignableFrom(typeDescription.getZClass()))
        result = readCorbaUnion(typeDescription);

      else  // otherwise read a struct
        result = readStruct(typeDescription);    

      break;

    default:
      throw new com.sun.star.uno.RuntimeException("unknown typeClass:" + typeDescription.getTypeClass());
    }

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readObject:" + typeDescription + " " + result);

    return result;
  }

  Object readAny() throws Exception {
    TypeDescription typeDescription = readTypeDescription();
    Object object = readObject(typeDescription);

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readAny:" + object);

    return object;
  }

  Object readSequence(TypeDescription typeDescription) throws Exception {
    Object result = null;

    typeDescription = typeDescription.getComponentType();
     
    if(typeDescription.getTypeClass().getValue() == TypeClass.BYTE_value) // read a byte sequence ?
        result = read_octet_array();

    else {
      int size = read_long();
     
      if(typeDescription.getTypeClass() == TypeClass.ANY) // take special care of any array (cause anys are mapped to objects)
        result = Array.newInstance(Object.class, size);
      else
        result = Array.newInstance(typeDescription.getZClass(), size);
     
      for(int i = 0; i < size; ++ i)
        Array.set(result, i, readObject(typeDescription));
    }

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readSequence:" + result);

    return result;
  }


  Union readUnion(TypeDescription typeDescription) throws Exception {
    throw new com.sun.star.uno.RuntimeException("Unmarshal.readUnion - not implemented!!!");
  }

  Enum readEnum(TypeDescription typeDescription) throws Exception {
    Integer index = new Integer(read_long());

    Method fromInt = typeDescription.getZClass().getMethod("fromInt", new Class[] {int.class});
    Enum result = (Enum)fromInt.invoke(null, new Object[]{index});

    if(DEBUG) System.err.println("##### " + getClass().getName() + ".readEnum:" + result);

    return result;
  }

  private XInterface read_objref(TypeDescription typeDescription) throws Exception {
    XInterface xInterface = null;

    IOR ior = (IOR)readObject(__IORTypeDescription);
   
    // is it the empty ref?
    if(ior.profiles.length != 0) {
      String sType = ior.type_id.theString;
      byte profileBody_bytes[] = ior.profiles[0].profile_data;

      Unmarshal unmarshal = new Unmarshal(profileBody_bytes,
                        profileBody_bytes.length,
                        littleEndian,
                        _bridge);
      ProfileBody_1_1 profileBody = (ProfileBody_1_1)unmarshal.readObject(__ProfileBody_1_1TypeDescription);
   
      byte key_bytes[] = profileBody.object_key;
     
      Unmarshal tmpUnmarshal = new Unmarshal(key_bytes, key_bytes.length, littleEndian, _bridge);
      ObjectKey objectKey = (ObjectKey)tmpUnmarshal.readObject(__ObjectKeyTypeDescription);
     
      xInterface = (XInterface)_bridge.mapInterfaceFrom(objectKey.sOid.theString, new Type(typeDescription));
     
      if(DEBUG) System.err.println("#### Unmarshal.read_objref - oid:" + objectKey.sOid.theString + " stype:" + objectKey.sType.theString + " xInterface:" + xInterface);
    }
    else
      if(DEBUG) System.err.println("#### Unmarshal.read_objref - oid: ior empty");

      return xInterface;
  }

  private CorbaUnion readCorbaUnion(TypeDescription corbaUnion_TypeDescription) throws Exception {
    CorbaUnion corbaUnion = (CorbaUnion)corbaUnion_TypeDescription.getZClass().newInstance();
   
    short discriminator = read_short();

    Field descriminatorField = corbaUnion_TypeDescription.getZClass().getDeclaredField("nDiscriminator");
    descriminatorField.set(corbaUnion, new Short(discriminator));
   
    Field fields[] = corbaUnion_TypeDescription.getFields();
    fields[discriminator + 2].set(corbaUnion, readObject(TypeDescription.getTypeDescription(fields[discriminator + 2].getType())));

      return corbaUnion;
  }
}
TOP

Related Classes of com.sun.star.lib.uno.protocols.iiop.Unmarshal$I2U

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.