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_HeaderNamesEnumeration.h"
16
17
18 static jlong JNICALL nxt_java_HeaderNamesEnumeration_nextElementPos(JNIEnv *env,
19 jclass cls, jlong headers_ptr, jlong size, jlong pos);
20 static jstring JNICALL nxt_java_HeaderNamesEnumeration_nextElement(JNIEnv *env,
21 jclass cls, jlong headers_ptr, jlong size, jlong pos);
22
23
24 static jclass nxt_java_HeaderNamesEnumeration_class;
25 static jmethodID nxt_java_HeaderNamesEnumeration_ctor;
26
27
28 int
nxt_java_initHeaderNamesEnumeration(JNIEnv * env,jobject cl)29 nxt_java_initHeaderNamesEnumeration(JNIEnv *env, jobject cl)
30 {
31 int res;
32 jclass cls;
33
34 cls = nxt_java_loadClass(env, cl, "nginx.unit.HeaderNamesEnumeration");
35 if (cls == NULL) {
36 return NXT_UNIT_ERROR;
37 }
38
39 nxt_java_HeaderNamesEnumeration_class = (*env)->NewGlobalRef(env, cls);
40 (*env)->DeleteLocalRef(env, cls);
41 cls = nxt_java_HeaderNamesEnumeration_class;
42
43 nxt_java_HeaderNamesEnumeration_ctor = (*env)->GetMethodID(env, cls,
44 "<init>", "(JJ)V");
45 if (nxt_java_HeaderNamesEnumeration_ctor == NULL) {
46 (*env)->DeleteGlobalRef(env, cls);
47 return NXT_UNIT_ERROR;
48 }
49
50 JNINativeMethod hnenum_methods[] = {
51 { (char *) "nextElementPos",
52 (char *) "(JJJ)J",
53 nxt_java_HeaderNamesEnumeration_nextElementPos },
54
55 { (char *) "nextElement",
56 (char *) "(JJJ)Ljava/lang/String;",
57 nxt_java_HeaderNamesEnumeration_nextElement },
58 };
59
60 res = (*env)->RegisterNatives(env, nxt_java_HeaderNamesEnumeration_class,
61 hnenum_methods,
62 sizeof(hnenum_methods)
63 / sizeof(hnenum_methods[0]));
64
65 nxt_unit_debug(NULL, "registered HeaderNamesEnumeration 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_newHeaderNamesEnumeration(JNIEnv * env,nxt_unit_field_t * f,uint32_t fields_count)77 nxt_java_newHeaderNamesEnumeration(JNIEnv *env, nxt_unit_field_t *f,
78 uint32_t fields_count)
79 {
80 return (*env)->NewObject(env,
81 nxt_java_HeaderNamesEnumeration_class,
82 nxt_java_HeaderNamesEnumeration_ctor, nxt_ptr2jlong(f),
83 (jlong) fields_count);
84 }
85
86
87 static jlong JNICALL
nxt_java_HeaderNamesEnumeration_nextElementPos(JNIEnv * env,jclass cls,jlong headers_ptr,jlong size,jlong pos)88 nxt_java_HeaderNamesEnumeration_nextElementPos(JNIEnv *env, jclass cls,
89 jlong headers_ptr, jlong size, jlong pos)
90 {
91 nxt_unit_field_t *f;
92
93 f = nxt_jlong2ptr(headers_ptr);
94
95 if (pos >= size) {
96 return size;
97 }
98
99 if (pos > 0) {
100 while (pos < size
101 && f[pos].hash == f[pos - 1].hash
102 && f[pos].name_length == f[pos - 1].name_length)
103 {
104 pos++;
105 }
106 }
107
108 return pos;
109 }
110
111
112 static jstring JNICALL
nxt_java_HeaderNamesEnumeration_nextElement(JNIEnv * env,jclass cls,jlong headers_ptr,jlong size,jlong pos)113 nxt_java_HeaderNamesEnumeration_nextElement(JNIEnv *env, jclass cls,
114 jlong headers_ptr, jlong size, jlong pos)
115 {
116 char *name, tmp;
117 jstring res;
118 nxt_unit_field_t *f;
119
120 f = nxt_jlong2ptr(headers_ptr);
121
122 if (pos > 0) {
123 while (pos < size
124 && f[pos].hash == f[pos - 1].hash
125 && f[pos].name_length == f[pos - 1].name_length)
126 {
127 pos++;
128 }
129 }
130
131 if (pos >= size) {
132 nxt_java_throw_NoSuchElementException(env, "pos >= size");
133
134 return NULL;
135 }
136
137 f += pos;
138
139 name = nxt_unit_sptr_get(&f->name);
140 tmp = name[f->name_length];
141
142 if (tmp != '\0') {
143 name[f->name_length] = '\0';
144 }
145
146 res = (*env)->NewStringUTF(env, name);
147
148 if (tmp != '\0') {
149 name[f->name_length] = tmp;
150 }
151
152 return res;
153 }
154