xref: /unit/src/java/nxt_jni.c (revision 977:4f9268f27b57)
1 
2 /*
3  * Copyright (C) NGINX, Inc.
4  */
5 
6 #include <nxt_auto_config.h>
7 
8 #include <jni.h>
9 #include <nxt_unit.h>
10 #include <nxt_unit_field.h>
11 
12 #include "nxt_jni.h"
13 
14 
15 static jclass     nxt_java_NoSuchElementException_class;
16 static jclass     nxt_java_IOException_class;
17 static jclass     nxt_java_IllegalStateException_class;
18 static jclass     nxt_java_File_class;
19 static jmethodID  nxt_java_File_ctor;
20 
21 static inline char nxt_java_lowcase(char c);
22 
23 
24 int
nxt_java_jni_init(JNIEnv * env)25 nxt_java_jni_init(JNIEnv *env)
26 {
27     jclass  cls;
28 
29     cls = (*env)->FindClass(env, "java/util/NoSuchElementException");
30     if (cls == NULL) {
31         return NXT_UNIT_ERROR;
32     }
33 
34     nxt_java_NoSuchElementException_class = (*env)->NewGlobalRef(env, cls);
35     (*env)->DeleteLocalRef(env, cls);
36 
37 
38     cls = (*env)->FindClass(env, "java/io/IOException");
39     if (cls == NULL) {
40         (*env)->DeleteGlobalRef(env, nxt_java_NoSuchElementException_class);
41         return NXT_UNIT_ERROR;
42     }
43 
44     nxt_java_IOException_class = (*env)->NewGlobalRef(env, cls);
45     (*env)->DeleteLocalRef(env, cls);
46 
47 
48     cls = (*env)->FindClass(env, "java/lang/IllegalStateException");
49     if (cls == NULL) {
50         (*env)->DeleteGlobalRef(env, nxt_java_NoSuchElementException_class);
51         (*env)->DeleteGlobalRef(env, nxt_java_IOException_class);
52         return NXT_UNIT_ERROR;
53     }
54 
55     nxt_java_IllegalStateException_class = (*env)->NewGlobalRef(env, cls);
56     (*env)->DeleteLocalRef(env, cls);
57 
58 
59     cls = (*env)->FindClass(env, "java/io/File");
60     if (cls == NULL) {
61         (*env)->DeleteGlobalRef(env, nxt_java_NoSuchElementException_class);
62         (*env)->DeleteGlobalRef(env, nxt_java_IOException_class);
63         (*env)->DeleteGlobalRef(env, nxt_java_IllegalStateException_class);
64         return NXT_UNIT_ERROR;
65     }
66 
67     nxt_java_File_class = (*env)->NewGlobalRef(env, cls);
68     (*env)->DeleteLocalRef(env, cls);
69 
70 
71     nxt_java_File_ctor = (*env)->GetMethodID(env, nxt_java_File_class, "<init>",
72                                              "(Ljava/lang/String;)V");
73     if (nxt_java_File_ctor == NULL) {
74         (*env)->DeleteGlobalRef(env, nxt_java_NoSuchElementException_class);
75         (*env)->DeleteGlobalRef(env, nxt_java_IOException_class);
76         (*env)->DeleteGlobalRef(env, nxt_java_IllegalStateException_class);
77         (*env)->DeleteGlobalRef(env, nxt_java_File_class);
78         return NXT_UNIT_ERROR;
79     }
80 
81     return NXT_UNIT_OK;
82 }
83 
84 
85 void
nxt_java_throw_NoSuchElementException(JNIEnv * env,const char * msg)86 nxt_java_throw_NoSuchElementException(JNIEnv *env, const char *msg)
87 {
88     (*env)->ThrowNew(env, nxt_java_NoSuchElementException_class, msg);
89 }
90 
91 
92 void
nxt_java_throw_IOException(JNIEnv * env,const char * msg)93 nxt_java_throw_IOException(JNIEnv *env, const char *msg)
94 {
95     (*env)->ThrowNew(env, nxt_java_IOException_class, msg);
96 }
97 
98 
99 void
nxt_java_throw_IllegalStateException(JNIEnv * env,const char * msg)100 nxt_java_throw_IllegalStateException(JNIEnv *env, const char *msg)
101 {
102     (*env)->ThrowNew(env, nxt_java_IllegalStateException_class, msg);
103 }
104 
105 
106 nxt_unit_field_t *
nxt_java_findHeader(nxt_unit_field_t * f,nxt_unit_field_t * end,const char * name,uint8_t name_len)107 nxt_java_findHeader(nxt_unit_field_t *f, nxt_unit_field_t *end,
108     const char *name, uint8_t name_len)
109 {
110     const char  *field_name;
111 
112     for (/* void */ ; f < end; f++) {
113         if (f->skip != 0 || f->name_length != name_len) {
114             continue;
115         }
116 
117         field_name = nxt_unit_sptr_get(&f->name);
118 
119         if (nxt_java_strcaseeq(name, field_name, name_len)) {
120             return f;
121         }
122     }
123 
124     return NULL;
125 }
126 
127 
128 int
nxt_java_strcaseeq(const char * str1,const char * str2,int len)129 nxt_java_strcaseeq(const char *str1, const char *str2, int len)
130 {
131     char        c1, c2;
132     const char  *end1;
133 
134     end1 = str1 + len;
135 
136     while (str1 < end1) {
137         c1 = nxt_java_lowcase(*str1++);
138         c2 = nxt_java_lowcase(*str2++);
139 
140         if (c1 != c2) {
141             return 0;
142         }
143     }
144 
145     return 1;
146 }
147 
148 
149 static inline char
nxt_java_lowcase(char c)150 nxt_java_lowcase(char c)
151 {
152     return (c >= 'A' && c <= 'Z') ? c | 0x20 : c;
153 }
154 
155 
156 jstring
nxt_java_newString(JNIEnv * env,char * str,uint32_t len)157 nxt_java_newString(JNIEnv *env, char *str, uint32_t len)
158 {
159     char     tmp;
160     jstring  res;
161 
162     tmp = str[len];
163 
164     if (tmp != '\0') {
165         str[len] = '\0';
166     }
167 
168     res = (*env)->NewStringUTF(env, str);
169 
170     if (tmp != '\0') {
171         str[len] = tmp;
172     }
173 
174     return res;
175 }
176