/*
** Author(s): Miguel Calejo, Vera Pereira
** Contact: interprolog@declarativa.com, http://www.declarativa.com, http://www.xsb.com
** Copyright (C) XSB Inc., USA, 2001
** Use and distribution, without any warranties, under the terms of the
** GNU Library General Public License, readable in http://www.fsf.org/copyleft/lgpl.html
*/
/* This file provides the implementation for the native methods of NativeEngine.java,
as well as the XSB Prolog built-in used by InterProlog */
#include <jni.h>
#include "com_xsb_interprolog_NativeEngine.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
// for interrupts:
#include "sig_xsb.h"
#include <signal.h>
// extern int *asynint_ptr;
extern void keyint_proc(int);
/* The following include is necessary to get the macros and routine
headers */
#include "xsb_config.h"
#include "auxlry.h"
#include "cell_xsb.h"
#include "memory_xsb.h"
#include "register.h"
#include "flags_xsb.h"
#include "heap_xsb.h"
#include "subp.h"
#include "cinterf.h"
#include "error_xsb.h"
#include "loader_xsb.h"
#include "cinterf.h"
JNIEnv *theEnv;
jobject theObj;
jboolean debug;
JNIEXPORT jbyteArray JNICALL
Java_com_xsb_interprolog_NativeEngine_get_1bytes
(JNIEnv *env, jobject obj) {
int i = 1;
jbyteArray bytes;
jsize size = p2p_arg(reg_term(1), 3);
int newHead, newTail;
jbyte *b;
if (size == -1) {
xsb_close_query();
return NULL;
}
b = (jbyte *) malloc(size);
newHead = p2p_car(p2p_arg(reg_term(1), 2));
newTail = p2p_cdr(p2p_arg(reg_term(1), 2));
b[i-1] = p2c_int(newHead);
while(is_nil(newTail) == 0) {
newHead = p2p_car(newTail);
b[i] = p2c_int(newHead);
newTail = p2p_cdr(newTail);
i++;
}
xsb_close_query();
bytes = (*env)->NewByteArray(env, size);
(*env)->SetByteArrayRegion(env, bytes, 0, size, b);
free(b);
return bytes;
}
JNIEXPORT jint JNICALL
Java_com_xsb_interprolog_NativeEngine_put_1bytes
(JNIEnv *env, jobject obj, jbyteArray b, jint size, jint args, jstring jStr) {
int head, tail, newVar, newVar2;
int i = 1;
int rc;
//long T0 = clock(), T1, T2, T3, T4;
jbyte *bytes; char *argString;
//printf("C:Entering put_bytes - %d mS",T0);
check_glstack_overflow(3, pcreg, (size+4)*8*sizeof(Cell)) ;
bytes = (*env)->GetByteArrayElements(env, b, 0);
//T1 = clock() - T0;
//printf("C:got bytes array - %d mS",T1);
argString = (*env)->GetStringUTFChars(env, jStr, 0);
c2p_functor(argString, args, reg_term(1));
c2p_list(p2p_arg(reg_term(1),1));
if (args == 3) {
newVar = p2p_arg(reg_term(1),2);
newVar = p2p_new();
newVar2 = p2p_arg(reg_term(1),3);
newVar2 = p2p_new();
}
head = p2p_car(p2p_arg(reg_term(1),1));
tail = p2p_cdr(p2p_arg(reg_term(1),1));
if (bytes[0]<0)
c2p_int((bytes[0]+256), head);
else
c2p_int(bytes[0], head);
while (i < size) {
c2p_list(tail);
head = p2p_car(tail);
tail = p2p_cdr(tail);
if (bytes[i]<0)
c2p_int((bytes[i]+256), head);
else
c2p_int(bytes[i], head);
i++;
}
c2p_nil(tail);
//T2 = clock() - T0 ;
//printf("C:constructed Prolog list - %d mS",T2);
theEnv = env;
theObj = obj;
rc = xsb_query();
//T3 = clock() - T0;
//printf("C:Returned from Prolog - %d mS",T3);
(*env)->ReleaseByteArrayElements(env, b, bytes, 0);
(*env)->ReleaseStringUTFChars(env,jStr, argString);
//T4 = clock() - T0;
//printf("C:leaving put_bytes - %d mS\n",T4);
return rc;
}
JNIEXPORT jint JNICALL
Java_com_xsb_interprolog_NativeEngine_xsb_1close_1query
(JNIEnv *env , jobject obj) {
return xsb_close_query();
}
JNIEXPORT jint JNICALL
Java_com_xsb_interprolog_NativeEngine_xsb_1command_1string
(JNIEnv *env, jobject obj, jstring jCommandString) {
int rcode;
char *CommandString = (*env)->GetStringUTFChars(env, jCommandString, 0);
theEnv = env;
theObj = obj;
rcode=xsb_command_string(CommandString);
(*env)->ReleaseStringUTFChars(env,jCommandString, CommandString);
return rcode;
}
JNIEXPORT jint JNICALL
Java_com_xsb_interprolog_NativeEngine_xsb_1init_1internal
(JNIEnv *env, jobject obj, jstring jXSBPath) {
int rcode;
int myargc=2;
char * myargv[2];
char *XSBPath = (*env)->GetStringUTFChars(env, jXSBPath, 0);
if (debug==JNI_TRUE) printf("Entering Java_com_xsb_interprolog_NativeEngine_xsb_1init_1internal\n");
myargv[0] = XSBPath;
myargv[1]="-n";
rcode=xsb_init(myargc,myargv);
(*env)->ReleaseStringUTFChars(env,jXSBPath, XSBPath);
if (debug==JNI_TRUE) printf("Exiting Java_com_xsb_interprolog_NativeEngine_xsb_1init_1internal\n");
return rcode;
}
JNIEXPORT void JNICALL
Java_com_xsb_interprolog_NativeEngine_xsb_1interrupt (JNIEnv *env, jobject obj){
/* Do XSB's "interrupt" thing, by simulating a ctrl-C: */
// cf. keyint_proc(SIGINT) in subp.c;
// *asynint_ptr |= KEYINT_MARK;
keyint_proc(SIGINT);
}
JNIEXPORT void JNICALL Java_com_xsb_interprolog_NativeEngine_xsb_1setDebug
(JNIEnv * env, jobject obj, jboolean d){
debug = d;
}
// the XSB Prolog built-in used in interprolog.P
// arguments: +length, +byte list, -new byte list
xsbBool interprolog_callback() {
JNIEnv *env = theEnv;
jobject obj = theObj;
jclass cls;
jmethodID mid;
int i = 1, size, newHead, newTail;
jbyte *b;
jbyteArray newBytes, bytes;
cls = (*env)->GetObjectClass(env, obj);
if (cls == NULL) {
printf("Could not find the class!\n");
return 0;
}
//printf("Got the class\n");
mid = (*env)->GetMethodID(env, cls, "callback", "([B)[B");
if (mid == NULL) {
printf("Could not find the method!\n");
return 0;
}
//printf("Got the method\n");
size = p2c_int(reg_term(1));
b = (jbyte *) malloc(size);
newHead = p2p_car(reg_term(2));
newTail = p2p_cdr(reg_term(2));
b[i-1] = p2c_int(newHead);
while(is_nil(newTail) == 0) {
newHead = p2p_car(newTail);
b[i] = p2c_int(newHead);
newTail = p2p_cdr(newTail);
i++;
}
bytes = (*env)->NewByteArray(env, size);
(*env)->SetByteArrayRegion(env, bytes, 0, size, b);
// Calls the method with bytes, expecting the return in newBytes
newBytes = (*env)->CallObjectMethod(env, obj, mid, bytes);
size = (*env)->GetArrayLength(env, newBytes);
b = (*env)->GetByteArrayElements(env, newBytes, 0);
check_glstack_overflow(3, pcreg, size*8*sizeof(Cell)) ;
c2p_list(reg_term(3));
newHead = p2p_car(reg_term(3));
newTail = p2p_cdr(reg_term(3));
if (b[0]<0)
c2p_int((b[0]+256), newHead);
else
c2p_int(b[0], newHead);
i = 1;
while (i < size) {
c2p_list(newTail);
newHead = p2p_car(newTail);
newTail = p2p_cdr(newTail);
if (b[i]<0)
c2p_int((b[i]+256), newHead);
else
c2p_int(b[i], newHead);
i++;
}
c2p_nil(newTail);
return 1;
}
syntax highlighted by Code2HTML, v. 0.9.1