--- a +++ b/trunk/php-java-bridge/proxyenv.c @@ -0,0 +1,307 @@ +/*-*- mode: C; tab-width:4 -*-*/ + +#include <stdarg.h> +#include <assert.h> +#include <errno.h> + +#include "protocol.h" + +static void swrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { + int n = fwrite(ptr, size, nmemb, stream); + //printf("write char:.:%d\n", (unsigned int) ((char*)ptr)[0]); + assert(n==nmemb); +} +static void sread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + int n = fread(ptr, size, nmemb, stream); + //printf("read char:.:%d\n", (unsigned int) ((char*)ptr)[0]); + assert(n==nmemb); +} +static void id(proxyenv *env, char id) { + swrite(&id, sizeof id, 1, (*env)->peer); +} + + +/* + * The following Invoke, CreateObject, GetSetProp and LastException methods start everything + */ +static void do_invoke(proxyenv *env, jobject php_reflect, jmethodID invoke, jobject obj, jstring method, jobjectArray array, jlong result) { + swrite(&php_reflect, sizeof php_reflect, 1, (*env)->peer); + swrite(&invoke, sizeof invoke, 1, (*env)->peer); + swrite(&obj, sizeof obj, 1, (*env)->peer); + swrite(&method, sizeof method, 1, (*env)->peer); + swrite(&array, sizeof array, 1, (*env)->peer); + swrite(&result, sizeof result, 1, (*env)->peer); + (*env)->handle_request(env); +} +static void Invoke(proxyenv *env, jobject php_reflect, jmethodID invoke, jobject obj, jstring method, jobjectArray array, jlong result) { + id(env, INVOKE); + do_invoke(env, php_reflect, invoke, obj, method, array, result); +} + +static void LastException(proxyenv *env, jobject php_reflect, jmethodID lastEx, jlong result) { + id(env, LASTEXCEPTION); + swrite(&php_reflect, sizeof php_reflect, 1, (*env)->peer); + swrite(&lastEx, sizeof lastEx, 1, (*env)->peer); + swrite(&result, sizeof result, 1, (*env)->peer); + (*env)->handle_request(env); +} +static void CreateObject(proxyenv *env, jobject php_reflect, jmethodID invoke, jstring method, jobjectArray array, jlong result) { + id(env, CREATEOBJECT); + swrite(&php_reflect, sizeof php_reflect, 1, (*env)->peer); + swrite(&invoke, sizeof invoke, 1, (*env)->peer); + swrite(&method, sizeof method, 1, (*env)->peer); + swrite(&array, sizeof array, 1, (*env)->peer); + swrite(&result, sizeof result, 1, (*env)->peer); + (*env)->handle_request(env); +} + +static void GetSetProp(proxyenv *env, jobject php_reflect, jmethodID gsp, jobject obj, jstring propName, jobjectArray value, jlong result) { + id(env, GETSETPROP); + do_invoke(env, php_reflect, gsp, obj, propName, value, result); +} + + + +static jobject AllocObject (proxyenv *env, jclass clazz) { + jobject result; + id(env, ALLOCOBJECT); + swrite(&clazz, sizeof clazz, 1, (*env)->peer); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static jobject CallObjectMethod (short count, proxyenv *env, jobject obj, jmethodID methodID, ...) { + va_list args; + jvalue arg; + jobject result; + id(env, CALLOBJECTMETHOD); + swrite(&count, sizeof count, 1, (*env)->peer); + swrite(&obj, sizeof obj, 1, (*env)->peer); + swrite(&methodID, sizeof methodID, 1, (*env)->peer); + va_start(args, methodID); + while(count--) { + arg=va_arg(args,jvalue ); + swrite(&arg, sizeof arg, 1, (*env)->peer); + } + va_end(args); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static void CallVoidMethod (short count, proxyenv *env, jobject obj, jmethodID methodID, ...) { + va_list args; + jvalue arg; + jobject result; + id(env, CALLVOIDMETHOD); + swrite(&count, sizeof count, 1, (*env)->peer); + swrite(&obj, sizeof obj, 1, (*env)->peer); + swrite(&methodID, sizeof methodID, 1, (*env)->peer); + va_start(args, methodID); + while(count--) { + arg=va_arg(args, jvalue); + swrite(&arg, sizeof arg, 1, (*env)->peer); + } + va_end(args); +} +static void DeleteGlobalRef (proxyenv *env, jobject gref) { + id(env, DELETEGLOBALREF); + swrite(&gref, sizeof gref, 1, (*env)->peer); +} +static void DeleteLocalRef (proxyenv *env, jobject obj) { + id(env, DELETELOCALREF); + swrite(&obj, sizeof obj, 1, (*env)->peer); +} +static void ExceptionClear (proxyenv *env) { + id(env, EXCEPTIONCLEAR); +} +static jthrowable ExceptionOccurred (proxyenv *env) { + jthrowable result; + id(env, EXCEPTIONOCCURRED); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static jclass FindClass (proxyenv *env, const char *name) { + short len=strlen(name); + jclass clazz; + id(env, FINDCLASS); + swrite(&len, sizeof len, 1, (*env)->peer); + swrite(name, sizeof*name, len, (*env)->peer); + sread(&clazz, sizeof clazz, 1, (*env)->peer); + return clazz; +} +static jsize GetArrayLength (proxyenv *env, jarray array) { + jsize result; + id(env, GETARRAYLENGTH); + swrite(&array, sizeof array, 1, (*env)->peer); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static jbyte *GetByteArrayElements (proxyenv *env, jbyteArray array, jboolean *isCopy) { + short count; + jboolean dummy; + jbyte *result; + id(env, GETBYTEARRAYELEMENTS); + swrite(&array, sizeof array, 1, (*env)->peer); + sread(&dummy, sizeof dummy, 1, (*env)->peer); + sread(&count, sizeof count, 1, (*env)->peer); + result=(jbyte*)calloc(count, sizeof*result); + assert(result); + sread(result, sizeof*result, count, (*env)->peer); + assert(isCopy); + if(isCopy) *isCopy=dummy; + swrite(&result, sizeof result, 1, (*env)->peer); + return result; +} +static jmethodID GetMethodID (proxyenv *env, jclass clazz, const char *name, const char *sig) { + jmethodID mid; + short len; + id(env, GETMETHODID); + swrite(&clazz, sizeof clazz, 1, (*env)->peer); + len=strlen(name); + swrite(&len, sizeof len, 1, (*env)->peer); + swrite(name, sizeof*name, len, (*env)->peer); + len=strlen(sig); + swrite(&len, sizeof len, 1, (*env)->peer); + swrite(sig, sizeof*sig, len, (*env)->peer); + sread(&mid, sizeof mid, 1, (*env)->peer); + return mid; +} +static jclass GetObjectClass (proxyenv *env, jobject obj) { + jclass result; + id(env, GETOBJECTCLASS); + swrite(&obj, sizeof obj, 1, (*env)->peer); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static const char* GetStringUTFChars (proxyenv *env, jstring str, jboolean *isCopy) { + short count; + char *result; + jboolean dummy; + id(env, GETSTRINGUTFCHARS); + swrite(&str, sizeof str, 1, (*env)->peer); + sread(&dummy, sizeof dummy, 1, (*env)->peer); + sread(&count, sizeof count, 1, (*env)->peer); + result=(char*)malloc(count+1); + assert(result); + sread(result, sizeof*result, count, (*env)->peer); + result[count]=0; + assert(isCopy); + if(isCopy) *isCopy=dummy; + swrite(&result, sizeof result, 1, (*env)->peer); + return result; +} +static jbyteArray NewByteArray (proxyenv *env, jsize len) { + jbyteArray result; + id(env, NEWBYTEARRAY); + swrite(&len, sizeof len, 1, (*env)->peer); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static jobject NewGlobalRef (proxyenv *env, jobject lobj) { + jobject result; + id(env, NEWGLOBALREF); + swrite(&lobj, sizeof lobj, 1, (*env)->peer); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static jobject NewObject (short count, proxyenv *env, jclass clazz, jmethodID methodID, ...) { + va_list args; + jvalue arg; + jobject result; + id(env, NEWOBJECT); + swrite(&count, sizeof count, 1, (*env)->peer); + swrite(&clazz, sizeof clazz, 1, (*env)->peer); + swrite(&methodID, sizeof methodID, 1, (*env)->peer); + va_start(args, methodID); + while(count--) { + arg=va_arg(args, jvalue); + swrite(&arg, sizeof arg, 1, (*env)->peer); + } + va_end(args); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static jobjectArray NewObjectArray (proxyenv *env, jsize len, jclass clazz, jobject init) { + jobjectArray result; + id(env, NEWOBJECTARRAY); + swrite(&len, sizeof len, 1, (*env)->peer); + swrite(&clazz, sizeof clazz, 1, (*env)->peer); + swrite(&init, sizeof init, 1, (*env)->peer); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static jstring NewStringUTF (proxyenv *env, const char *utf) { + jstring result; + short length=strlen(utf); + id(env, NEWSTRINGUTF); + swrite(&length, sizeof length, 1, (*env)->peer); + swrite(utf, sizeof*utf, length, (*env)->peer); + sread(&result, sizeof result, 1, (*env)->peer); + return result; +} +static void ReleaseByteArrayElements (proxyenv *env, jbyteArray array, jbyte *elems, jint mode) { + short count; + id(env, RELEASEBYTEARRAYELEMENTS); + swrite(&array, sizeof array, 1, (*env)->peer); + swrite(&elems, sizeof elems, 1, (*env)->peer); + swrite(&mode, sizeof mode, 1, (*env)->peer); + assert(!mode); + free(elems); +} +static void ReleaseStringUTFChars (proxyenv *env, jstring array, const char*elems) { + short count; + id(env, RELEASESTRINGUTFCHARS); + swrite(&array, sizeof array, 1, (*env)->peer); + swrite(&elems, sizeof elems, 1, (*env)->peer); + free(elems); +} +static void SetByteArrayRegion (proxyenv *env, jbyteArray array, jsize start, jsize len, jbyte *buf) { + id(env, SETBYTEARRAYREGION); + swrite(&array, sizeof array, 1, (*env)->peer); + swrite(&start, sizeof start, 1, (*env)->peer); + swrite(&len, sizeof len, 1, (*env)->peer); + swrite(buf, sizeof*buf, len, (*env)->peer); +} +static void SetObjectArrayElement (proxyenv *env, jobjectArray array, jsize index, jobject val) { + id(env, SETOBJECTARRAYELEMENT); + swrite(&array, sizeof array, 1, (*env)->peer); + swrite(&index, sizeof index, 1, (*env)->peer); + swrite(&val, sizeof val, 1, (*env)->peer); +} + + +proxyenv *java_createSecureEnvironment(FILE *peer, int (*handle_request)(proxyenv *env)) { + proxyenv *env; + env=(proxyenv*)malloc(sizeof *env); + *env=(proxyenv)calloc(1, sizeof **env); + + (*env)->peer = peer; + (*env)->handle_request = handle_request; + + (*env)->LastException=LastException; + (*env)->GetSetProp=GetSetProp; + (*env)->Invoke=Invoke; + (*env)->CreateObject=CreateObject; + (*env)->AllocObject=AllocObject; + (*env)->CallObjectMethod=CallObjectMethod; + (*env)->CallVoidMethod=CallVoidMethod; + (*env)->DeleteGlobalRef=DeleteGlobalRef; + (*env)->DeleteLocalRef=DeleteLocalRef; + (*env)->ExceptionClear=ExceptionClear; + (*env)->ExceptionOccurred=ExceptionOccurred; + (*env)->FindClass=FindClass; + (*env)->GetArrayLength=GetArrayLength; + (*env)->GetByteArrayElements=GetByteArrayElements; + (*env)->GetMethodID=GetMethodID; + (*env)->GetObjectClass=GetObjectClass; + (*env)->GetStringUTFChars=GetStringUTFChars; + (*env)->NewByteArray=NewByteArray; + (*env)->NewGlobalRef=NewGlobalRef; + (*env)->NewObject=NewObject; + (*env)->NewObjectArray=NewObjectArray; + (*env)->NewStringUTF=NewStringUTF; + (*env)->ReleaseByteArrayElements=ReleaseByteArrayElements; + (*env)->ReleaseStringUTFChars=ReleaseStringUTFChars; + (*env)->SetByteArrayRegion=SetByteArrayRegion; + (*env)->SetObjectArrayElement=SetObjectArrayElement; + + return env; +}