xref: /unit/src/java/nxt_jni_HeaderNamesEnumeration.c (revision 977:4f9268f27b57)
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