summaryrefslogtreecommitdiff
path: root/deps/nghttp2/lib/nghttp2_hd_huffman.c
diff options
context:
space:
mode:
authorgengjiawen <technicalcute@gmail.com>2019-11-15 23:47:45 +0800
committerAnna Henningsen <anna@addaleax.net>2019-11-18 15:45:52 +0100
commit7ae13c360b3a6e3c843432312f7b6f4f137d3cb9 (patch)
treecfba705333ba865ed5abaaa1f0f3132eaa337b92 /deps/nghttp2/lib/nghttp2_hd_huffman.c
parent20b7f4a5e93bc587976f19c198fa9291dca79674 (diff)
downloadandroid-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.c223
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;
}