1
2 /*
3 * Copyright (C) NGINX, Inc.
4 */
5
6 #include <nxt_auto_config.h>
7
8 #include <nxt_unit.h>
9 #include <nxt_unit_request.h>
10 #include <jni.h>
11 #include <stdio.h>
12
13 #include "nxt_jni.h"
14 #include "nxt_jni_URLClassLoader.h"
15 #include "nxt_jni_HeadersEnumeration.h"
16
17
18 static jclass nxt_java_HeadersEnumeration_class;
19 static jmethodID nxt_java_HeadersEnumeration_ctor;
20
21
22 static jlong JNICALL nxt_java_HeadersEnumeration_nextElementPos(JNIEnv *env,
23 jclass cls, jlong headers_ptr, jlong size, jlong ipos, jlong pos);
24
25 static jstring JNICALL nxt_java_HeadersEnumeration_nextElement(JNIEnv *env,
26 jclass cls, jlong headers_ptr, jlong size, jlong ipos, jlong pos);
27
28
29 int
nxt_java_initHeadersEnumeration(JNIEnv * env,jobject cl)30 nxt_java_initHeadersEnumeration(JNIEnv *env, jobject cl)
31 {
32 int res;
33 jclass cls;
34
35 cls = nxt_java_loadClass(env, cl, "nginx.unit.HeadersEnumeration");
36 if (cls == NULL) {
37 return NXT_UNIT_ERROR;
38 }
39
40 nxt_java_HeadersEnumeration_class = (*env)->NewGlobalRef(env, cls);
41 (*env)->DeleteLocalRef(env, cls);
42 cls = nxt_java_HeadersEnumeration_class;
43
44 nxt_java_HeadersEnumeration_ctor = (*env)->GetMethodID(env, cls,
45 "<init>", "(JJJ)V");
46 if (nxt_java_HeadersEnumeration_ctor == NULL) {
47 (*env)->DeleteGlobalRef(env, cls);
48 return NXT_UNIT_ERROR;
49 }
50
51 JNINativeMethod methods[] = {
52 { (char *) "nextElementPos",
53 (char *) "(JJJJ)J",
54 nxt_java_HeadersEnumeration_nextElementPos },
55
56 { (char *) "nextElement",
57 (char *) "(JJJJ)Ljava/lang/String;",
58 nxt_java_HeadersEnumeration_nextElement },
59 };
60
61 res = (*env)->RegisterNatives(env, nxt_java_HeadersEnumeration_class,
62 methods,
63 sizeof(methods) / sizeof(methods[0]));
64
65 nxt_unit_debug(NULL, "registered HeadersEnumeration methods: %d", res);
66
67 if (res != 0) {
68 (*env)->DeleteGlobalRef(env, cls);
69 return NXT_UNIT_ERROR;
70 }
71
72 return NXT_UNIT_OK;
73 }
74
75
76 jobject
nxt_java_newHeadersEnumeration(JNIEnv * env,nxt_unit_field_t * f,uint32_t fields_count,uint32_t pos)77 nxt_java_newHeadersEnumeration(JNIEnv *env, nxt_unit_field_t *f,
78 uint32_t fields_count, uint32_t pos)
79 {
80 return (*env)->NewObject(env,
81 nxt_java_HeadersEnumeration_class,
82 nxt_java_HeadersEnumeration_ctor, nxt_ptr2jlong(f),
83 (jlong) fields_count, (jlong) pos);
84 }
85
86
87 static jlong JNICALL
nxt_java_HeadersEnumeration_nextElementPos(JNIEnv * env,jclass cls,jlong headers_ptr,jlong size,jlong ipos,jlong pos)88 nxt_java_HeadersEnumeration_nextElementPos(JNIEnv *env, jclass cls,
89 jlong headers_ptr, jlong size, jlong ipos, jlong pos)
90 {
91 nxt_unit_field_t *f, *init_field;
92
93 f = nxt_jlong2ptr(headers_ptr);
94
95 init_field = f + ipos;
96
97 if (pos >= size) {
98 return size;
99 }
100
101 f += pos;
102
103 if (f->hash != init_field->hash
104 || f->name_length != init_field->name_length)
105 {
106 return size;
107 }
108
109 if (!nxt_java_strcaseeq(nxt_unit_sptr_get(&f->name),
110 nxt_unit_sptr_get(&init_field->name),
111 init_field->name_length))
112 {
113 return size;
114 }
115
116 return pos;
117 }
118
119
120 static jstring JNICALL
nxt_java_HeadersEnumeration_nextElement(JNIEnv * env,jclass cls,jlong headers_ptr,jlong size,jlong ipos,jlong pos)121 nxt_java_HeadersEnumeration_nextElement(JNIEnv *env, jclass cls,
122 jlong headers_ptr, jlong size, jlong ipos, jlong pos)
123 {
124 nxt_unit_field_t *f, *init_field;
125
126 f = nxt_jlong2ptr(headers_ptr);
127
128 init_field = f + ipos;
129
130 if (pos >= size) {
131 nxt_java_throw_IOException(env, "pos >= size");
132
133 return NULL;
134 }
135
136 f += pos;
137
138 if (f->hash != init_field->hash
139 || f->name_length != init_field->name_length)
140 {
141 nxt_java_throw_IOException(env, "f->hash != hash");
142
143 return NULL;
144 }
145
146 return nxt_java_newString(env, nxt_unit_sptr_get(&f->value),
147 f->value_length);
148 }
149