1 /*
2  * Copyright (C) 2008 - 2013 Vivien Malerba <malerba@gnome-db.org>
3  * Copyright (C) 2010 David King <davidk@openismus.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA  02110-1301, USA.
19  */
20 
21 #include "GdaInputStream.h"
main(int,char **)22 #include "jni-wrapper.h"
23 #include <libgda/libgda.h>
24 #include <libgda/gda-blob-op.h>
25 #include <glib/gi18n-lib.h>
26 
27 jclass GdaInputStream__class = NULL;
28 
29 JNIEXPORT void
30 JNICALL Java_GdaInputStream_initIDs (JNIEnv *env, jclass klass)
31 {
32 	GdaInputStream__class = (*env)->NewGlobalRef (env, klass);
33 }
34 
35 JNIEXPORT jintArray
36 JNICALL Java_GdaInputStream_readData (JNIEnv *jenv, G_GNUC_UNUSED jobject obj,
37 				      jlong gda_blob_pointer, jlong offset, jlong size)
38 {
39 	GdaBlob *blob = (GdaBlob*) jni_jlong_to_cpointer (gda_blob_pointer);
40 	jintArray jdata;
41 	if (!blob) {
42 		jclass cls;
43 		cls = (*jenv)->FindClass (jenv, "java/lang/IllegalArgumentException");
44 		if (!cls) {
45 			/* Unable to find the exception class */
46 			return NULL;
47 		}
48 		(*jenv)->ThrowNew (jenv, cls, _("Invalid argument: NULL"));
49 		return NULL;
50 	}
51 
52 	guchar *raw_data;
53 	jint *data;
54 	GdaBlob *nblob = NULL;
55 	gint real_size;
56 	if (blob->op) {
57 		nblob = g_new0 (GdaBlob, 1);
58 		gda_blob_set_op (nblob, blob->op);
59 		real_size =  gda_blob_op_read (nblob->op, nblob, offset, size);
60 		if (real_size < 0) {
61 			/* throw an exception */
62 			jclass cls;
63 			cls = (*jenv)->FindClass (jenv, "java/sql/SQLException");
64 			if (!cls) {
65 				/* Unable to find the exception class */
66 				return NULL;
67 			}
68 			(*jenv)->ThrowNew (jenv, cls, _("Can't read BLOB"));
69 			return NULL;
70 		}
71 		raw_data = ((GdaBinary*) nblob)->data;
72 	}
73 	else {
74 		GdaBinary *bin = (GdaBinary *) blob;
75 		if (offset + size > bin->binary_length)
76 			real_size = bin->binary_length - offset;
77 		else
78 			real_size = size;
79 		raw_data = bin->data + offset;
80 	}
81 
82 	/* convert bin->data to a jintArray */
83 	int i;
84 	data = g_new (jint, real_size);
85 	for (i = 0; i < real_size; i++)
86 		data[i] = (jint) (raw_data[i]);
87 
88 	jdata = (*jenv)->NewIntArray (jenv, real_size);
89 	if ((*jenv)->ExceptionCheck (jenv)) {
90 		jdata = NULL;
91 		goto out;
92 	}
93 
94 	(*jenv)->SetIntArrayRegion (jenv, jdata, 0, real_size, data);
95 	if ((*jenv)->ExceptionCheck (jenv)) {
96 		jdata = NULL;
97 		(*jenv)->DeleteLocalRef (jenv, jdata);
98 		goto out;
99 	}
100 
101  out:
102 	g_free (data);
103 	if (nblob)
104 		gda_blob_free ((gpointer) nblob);
105 
106 	return jdata;
107 }
108 
109 JNIEXPORT jbyteArray JNICALL
110 Java_GdaInputStream_readByteData (JNIEnv *jenv, G_GNUC_UNUSED jobject obj,
111 				      jlong gda_blob_pointer, jlong offset, jlong size)
112 {
113 	GdaBlob *blob = (GdaBlob*) jni_jlong_to_cpointer (gda_blob_pointer);
114 	jbyteArray jdata;
115 	if (!blob) {
116 		jclass cls;
117 		cls = (*jenv)->FindClass (jenv, "java/lang/IllegalArgumentException");
118 		if (!cls) {
119 			/* Unable to find the exception class */
120 			return NULL;
121 		}
122 		(*jenv)->ThrowNew (jenv, cls, _("Invalid argument: NULL"));
123 		return NULL;
124 	}
125 
126 	guchar *raw_data;
127 	GdaBlob *nblob = NULL;
128 	gint real_size;
129 	if (blob->op) {
130 		nblob = g_new0 (GdaBlob, 1);
131 		gda_blob_set_op (nblob, blob->op);
132 		real_size =  gda_blob_op_read (nblob->op, nblob, offset, size);
133 		if (real_size < 0) {
134 			/* throw an exception */
135 			jclass cls;
136 			cls = (*jenv)->FindClass (jenv, "java/sql/SQLException");
137 			if (!cls) {
138 				/* Unable to find the exception class */
139 				return NULL;
140 			}
141 			(*jenv)->ThrowNew (jenv, cls, _("Can't read BLOB"));
142 			return NULL;
143 		}
144 		raw_data = ((GdaBinary*) nblob)->data;
145 	}
146 	else {
147 		GdaBinary *bin = (GdaBinary *) blob;
148 		if (offset + size > bin->binary_length)
149 			real_size = bin->binary_length - offset;
150 		else
151 			real_size = size;
152 		raw_data = bin->data + offset;
153 	}
154 
155 	/* convert bin->data to a jintArray */
156 	jdata = (*jenv)->NewByteArray (jenv, real_size);
157 	if ((*jenv)->ExceptionCheck (jenv)) {
158 		jdata = NULL;
159 		goto out;
160 	}
161 
162 	(*jenv)->SetByteArrayRegion (jenv, jdata, 0, real_size, (const jbyte *) raw_data);
163 	if ((*jenv)->ExceptionCheck (jenv)) {
164 		jdata = NULL;
165 		(*jenv)->DeleteLocalRef (jenv, jdata);
166 		goto out;
167 	}
168 
169  out:
170 	if (nblob)
171 		gda_blob_free ((gpointer) nblob);
172 
173 	return jdata;
174 }
175