48 |
48 |
49 static jfieldID unpackerPtrFID; |
49 static jfieldID unpackerPtrFID; |
50 static jmethodID currentInstMID; |
50 static jmethodID currentInstMID; |
51 static jmethodID readInputMID; |
51 static jmethodID readInputMID; |
52 static jclass NIclazz; |
52 static jclass NIclazz; |
|
53 static jmethodID getUnpackerPtrMID; |
53 |
54 |
54 static char* dbg = null; |
55 static char* dbg = null; |
55 |
56 |
56 #define THROW_IOE(x) JNU_ThrowIOException(env,x) |
57 #define THROW_IOE(x) JNU_ThrowIOException(env,x) |
57 |
58 |
58 static jlong read_input_via_jni(unpacker* self, |
59 static jlong read_input_via_jni(unpacker* self, |
59 void* buf, jlong minlen, jlong maxlen); |
60 void* buf, jlong minlen, jlong maxlen); |
60 |
61 |
61 static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) { |
62 static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) { |
62 unpacker* uPtr; |
63 unpacker* uPtr; |
63 uPtr = (unpacker*)jlong2ptr(env->GetLongField(pObj, unpackerPtrFID)); |
64 jlong p = env->CallLongMethod(pObj, getUnpackerPtrMID); |
64 //fprintf(stderr, "get_unpacker(%p) uPtr=%p\n", pObj, uPtr); |
65 uPtr = (unpacker*)jlong2ptr(p); |
65 if (uPtr == null) { |
66 if (uPtr == null) { |
66 if (noCreate) return null; |
67 if (noCreate) return null; |
67 uPtr = new unpacker(); |
68 uPtr = new unpacker(); |
68 if (uPtr == null) { |
69 if (uPtr == null) { |
69 THROW_IOE(ERROR_ENOMEM); |
70 THROW_IOE(ERROR_ENOMEM); |
92 JNIEnv* env = (JNIEnv*) envRaw; |
93 JNIEnv* env = (JNIEnv*) envRaw; |
93 //fprintf(stderr, "get_unpacker() env=%p\n", env); |
94 //fprintf(stderr, "get_unpacker() env=%p\n", env); |
94 if (env == null) |
95 if (env == null) |
95 return null; |
96 return null; |
96 jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID); |
97 jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID); |
97 //fprintf(stderr, "get_unpacker() pObj=%p\n", pObj); |
98 //fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj); |
98 if (pObj == null) |
99 if (pObj != null) { |
99 return null; |
100 // Got pObj and env; now do it the easy way. |
100 // Got pObj and env; now do it the easy way. |
101 return get_unpacker(env, pObj); |
101 return get_unpacker(env, pObj); |
102 } |
|
103 // this should really not happen, if it does something is seriously |
|
104 // wrong throw an exception |
|
105 THROW_IOE(ERROR_INTERNAL); |
|
106 return null; |
102 } |
107 } |
103 |
108 |
104 static void free_unpacker(JNIEnv *env, jobject pObj, unpacker* uPtr) { |
109 static void free_unpacker(JNIEnv *env, jobject pObj, unpacker* uPtr) { |
105 if (uPtr != null) { |
110 if (uPtr != null) { |
106 //fprintf(stderr, "free_unpacker(%p) uPtr=%p\n", pObj, uPtr); |
111 //fprintf(stderr, "free_unpacker(%p) uPtr=%p\n", pObj, uPtr); |
135 unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J"); |
140 unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J"); |
136 currentInstMID = env->GetStaticMethodID(clazz, "currentInstance", |
141 currentInstMID = env->GetStaticMethodID(clazz, "currentInstance", |
137 "()Ljava/lang/Object;"); |
142 "()Ljava/lang/Object;"); |
138 readInputMID = env->GetMethodID(clazz, "readInputFn", |
143 readInputMID = env->GetMethodID(clazz, "readInputFn", |
139 "(Ljava/nio/ByteBuffer;J)J"); |
144 "(Ljava/nio/ByteBuffer;J)J"); |
|
145 getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J"); |
|
146 |
140 if (unpackerPtrFID == null || |
147 if (unpackerPtrFID == null || |
141 currentInstMID == null || |
148 currentInstMID == null || |
142 readInputMID == null || |
149 readInputMID == null || |
143 NIclazz == null) { |
150 NIclazz == null || |
|
151 getUnpackerPtrMID == null) { |
144 THROW_IOE("cannot init class members"); |
152 THROW_IOE("cannot init class members"); |
145 } |
153 } |
146 } |
154 } |
147 |
155 |
148 JNIEXPORT jlong JNICALL |
156 JNIEXPORT jlong JNICALL |
149 Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj, |
157 Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj, |
150 jobject pBuf, jlong offset) { |
158 jobject pBuf, jlong offset) { |
151 unpacker* uPtr = get_unpacker(env, pObj); |
159 // try to get the unpacker pointer the hard way first, we do this to ensure |
152 |
160 // valid object pointers and env is intact, if not now is good time to bail. |
|
161 unpacker* uPtr = get_unpacker(); |
|
162 //fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr); |
|
163 if (uPtr == null) { |
|
164 return -1; |
|
165 } |
153 // redirect our io to the default log file or whatever. |
166 // redirect our io to the default log file or whatever. |
154 uPtr->redirect_stdio(); |
167 uPtr->redirect_stdio(); |
155 |
168 |
156 void* buf = null; |
169 void* buf = null; |
157 size_t buflen = 0; |
170 size_t buflen = 0; |
163 if ((size_t)offset >= buflen) |
176 if ((size_t)offset >= buflen) |
164 { buf = null; buflen = 0; } |
177 { buf = null; buflen = 0; } |
165 else |
178 else |
166 { buf = (char*)buf + (size_t)offset; buflen -= (size_t)offset; } |
179 { buf = (char*)buf + (size_t)offset; buflen -= (size_t)offset; } |
167 } |
180 } |
168 |
181 // before we start off we make sure there is no other error by the time we |
|
182 // get here |
|
183 if (uPtr->aborting()) { |
|
184 THROW_IOE(uPtr->get_abort_message()); |
|
185 return 0; |
|
186 } |
169 uPtr->start(buf, buflen); |
187 uPtr->start(buf, buflen); |
170 if (uPtr->aborting()) { |
188 if (uPtr->aborting()) { |
171 THROW_IOE(uPtr->get_abort_message()); |
189 THROW_IOE(uPtr->get_abort_message()); |
172 return 0; |
190 return 0; |
173 } |
191 } |