
org.jinterop.dcom.core.JIPointer Maven / Gradle / Ivy
/** j-Interop (Pure Java implementation of DCOM protocol)
* Copyright (C) 2006 Vikram Roopchand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* Though a sincere effort has been made to deliver a professional,
* quality product,the library itself is distributed WITHOUT ANY WARRANTY;
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
package org.jinterop.dcom.core;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import ndr.NetworkDataRepresentation;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.common.JIRuntimeException;
/**
* Representation of a COM pointer.
*
* @since 1.0
*/
public final class JIPointer implements Serializable {
private static final long serialVersionUID = -3434037097460692619L;
private Object referent = null;
private boolean isReferenceTypePtr = false;
private boolean isDeffered = false;
private int referentId = -1;
private boolean isNull = false;
private int flags = JIFlags.FLAG_NULL;
private JIPointer() {
}
/**
* Creates an instance of this class where the referent is of the type
* value
. Used when deserializing this pointer.
*
* @param value null
is acceptable
* @param isReferenceTypePtr true
if a referent identifier will
* not precede this ptr.
*/
public JIPointer(Class value, boolean isReferenceTypePtr) {
//null pointer.
if (value == null) {
value = Integer.class;
isReferenceTypePtr = true;
isNull = true;
}
//Should not defer since the enclosing struct,union,array will defer it by itself
// this is important since , ptr to a ptr to a ptr (and more) will need to
//deserialize completely after the first deferement i.e they are not further deffered.
this.referent = value;
this.isReferenceTypePtr = isReferenceTypePtr;
}
/**
* Creates an instance of this class where the referent is
* value
. Used when serializing this pointer.
*
* @param value null
is acceptable
* @param isReferenceTypePtr true
if a referent Identifier will
* not precede this ptr.
*/
public JIPointer(Object value, boolean isReferenceTypePtr) {
if (value == null) {
//since a null is being sent for a pointer , it has to be shown
//as 0x0.
value = new Integer(0);
isReferenceTypePtr = true;
isNull = true;
}
// if (value.getClass().equals(JIArray.class))
// {
// if (((JIArray)value).getDimensions() > 1)
// throw new IllegalArgumentException("Only single dimension arrays accepted");
// }
//Should not defer since the enclosing struct,union,array will defer it by itself
// this is important since , ptr to a ptr to a ptr (and more) will need to
//deserialize completely after the first deferement i.e they are not further deffered.
this.referent = value;
this.referentId = new Object().hashCode();
this.isReferenceTypePtr = isReferenceTypePtr;
}
/**
* Sets the flags associated with the referent.
*
* @exclude
* @param flags JIFlags only.
*/
void setFlags(int flags) {
this.flags = flags;
}
/**
* Creates an instance of this class where the referent is
* value
. Used when serializing this pointer. This pointer is
* not of reference type.
*
* @param value
*/
public JIPointer(Object value) {
this(value, false);
}
/**
* Returns the referent encapsulated by this pointer.
*
* @return
*/
public Object getReferent() {
return isNull ? null : referent;
}
void encode(NetworkDataRepresentation ndr, List defferedPointers, int FLAG) {
FLAG |= flags;
if (isNull) {
JIMarshalUnMarshalHelper.serialize(ndr, Integer.class, new Integer(0), defferedPointers, FLAG);
return;
}
//it is deffered or part of an array, this logic will not get called twice since the
//deffered list will come in withb FLAG_NULL
if (!isNull && (isDeffered || (FLAG & JIFlags.FLAG_REPRESENTATION_ARRAY) == JIFlags.FLAG_REPRESENTATION_ARRAY /* ||
* (FLAG & JIFlags.FLAG_REPRESENTATION_NESTED_POINTER ) == JIFlags.FLAG_REPRESENTATION_NESTED_POINTER */)) {
int referentIdToPut = referentId == -1 ? referent.hashCode() : referentId;
JIMarshalUnMarshalHelper.serialize(ndr, Integer.class, new Integer(referentIdToPut), defferedPointers, FLAG);
isDeffered = false;
isReferenceTypePtr = true;
// try{
defferedPointers.add(this);
// }catch(NullPointerException e)
// {
// int ni = 0;
// }
return;
}
if (!isNull && !isReferenceTypePtr) {
int referentIdToPut = referentId == -1 ? referent.hashCode() : referentId;
JIMarshalUnMarshalHelper.serialize(ndr, Integer.class, new Integer(referentIdToPut), defferedPointers, FLAG);
}
try {
if (!isNull && referent.getClass().equals(JIVariant.class) && ((JIVariant) referent).isArray()) {
//write the length first before all elements
//ndr.writeUnsignedLong(((Object[])(((JIVariant)referent).getObject())).length);
JIMarshalUnMarshalHelper.serialize(ndr, Integer.class, new Integer(((Object[]) (((JIVariant) referent).getObject())).length), defferedPointers, FLAG);
}
} catch (JIException e) {
throw new JIRuntimeException(e.getErrorCode());
}
JIMarshalUnMarshalHelper.serialize(ndr, referent.getClass(), referent, defferedPointers, FLAG);
}
//class of type being decoded. If the type being expected is an array , the varType
//should be the actual array type and not JIArray.
JIPointer decode(NetworkDataRepresentation ndr, List defferedPointers, int FLAG, Map additionalData) {
//shallowClone();
FLAG |= flags;
JIPointer retVal = new JIPointer();
retVal.setFlags(flags);
retVal.isNull = isNull;
//retVal.isDeffered = isDeffered;
if (isDeffered || (FLAG & JIFlags.FLAG_REPRESENTATION_ARRAY) == JIFlags.FLAG_REPRESENTATION_ARRAY /* || (FLAG & JIFlags.FLAG_REPRESENTATION_NESTED_POINTER ) == JIFlags.FLAG_REPRESENTATION_NESTED_POINTER */) {
retVal.referentId = ((Number) JIMarshalUnMarshalHelper.deSerialize(ndr, Integer.class, defferedPointers, FLAG, additionalData)).intValue();
retVal.referent = referent; //will only be the class or object
if (retVal.referentId == 0) {
//null pointer
// just return
retVal.isNull = true;
retVal.isDeffered = false;
return retVal;
}
retVal.isDeffered = false;
retVal.isReferenceTypePtr = true;
defferedPointers.add(retVal);
return retVal;
}
if (!isReferenceTypePtr) {
//referentId = ndr.readUnsignedLong();
retVal.referentId = ((Number) JIMarshalUnMarshalHelper.deSerialize(ndr, Integer.class, defferedPointers, FLAG, additionalData)).intValue();
retVal.referent = referent; //will only be the class or object
if (retVal.referentId == 0) {
//null pointer
// just return
retVal.isNull = true;
return retVal;
}
}
retVal.referent = JIMarshalUnMarshalHelper.deSerialize(ndr, referent, defferedPointers, FLAG, additionalData);
return retVal;
}
void setDeffered(boolean deffered) {
isDeffered = deffered;
}
boolean getDeffered() {
return isDeffered;
}
void setReferent(int referent) {
this.referentId = referent;
}
/**
* Returns status whether this is a reference type pointer or not.
*
* @return true
if this is a reference type pointer.
*/
public boolean isReference() {
return isReferenceTypePtr;
}
/**
* Returns the referent identifier.
*
* @return
*/
public Integer getReferentIdentifier() {
return new Integer(referentId);
}
/**
* @exclude @return
*/
int getLength() {
if (isNull) {
return 4;
}
//4 for pointer
if (referent instanceof Class) {
return 4 + JIMarshalUnMarshalHelper.getLengthInBytes((Class) referent, referent, JIFlags.FLAG_NULL);
}
return 4 + JIMarshalUnMarshalHelper.getLengthInBytes(referent.getClass(), referent, JIFlags.FLAG_NULL);
}
void replaceSelfWithNewPointer(JIPointer replacement) {
this.isDeffered = replacement.isDeffered;
this.isNull = replacement.isNull;
this.isReferenceTypePtr = replacement.isReferenceTypePtr;
this.referent = replacement.referent;
}
/**
* Returns status if this pointer is null
.
*
* @return true
if the pointer is null
.
*/
public boolean isNull() {
return isNull;
}
void setValue(Object value) {
referent = value;
}
@Override
public String toString() {
return referent == null ? "[null]" : "[" + referent.toString() + "]";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy