diff options
author | Max Romanov <max.romanov@nginx.com> | 2020-03-12 17:54:05 +0300 |
---|---|---|
committer | Max Romanov <max.romanov@nginx.com> | 2020-03-12 17:54:05 +0300 |
commit | 2454dfe876c7d761aa46f972addd3e7c97bb8d68 (patch) | |
tree | 119e3b55c7c1ed2b5d7346d2668e6caccb5c6998 | |
parent | 23636ce02cf8a9abc6759b88a117f84b8457a7cd (diff) | |
download | unit-2454dfe876c7d761aa46f972addd3e7c97bb8d68.tar.gz unit-2454dfe876c7d761aa46f972addd3e7c97bb8d68.tar.bz2 |
Introducing readline function in libunit.
Ruby and Java modules now use this function instead of own
implementations.
-rw-r--r-- | src/java/nxt_jni_InputStream.c | 28 | ||||
-rw-r--r-- | src/nxt_unit.c | 38 | ||||
-rw-r--r-- | src/nxt_unit.h | 3 | ||||
-rw-r--r-- | src/ruby/nxt_ruby_stream_io.c | 28 |
4 files changed, 53 insertions, 44 deletions
diff --git a/src/java/nxt_jni_InputStream.c b/src/java/nxt_jni_InputStream.c index b96ff742..3b74b0c1 100644 --- a/src/java/nxt_jni_InputStream.c +++ b/src/java/nxt_jni_InputStream.c @@ -90,40 +90,20 @@ static jint JNICALL nxt_java_InputStream_readLine(JNIEnv *env, jclass cls, jlong req_info_ptr, jarray out, jint off, jint len) { - char *p; - jint size, b_size; uint8_t *data; ssize_t res; - nxt_unit_buf_t *b; nxt_unit_request_info_t *req; req = nxt_jlong2ptr(req_info_ptr); - size = 0; - - for (b = req->content_buf; b; b = nxt_unit_buf_next(b)) { - b_size = b->end - b->free; - p = memchr(b->free, '\n', b_size); - - if (p != NULL) { - p++; - size += p - b->free; - break; - } + data = (*env)->GetPrimitiveArrayCritical(env, out, NULL); - size += b_size; + res = nxt_unit_request_readline_size(req, len); - if (size >= len) { - break; - } + if (res > 0) { + res = nxt_unit_request_read(req, data + off, res); } - len = len < size ? len : size; - - data = (*env)->GetPrimitiveArrayCritical(env, out, NULL); - - res = nxt_unit_request_read(req, data + off, len); - nxt_unit_req_debug(req, "readLine '%.*s'", res, (char *) data + off); (*env)->ReleasePrimitiveArrayCritical(env, out, data, 0); diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 7c3d945c..07717545 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -2428,6 +2428,44 @@ nxt_unit_request_read(nxt_unit_request_info_t *req, void *dst, size_t size) } +ssize_t +nxt_unit_request_readline_size(nxt_unit_request_info_t *req, size_t max_size) +{ + char *p; + size_t l_size, b_size; + nxt_unit_buf_t *b; + + if (req->content_length == 0) { + return 0; + } + + l_size = 0; + + b = req->content_buf; + + while (b != NULL) { + b_size = b->end - b->free; + p = memchr(b->free, '\n', b_size); + + if (p != NULL) { + p++; + l_size += p - b->free; + break; + } + + l_size += b_size; + + if (max_size <= l_size) { + break; + } + + b = nxt_unit_buf_next(b); + } + + return nxt_min(max_size, l_size); +} + + static ssize_t nxt_unit_buf_read(nxt_unit_buf_t **b, uint64_t *len, void *dst, size_t size) { diff --git a/src/nxt_unit.h b/src/nxt_unit.h index c8aaa124..8e9e3015 100644 --- a/src/nxt_unit.h +++ b/src/nxt_unit.h @@ -335,6 +335,9 @@ int nxt_unit_response_write_cb(nxt_unit_request_info_t *req, ssize_t nxt_unit_request_read(nxt_unit_request_info_t *req, void *dst, size_t size); +ssize_t nxt_unit_request_readline_size(nxt_unit_request_info_t *req, + size_t max_size); + void nxt_unit_request_done(nxt_unit_request_info_t *req, int rc); diff --git a/src/ruby/nxt_ruby_stream_io.c b/src/ruby/nxt_ruby_stream_io.c index 7e8b3ce1..cc110035 100644 --- a/src/ruby/nxt_ruby_stream_io.c +++ b/src/ruby/nxt_ruby_stream_io.c @@ -88,9 +88,7 @@ static VALUE nxt_ruby_stream_io_gets(VALUE obj) { VALUE buf; - char *p; - size_t size, b_size; - nxt_unit_buf_t *b; + ssize_t res; nxt_ruby_run_ctx_t *run_ctx; nxt_unit_request_info_t *req; @@ -102,30 +100,20 @@ nxt_ruby_stream_io_gets(VALUE obj) return Qnil; } - size = 0; - - for (b = req->content_buf; b; b = nxt_unit_buf_next(b)) { - b_size = b->end - b->free; - p = memchr(b->free, '\n', b_size); - - if (p != NULL) { - p++; - size += p - b->free; - break; - } - - size += b_size; + res = nxt_unit_request_readline_size(req, SSIZE_MAX); + if (nxt_slow_path(res < 0)) { + return Qnil; } - buf = rb_str_buf_new(size); + buf = rb_str_buf_new(res); - if (buf == Qnil) { + if (nxt_slow_path(buf == Qnil)) { return Qnil; } - size = nxt_unit_request_read(req, RSTRING_PTR(buf), size); + res = nxt_unit_request_read(req, RSTRING_PTR(buf), res); - rb_str_set_len(buf, size); + rb_str_set_len(buf, res); return buf; } |