219 lines
6.0 KiB
C
219 lines
6.0 KiB
C
/*****************************************************************************
|
|
* _ _ ____ _
|
|
* Project ___| | | | _ \| |
|
|
* / __| | | | |_) | |
|
|
* | (__| |_| | _ <| |___
|
|
* \___|\___/|_| \_\_____|
|
|
*
|
|
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
*
|
|
* In order to be useful for every potential user, curl and libcurl are
|
|
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
|
*
|
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
|
* copies of the Software, and permit persons to whom the Software is
|
|
* furnished to do so, under the terms of the MPL or the MIT/X-derivate
|
|
* licenses. You may pick one of these licenses.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
* $Id$
|
|
*****************************************************************************/
|
|
|
|
#include <curl/curl.h> /* libcurl header */
|
|
#include "CurlGlue.h" /* the JNI-generated glue header file */
|
|
|
|
/*
|
|
* This is a private struct allocated for every 'CurlGlue' object.
|
|
*/
|
|
struct javacurl {
|
|
void *libcurl;
|
|
void *whatever;
|
|
struct writecallback {
|
|
jmethodID mid;
|
|
JNIEnv *java;
|
|
jclass cls; /* global reference */
|
|
jobject object;
|
|
} write;
|
|
};
|
|
|
|
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1init(JNIEnv *java,
|
|
jobject myself)
|
|
{
|
|
void *libhandle;
|
|
struct javacurl *jcurl=NULL;
|
|
|
|
libhandle = curl_easy_init();
|
|
|
|
if(libhandle) {
|
|
jcurl=(struct javacurl *)malloc(sizeof(struct javacurl));
|
|
if(jcurl) {
|
|
memset(jcurl, 0, sizeof(struct javacurl));
|
|
jcurl->libcurl = libhandle;
|
|
|
|
}
|
|
else {
|
|
curl_easy_cleanup(libhandle);
|
|
return (jint)0;
|
|
}
|
|
}
|
|
|
|
return (jint) jcurl; /* nasty typecast */
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_CurlGlue_jni_1cleanup(JNIEnv *java,
|
|
jobject myself,
|
|
jint jcurl)
|
|
{
|
|
|
|
struct javacurl *curl = (struct javacurl*)jcurl;
|
|
|
|
if(curl->write.cls) {
|
|
/* a global reference we must delete */
|
|
(*java)->DeleteGlobalRef(java, curl->write.cls);
|
|
(*java)->DeleteGlobalRef(java, curl->write.object);
|
|
}
|
|
|
|
curl_easy_cleanup(curl->libcurl); /* cleanup libcurl stuff */
|
|
|
|
free((void *)curl); /* free the struct too */
|
|
}
|
|
|
|
/*
|
|
* setopt() int + string
|
|
*/
|
|
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILjava_lang_String_2
|
|
(JNIEnv *java, jobject myself, jint jcurl, jint option, jstring value)
|
|
{
|
|
/* get the actual string C-style */
|
|
const char *str = (*java)->GetStringUTFChars(java, value, 0);
|
|
|
|
void *handle = (void *)((struct javacurl*)jcurl)->libcurl;
|
|
|
|
puts("setopt int + string");
|
|
|
|
return (jint)curl_easy_setopt(handle, (CURLoption)option, str);
|
|
|
|
}
|
|
|
|
/*
|
|
* setopt() int + int
|
|
*/
|
|
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__III
|
|
(JNIEnv *java, jobject myself, jint jcurl, jint option, jint value)
|
|
{
|
|
void *handle = (void *)((struct javacurl*)jcurl)->libcurl;
|
|
CURLoption opt = (CURLoption)option;
|
|
|
|
puts("setopt int + int");
|
|
|
|
switch(opt) {
|
|
case CURLOPT_FILE:
|
|
/* silently ignored, we don't need user-specified callback data when
|
|
we have an object, and besides the CURLOPT_FILE is not exported
|
|
to the java interface */
|
|
return 0;
|
|
}
|
|
|
|
return (jint)curl_easy_setopt(handle, (CURLoption)option, value);
|
|
}
|
|
|
|
static int javacurl_write_callback(void *ptr,
|
|
size_t size,
|
|
size_t nmemb,
|
|
FILE *stream)
|
|
{
|
|
struct javacurl *curl = (struct javacurl *)stream;
|
|
size_t realsize = size * nmemb;
|
|
JNIEnv *java = curl->write.java;
|
|
jbyteArray jb=NULL;
|
|
int ret=0;
|
|
|
|
fprintf(stderr, "%d bytes data received in callback:\n"
|
|
"ptr=%p, java=%p cls=%p\n",
|
|
realsize, curl, java, curl->write.cls);
|
|
|
|
jb=(*java)->NewByteArray(java, realsize);
|
|
(*java)->SetByteArrayRegion(java, jb, 0,
|
|
realsize, (jbyte *)ptr);
|
|
|
|
fprintf(stderr, "created byte-array\n");
|
|
|
|
ret = (*java)->CallIntMethod(java,
|
|
curl->write.object,
|
|
curl->write.mid,
|
|
jb);
|
|
|
|
fprintf(stderr, "java-method returned %d\n", ret);
|
|
|
|
return realsize;
|
|
}
|
|
|
|
/*
|
|
* setopt() int + object
|
|
*/
|
|
|
|
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILCurlWrite_2
|
|
(JNIEnv *java, jobject myself, jint jcurl, jint option, jobject object)
|
|
{
|
|
jclass cls_local = (*java)->GetObjectClass(java, object);
|
|
jmethodID mid;
|
|
struct javacurl *curl = (struct javacurl *)jcurl;
|
|
jclass cls;
|
|
jobject obj_global;
|
|
|
|
switch(option) {
|
|
case CURLOPT_WRITEFUNCTION:
|
|
/* this makes a reference that'll be alive until we kill it! */
|
|
cls = (*java)->NewGlobalRef(java, cls_local);
|
|
|
|
printf("setopt int + object, option = %d cls= %p\n",
|
|
option, cls);
|
|
|
|
if(!cls) {
|
|
puts("couldn't make local reference global");
|
|
return 0;
|
|
}
|
|
|
|
/* this is the write callback */
|
|
mid = (*java)->GetMethodID(java, cls, "handleString", "([B)I");
|
|
if(!mid) {
|
|
puts("no callback method found");
|
|
return 0;
|
|
}
|
|
|
|
obj_global = (*java)->NewGlobalRef(java, object);
|
|
|
|
curl->write.mid = mid;
|
|
curl->write.cls = cls;
|
|
curl->write.object = obj_global;
|
|
/*curl->write.java = java; stored on perform */
|
|
|
|
fprintf(stderr, "setopt write callback and write file pointer %p, java = %p\n",
|
|
curl, java);
|
|
|
|
curl_easy_setopt(curl->libcurl, CURLOPT_WRITEFUNCTION,
|
|
javacurl_write_callback);
|
|
curl_easy_setopt(curl->libcurl, CURLOPT_FILE,
|
|
curl);
|
|
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_CurlGlue_getinfo
|
|
(JNIEnv *java, jobject value)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1perform
|
|
(JNIEnv *java, jobject myself, jint jcurl)
|
|
{
|
|
struct javacurl *curl=(struct javacurl*)jcurl;
|
|
curl->write.java = java;
|
|
return (jint)curl_easy_perform(curl->libcurl);
|
|
}
|