xref: /unit/src/java/nxt_jni_HeadersEnumeration.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_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