diff options
author | gengjiawen <technicalcute@gmail.com> | 2019-11-15 23:47:45 +0800 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-11-18 15:45:52 +0100 |
commit | 7ae13c360b3a6e3c843432312f7b6f4f137d3cb9 (patch) | |
tree | cfba705333ba865ed5abaaa1f0f3132eaa337b92 /deps/nghttp2/lib/nghttp2_hd_huffman.c | |
parent | 20b7f4a5e93bc587976f19c198fa9291dca79674 (diff) | |
download | android-node-v8-7ae13c360b3a6e3c843432312f7b6f4f137d3cb9.tar.gz android-node-v8-7ae13c360b3a6e3c843432312f7b6f4f137d3cb9.tar.bz2 android-node-v8-7ae13c360b3a6e3c843432312f7b6f4f137d3cb9.zip |
deps: update nghttp2 to 1.40.0
PR-URL: https://github.com/nodejs/node/pull/30493
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'deps/nghttp2/lib/nghttp2_hd_huffman.c')
-rw-r--r-- | deps/nghttp2/lib/nghttp2_hd_huffman.c | 223 |
1 files changed, 68 insertions, 155 deletions
diff --git a/deps/nghttp2/lib/nghttp2_hd_huffman.c b/deps/nghttp2/lib/nghttp2_hd_huffman.c index 8881aacb2e..ac90f49c44 100644 --- a/deps/nghttp2/lib/nghttp2_hd_huffman.c +++ b/deps/nghttp2/lib/nghttp2_hd_huffman.c @@ -29,114 +29,7 @@ #include <stdio.h> #include "nghttp2_hd.h" - -/* - * Encodes huffman code |sym| into |*dest_ptr|, whose least |rembits| - * bits are not filled yet. The |rembits| must be in range [1, 8], - * inclusive. At the end of the process, the |*dest_ptr| is updated - * and points where next output should be placed. The number of - * unfilled bits in the pointed location is returned. - */ -static ssize_t huff_encode_sym(nghttp2_bufs *bufs, size_t *avail_ptr, - size_t rembits, const nghttp2_huff_sym *sym) { - int rv; - size_t nbits = sym->nbits; - uint32_t code = sym->code; - - /* We assume that sym->nbits <= 32 */ - if (rembits > nbits) { - nghttp2_bufs_fast_orb_hold(bufs, (uint8_t)(code << (rembits - nbits))); - return (ssize_t)(rembits - nbits); - } - - if (rembits == nbits) { - nghttp2_bufs_fast_orb(bufs, (uint8_t)code); - --*avail_ptr; - return 8; - } - - nghttp2_bufs_fast_orb(bufs, (uint8_t)(code >> (nbits - rembits))); - --*avail_ptr; - - nbits -= rembits; - if (nbits & 0x7) { - /* align code to MSB byte boundary */ - code <<= 8 - (nbits & 0x7); - } - - if (*avail_ptr < (nbits + 7) / 8) { - /* slow path */ - if (nbits > 24) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 24)); - if (rv != 0) { - return rv; - } - nbits -= 8; - } - if (nbits > 16) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 16)); - if (rv != 0) { - return rv; - } - nbits -= 8; - } - if (nbits > 8) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 8)); - if (rv != 0) { - return rv; - } - nbits -= 8; - } - if (nbits == 8) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)code); - if (rv != 0) { - return rv; - } - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return 8; - } - - rv = nghttp2_bufs_addb_hold(bufs, (uint8_t)code); - if (rv != 0) { - return rv; - } - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return (ssize_t)(8 - nbits); - } - - /* fast path, since most code is less than 8 */ - if (nbits < 8) { - nghttp2_bufs_fast_addb_hold(bufs, (uint8_t)code); - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return (ssize_t)(8 - nbits); - } - - /* handle longer code path */ - if (nbits > 24) { - nghttp2_bufs_fast_addb(bufs, (uint8_t)(code >> 24)); - nbits -= 8; - } - - if (nbits > 16) { - nghttp2_bufs_fast_addb(bufs, (uint8_t)(code >> 16)); - nbits -= 8; - } - - if (nbits > 8) { - nghttp2_bufs_fast_addb(bufs, (uint8_t)(code >> 8)); - nbits -= 8; - } - - if (nbits == 8) { - nghttp2_bufs_fast_addb(bufs, (uint8_t)code); - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return 8; - } - - nghttp2_bufs_fast_addb_hold(bufs, (uint8_t)code); - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return (ssize_t)(8 - nbits); -} +#include "nghttp2_net.h" size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len) { size_t i; @@ -151,81 +44,101 @@ size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len) { int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src, size_t srclen) { - int rv; - ssize_t rembits = 8; - size_t i; + const nghttp2_huff_sym *sym; + const uint8_t *end = src + srclen; + uint64_t code = 0; + uint32_t x; + size_t nbits = 0; size_t avail; + int rv; avail = nghttp2_bufs_cur_avail(bufs); - for (i = 0; i < srclen; ++i) { - const nghttp2_huff_sym *sym = &huff_sym_table[src[i]]; - if (rembits == 8) { - if (avail) { - nghttp2_bufs_fast_addb_hold(bufs, 0); - } else { - rv = nghttp2_bufs_addb_hold(bufs, 0); - if (rv != 0) { - return rv; - } - avail = nghttp2_bufs_cur_avail(bufs); + for (; src != end;) { + sym = &huff_sym_table[*src++]; + code |= (uint64_t)sym->code << (32 - nbits); + nbits += sym->nbits; + if (nbits < 32) { + continue; + } + if (avail >= 4) { + x = htonl((uint32_t)(code >> 32)); + memcpy(bufs->cur->buf.last, &x, 4); + bufs->cur->buf.last += 4; + avail -= 4; + code <<= 32; + nbits -= 32; + continue; + } + + for (; nbits >= 8;) { + rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56)); + if (rv != 0) { + return rv; } + code <<= 8; + nbits -= 8; } - rembits = huff_encode_sym(bufs, &avail, (size_t)rembits, sym); - if (rembits < 0) { - return (int)rembits; + + avail = nghttp2_bufs_cur_avail(bufs); + } + + for (; nbits >= 8;) { + rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56)); + if (rv != 0) { + return rv; } + code <<= 8; + nbits -= 8; } - /* 256 is special terminal symbol, pad with its prefix */ - if (rembits < 8) { - /* if rembits < 8, we should have at least 1 buffer space - available */ - const nghttp2_huff_sym *sym = &huff_sym_table[256]; - assert(avail); - /* Caution we no longer adjust avail here */ - nghttp2_bufs_fast_orb( - bufs, (uint8_t)(sym->code >> (sym->nbits - (size_t)rembits))); + + if (nbits) { + rv = nghttp2_bufs_addb( + bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1))); + if (rv != 0) { + return rv; + } } return 0; } void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) { - ctx->state = 0; - ctx->accept = 1; + ctx->fstate = NGHTTP2_HUFF_ACCEPTED; } ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, nghttp2_buf *buf, const uint8_t *src, size_t srclen, int final) { - size_t i; + const uint8_t *end = src + srclen; + nghttp2_huff_decode node = {ctx->fstate, 0}; + const nghttp2_huff_decode *t = &node; + uint8_t c; /* We use the decoding algorithm described in http://graphics.ics.uci.edu/pub/Prefix.pdf */ - for (i = 0; i < srclen; ++i) { - const nghttp2_huff_decode *t; - - t = &huff_decode_table[ctx->state][src[i] >> 4]; - if (t->flags & NGHTTP2_HUFF_FAIL) { - return NGHTTP2_ERR_HEADER_COMP; - } - if (t->flags & NGHTTP2_HUFF_SYM) { + for (; src != end;) { + c = *src++; + t = &huff_decode_table[t->fstate & 0x1ff][c >> 4]; + if (t->fstate & NGHTTP2_HUFF_SYM) { *buf->last++ = t->sym; } - t = &huff_decode_table[t->state][src[i] & 0xf]; - if (t->flags & NGHTTP2_HUFF_FAIL) { - return NGHTTP2_ERR_HEADER_COMP; - } - if (t->flags & NGHTTP2_HUFF_SYM) { + t = &huff_decode_table[t->fstate & 0x1ff][c & 0xf]; + if (t->fstate & NGHTTP2_HUFF_SYM) { *buf->last++ = t->sym; } - - ctx->state = t->state; - ctx->accept = (t->flags & NGHTTP2_HUFF_ACCEPTED) != 0; } - if (final && !ctx->accept) { + + ctx->fstate = t->fstate; + + if (final && !(ctx->fstate & NGHTTP2_HUFF_ACCEPTED)) { return NGHTTP2_ERR_HEADER_COMP; } - return (ssize_t)i; + + return (ssize_t)srclen; +} + +int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) { + return ctx->fstate == 0x100; } |