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