CACAO
com_sun_cldc_io_ResourceInputStream.cpp
Go to the documentation of this file.
1 /* src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.cpp
2 
3  Copyright (C) 2007-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <errno.h>
29 #include <zlib.h>
30 
31 #include "mm/memory.hpp"
32 
33 #include "native/jni.hpp"
34 #include "native/native.hpp"
35 
36 #if defined(ENABLE_JNI_HEADERS)
37 # include "native/include/com_sun_cldc_io_ResourceInputStream.h"
38 #endif
39 
40 #include "threads/mutex.hpp"
41 
42 #include "toolbox/endianess.hpp"
43 
44 #include "vm/array.hpp"
45 #include "vm/exceptions.hpp"
46 #include "vm/javaobjects.hpp"
47 #include "vm/os.hpp"
48 #include "vm/string.hpp"
49 #include "vm/types.hpp"
50 #include "vm/vm.hpp" /* REMOVE ME: temporarily */
51 #include "vm/zip.hpp"
52 
53 
55  // try to find the class in the current archive
56 
57  const ZipFileEntry *zip = lce->zip->find(c->name);
58 
59  if (zip == NULL)
60  return NULL;
61 
62  // load data from zip file
63 
64  size_t size = zip->uncompressedsize;
65  uint8_t *data = MNEW(u1, size);
66 
67  zip->get(data);
68 
69  // Create a file descriptor object.
70  classinfo *ci = load_class_bootstrap(Utf8String::from_utf8("com/sun/cldchi/jvm/FileDescriptor"));
72 
73  if (h == NULL)
74  return NULL;
75 
76  com_sun_cldchi_jvm_FileDescriptor fd(h, (int64_t) data, 0, size);
77 
78  return fd.get_handle();
79 }
80 
81 
82 static java_handle_t* file_read_resource(char *path)
83 {
84  int len;
85  struct stat statBuffer;
86  u1 *filep;
87  classinfo *ci;
88  int fd;
89 
90  fd = open(path, O_RDONLY);
91 
92  if (fd > 0) {
93 
94  if (fstat(fd, &statBuffer) != -1) {
95  len = statBuffer.st_size;
96  } else {
97  return NULL;
98  }
99 
100  /* Map file into the memory */
101  filep = (u1*) mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
102 
103  /* Create a file descriptor object */
104  ci = load_class_bootstrap(Utf8String::from_utf8("com/sun/cldchi/jvm/FileDescriptor"));
106 
107  if (h == NULL)
108  return NULL;
109 
110  com_sun_cldchi_jvm_FileDescriptor fd(h, (int64_t) filep, 0, len);
111 
112  return fd.get_handle();
113  }
114  else {
115  return NULL;
116  }
117 }
118 
119 
120 // Native functions are exported as C functions.
121 extern "C" {
122 
123 /*
124  * Class: com/sun/cldc/io/ResourceInputStream
125  * Method: open
126  * Signature: (Ljava/lang/String;)Ljava/lang/Object;
127  */
129 {
130  char *filename;
131  s4 filenamelen;
132  char *path;
133  Utf8String uname;
134  java_handle_t* descriptor;
135 
136  // Get current list of classpath entries.
137  SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
138 
139  /* get the classname as char string (do it here for the warning at
140  the end of the function) */
141 
142  Buffer<> filename, path;
143 
144  filename.write(name);
145 
146  /* walk through all classpath entries */
147 
148  for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
149  list_classpath_entry* lce = *it;
150 
151 #if defined(ENABLE_ZLIB)
152  if (lce->type == CLASSPATH_ARCHIVE) {
153  /* enter a monitor on zip/jar archives */
154  MutexLocker(lce->mutex);
155 
156  /* try to get the file in current archive */
157  descriptor = zip_read_resource(lce, uname);
158 
159  if (descriptor != NULL) { /* file exists */
160  break;
161  }
162 
163  } else {
164 #endif
165  path.write(lce->path).write(filename);
166 
167  descriptor = file_read_resource(path);
168 
169  path.clear();
170 
171  if (descriptor != NULL) { /* file exists */
172  break;
173  }
174 #if defined(ENABLE_ZLIB)
175  }
176 #endif
177  }
178 
179  return (jobject) descriptor;
180 }
181 
182 
183 /*
184  * Class: com/sun/cldc/io/ResourceInputStream
185  * Method: bytesRemain
186  * Signature: (Ljava/lang/Object;)I
187  */
189 {
190  com_sun_cldchi_jvm_FileDescriptor fd(jobj);
191  int32_t length = fd.get_position();
192  int32_t position = fd.get_length();
193 
194  return length - position;
195 }
196 
197 
198 /*
199  * Class: com/sun/cldc/io/ResourceInputStream
200  * Method: readByte
201  * Signature: (Ljava/lang/Object;)I
202  */
204 {
205  com_sun_cldchi_jvm_FileDescriptor fd(jobj);
206 
207  int64_t filep = fd.get_pointer();
208  int32_t position = fd.get_position();
209  int32_t length = fd.get_length();
210 
211  uint8_t byte;
212 
213  if (position < length) {
214  byte = ((uint8_t*) filep)[position];
215  position++;
216  }
217  else {
218  return -1; /* EOF */
219  }
220 
221  // Update access position.
222  fd.set_position(position);
223 
224  return (byte & 0xFF);
225 }
226 
227 
228 /*
229  * Class: com/sun/cldc/io/ResourceInputStream
230  * Method: readBytes
231  * Signature: (Ljava/lang/Object;[BII)I
232  */
233 JNIEXPORT jint JNICALL Java_com_sun_cldc_io_ResourceInputStream_readBytes(JNIEnv *env, jclass clazz, jobject jobj, jbyteArray byteArray, jint off, jint len)
234 {
235  /* get pointer to the buffer */
236  // XXX Not GC safe.
237  ByteArray ba(byteArray);
238  void* buf = (void*) (((int8_t*) ba.get_raw_data_ptr()) + off);
239 
240  com_sun_cldchi_jvm_FileDescriptor fd(jobj);
241 
242  int64_t filep = fd.get_pointer();
243  int32_t position = fd.get_position();
244  int32_t fileLength = fd.get_length();
245 
246  int32_t readBytes = -1;
247 
248  if (position < fileLength) {
249  int32_t available = fileLength - position;
250 
251  if (available < len) {
252  readBytes = available;
253  } else {
254  readBytes = len;
255  }
256 
257  os::memcpy(buf, ((uint8_t*) filep) + position, readBytes * sizeof(uint8_t));
258  position += readBytes;
259  }
260  else {
261  return -1; /* EOF */
262  }
263 
264  // Update access position.
265  fd.set_position(position);
266 
267  return readBytes;
268 }
269 
270 
271 /*
272  * Class: com/sun/cldc/io/ResourceInputStream
273  * Method: clone
274  * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
275  */
277 {
278  com_sun_cldchi_jvm_FileDescriptor fd(jobj);
279 
280  classinfo* c = load_class_bootstrap(Utf8String::from_utf8("com/sun/cldchi/jvm/FileDescriptor"));
282 
283  if (h == NULL)
284  return NULL;
285 
286  com_sun_cldchi_jvm_FileDescriptor clonefd(h, fd);
287 
288  return (jobject) clonefd.get_handle();
289 }
290 
291 } // extern "C"
292 
293 
294 /* native methods implemented by this file ************************************/
295 
296 static JNINativeMethod methods[] = {
297  { (char*) "open", (char*) "(Ljava/lang/String;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_open },
298  { (char*) "bytesRemain", (char*) "(Ljava/lang/Object;)I", (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_bytesRemain },
299  { (char*) "readByte", (char*) "(Ljava/lang/Object;)I", (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_readByte },
300  { (char*) "readBytes", (char*) "(Ljava/lang/Object;[BII)I", (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_readBytes },
301  { (char*) "clone", (char*) "(Ljava/lang/Object;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_clone },
302 };
303 
304 
305 /* _Jv_com_sun_cldc_io_ResourceInputStream_init ********************************
306 
307  Register native functions.
308 
309 *******************************************************************************/
310 
312 {
313  Utf8String u = Utf8String::from_utf8("com/sun/cldc/io/ResourceInputStream");
314 
317 }
318 
319 
320 /*
321  * These are local overrides for various environment variables in Emacs.
322  * Please do not remove this and leave it at the end of the file, where
323  * Emacs will automagically detect them.
324  * ---------------------------------------------------------------------
325  * Local variables:
326  * mode: c++
327  * indent-tabs-mode: t
328  * c-basic-offset: 4
329  * tab-width: 4
330  * End:
331  * vim:noexpandtab:sw=4:ts=4:
332  */
JNIEXPORT jobject JNICALL Java_com_sun_cldc_io_ResourceInputStream_clone(JNIEnv *env, jclass clazz, jobject jobj)
JNIEXPORT jint JNICALL Java_com_sun_cldc_io_ResourceInputStream_bytesRemain(JNIEnv *env, jclass clazz, jobject jobj)
Table containing all native methods registered with the VM.
Definition: native.hpp:132
ZipFile * zip
Definition: suck.hpp:55
NativeMethods & get_nativemethods()
Definition: vm.hpp:128
void register_methods(Utf8String classname, const JNINativeMethod *methods, size_t count)
Register native methods with the VM.
Definition: native.cpp:242
_Jv_JNIEnv JNIEnv
Definition: jni.hpp:112
#define NATIVE_METHODS_COUNT
Definition: native.hpp:45
int8_t * get_raw_data_ptr()
Definition: array.hpp:333
u4 uncompressedsize
Definition: zip.hpp:81
char * path
Definition: suck.hpp:52
classinfo * load_class_bootstrap(Utf8String name)
Definition: loader.cpp:1276
uint8_t u1
Definition: types.hpp:40
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
JNIEXPORT jobject JNICALL Java_com_sun_cldc_io_ResourceInputStream_open(JNIEnv *env, jclass clazz, jstring name)
static JNINativeMethod methods[]
void get(uint8_t *dst) const
Definition: zip.cpp:279
void _Jv_com_sun_cldc_io_ResourceInputStream_init(void)
static Utf8String from_utf8(const char *, size_t)
Definition: utf8.cpp:335
Classpath entries list.
Definition: suck.hpp:62
int32_t s4
Definition: types.hpp:45
s4 type
Definition: suck.hpp:51
static void * memcpy(void *dest, const void *src, size_t n)
Definition: os.hpp:492
Mutex * mutex
Definition: suck.hpp:50
EntryRef find(Utf8String filename)
Find file in zip archive.
Definition: zip.hpp:108
Definition: suck.hpp:49
JNIEXPORT jint JNICALL Java_com_sun_cldc_io_ResourceInputStream_readBytes(JNIEnv *env, jclass clazz, jobject jobj, jbyteArray byteArray, jint off, jint len)
java_handle_t * native_new_and_init(classinfo *c)
Registers a new native agent by specified by it&#39;s library name and with an optional options string...
Definition: native.cpp:729
static java_handle_t * zip_read_resource(list_classpath_entry *lce, Utf8String name)
#define MNEW(type, num)
Definition: memory.hpp:96
Buffer & write(char)
Definition: buffer.hpp:280
SuckClasspath & get_suckclasspath()
Definition: vm.hpp:129
static java_handle_t * file_read_resource(char *path)
const char const void jint length
Definition: jvmti.h:352
AnyObjLocker< Mutex > MutexLocker
Definition: mutex.hpp:60
JNIEXPORT jint JNICALL Java_com_sun_cldc_io_ResourceInputStream_readByte(JNIEnv *env, jclass clazz, jobject jobj)
static VM * get_current()
Definition: vm.hpp:99