Skip to content

Commit

Permalink
SF 1650134 - preliminary VT_Variant support VariantVariant
Browse files Browse the repository at this point in the history
  • Loading branch information
clay_shooter committed Apr 18, 2007
1 parent a7686ed commit 3a32be8
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 6 deletions.
8 changes: 7 additions & 1 deletion jacob/docs/ReleaseNotes.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,13 @@ <h3>Tracked Changes</h3>
</tr>
<tr>
<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>
Expand Down
63 changes: 63 additions & 0 deletions jacob/jni/Variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,4 +1013,67 @@ JNIEXPORT jboolean JNICALL Java_com_jacob_com_Variant_isVariantConsideredNull
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;

}


}
17 changes: 17 additions & 0 deletions jacob/jni/Variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,23 @@ JNIEXPORT jbyteArray JNICALL Java_com_jacob_com_Variant_SerializationWriteToByte
JNIEXPORT void JNICALL Java_com_jacob_com_Variant_SerializationReadFromBytes
(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
* Method: isVariantConsideredNull
Expand Down
87 changes: 82 additions & 5 deletions jacob/src/com/jacob/com/Variant.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
* between Java and COM. It provides a single class that can handle all data
* types.
* <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
* (and has been since 2000/xp). The underlying
* marshalling/unmarshalling code is broken in the JNI layer.
Expand Down Expand Up @@ -78,7 +82,7 @@ public class Variant extends JacobObject {
/** variant's type is short VT_I2*/
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;

/** variant's type is float VT_R4*/
Expand Down Expand Up @@ -350,6 +354,72 @@ public void putStringRef(String in){
getvt();
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
* @return short
Expand Down Expand Up @@ -1451,6 +1521,9 @@ public Variant(Object pValueObject, boolean fByRef) {
putDispatchRef((Dispatch)pValueObject);
else
putDispatch((Dispatch)pValueObject);
} else if (pValueObject instanceof Variant){
// newly added 1.12-pre6
putVariant((Variant)pValueObject);
} else {
// should really throw an illegal argument exception if its an invalid type
if (fByRef)
Expand Down Expand Up @@ -1629,12 +1702,13 @@ public boolean isNull(){
* <p>
* Unlike other toXXX() methods, it does not do a type conversion
* 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.
* @throws IllegalStateException if no underlying windows data structure
* @throws NotImplementedException if unsupported conversion is requested
*/
protected Object toJavaObject() throws JacobException {
public Object toJavaObject() throws JacobException {
Object result = null;

short type = this.getvt(); //variant type
Expand Down Expand Up @@ -1707,8 +1781,11 @@ protected Object toJavaObject() throws JacobException {
case Variant.VariantBoolean | Variant.VariantByref: //11
result = new Boolean(this.getBooleanRef());
break;
case Variant.VariantVariant : //12
result = new NotImplementedException("toJavaObject() Not implemented for VariantVariant");
case Variant.VariantVariant : //12 they are always by ref
result = new NotImplementedException("toJavaObject() Not implemented for VariantVariant without ByRef");
break;
case Variant.VariantVariant | Variant.VariantByref: //12
result = getVariant();
break;
case Variant.VariantObject : //13
result = new NotImplementedException("toJavaObject() Not implemented for VariantObject");
Expand Down

0 comments on commit 3a32be8

Please sign in to comment.