Skip to content

Commit

Permalink
expose variantToObject and have new single invoke0 use it in Dispatch…
Browse files Browse the repository at this point in the history
….cpp
  • Loading branch information
enebo committed Oct 7, 2010
1 parent fbf7e1c commit b17a976
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 0 deletions.
87 changes: 87 additions & 0 deletions jni/Dispatch.cpp
Expand Up @@ -387,6 +387,93 @@ static wchar_t* CreateErrorMsgFromInfo(HRESULT inResult, EXCEPINFO* ioInfo,

#define SETNOPARAMS(dp) SETDISPPARAMS(dp, 0, NULL, 0, NULL)

JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev0
(JNIEnv *env, jclass clazz, jint dispPointer, jstring name, jint dispid,
jint lcid, jint wFlags) {
DISPPARAMS dispparams;
EXCEPINFO excepInfo;

IDispatch *pIDispatch = (IDispatch *) dispPointer;
if (!pIDispatch) return NULL;

int dispID = dispid;
if (name != NULL) {
const char *nm = env->GetStringUTFChars(name, NULL);
HRESULT hr;
if (FAILED(hr = name2ID(pIDispatch, nm, (long *)&dispID, lcid))) {
char buf[1024];
sprintf_s(buf, 1024, "Can't map name to dispid: %s", nm);
ThrowComFail(env, buf, -1);
return NULL;
}
env->ReleaseStringUTFChars(name, nm);
}

VARIANT returnValue;
DISPID dispidPropertyPut = DISPID_PROPERTYPUT;
VariantInit(&returnValue);

// determine how to dispatch
switch (wFlags) {
case DISPATCH_PROPERTYGET: // GET
case DISPATCH_METHOD: // METHOD
case DISPATCH_METHOD|DISPATCH_PROPERTYGET: {
SETDISPPARAMS(dispparams, 0, NULL, 0, NULL);
break;
}
case DISPATCH_PROPERTYPUT:
case DISPATCH_PROPERTYPUTREF: { // jacob-msg 1075 - SF 1053872
SETDISPPARAMS(dispparams, 0, NULL, 1, &dispidPropertyPut);
break;
}
}

HRESULT hr = pIDispatch->Invoke(dispID, IID_NULL,
lcid, (WORD) wFlags, &dispparams, &returnValue, &excepInfo, NULL);

// check for error and display a somewhat verbose error message
if (!SUCCEEDED(hr)) {
// two buffers that may have to be freed later
wchar_t *buf = NULL;
char *dispIdAsName = NULL;
// this method can get called with a name or a dispatch id
// we need to handle both SF 1114159
if (name != NULL){
const char *nm = env->GetStringUTFChars(name, NULL);
buf = CreateErrorMsgFromInfo(hr, &excepInfo, nm);
env->ReleaseStringUTFChars(name, nm);
} else {
dispIdAsName = new char[256];
// get the id string
_itoa_s (dispID, dispIdAsName, 256,10);
//continue on mostly as before
buf = CreateErrorMsgFromInfo(hr,&excepInfo,dispIdAsName);
}

// jacob-msg 3696 - SF 1053866
if(hr == DISP_E_EXCEPTION)
{
if(excepInfo.scode != 0)
{
hr = excepInfo.scode;
}
else
{
hr = _com_error::WCodeToHRESULT(excepInfo.wCode);
}
}

ThrowComFailUnicode(env, buf, hr);
if (buf) delete buf;
if (dispIdAsName) delete dispIdAsName;
return NULL;
}

jobject result = variantToObject(env, &returnValue);
VariantClear(&returnValue);
return result;
}

JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev
(JNIEnv *env, jclass clazz,
jint dispPointer, jstring name, jint dispid,
Expand Down
8 changes: 8 additions & 0 deletions jni/Dispatch.h
Expand Up @@ -65,6 +65,14 @@ JNIEXPORT jint JNICALL Java_com_jacob_com_Dispatch_coCreateInstanceNative
JNIEXPORT jintArray JNICALL Java_com_jacob_com_Dispatch_getIDsOfNames
(JNIEnv *, jclass, jint, jobject, jint, jobjectArray);

/*
* Class: Dispatch
* Method: invokev0
* Signature: (ILjava/lang/String;III[LVariant;[I)LVariant;
*/
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev0
(JNIEnv *, jclass, jint, jstring, jint, jint, jint);

/*
* Class: Dispatch
* Method: invokev
Expand Down
29 changes: 29 additions & 0 deletions jni/Variant.cpp
Expand Up @@ -32,12 +32,14 @@ extern "C"
{

/* Initialized by initializeNative */
jclass BOOLEAN_CLASS = 0;
jclass DISPATCH_CLASS = 0;
jclass VARIANT_CLASS = 0;

jfieldID POINTER_FIELD = 0;
jfieldID VARIANT_TYPE = 0;

jmethodID BOOLEAN_CONSTRUCTOR = 0;
jmethodID DISPATCH_CONSTRUCTOR = 0;
jmethodID VARIANT_CONSTRUCTOR = 0;
jmethodID VARIANT_GETSTRING = 0;
Expand All @@ -53,6 +55,7 @@ jmethodID VARIANT_GETBYTE = 0;
jmethodID VARIANT_GETVARIANT = 0;
jmethodID VARIANT_CREATEDISPATCH = 0;
jmethodID VARIANT_CREATEDATE = 0;
jmethodID VARIANT_CREATEINT = 0;
jobject TRUE_VARIANT = 0;
jobject FALSE_VARIANT = 0;

Expand All @@ -61,12 +64,15 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_initializeNative
// prepare a new return value
VARIANT_CLASS = (jclass) env->NewGlobalRef(env->FindClass("com/jacob/com/Variant"));
DISPATCH_CLASS = (jclass) env->NewGlobalRef(env->FindClass("com/jacob/com/Dispatch"));
BOOLEAN_CLASS = (jclass) env->NewGlobalRef(env->FindClass("java/lang/Boolean"));

jfieldID trueField = env->GetStaticFieldID(VARIANT_CLASS, "VT_TRUE", "Lcom/jacob/com/Variant;");
jfieldID falseField = env->GetStaticFieldID(VARIANT_CLASS, "VT_FALSE", "Lcom/jacob/com/Variant;");
TRUE_VARIANT = env->NewGlobalRef(env->GetStaticObjectField(VARIANT_CLASS, trueField));
FALSE_VARIANT = env->NewGlobalRef(env->GetStaticObjectField(VARIANT_CLASS, falseField));


BOOLEAN_CONSTRUCTOR = env->GetMethodID(BOOLEAN_CLASS, "<init>", "(Z)V");
DISPATCH_CONSTRUCTOR = env->GetMethodID(DISPATCH_CLASS, "<init>", "(I)V");
VARIANT_CONSTRUCTOR = env->GetMethodID(VARIANT_CLASS, "<init>", "(Ljava/lang/Object;S)V");
VARIANT_TYPE = env->GetFieldID(VARIANT_CLASS, "type", "S");
Expand All @@ -84,6 +90,7 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_Variant_initializeNative

VARIANT_CREATEDISPATCH = env->GetStaticMethodID(clazz, "createDispatchVariant", "(I)Lcom/jacob/com/Variant;");
VARIANT_CREATEDATE = env->GetStaticMethodID(clazz, "createDateVariant", "(D)Lcom/jacob/com/Variant;");
VARIANT_CREATEINT = env->GetStaticMethodID(clazz, "createIntVariant", "(I)Lcom/jacob/com/Variant;");

return NULL;
}
Expand All @@ -102,12 +109,20 @@ jobject createBooleanVariant(JNIEnv *env, jboolean value) {
return value == 0 ? FALSE_VARIANT : TRUE_VARIANT;
}

jobject createIntVariant(JNIEnv *env, jint value) {
return env->CallStaticObjectMethod(VARIANT_CLASS, VARIANT_CREATEINT, value);
}

jobject createBoxedByte(JNIEnv *env, jbyte value) {
jclass clazz = env->FindClass("java/lang/Byte");
jmethodID constructor = env->GetMethodID(clazz, "<init>", "(B)V");
return env->NewObject(clazz, constructor, value);
}

jobject createBoxedBoolean(JNIEnv *env, jboolean value) {
return env->NewObject(BOOLEAN_CLASS, BOOLEAN_CONSTRUCTOR, value);
}

jobject createBoxedDouble(JNIEnv *env, jdouble value) {
jclass clazz = env->FindClass("java/lang/Double");
jmethodID constructor = env->GetMethodID(clazz, "<init>", "(D)V");
Expand Down Expand Up @@ -140,6 +155,12 @@ jobject createCurrency(JNIEnv *env, CY cy) {
return env->NewObject(clazz, constructor, jl);
}

jobject createDate(JNIEnv *env, jdouble date) {
jclass clazz = env->FindClass("com/jacob/com/DateUtilities");
jmethodID constructor = env->GetStaticMethodID(clazz, "convertWindowsTimeToDate", "(D)Ljava/util/Date;");
return env->CallStaticObjectMethod(clazz, constructor, date);
}

jobject createDispatch(JNIEnv *env, IDispatch* value) {
if (value) value->AddRef();

Expand Down Expand Up @@ -178,10 +199,16 @@ jobject variantToObject(JNIEnv *env, VARIANT* v) {
return createBoxedDouble(env, (jdouble) V_R8(v));
case VT_R8|VT_BYREF:
return createBoxedDouble(env, (jdouble) *V_R8REF(v));
case VT_BOOL:
return createBoxedBoolean(env, (jboolean) V_BOOL(v));
case VT_BOOL|VT_BYREF:
return createBoxedBoolean(env, (jboolean) *V_BOOLREF(v));
case VT_CY:
return createCurrency(env, V_CY(v));
case VT_CY|VT_BYREF:
return createCurrency(env, *V_CYREF(v));
case VT_DATE:
return createDate(env, (jdouble) V_DATE(v));
case VT_BSTR:
return createString(env, (BSTR) V_BSTR(v));
case VT_BSTR|VT_BYREF:
Expand Down Expand Up @@ -225,6 +252,8 @@ jobject createVariant(JNIEnv *env, VARIANT* v) {
return createBooleanVariant(env, (jboolean) *V_BOOLREF(v));
case VT_DATE:
return createDateVariant(env, (jdouble) V_DATE(v));
case VT_I4:
return createIntVariant(env, (jint) V_I4(v));
case VT_DATE|VT_BYREF:
return createDateVariant(env, (jdouble) *V_DATEREF(v));
case VT_DISPATCH:
Expand Down
1 change: 1 addition & 0 deletions jni/util.h
Expand Up @@ -33,6 +33,7 @@ extern "C" {
jobject createVariant(JNIEnv *env, VARIANT* variant);
void populateVariant(JNIEnv *env, jobject javaVariant, VARIANT* variant);
VARIANT *extractVariant(JNIEnv *env, jobject arg);
jobject variantToObject(JNIEnv *env, VARIANT* variant);

void ThrowComFail(JNIEnv *env, const char* desc, jint hr);
void ThrowComFailUnicode(JNIEnv *env, const wchar_t* desc, jint hr);
Expand Down

0 comments on commit b17a976

Please sign in to comment.