SF 1650134 - preliminary VT_Variant support VariantVariant
This commit is contained in:
@@ -65,7 +65,13 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td width="13%" valign="top">1690420</td>
|
<td width="13%" valign="top">1690420</td>
|
||||||
<td width="87%" valign="top">(pre-release 4)Incorrect memcpy lengths for Currency Variants</td>
|
<td width="87%" valign="top">(pre-release 4) Incorrect memcpy lengths for Currency Variants</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="13%" valign="top">1650134</td>
|
||||||
|
<td width="87%" valign="top">(pre-release 6) Beta support for VT_VARIANT (VariantVariant).
|
||||||
|
Includes support for putVariant, getVariant, toJavaObject, Variant(Object,flag).
|
||||||
|
Enclosed variants are retreived as Java objects. </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -1013,4 +1013,67 @@ JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_isVariantConsideredNull
|
|||||||
return JNI_FALSE;
|
return JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a variant into a the Variant as its data and sets the type
|
||||||
|
* to VT_VARIANT|VT_BYREF.
|
||||||
|
* Added 1.12 pre 6
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantVariant
|
||||||
|
(JNIEnv *env, jobject _this, jobject var)
|
||||||
|
{
|
||||||
|
|
||||||
|
VARIANT *vVar = extractVariant(env, var);
|
||||||
|
VARIANT *v = extractVariant(env, _this);
|
||||||
|
|
||||||
|
if (v) {
|
||||||
|
VariantClear(v); // whatever was there before
|
||||||
|
|
||||||
|
V_VT(v) = VT_VARIANT|VT_BYREF;
|
||||||
|
V_VARIANTREF(v) = vVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieves the enclosed variant when they are of type VT_VARIANT
|
||||||
|
* Added 1.12 pre 6
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_getVariantVariant
|
||||||
|
(JNIEnv *env, jobject _this)
|
||||||
|
{
|
||||||
|
|
||||||
|
VARIANT *v = extractVariant(env, _this);
|
||||||
|
if (v) {
|
||||||
|
|
||||||
|
if (V_VT(v) != (VT_VARIANT|VT_BYREF)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Construct a new Variant
|
||||||
|
jclass variantClass = env->FindClass("com/jacob/com/Variant");
|
||||||
|
jmethodID defaultCon = env->GetMethodID(variantClass, "<init>", "()V");
|
||||||
|
jobject newVariant = env->NewObject(variantClass, defaultCon);
|
||||||
|
|
||||||
|
VARIANT *refVar = V_VARIANTREF(v);
|
||||||
|
VARIANT *newV = extractVariant(env, newVariant);
|
||||||
|
|
||||||
|
// we could have made a copy of refV here but we aren't every going to free
|
||||||
|
// it outside of the scope of the enclosing context so we will just used the
|
||||||
|
// enclosed. This relies on the java layer to zero out its ref to this
|
||||||
|
// enclosed variant before the gc can come along and free the memory out from
|
||||||
|
// under this enclosing variant.
|
||||||
|
|
||||||
|
jfieldID jf = env->GetFieldID( variantClass, VARIANT_FLD, "I");
|
||||||
|
env->SetIntField(newVariant, jf, (unsigned int)refVar);
|
||||||
|
|
||||||
|
return newVariant;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -496,6 +496,23 @@ JNIEXPORT jbyteArray JNICALL Java_com_jacob_com_Variant_SerializationWriteToByte
|
|||||||
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_SerializationReadFromBytes
|
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_SerializationReadFromBytes
|
||||||
(JNIEnv *, jobject, jbyteArray);
|
(JNIEnv *, jobject, jbyteArray);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_jacob_com_Variant
|
||||||
|
* Method: putVariantVariant
|
||||||
|
* Signature: (Lcom/jacob/com/Variant;)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_putVariantVariant
|
||||||
|
(JNIEnv *, jobject, jobject);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_jacob_com_Variant
|
||||||
|
* Method: getVariantVariant
|
||||||
|
* Signature: ()Lcom/jacob/com/Variant;
|
||||||
|
*/
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_getVariantVariant
|
||||||
|
(JNIEnv *, jobject);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: com_jacob_com_Variant
|
* Class: com_jacob_com_Variant
|
||||||
* Method: isVariantConsideredNull
|
* Method: isVariantConsideredNull
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ import java.util.Date;
|
|||||||
* between Java and COM. It provides a single class that can handle all data
|
* between Java and COM. It provides a single class that can handle all data
|
||||||
* types.
|
* types.
|
||||||
* <p>
|
* <p>
|
||||||
|
* PROPVARIANT introduces new types so eventually Variant will need to be
|
||||||
|
* upgraded to support PropVariant types.
|
||||||
|
* http://blogs.msdn.com/benkaras/archive/2006/09/13/749962.aspx
|
||||||
|
* <p>
|
||||||
* This object no longer implements Serializable because serialization is broken
|
* This object no longer implements Serializable because serialization is broken
|
||||||
* (and has been since 2000/xp). The underlying
|
* (and has been since 2000/xp). The underlying
|
||||||
* marshalling/unmarshalling code is broken in the JNI layer.
|
* marshalling/unmarshalling code is broken in the JNI layer.
|
||||||
@@ -78,7 +82,7 @@ public class Variant extends JacobObject {
|
|||||||
/** variant's type is short VT_I2*/
|
/** variant's type is short VT_I2*/
|
||||||
public static final short VariantShort = 2;
|
public static final short VariantShort = 2;
|
||||||
|
|
||||||
/** variant's type is int VT_I4*/
|
/** variant's type is int VT_I4, a Long in VC*/
|
||||||
public static final short VariantInt = 3;
|
public static final short VariantInt = 3;
|
||||||
|
|
||||||
/** variant's type is float VT_R4*/
|
/** variant's type is float VT_R4*/
|
||||||
@@ -350,6 +354,72 @@ public class Variant extends JacobObject {
|
|||||||
getvt();
|
getvt();
|
||||||
putVariantStringRef(in);
|
putVariantStringRef(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a variant into this variant making it type VT_VARIANT.
|
||||||
|
* Added 1.12 pre 6
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if inVariant = null
|
||||||
|
* @param in
|
||||||
|
* a variant that is to be referenced by this variant
|
||||||
|
*/
|
||||||
|
public void putVariant(Variant inVariant) {
|
||||||
|
if (inVariant == null) {
|
||||||
|
throw new IllegalArgumentException("Cannot put null in as a variant");
|
||||||
|
} else {
|
||||||
|
putVariantVariant(inVariant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All VariantVariant type variants are BYREF.
|
||||||
|
*
|
||||||
|
* Set the content of this variant to a string (VT_VARIANT|VT_BYREF).
|
||||||
|
*
|
||||||
|
* Added 1.12 pre 6 - VT_VARIANT support is at an alpha level
|
||||||
|
* @param in variant to be wrapped
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private native void putVariantVariant(Variant in);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to get the value from a windows type of VT_VARIANT
|
||||||
|
* or a jacob Variant type of VariantVariant.
|
||||||
|
* Added 1.12 pre 6 - VT_VARIANT support is at an alpha level
|
||||||
|
* @returns Object a java Object that represents the content of the enclosed Variant
|
||||||
|
*/
|
||||||
|
public Object getVariant() {
|
||||||
|
if ((this.getvt() & VariantVariant) == VariantVariant
|
||||||
|
&& (this.getvt() & VariantByref) == VariantByref) {
|
||||||
|
if (JacobObject.isDebugEnabled()){
|
||||||
|
JacobObject.debug("About to call getVariantVariant()");
|
||||||
|
}
|
||||||
|
Variant enclosedVariant = getVariantVariant();
|
||||||
|
Object enclosedVariantAsJava = enclosedVariant.toJavaObject();
|
||||||
|
// zero out the reference to the underlying windows memory so that
|
||||||
|
// it is still only owned in one place by one java object
|
||||||
|
// (this object of type VariantVariant)
|
||||||
|
//enclosedVariant.putEmpty(); // don't know if this would have had side effects
|
||||||
|
if (JacobObject.isDebugEnabled()){
|
||||||
|
JacobObject.debug("Zeroing out enclosed Variant's ref to windows memory");
|
||||||
|
}
|
||||||
|
enclosedVariant.m_pVariant = 0;
|
||||||
|
return enclosedVariantAsJava;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"getVariant() only legal on Variants of type VariantVariant, not "
|
||||||
|
+ this.getvt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the variant type via a native method call.
|
||||||
|
* Added 1.12 pre 6 - VT_VARIANT support is at an alpha level
|
||||||
|
* @return Variant one of the VT_Variant types
|
||||||
|
*/
|
||||||
|
private native Variant getVariantVariant();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the content of this variant as a short
|
* get the content of this variant as a short
|
||||||
* @return short
|
* @return short
|
||||||
@@ -1451,6 +1521,9 @@ public class Variant extends JacobObject {
|
|||||||
putDispatchRef((Dispatch)pValueObject);
|
putDispatchRef((Dispatch)pValueObject);
|
||||||
else
|
else
|
||||||
putDispatch((Dispatch)pValueObject);
|
putDispatch((Dispatch)pValueObject);
|
||||||
|
} else if (pValueObject instanceof Variant){
|
||||||
|
// newly added 1.12-pre6
|
||||||
|
putVariant((Variant)pValueObject);
|
||||||
} else {
|
} else {
|
||||||
// should really throw an illegal argument exception if its an invalid type
|
// should really throw an illegal argument exception if its an invalid type
|
||||||
if (fByRef)
|
if (fByRef)
|
||||||
@@ -1629,12 +1702,13 @@ public class Variant extends JacobObject {
|
|||||||
* <p>
|
* <p>
|
||||||
* Unlike other toXXX() methods, it does not do a type conversion
|
* Unlike other toXXX() methods, it does not do a type conversion
|
||||||
* except for special data types (it shouldn't do any!)
|
* except for special data types (it shouldn't do any!)
|
||||||
*
|
* <p>
|
||||||
|
* Converts Variant.VariantArray types to SafeArrays
|
||||||
* @return Corresponding Java object of the type matching the Variant type.
|
* @return Corresponding Java object of the type matching the Variant type.
|
||||||
* @throws IllegalStateException if no underlying windows data structure
|
* @throws IllegalStateException if no underlying windows data structure
|
||||||
* @throws NotImplementedException if unsupported conversion is requested
|
* @throws NotImplementedException if unsupported conversion is requested
|
||||||
*/
|
*/
|
||||||
protected Object toJavaObject() throws JacobException {
|
public Object toJavaObject() throws JacobException {
|
||||||
Object result = null;
|
Object result = null;
|
||||||
|
|
||||||
short type = this.getvt(); //variant type
|
short type = this.getvt(); //variant type
|
||||||
@@ -1707,8 +1781,11 @@ public class Variant extends JacobObject {
|
|||||||
case Variant.VariantBoolean | Variant.VariantByref: //11
|
case Variant.VariantBoolean | Variant.VariantByref: //11
|
||||||
result = new Boolean(this.getBooleanRef());
|
result = new Boolean(this.getBooleanRef());
|
||||||
break;
|
break;
|
||||||
case Variant.VariantVariant : //12
|
case Variant.VariantVariant : //12 they are always by ref
|
||||||
result = new NotImplementedException("toJavaObject() Not implemented for VariantVariant");
|
result = new NotImplementedException("toJavaObject() Not implemented for VariantVariant without ByRef");
|
||||||
|
break;
|
||||||
|
case Variant.VariantVariant | Variant.VariantByref: //12
|
||||||
|
result = getVariant();
|
||||||
break;
|
break;
|
||||||
case Variant.VariantObject : //13
|
case Variant.VariantObject : //13
|
||||||
result = new NotImplementedException("toJavaObject() Not implemented for VariantObject");
|
result = new NotImplementedException("toJavaObject() Not implemented for VariantObject");
|
||||||
|
|||||||
Reference in New Issue
Block a user