xref: /unit/src/java/nxt_jni_InputStream.c (revision 1436:44ccce64ddf9)
1977Smax.romanov@gmail.com 
2977Smax.romanov@gmail.com /*
3977Smax.romanov@gmail.com  * Copyright (C) NGINX, Inc.
4977Smax.romanov@gmail.com  */
5977Smax.romanov@gmail.com 
6977Smax.romanov@gmail.com #include <nxt_auto_config.h>
7977Smax.romanov@gmail.com 
8977Smax.romanov@gmail.com #include <jni.h>
9977Smax.romanov@gmail.com #include <nxt_unit.h>
10977Smax.romanov@gmail.com #include <string.h>
11977Smax.romanov@gmail.com 
12977Smax.romanov@gmail.com #include "nxt_jni.h"
13977Smax.romanov@gmail.com #include "nxt_jni_InputStream.h"
14977Smax.romanov@gmail.com #include "nxt_jni_URLClassLoader.h"
15977Smax.romanov@gmail.com 
16977Smax.romanov@gmail.com 
17977Smax.romanov@gmail.com static jint JNICALL nxt_java_InputStream_readLine(JNIEnv *env, jclass cls,
18977Smax.romanov@gmail.com     jlong req_info_ptr, jarray b, jint off, jint len);
19977Smax.romanov@gmail.com static jboolean JNICALL nxt_java_InputStream_isFinished(JNIEnv *env, jclass cls,
20977Smax.romanov@gmail.com     jlong req_info_ptr);
21977Smax.romanov@gmail.com static jint JNICALL nxt_java_InputStream_readByte(JNIEnv *env, jclass cls,
22977Smax.romanov@gmail.com     jlong req_info_ptr);
23977Smax.romanov@gmail.com static jint JNICALL nxt_java_InputStream_read(JNIEnv *env, jclass cls,
24977Smax.romanov@gmail.com     jlong req_info_ptr, jarray b, jint off, jint len);
25977Smax.romanov@gmail.com static jlong JNICALL nxt_java_InputStream_skip(JNIEnv *env, jclass cls,
26977Smax.romanov@gmail.com     jlong req_info_ptr, jlong n);
27977Smax.romanov@gmail.com static jint JNICALL nxt_java_InputStream_available(JNIEnv *env, jclass cls,
28977Smax.romanov@gmail.com     jlong req_info_ptr);
29977Smax.romanov@gmail.com 
30977Smax.romanov@gmail.com 
31977Smax.romanov@gmail.com static jclass  nxt_java_InputStream_class;
32977Smax.romanov@gmail.com 
33977Smax.romanov@gmail.com 
34977Smax.romanov@gmail.com int
nxt_java_initInputStream(JNIEnv * env,jobject cl)35977Smax.romanov@gmail.com nxt_java_initInputStream(JNIEnv *env, jobject cl)
36977Smax.romanov@gmail.com {
37977Smax.romanov@gmail.com     int     res;
38977Smax.romanov@gmail.com     jclass  cls;
39977Smax.romanov@gmail.com 
40977Smax.romanov@gmail.com     cls = nxt_java_loadClass(env, cl, "nginx.unit.InputStream");
41977Smax.romanov@gmail.com     if (cls == NULL) {
42977Smax.romanov@gmail.com         return NXT_UNIT_ERROR;
43977Smax.romanov@gmail.com     }
44977Smax.romanov@gmail.com 
45977Smax.romanov@gmail.com     nxt_java_InputStream_class = (*env)->NewGlobalRef(env, cls);
46977Smax.romanov@gmail.com     (*env)->DeleteLocalRef(env, cls);
47977Smax.romanov@gmail.com 
48977Smax.romanov@gmail.com     JNINativeMethod is_methods[] = {
49977Smax.romanov@gmail.com         { (char *) "readLine",
50977Smax.romanov@gmail.com           (char *) "(J[BII)I",
51977Smax.romanov@gmail.com           nxt_java_InputStream_readLine },
52977Smax.romanov@gmail.com 
53977Smax.romanov@gmail.com         { (char *) "isFinished",
54977Smax.romanov@gmail.com           (char *) "(J)Z",
55977Smax.romanov@gmail.com           nxt_java_InputStream_isFinished },
56977Smax.romanov@gmail.com 
57977Smax.romanov@gmail.com         { (char *) "read",
58977Smax.romanov@gmail.com           (char *) "(J)I",
59977Smax.romanov@gmail.com           nxt_java_InputStream_readByte },
60977Smax.romanov@gmail.com 
61977Smax.romanov@gmail.com         { (char *) "read",
62977Smax.romanov@gmail.com           (char *) "(J[BII)I",
63977Smax.romanov@gmail.com           nxt_java_InputStream_read },
64977Smax.romanov@gmail.com 
65977Smax.romanov@gmail.com         { (char *) "skip",
66977Smax.romanov@gmail.com           (char *) "(JJ)J",
67977Smax.romanov@gmail.com           nxt_java_InputStream_skip },
68977Smax.romanov@gmail.com 
69977Smax.romanov@gmail.com         { (char *) "available",
70977Smax.romanov@gmail.com           (char *) "(J)I",
71977Smax.romanov@gmail.com           nxt_java_InputStream_available },
72977Smax.romanov@gmail.com     };
73977Smax.romanov@gmail.com 
74977Smax.romanov@gmail.com     res = (*env)->RegisterNatives(env, nxt_java_InputStream_class,
75977Smax.romanov@gmail.com                                   is_methods,
76977Smax.romanov@gmail.com                                   sizeof(is_methods) / sizeof(is_methods[0]));
77977Smax.romanov@gmail.com 
78977Smax.romanov@gmail.com     nxt_unit_debug(NULL, "registered InputStream methods: %d", res);
79977Smax.romanov@gmail.com 
80977Smax.romanov@gmail.com     if (res != 0) {
81977Smax.romanov@gmail.com         (*env)->DeleteGlobalRef(env, cls);
82977Smax.romanov@gmail.com         return NXT_UNIT_ERROR;
83977Smax.romanov@gmail.com     }
84977Smax.romanov@gmail.com 
85977Smax.romanov@gmail.com     return NXT_UNIT_OK;
86977Smax.romanov@gmail.com }
87977Smax.romanov@gmail.com 
88977Smax.romanov@gmail.com 
89977Smax.romanov@gmail.com static jint JNICALL
nxt_java_InputStream_readLine(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray out,jint off,jint len)90977Smax.romanov@gmail.com nxt_java_InputStream_readLine(JNIEnv *env, jclass cls,
91977Smax.romanov@gmail.com     jlong req_info_ptr, jarray out, jint off, jint len)
92977Smax.romanov@gmail.com {
93977Smax.romanov@gmail.com     uint8_t                  *data;
94977Smax.romanov@gmail.com     ssize_t                  res;
95977Smax.romanov@gmail.com     nxt_unit_request_info_t  *req;
96977Smax.romanov@gmail.com 
97977Smax.romanov@gmail.com     req = nxt_jlong2ptr(req_info_ptr);
98977Smax.romanov@gmail.com 
99977Smax.romanov@gmail.com     data = (*env)->GetPrimitiveArrayCritical(env, out, NULL);
100977Smax.romanov@gmail.com 
1011398Smax.romanov@nginx.com     res = nxt_unit_request_readline_size(req, len);
1021398Smax.romanov@nginx.com 
1031398Smax.romanov@nginx.com     if (res > 0) {
1041398Smax.romanov@nginx.com         res = nxt_unit_request_read(req, data + off, res);
1051398Smax.romanov@nginx.com     }
106977Smax.romanov@gmail.com 
107*1436Smax.romanov@nginx.com     nxt_unit_req_debug(req, "readLine '%.*s'", (int) res, (char *) data + off);
108977Smax.romanov@gmail.com 
109977Smax.romanov@gmail.com     (*env)->ReleasePrimitiveArrayCritical(env, out, data, 0);
110977Smax.romanov@gmail.com 
111977Smax.romanov@gmail.com     return res > 0 ? res : -1;
112977Smax.romanov@gmail.com }
113977Smax.romanov@gmail.com 
114977Smax.romanov@gmail.com 
115977Smax.romanov@gmail.com static jboolean JNICALL
nxt_java_InputStream_isFinished(JNIEnv * env,jclass cls,jlong req_info_ptr)116977Smax.romanov@gmail.com nxt_java_InputStream_isFinished(JNIEnv *env, jclass cls, jlong req_info_ptr)
117977Smax.romanov@gmail.com {
118977Smax.romanov@gmail.com     nxt_unit_request_info_t  *req;
119977Smax.romanov@gmail.com 
120977Smax.romanov@gmail.com     req = nxt_jlong2ptr(req_info_ptr);
121977Smax.romanov@gmail.com 
122977Smax.romanov@gmail.com     return req->content_length == 0;
123977Smax.romanov@gmail.com }
124977Smax.romanov@gmail.com 
125977Smax.romanov@gmail.com 
126977Smax.romanov@gmail.com static jint JNICALL
nxt_java_InputStream_readByte(JNIEnv * env,jclass cls,jlong req_info_ptr)127977Smax.romanov@gmail.com nxt_java_InputStream_readByte(JNIEnv *env, jclass cls, jlong req_info_ptr)
128977Smax.romanov@gmail.com {
129977Smax.romanov@gmail.com     uint8_t                  b;
130977Smax.romanov@gmail.com     ssize_t                  size;
131977Smax.romanov@gmail.com     nxt_unit_request_info_t  *req;
132977Smax.romanov@gmail.com 
133977Smax.romanov@gmail.com     req = nxt_jlong2ptr(req_info_ptr);
134977Smax.romanov@gmail.com 
135977Smax.romanov@gmail.com     size = nxt_unit_request_read(req, &b, 1);
136977Smax.romanov@gmail.com 
137977Smax.romanov@gmail.com     return size == 1 ? b : -1;
138977Smax.romanov@gmail.com }
139977Smax.romanov@gmail.com 
140977Smax.romanov@gmail.com 
141977Smax.romanov@gmail.com static jint JNICALL
nxt_java_InputStream_read(JNIEnv * env,jclass cls,jlong req_info_ptr,jarray b,jint off,jint len)142977Smax.romanov@gmail.com nxt_java_InputStream_read(JNIEnv *env, jclass cls, jlong req_info_ptr,
143977Smax.romanov@gmail.com     jarray b, jint off, jint len)
144977Smax.romanov@gmail.com {
145977Smax.romanov@gmail.com     uint8_t                  *data;
146977Smax.romanov@gmail.com     ssize_t                  res;
147977Smax.romanov@gmail.com     nxt_unit_request_info_t  *req;
148977Smax.romanov@gmail.com 
149977Smax.romanov@gmail.com     req = nxt_jlong2ptr(req_info_ptr);
150977Smax.romanov@gmail.com 
151977Smax.romanov@gmail.com     data = (*env)->GetPrimitiveArrayCritical(env, b, NULL);
152977Smax.romanov@gmail.com 
153977Smax.romanov@gmail.com     res = nxt_unit_request_read(req, data + off, len);
154977Smax.romanov@gmail.com 
155*1436Smax.romanov@nginx.com     nxt_unit_req_debug(req, "read '%.*s'", (int) res, (char *) data + off);
156977Smax.romanov@gmail.com 
157977Smax.romanov@gmail.com     (*env)->ReleasePrimitiveArrayCritical(env, b, data, 0);
158977Smax.romanov@gmail.com 
159977Smax.romanov@gmail.com     return res > 0 ? res : -1;
160977Smax.romanov@gmail.com }
161977Smax.romanov@gmail.com 
162977Smax.romanov@gmail.com 
163977Smax.romanov@gmail.com static jlong JNICALL
nxt_java_InputStream_skip(JNIEnv * env,jclass cls,jlong req_info_ptr,jlong n)164977Smax.romanov@gmail.com nxt_java_InputStream_skip(JNIEnv *env, jclass cls, jlong req_info_ptr, jlong n)
165977Smax.romanov@gmail.com {
166977Smax.romanov@gmail.com     size_t                   rest, b_size;
167977Smax.romanov@gmail.com     nxt_unit_buf_t           *buf;
168977Smax.romanov@gmail.com     nxt_unit_request_info_t  *req;
169977Smax.romanov@gmail.com 
170977Smax.romanov@gmail.com     req = nxt_jlong2ptr(req_info_ptr);
171977Smax.romanov@gmail.com 
172977Smax.romanov@gmail.com     rest = n;
173977Smax.romanov@gmail.com 
174977Smax.romanov@gmail.com     buf = req->content_buf;
175977Smax.romanov@gmail.com 
176977Smax.romanov@gmail.com     while (buf != NULL) {
177977Smax.romanov@gmail.com         b_size = buf->end - buf->free;
178977Smax.romanov@gmail.com         b_size = rest < b_size ? rest : b_size;
179977Smax.romanov@gmail.com 
180977Smax.romanov@gmail.com         buf->free += b_size;
181977Smax.romanov@gmail.com         rest -= b_size;
182977Smax.romanov@gmail.com 
183977Smax.romanov@gmail.com         if (rest == 0) {
184977Smax.romanov@gmail.com             if (buf->end == buf->free) {
185977Smax.romanov@gmail.com                 buf = nxt_unit_buf_next(buf);
186977Smax.romanov@gmail.com             }
187977Smax.romanov@gmail.com 
188977Smax.romanov@gmail.com             break;
189977Smax.romanov@gmail.com         }
190977Smax.romanov@gmail.com 
191977Smax.romanov@gmail.com         buf = nxt_unit_buf_next(buf);
192977Smax.romanov@gmail.com     }
193977Smax.romanov@gmail.com 
194977Smax.romanov@gmail.com     n = n < (jlong) req->content_length ? n : (jlong) req->content_length;
195977Smax.romanov@gmail.com 
196977Smax.romanov@gmail.com     req->content_length -= n;
197977Smax.romanov@gmail.com 
198977Smax.romanov@gmail.com     return n;
199977Smax.romanov@gmail.com }
200977Smax.romanov@gmail.com 
201977Smax.romanov@gmail.com 
202977Smax.romanov@gmail.com static jint JNICALL
nxt_java_InputStream_available(JNIEnv * env,jclass cls,jlong req_info_ptr)203977Smax.romanov@gmail.com nxt_java_InputStream_available(JNIEnv *env, jclass cls, jlong req_info_ptr)
204977Smax.romanov@gmail.com {
205977Smax.romanov@gmail.com     nxt_unit_request_info_t  *req;
206977Smax.romanov@gmail.com 
207977Smax.romanov@gmail.com     req = nxt_jlong2ptr(req_info_ptr);
208977Smax.romanov@gmail.com 
209977Smax.romanov@gmail.com     return req->content_length;
210977Smax.romanov@gmail.com }
211