aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexis La Goutte <alexis.lagoutte@gmail.com>2014-05-30 15:14:40 -0400
committerMichael Mann <mmann78@netscape.net>2014-05-31 13:11:05 +0000
commit62fd14cbd713765e24212595f8778164dd5b7b44 (patch)
tree09838f6a126050e4f7c9a29c70e52e5e2e1aabbe
parent531541660b31e87922021158454b2441e67935fa (diff)
Add nghttp2 lib (HPACK)
Change-Id: I2a361951924045035a2a5d38f943e6b97c170f36 Reviewed-on: https://code.wireshark.org/review/1623 Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com> Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--configure.ac1
-rw-r--r--wsutil/CMakeLists.txt5
-rw-r--r--wsutil/Makefile.am6
-rw-r--r--wsutil/Makefile.nmake22
-rw-r--r--wsutil/nghttp2/Makefile.am63
-rw-r--r--wsutil/nghttp2/Makefile.common52
-rw-r--r--wsutil/nghttp2/Makefile.nmake43
-rw-r--r--wsutil/nghttp2/README.nghttp293
-rw-r--r--wsutil/nghttp2/nghttp2/nghttp2.h3037
-rw-r--r--wsutil/nghttp2/nghttp2/nghttp2ver.h42
-rw-r--r--wsutil/nghttp2/nghttp2_buf.c477
-rw-r--r--wsutil/nghttp2/nghttp2_buf.h371
-rw-r--r--wsutil/nghttp2/nghttp2_hd.c2056
-rw-r--r--wsutil/nghttp2/nghttp2_hd.h353
-rw-r--r--wsutil/nghttp2/nghttp2_hd_huffman.c205
-rw-r--r--wsutil/nghttp2/nghttp2_hd_huffman.h70
-rw-r--r--wsutil/nghttp2/nghttp2_hd_huffman_data.c5152
-rw-r--r--wsutil/nghttp2/nghttp2_helper.c409
-rw-r--r--wsutil/nghttp2/nghttp2_helper.h135
-rw-r--r--wsutil/nghttp2/nghttp2_int.h50
-rw-r--r--wsutil/nghttp2/nghttp2_net.h44
21 files changed, 12683 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 804e136dd9..d17b28f210 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2937,6 +2937,7 @@ AC_OUTPUT(
tools/lemon/Makefile
wiretap/Makefile
wsutil/Makefile
+ wsutil/nghttp2/Makefile
echld/Makefile
_CUSTOM_AC_OUTPUT_
,)
diff --git a/wsutil/CMakeLists.txt b/wsutil/CMakeLists.txt
index b7e8dc4913..eb319c4520 100644
--- a/wsutil/CMakeLists.txt
+++ b/wsutil/CMakeLists.txt
@@ -68,6 +68,11 @@ set(WSUTIL_FILES
type_util.c
u3.c
unicode-utils.c
+ nghttp2/nghttp2_buf.c
+ nghttp2/nghttp2_hd.c
+ nghttp2/nghttp2_hd_huffman.c
+ nghttp2/nghttp2_hd_huffman_data.c
+ nghttp2/nghttp2_helper.c
${WSUTIL_PLATFORM_FILES}
)
diff --git a/wsutil/Makefile.am b/wsutil/Makefile.am
index 0a971643b1..ed82c9ab6e 100644
--- a/wsutil/Makefile.am
+++ b/wsutil/Makefile.am
@@ -18,6 +18,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+SUBDIRS = nghttp2
+
+DIST_SUBDIRS = $(SUBDIRS)
+
ACLOCAL_AMFLAGS = `../aclocal-flags`
# Optional objects that I know how to build. These will be
@@ -84,11 +88,13 @@ EXTRA_libwsutil_la_SOURCES= \
wsgetopt_int.h
libwsutil_la_DEPENDENCIES= \
+ nghttp2/libnghttp2.la \
$(wsutil_optional_objects)
libwsutil_la_LIBADD = \
@GLIB_LIBS@ \
@LIBGCRYPT_LIBS@ \
+ nghttp2/libnghttp2.la \
$(wsutil_optional_objects)
EXTRA_DIST = \
diff --git a/wsutil/Makefile.nmake b/wsutil/Makefile.nmake
index bd45873f1f..873a4348cd 100644
--- a/wsutil/Makefile.nmake
+++ b/wsutil/Makefile.nmake
@@ -27,13 +27,19 @@ OBJECTS = file_util.obj \
inet_pton.obj \
$(LIBWSUTIL_SRC:.c=.obj) \
strptime.obj \
- wsgetopt.obj
+ wsgetopt.obj \
+ nghttp2/nghttp2_buf.obj \
+ nghttp2/nghttp2_hd.obj \
+ nghttp2/nghttp2_hd_huffman.obj \
+ nghttp2/nghttp2_hd_huffman_data.obj \
+ nghttp2/nghttp2_helper.obj
# For use when making libwsutil.dll
libwsutil.lib: libwsutil.dll
libwsutil.exp: libwsutil.dll
-libwsutil.dll : $(OBJECTS) ..\image\libwsutil.res
+libwsutil.dll : $(OBJECTS) nghttp ..\image\libwsutil.res
+ @echo Linking libwsutil.dll
$(link) $(dlllflags) $(conlibsdll) shell32.lib \
$(LOCAL_LDFLAGS) $(DLL_LDFLAGS) \
/OUT:libwsutil.dll \
@@ -41,7 +47,7 @@ libwsutil.dll : $(OBJECTS) ..\image\libwsutil.res
..\image\libwsutil.res \
$(OBJECTS) $(libwsutil_LIBS)
-clean :
+clean-local:
rm -f $(OBJECTS) \
libwsutil.lib \
libwsutil.exp \
@@ -49,10 +55,20 @@ clean :
libwsutil.dll.manifest \
*.pdb *.sbr
+clean: clean-local
+ cd nghttp2
+ $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake clean
+ cd ..
+
distclean: clean
maintainer-clean: distclean
+nghttp: ..\config.h
+ cd nghttp2
+ $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake
+ cd ..
+
checkapi:
## $(PERL) ../tools/checkAPIs.pl -g abort -g termoutput \
$(PERL) ../tools/checkAPIs.pl -g termoutput -build \
diff --git a/wsutil/nghttp2/Makefile.am b/wsutil/nghttp2/Makefile.am
new file mode 100644
index 0000000000..ebb0891a45
--- /dev/null
+++ b/wsutil/nghttp2/Makefile.am
@@ -0,0 +1,63 @@
+# Makefile.am
+# Automake file for libnghttp2 library
+#
+# Wireshark - Network traffic analyzer
+# By Gerald Combs <gerald@wireshark.org>
+# Copyright 1998 Gerald Combs
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+if HAVE_WARNINGS_AS_ERRORS
+AM_CFLAGS = -Werror
+endif
+
+include Makefile.common
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ $(LIBNGHTTP2_CFLAGS)
+
+noinst_LTLIBRARIES = libnghttp2.la
+
+CLEANFILES = \
+ libnghttp2.a \
+ libnghttp2.la \
+ *~
+
+DISTCLEANFILES =
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
+
+libnghttp2_la_SOURCES = \
+ $(LIBNGHTTP2_SRC) \
+ $(LIBNGHTTP2_INCLUDES)
+
+EXTRA_DIST = \
+ Makefile.common \
+ Makefile.nmake
+
+#
+# Editor modelines - http://www.wireshark.org/tools/modelines.html
+#
+# Local variables:
+# c-basic-offset: 8
+# tab-width: 8
+# indent-tabs-mode: t
+# End:
+#
+# vi: set shiftwidth=8 tabstop=8 noexpandtab:
+# :indentSize=8:tabSize=8:noTabs=false:
+#
diff --git a/wsutil/nghttp2/Makefile.common b/wsutil/nghttp2/Makefile.common
new file mode 100644
index 0000000000..2e8781daaa
--- /dev/null
+++ b/wsutil/nghttp2/Makefile.common
@@ -0,0 +1,52 @@
+# Makefile.common
+# Contains the stuff from Makefile.am and Makefile.nmake that is
+# a) common to both files and
+# b) portable between both files
+#
+# Wireshark - Network traffic analyzer
+# By Gerald Combs <gerald@wireshark.org>
+# Copyright 1998 Gerald Combs
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+LIBNGHTTP2_SRC = \
+ nghttp2_buf.c \
+ nghttp2_hd.c \
+ nghttp2_hd_huffman.c \
+ nghttp2_hd_huffman_data.c \
+ nghttp2_helper.c
+
+LIBNGHTTP2_INCLUDES = \
+ nghttp2_buf.h \
+ nghttp2_ent.h \
+ nghttp2_hd.h \
+ nghttp2_hd_huffman.h \
+ nghttp2_helper.h \
+ nghttp2/nghttp2.h \
+ nghttp2/nghttp2ver.h
+
+
+#
+# Editor modelines - http://www.wireshark.org/tools/modelines.html
+#
+# Local variables:
+# c-basic-offset: 8
+# tab-width: 8
+# indent-tabs-mode: t
+# End:
+#
+# vi: set shiftwidth=8 tabstop=8 noexpandtab:
+# :indentSize=8:tabSize=8:noTabs=false:
+#
diff --git a/wsutil/nghttp2/Makefile.nmake b/wsutil/nghttp2/Makefile.nmake
new file mode 100644
index 0000000000..0f4e747e1e
--- /dev/null
+++ b/wsutil/nghttp2/Makefile.nmake
@@ -0,0 +1,43 @@
+## Makefile for building nghttp2.lib with Microsoft C and nmake
+## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
+#
+
+include ..\..\config.nmake
+include Makefile.common
+
+############### no need to modify below this line #########
+
+CFLAGS=$(WARNINGS_ARE_ERRORS) $(STANDARD_CFLAGS) \
+ /I../.. $(GLIB_CFLAGS) -DWS_BUILD_DLL
+
+.c.obj::
+ $(CC) $(CFLAGS) -Fd.\ -c $<
+
+NGHTTP2_OBJECTS = $(LIBNGHTTP2_SRC:.c=.obj)
+
+nghttp2.lib: $(NGHTTP2_OBJECTS)
+ link /lib /out:nghttp2.lib $(NGHTTP2_OBJECTS)
+
+clean:
+ rm -f $(NGHTTP2_OBJECTS) nghttp2.lib *.pdb *.sbr
+
+distclean: clean
+
+maintainer-clean: distclean
+
+checkapi:
+ $(PERL) ../../tools/checkAPIs.pl -g termoutput -build \
+ $(LIBNGHTTP2_SRC)
+
+#
+# Editor modelines - http://www.wireshark.org/tools/modelines.html
+#
+# Local variables:
+# c-basic-offset: 8
+# tab-width: 8
+# indent-tabs-mode: t
+# End:
+#
+# vi: set shiftwidth=8 tabstop=8 noexpandtab:
+# :indentSize=8:tabSize=8:noTabs=false:
+#
diff --git a/wsutil/nghttp2/README.nghttp2 b/wsutil/nghttp2/README.nghttp2
new file mode 100644
index 0000000000..85ab13799b
--- /dev/null
+++ b/wsutil/nghttp2/README.nghttp2
@@ -0,0 +1,93 @@
+Code from nghttp2 library ( https://github.com/tatsuhiro-t/nghttp2)
+Thanks for Tatsuhiro Tsujikawa for permission to use nghttp2 lib.
+
+Update library from source
+
+download (clone) last release of nghttp2
+and in folder wsutil/nghttp2 copy following file
+
+cp ../../../nghttp2/lib/nghttp2_buf.[ch] .
+cp ../../../nghttp2/lib/nghttp2_hd*.[ch] .
+cp ../../../nghttp2/lib/nghttp2_helper.[ch] .
+cp ../../../nghttp2/lib/nghttp2_int.h .
+cp ../../../nghttp2/lib/nghttp2_net.h .
+cp ../../../nghttp2/lib/includes/nghttp2/nghttp2.h nghttp2/
+cp ../../../nghttp2/lib/includes/nghttp2/nghttp2ver.h nghttp2/
+
+Change path to nghttp2.h
+find . -name "nghttp2*" -type f -exec sed -i 's/<nghttp2\/nghttp2.h>/<wsutil\/nghttp2\/nghttp2\/nghttp2.h>/g' {} \;
+
+Fix c++-compat error
+
+in nghttp2/nghttp2_helper.h remove check for CONFIG.H
+
+in nghttp2/nghttp2/nghttp2.h
+
+Add on the top
+#include "ws_symbol_export.h"
+
+#include "config.h"
+
+Replace
+
+#include <stdint.h>
+
+By
+
+#ifdef _MSC_VER
+
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#else
+#include <stdint.h>
+#endif
+
+Replace
+
+#include <nghttp2/nghttp2ver.h>
+
+by
+
+#include <wsutil/nghttp2/nghttp2/nghttp2ver.h>
+
+
+and export (WS_DLL_PUBLIC) following function :
+nghttp2_hd_inflate_end_headers
+nghttp2_hd_inflate_new
+nghttp2_hd_inflate_hd
diff --git a/wsutil/nghttp2/nghttp2/nghttp2.h b/wsutil/nghttp2/nghttp2/nghttp2.h
new file mode 100644
index 0000000000..d51ebd87ca
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2/nghttp2.h
@@ -0,0 +1,3037 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013, 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_H
+#define NGHTTP2_H
+
+#include "ws_symbol_export.h"
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#ifdef _MSC_VER
+
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#else
+#include <stdint.h>
+#endif
+#include <sys/types.h>
+
+#include <wsutil/nghttp2/nghttp2/nghttp2ver.h>
+
+/**
+ * @macro
+ *
+ * The protocol version identification string of this library
+ * supports. This identifier is used if HTTP/2 is used over TLS.
+ */
+#define NGHTTP2_PROTO_VERSION_ID "h2-12"
+/**
+ * @macro
+ *
+ * The length of :macro:`NGHTTP2_PROTO_VERSION_ID`.
+ */
+#define NGHTTP2_PROTO_VERSION_ID_LEN 5
+
+/**
+ * @macro
+ *
+ * The protocol version identification string of this library
+ * supports. This identifier is used if HTTP/2 is used over cleartext
+ * TCP.
+ */
+#define NGHTTP2_CLEARTEXT_PROTO_VERSION_ID "h2c-12"
+
+/**
+ * @macro
+ *
+ * The length of :macro:`NGHTTP2_CLEARTEXT_PROTO_VERSION_ID`.
+ */
+#define NGHTTP2_CLEARTEXT_PROTO_VERSION_ID_LEN 6
+
+struct nghttp2_session;
+/**
+ * @struct
+ *
+ * The primary structure to hold the resources needed for a HTTP/2
+ * session. The details of this structure are intentionally hidden
+ * from the public API.
+ */
+typedef struct nghttp2_session nghttp2_session;
+
+/**
+ * @macro
+ *
+ * The age of :type:`nghttp2_info`
+ */
+#define NGHTTP2_VERSION_AGE 1
+
+/**
+ * @struct
+ *
+ * This struct is what `nghttp2_version()` returns. It holds
+ * information about the particular nghttp2 version.
+ */
+typedef struct {
+ /**
+ * Age of this struct. This instance of nghttp2 sets it to
+ * :macro:`NGHTTP2_VERSION_AGE` but a future version may bump it and
+ * add more struct fields at the bottom
+ */
+ int age;
+ /**
+ * the :macro:`NGHTTP2_VERSION_NUM` number (since age ==1)
+ */
+ int version_num;
+ /**
+ * points to the :macro:`NGHTTP2_VERSION` string (since age ==1)
+ */
+ const char *version_str;
+ /**
+ * points to the :macro:`NGHTTP2_PROTO_VERSION_ID` string this
+ * instance implements (since age ==1)
+ */
+ const char *proto_str;
+ /* -------- the above fields all exist when age == 1 */
+} nghttp2_info;
+
+/**
+ * @macro
+ *
+ * The default weight of stream dependency.
+ */
+#define NGHTTP2_DEFAULT_WEIGHT 16
+
+/**
+ * @macro
+ *
+ * The maximum weight of stream dependency.
+ */
+#define NGHTTP2_MAX_WEIGHT 256
+
+/**
+ * @macro
+ *
+ * The minimum weight of stream dependency.
+ */
+#define NGHTTP2_MIN_WEIGHT 1
+
+/**
+ * @macro
+ *
+ * The maximum window size
+ */
+#define NGHTTP2_MAX_WINDOW_SIZE ((int32_t)((1U << 31) - 1))
+
+/**
+ * @macro
+ *
+ * The initial window size for stream level flow control.
+ */
+#define NGHTTP2_INITIAL_WINDOW_SIZE ((1 << 16) - 1)
+/**
+ * @macro
+ *
+ * The initial window size for connection level flow control.
+ */
+#define NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE ((1 << 16) - 1)
+
+/**
+ * @macro
+ *
+ * The default header table size.
+ */
+#define NGHTTP2_DEFAULT_HEADER_TABLE_SIZE (1 << 12)
+
+/**
+ * @macro
+ *
+ * The client connection preface.
+ */
+#define NGHTTP2_CLIENT_CONNECTION_PREFACE "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
+
+/**
+ * @macro
+ *
+ * The length of :macro:`NGHTTP2_CLIENT_CONNECTION_PREFACE`.
+ */
+#define NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN 24
+
+/**
+ * @macro
+ *
+ * The client connection header. This macro is obsoleted by
+ * NGHTTP2_CLIENT_CONNECTION_PREFACE.
+ */
+#define NGHTTP2_CLIENT_CONNECTION_HEADER NGHTTP2_CLIENT_CONNECTION_PREFACE
+
+/**
+ * @macro
+ *
+ * The length of :macro:`NGHTTP2_CLIENT_CONNECTION_HEADER`.
+ */
+#define NGHTTP2_CLIENT_CONNECTION_HEADER_LEN \
+ NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN
+
+/**
+ * @enum
+ *
+ * Error codes used in this library. The code range is [-999, -500],
+ * inclusive. The following values are defined:
+ */
+typedef enum {
+ /**
+ * Invalid argument passed.
+ */
+ NGHTTP2_ERR_INVALID_ARGUMENT = -501,
+ /**
+ * Ouf of buffer space.
+ */
+ NGHTTP2_ERR_BUFFER_ERROR = -502,
+ /**
+ * The specified protocol version is not supported.
+ */
+ NGHTTP2_ERR_UNSUPPORTED_VERSION = -503,
+ /**
+ * Used as a return value from :type:`nghttp2_send_callback` and
+ * :type:`nghttp2_recv_callback` to indicate that the operation
+ * would block.
+ */
+ NGHTTP2_ERR_WOULDBLOCK = -504,
+ /**
+ * General protocol error
+ */
+ NGHTTP2_ERR_PROTO = -505,
+ /**
+ * The frame is invalid.
+ */
+ NGHTTP2_ERR_INVALID_FRAME = -506,
+ /**
+ * The peer performed a shutdown on the connection.
+ */
+ NGHTTP2_ERR_EOF = -507,
+ /**
+ * Used as a return value from
+ * :func:`nghttp2_data_source_read_callback` to indicate that data
+ * transfer is postponed. See
+ * :func:`nghttp2_data_source_read_callback` for details.
+ */
+ NGHTTP2_ERR_DEFERRED = -508,
+ /**
+ * Stream ID has reached the maximum value. Therefore no stream ID
+ * is available.
+ */
+ NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE = -509,
+ /**
+ * The stream is already closed; or the stream ID is invalid.
+ */
+ NGHTTP2_ERR_STREAM_CLOSED = -510,
+ /**
+ * RST_STREAM has been added to the outbound queue. The stream is
+ * in closing state.
+ */
+ NGHTTP2_ERR_STREAM_CLOSING = -511,
+ /**
+ * The transmission is not allowed for this stream (e.g., a frame
+ * with END_STREAM flag set has already sent).
+ */
+ NGHTTP2_ERR_STREAM_SHUT_WR = -512,
+ /**
+ * The stream ID is invalid.
+ */
+ NGHTTP2_ERR_INVALID_STREAM_ID = -513,
+ /**
+ * The state of the stream is not valid (e.g., DATA cannot be sent
+ * to the stream if response HEADERS has not been sent).
+ */
+ NGHTTP2_ERR_INVALID_STREAM_STATE = -514,
+ /**
+ * Another DATA frame has already been deferred.
+ */
+ NGHTTP2_ERR_DEFERRED_DATA_EXIST = -515,
+ /**
+ * Starting new stream is not allowed (e.g., GOAWAY has been sent
+ * and/or received).
+ */
+ NGHTTP2_ERR_START_STREAM_NOT_ALLOWED = -516,
+ /**
+ * GOAWAY has already been sent.
+ */
+ NGHTTP2_ERR_GOAWAY_ALREADY_SENT = -517,
+ /**
+ * The received frame contains the invalid header block (e.g., There
+ * are duplicate header names; or the header names are not encoded
+ * in US-ASCII character set and not lower cased; or the header name
+ * is zero-length string; or the header value contains multiple
+ * in-sequence NUL bytes).
+ */
+ NGHTTP2_ERR_INVALID_HEADER_BLOCK = -518,
+ /**
+ * Indicates that the context is not suitable to perform the
+ * requested operation.
+ */
+ NGHTTP2_ERR_INVALID_STATE = -519,
+ /**
+ * The user callback function failed due to the temporal error.
+ */
+ NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE = -521,
+ /**
+ * The length of the frame is invalid, either too large or too small.
+ */
+ NGHTTP2_ERR_FRAME_SIZE_ERROR = -522,
+ /**
+ * Header block inflate/deflate error.
+ */
+ NGHTTP2_ERR_HEADER_COMP = -523,
+ /**
+ * Flow control error
+ */
+ NGHTTP2_ERR_FLOW_CONTROL = -524,
+ /**
+ * Insufficient buffer size given to function.
+ */
+ NGHTTP2_ERR_INSUFF_BUFSIZE = -525,
+ /**
+ * Callback was paused by the application
+ */
+ NGHTTP2_ERR_PAUSE = -526,
+ /**
+ * There are too many in-flight SETTING frame and no more
+ * transmission of SETTINGS is allowed.
+ */
+ NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS = -527,
+ /**
+ * The server push is disabled.
+ */
+ NGHTTP2_ERR_PUSH_DISABLED = -528,
+ /**
+ * DATA frame for a given stream has been already submitted and has
+ * not been fully processed yet.
+ */
+ NGHTTP2_ERR_DATA_EXIST = -529,
+ /**
+ * The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
+ * under unexpected condition and processing was terminated (e.g.,
+ * out of memory). If application receives this error code, it must
+ * stop using that :type:`nghttp2_session` object and only allowed
+ * operation for that object is deallocate it using
+ * `nghttp2_session_del()`.
+ */
+ NGHTTP2_ERR_FATAL = -900,
+ /**
+ * Out of memory. This is a fatal error.
+ */
+ NGHTTP2_ERR_NOMEM = -901,
+ /**
+ * The user callback function failed. This is a fatal error.
+ */
+ NGHTTP2_ERR_CALLBACK_FAILURE = -902
+} nghttp2_error;
+
+typedef enum {
+ NGHTTP2_MSG_MORE
+} nghttp2_io_flag;
+
+/**
+ * @enum
+ *
+ * The flags for header field name/value pair.
+ */
+typedef enum {
+ /**
+ * No flag set.
+ */
+ NGHTTP2_NV_FLAG_NONE = 0,
+ /**
+ * Indicates that this name/value pair must not be indexed.
+ */
+ NGHTTP2_NV_FLAG_NO_INDEX = 0x01
+} nghttp2_nv_flag;
+
+/**
+ * @struct
+ *
+ * The name/value pair, which mainly used to represent header fields.
+ */
+typedef struct {
+ /**
+ * The |name| byte string, which is not necessarily ``NULL``
+ * terminated.
+ */
+ uint8_t *name;
+ /**
+ * The |value| byte string, which is not necessarily ``NULL``
+ * terminated.
+ */
+ uint8_t *value;
+ /**
+ * The length of the |name|.
+ */
+ size_t namelen;
+ /**
+ * The length of the |value|.
+ */
+ size_t valuelen;
+ /**
+ * Bitwise OR of one or more of :type:`nghttp2_nv_flag`.
+ */
+ uint8_t flags;
+} nghttp2_nv;
+
+/**
+ * @enum
+ * The control frame types in HTTP/2.
+ */
+typedef enum {
+ /**
+ * The DATA frame.
+ */
+ NGHTTP2_DATA = 0,
+ /**
+ * The HEADERS frame.
+ */
+ NGHTTP2_HEADERS = 0x01,
+ /**
+ * The PRIORITY frame.
+ */
+ NGHTTP2_PRIORITY = 0x02,
+ /**
+ * The RST_STREAM frame.
+ */
+ NGHTTP2_RST_STREAM = 0x03,
+ /**
+ * The SETTINGS frame.
+ */
+ NGHTTP2_SETTINGS = 0x04,
+ /**
+ * The PUSH_PROMISE frame.
+ */
+ NGHTTP2_PUSH_PROMISE = 0x05,
+ /**
+ * The PING frame.
+ */
+ NGHTTP2_PING = 0x06,
+ /**
+ * The GOAWAY frame.
+ */
+ NGHTTP2_GOAWAY = 0x07,
+ /**
+ * The WINDOW_UPDATE frame.
+ */
+ NGHTTP2_WINDOW_UPDATE = 0x08,
+ /**
+ * The CONTINUATION frame.
+ */
+ NGHTTP2_CONTINUATION = 0x09,
+ /**
+ * The ALTSVC frame.
+ */
+ NGHTTP2_ALTSVC = 0x0a,
+ /**
+ * The BLOCKED frame.
+ */
+ NGHTTP2_BLOCKED = 0x0b
+} nghttp2_frame_type;
+
+/**
+ * @enum
+ *
+ * The flags for HTTP/2 frames. This enum defines all flags for all
+ * frames.
+ */
+typedef enum {
+ /**
+ * No flag set.
+ */
+ NGHTTP2_FLAG_NONE = 0,
+ /**
+ * The END_STREAM flag.
+ */
+ NGHTTP2_FLAG_END_STREAM = 0x01,
+ /**
+ * The END_HEADERS flag.
+ */
+ NGHTTP2_FLAG_END_HEADERS = 0x04,
+ /**
+ * The ACK flag.
+ */
+ NGHTTP2_FLAG_ACK = 0x01,
+ /**
+ * The END_SEGMENT flag.
+ */
+ NGHTTP2_FLAG_END_SEGMENT = 0x02,
+ /**
+ * The PAD_LOW flag.
+ */
+ NGHTTP2_FLAG_PAD_LOW = 0x08,
+ /**
+ * The PAD_HIGH flag.
+ */
+ NGHTTP2_FLAG_PAD_HIGH = 0x10,
+ /**
+ * The PRIORITY flag.
+ */
+ NGHTTP2_FLAG_PRIORITY = 0x20,
+ /**
+ * THE COMPRESSED flag.
+ */
+ NGHTTP2_FLAG_COMPRESSED = 0x20
+} nghttp2_flag;
+
+/**
+ * @enum
+ * The SETTINGS ID.
+ */
+typedef enum {
+ /**
+ * SETTINGS_HEADER_TABLE_SIZE
+ */
+ NGHTTP2_SETTINGS_HEADER_TABLE_SIZE = 1,
+ /**
+ * SETTINGS_ENABLE_PUSH
+ */
+ NGHTTP2_SETTINGS_ENABLE_PUSH = 2,
+ /**
+ * SETTINGS_MAX_CONCURRENT_STREAMS
+ */
+ NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 3,
+ /**
+ * SETTINGS_INITIAL_WINDOW_SIZE
+ */
+ NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 4,
+ /**
+ * SETTINGS_COMPRESS_DATA
+ */
+ NGHTTP2_SETTINGS_COMPRESS_DATA = 5,
+ /**
+ * Maximum ID of :type:`nghttp2_settings_id`.
+ */
+ NGHTTP2_SETTINGS_MAX = 5
+} nghttp2_settings_id;
+
+/**
+ * @macro
+ * Default maximum concurrent streams.
+ */
+#define NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1)
+
+/**
+ * @enum
+ * The status codes for the RST_STREAM and GOAWAY frames.
+ */
+typedef enum {
+ /**
+ * No errors.
+ */
+ NGHTTP2_NO_ERROR = 0,
+ /**
+ * PROTOCOL_ERROR
+ */
+ NGHTTP2_PROTOCOL_ERROR = 1,
+ /**
+ * INTERNAL_ERROR
+ */
+ NGHTTP2_INTERNAL_ERROR = 2,
+ /**
+ * FLOW_CONTROL_ERROR
+ */
+ NGHTTP2_FLOW_CONTROL_ERROR = 3,
+ /**
+ * SETTINGS_TIMEOUT
+ */
+ NGHTTP2_SETTINGS_TIMEOUT = 4,
+ /**
+ * STREAM_CLOSED
+ */
+ NGHTTP2_STREAM_CLOSED = 5,
+ /**
+ * FRAME_SIZE_ERROR
+ */
+ NGHTTP2_FRAME_SIZE_ERROR = 6,
+ /**
+ * REFUSED_STREAM
+ */
+ NGHTTP2_REFUSED_STREAM = 7,
+ /**
+ * CANCEL
+ */
+ NGHTTP2_CANCEL = 8,
+ /**
+ * COMPRESSION_ERROR
+ */
+ NGHTTP2_COMPRESSION_ERROR = 9,
+ /**
+ * CONNECT_ERROR
+ */
+ NGHTTP2_CONNECT_ERROR = 10,
+ /**
+ * ENHANCE_YOUR_CALM
+ */
+ NGHTTP2_ENHANCE_YOUR_CALM = 11,
+ /**
+ * INADEQUATE_SECURITY
+ */
+ NGHTTP2_INADEQUATE_SECURITY = 12
+} nghttp2_error_code;
+
+/**
+ * @struct
+ * The frame header.
+ */
+typedef struct {
+ /**
+ * The length field of this frame, excluding frame header.
+ */
+ size_t length;
+ /**
+ * The stream identifier (aka, stream ID)
+ */
+ int32_t stream_id;
+ /**
+ * The type of this frame. See `nghttp2_frame`.
+ */
+ uint8_t type;
+ /**
+ * The flags.
+ */
+ uint8_t flags;
+} nghttp2_frame_hd;
+
+
+/**
+ * @union
+ *
+ * This union represents the some kind of data source passed to
+ * :type:`nghttp2_data_source_read_callback`.
+ */
+typedef union {
+ /**
+ * The integer field, suitable for a file descriptor.
+ */
+ int fd;
+ /**
+ * The pointer to an arbitrary object.
+ */
+ void *ptr;
+} nghttp2_data_source;
+
+/**
+ * @enum
+ *
+ * The flags used to set in |data_flags| output parameter in
+ * :type:`nghttp2_data_source_read_callback`.
+ */
+typedef enum {
+ /**
+ * No flag set.
+ */
+ NGHTTP2_DATA_FLAG_NONE = 0,
+ /**
+ * Indicates EOF was sensed.
+ */
+ NGHTTP2_DATA_FLAG_EOF = 0x01,
+ /**
+ * Indicates data was compressed by application.
+ */
+ NGHTTP2_DATA_FLAG_COMPRESSED = 0x02
+} nghttp2_data_flag;
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the library wants to read data from
+ * the |source|. The read data is sent in the stream |stream_id|.
+ * The implementation of this function must read at most |length|
+ * bytes of data from |source| (or possibly other places) and store
+ * them in |buf| and return number of data stored in |buf|. If EOF is
+ * reached, set :enum:`NGHTTP2_DATA_FLAG_EOF` flag in |*data_flags|.
+ *
+ * To send compressed data payload without affecting content-length,
+ * set :enum:`NGHTTP2_DATA_FLAG_COMPRESSED` flag in |*data_flags|.
+ * Compression must be done by application prior to fill data in
+ * |buf|.
+ *
+ * If the application wants to postpone DATA frames (e.g.,
+ * asynchronous I/O, or reading data blocks for long time), it is
+ * achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading
+ * any data in this invocation. The library removes DATA frame from
+ * the outgoing queue temporarily. To move back deferred DATA frame
+ * to outgoing queue, call `nghttp2_session_resume_data()`. In case
+ * of error, there are 2 choices. Returning
+ * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream
+ * by issuing RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`.
+ * Returning :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the
+ * entire session failure.
+ */
+typedef ssize_t (*nghttp2_data_source_read_callback)
+(nghttp2_session *session, int32_t stream_id,
+ uint8_t *buf, size_t length, uint32_t *data_flags,
+ nghttp2_data_source *source, void *user_data);
+
+/**
+ * @struct
+ *
+ * This struct represents the data source and the way to read a chunk
+ * of data from it.
+ */
+typedef struct {
+ /**
+ * The data source.
+ */
+ nghttp2_data_source source;
+ /**
+ * The callback function to read a chunk of data from the |source|.
+ */
+ nghttp2_data_source_read_callback read_callback;
+} nghttp2_data_provider;
+
+/**
+ * @struct
+ *
+ * The DATA frame. The received data is delivered via
+ * :type:`nghttp2_on_data_chunk_recv_callback`.
+ */
+typedef struct {
+ nghttp2_frame_hd hd;
+ /**
+ * The length of the padding in this frame. This includes PAD_HIGH
+ * and PAD_LOW.
+ */
+ size_t padlen;
+} nghttp2_data;
+
+/**
+ * @enum
+ *
+ * The category of HEADERS, which indicates the role of the frame. In
+ * HTTP/2 spec, request, response, push response and other arbitrary
+ * headers (e.g., trailers) are all called just HEADERS. To give the
+ * application the role of incoming HEADERS frame, we define several
+ * categories.
+ */
+typedef enum {
+ /**
+ * The HEADERS frame is opening new stream, which is analogous to
+ * SYN_STREAM in SPDY.
+ */
+ NGHTTP2_HCAT_REQUEST = 0,
+ /**
+ * The HEADERS frame is the first response headers, which is
+ * analogous to SYN_REPLY in SPDY.
+ */
+ NGHTTP2_HCAT_RESPONSE = 1,
+ /**
+ * The HEADERS frame is the first headers sent against reserved
+ * stream.
+ */
+ NGHTTP2_HCAT_PUSH_RESPONSE = 2,
+ /**
+ * The HEADERS frame which does not apply for the above categories,
+ * which is analogous to HEADERS in SPDY.
+ */
+ NGHTTP2_HCAT_HEADERS = 3
+} nghttp2_headers_category;
+
+/**
+ * @struct
+ *
+ * The structure to specify stream dependency.
+ */
+typedef struct {
+ /**
+ * The stream ID of the stream to depend on. Specifying 0 makes
+ * stream not depend any other stream.
+ */
+ int32_t stream_id;
+ /**
+ * The weight of this dependency.
+ */
+ int32_t weight;
+ /**
+ * nonzero means exclusive dependency
+ */
+ uint8_t exclusive;
+} nghttp2_priority_spec;
+
+/**
+ * @struct
+ *
+ * The HEADERS frame. It has the following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * The length of the padding in this frame. This includes PAD_HIGH
+ * and PAD_LOW.
+ */
+ size_t padlen;
+ /**
+ * The priority specification
+ */
+ nghttp2_priority_spec pri_spec;
+ /**
+ * The name/value pairs.
+ */
+ nghttp2_nv *nva;
+ /**
+ * The number of name/value pairs in |nva|.
+ */
+ size_t nvlen;
+ /**
+ * The category of this HEADERS frame.
+ */
+ nghttp2_headers_category cat;
+} nghttp2_headers;
+
+/**
+ * @struct
+ *
+ * The PRIORITY frame. It has the following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * The priority specification.
+ */
+ nghttp2_priority_spec pri_spec;
+} nghttp2_priority;
+
+/**
+ * @struct
+ *
+ * The RST_STREAM frame. It has the following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * The error code. See :type:`nghttp2_error_code`.
+ */
+ nghttp2_error_code error_code;
+} nghttp2_rst_stream;
+
+/**
+ * @struct
+ *
+ * The SETTINGS ID/Value pair. It has the following members:
+ */
+typedef struct {
+ /**
+ * The SETTINGS ID. See :type:`nghttp2_settings_id`.
+ */
+ int32_t settings_id;
+ /**
+ * The value of this entry.
+ */
+ uint32_t value;
+} nghttp2_settings_entry;
+
+/**
+ * @struct
+ *
+ * The SETTINGS frame. It has the following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * The number of SETTINGS ID/Value pairs in |iv|.
+ */
+ size_t niv;
+ /**
+ * The pointer to the array of SETTINGS ID/Value pair.
+ */
+ nghttp2_settings_entry *iv;
+} nghttp2_settings;
+
+/**
+ * @struct
+ *
+ * The PUSH_PROMISE frame. It has the following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * The length of the padding in this frame. This includes PAD_HIGH
+ * and PAD_LOW.
+ */
+ size_t padlen;
+ /**
+ * The name/value pairs.
+ */
+ nghttp2_nv *nva;
+ /**
+ * The number of name/value pairs in |nva|.
+ */
+ size_t nvlen;
+ /**
+ * The promised stream ID
+ */
+ int32_t promised_stream_id;
+} nghttp2_push_promise;
+
+/**
+ * @struct
+ *
+ * The PING frame. It has the following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * The opaque data
+ */
+ uint8_t opaque_data[8];
+} nghttp2_ping;
+
+/**
+ * @struct
+ *
+ * The GOAWAY frame. It has the following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * The last stream stream ID.
+ */
+ int32_t last_stream_id;
+ /**
+ * The error code. See :type:`nghttp2_error_code`.
+ */
+ nghttp2_error_code error_code;
+ /**
+ * The additional debug data
+ */
+ uint8_t *opaque_data;
+ /**
+ * The length of |opaque_data| member.
+ */
+ size_t opaque_data_len;
+} nghttp2_goaway;
+
+/**
+ * @struct
+ *
+ * The WINDOW_UPDATE frame. It has the following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * The window size increment.
+ */
+ int32_t window_size_increment;
+} nghttp2_window_update;
+
+/**
+ * @struct
+ *
+ * The ALTSVC frame. It has following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * Protocol ID
+ */
+ uint8_t *protocol_id;
+ /**
+ * Host
+ */
+ uint8_t *host;
+ /**
+ * Origin
+ */
+ uint8_t *origin;
+ /**
+ * The length of |protocol_id|
+ */
+ size_t protocol_id_len;
+ /**
+ * The length of |host|
+ */
+ size_t host_len;
+ /**
+ * The length of |origin|
+ */
+ size_t origin_len;
+ /**
+ * Max-Age
+ */
+ uint32_t max_age;
+ /**
+ * Port
+ */
+ uint16_t port;
+} nghttp2_altsvc;
+
+/**
+ * @struct
+ *
+ * The BLOCKED frame. It has following members:
+ */
+typedef struct {
+ /**
+ * The frame header.
+ */
+ nghttp2_frame_hd hd;
+} nghttp2_blocked;
+
+/**
+ * @union
+ *
+ * This union includes all frames to pass them to various function
+ * calls as nghttp2_frame type. The CONTINUATION frame is omitted
+ * from here because the library deals with it internally.
+ */
+typedef union {
+ /**
+ * The frame header, which is convenient to inspect frame header.
+ */
+ nghttp2_frame_hd hd;
+ /**
+ * The DATA frame.
+ */
+ nghttp2_data data;
+ /**
+ * The HEADERS frame.
+ */
+ nghttp2_headers headers;
+ /**
+ * The PRIORITY frame.
+ */
+ nghttp2_priority priority;
+ /**
+ * The RST_STREAM frame.
+ */
+ nghttp2_rst_stream rst_stream;
+ /**
+ * The SETTINGS frame.
+ */
+ nghttp2_settings settings;
+ /**
+ * The PUSH_PROMISE frame.
+ */
+ nghttp2_push_promise push_promise;
+ /**
+ * The PING frame.
+ */
+ nghttp2_ping ping;
+ /**
+ * The GOAWAY frame.
+ */
+ nghttp2_goaway goaway;
+ /**
+ * The WINDOW_UPDATE frame.
+ */
+ nghttp2_window_update window_update;
+ /**
+ * The ALTSVC frame.
+ */
+ nghttp2_altsvc altsvc;
+ /**
+ * The BLOCKED frame.
+ */
+ nghttp2_blocked blocked;
+} nghttp2_frame;
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when |session| wants to send data to the
+ * remote peer. The implementation of this function must send at most
+ * |length| bytes of data stored in |data|. The |flags| is currently
+ * not used and always 0. It must return the number of bytes sent if
+ * it succeeds. If it cannot send any single byte without blocking,
+ * it must return :enum:`NGHTTP2_ERR_WOULDBLOCK`. For other errors,
+ * it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. The
+ * |user_data| pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * This callback is required if the application uses
+ * `nghttp2_session_send()` to send data to the remote endpoint. If
+ * the application uses solely `nghttp2_session_mem_send()` instead,
+ * this callback function is unnecessary.
+ */
+typedef ssize_t (*nghttp2_send_callback)
+(nghttp2_session *session,
+ const uint8_t *data, size_t length, int flags, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when |session| wants to receive data from
+ * the remote peer. The implementation of this function must read at
+ * most |length| bytes of data and store it in |buf|. The |flags| is
+ * currently not used and always 0. It must return the number of
+ * bytes written in |buf| if it succeeds. If it cannot read any
+ * single byte without blocking, it must return
+ * :enum:`NGHTTP2_ERR_WOULDBLOCK`. If it gets EOF before it reads any
+ * single byte, it must return :enum:`NGHTTP2_ERR_EOF`. For other
+ * errors, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * Returning 0 is treated as :enum:`NGHTTP2_ERR_WOULDBLOCK`. The
+ * |user_data| pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * This callback is required if the application uses
+ * `nghttp2_session_recv()` to receive data from the remote endpoint.
+ * If the application uses solely `nghttp2_session_mem_recv()`
+ * instead, this callback function is unnecessary.
+ */
+typedef ssize_t (*nghttp2_recv_callback)
+(nghttp2_session *session,
+ uint8_t *buf, size_t length, int flags, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked by `nghttp2_session_recv()` when a frame
+ * is received. The |user_data| pointer is the third argument passed
+ * in to the call to `nghttp2_session_client_new()` or
+ * `nghttp2_session_server_new()`.
+ *
+ * If frame is HEADERS or PUSH_PROMISE, the ``nva`` and ``nvlen``
+ * member of their data structure are always ``NULL`` and 0
+ * respectively. The header name/value pairs are emitted via
+ * :type:`nghttp2_on_header_callback`.
+ *
+ * For HEADERS, PUSH_PROMISE and DATA frames, this callback may be
+ * called after stream is closed (see
+ * :type:`nghttp2_on_stream_close_callback`). The application should
+ * check that stream is still alive using its own stream management or
+ * :func:`nghttp2_session_get_stream_user_data()`.
+ *
+ * Only HEADERS and DATA frame can signal the end of incoming data.
+ * If ``frame->hd.flags & NGHTTP2_FLAG_END_STREAM`` is nonzero, the
+ * |frame| is the last frame from the remote peer in this stream.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero value is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_frame_recv_callback)
+(nghttp2_session *session, const nghttp2_frame *frame, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked by `nghttp2_session_recv()` when an
+ * invalid non-DATA frame is received. The |error_code| is one of the
+ * :enum:`nghttp2_error_code` and indicates the error. When this
+ * callback function is invoked, the library automatically submits
+ * either RST_STREAM or GOAWAY frame. The |user_data| pointer is the
+ * third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * If frame is HEADERS or PUSH_PROMISE, the ``nva`` and ``nvlen``
+ * member of their data structure are always ``NULL`` and 0
+ * respectively.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_invalid_frame_recv_callback)
+(nghttp2_session *session, const nghttp2_frame *frame,
+ nghttp2_error_code error_code, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when a chunk of data in DATA frame is
+ * received. The |stream_id| is the stream ID this DATA frame belongs
+ * to. The |flags| is the flags of DATA frame which this data chunk
+ * is contained. ``(flags & NGHTTP2_FLAG_END_STREAM) != 0`` does not
+ * necessarily mean this chunk of data is the last one in the stream.
+ * You should use :type:`nghttp2_on_frame_recv_callback` to know all
+ * data frames are received. The |user_data| pointer is the third
+ * argument passed in to the call to `nghttp2_session_client_new()` or
+ * `nghttp2_session_server_new()`.
+ *
+ * If the application uses `nghttp2_session_mem_recv()`, it can return
+ * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
+ * return without processing further input bytes. The memory by
+ * pointed by the |data| is retained until
+ * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
+ * The application must retain the input bytes which was used to
+ * produce the |data| parameter, because it may refer to the memory
+ * region included in the input bytes.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_data_chunk_recv_callback)
+(nghttp2_session *session, uint8_t flags, int32_t stream_id,
+ const uint8_t *data, size_t len, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked just before the non-DATA frame |frame| is
+ * sent. The |user_data| pointer is the third argument passed in to
+ * the call to `nghttp2_session_client_new()` or
+ * `nghttp2_session_server_new()`.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_before_frame_send_callback)
+(nghttp2_session *session, const nghttp2_frame *frame, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked after the frame |frame| is sent. The
+ * |user_data| pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_frame_send_callback)
+(nghttp2_session *session, const nghttp2_frame *frame, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked after the non-DATA frame |frame| is not
+ * sent because of the error. The error is indicated by the
+ * |lib_error_code|, which is one of the values defined in
+ * :type:`nghttp2_error`. The |user_data| pointer is the third
+ * argument passed in to the call to `nghttp2_session_client_new()` or
+ * `nghttp2_session_server_new()`.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_frame_not_send_callback)
+(nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code,
+ void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the stream |stream_id| is closed.
+ * The reason of closure is indicated by the |error_code|. The
+ * stream_user_data, which was specified in `nghttp2_submit_request()`
+ * or `nghttp2_submit_headers()`, is still available in this function.
+ * The |user_data| pointer is the third argument passed in to the call
+ * to `nghttp2_session_client_new()` or
+ * `nghttp2_session_server_new()`.
+ *
+ * This function is also called for a stream in reserved state.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_stream_close_callback)
+(nghttp2_session *session, int32_t stream_id, nghttp2_error_code error_code,
+ void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the received frame type is unknown.
+ * The |head| is the pointer to the header of the received frame. The
+ * |headlen| is the length of the |head|. According to the spec, the
+ * |headlen| is always 8. In other words, the |head| is the first 8
+ * bytes of the received frame. The |payload| is the pointer to the
+ * data portion of the received frame. The |payloadlen| is the length
+ * of the |payload|. This is the data after the length field. The
+ * |user_data| pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_unknown_frame_recv_callback)
+(nghttp2_session *session,
+ const uint8_t *head, size_t headlen,
+ const uint8_t *payload, size_t payloadlen,
+ void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the reception of header block in
+ * HEADERS or PUSH_PROMISE is started. Each header name/value pair
+ * will be emitted by :type:`nghttp2_on_header_callback`.
+ *
+ * The ``frame->hd.flags`` may not have
+ * :enum:`NGHTTP2_FLAG_END_HEADERS` flag set, which indicates that one
+ * or more CONTINUATION frames are involved. But the application does
+ * not need to care about that because the header name/value pairs are
+ * emitted transparently regardless of CONTINUATION frames.
+ *
+ * The implementation of this function must return 0 if it succeeds or
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If nonzero value other than
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned, it is treated as
+ * if :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned. If
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+ * `nghttp2_session_mem_recv()` function will immediately return
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_begin_headers_callback)
+(nghttp2_session *session, const nghttp2_frame *frame, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when a header name/value pair is received
+ * for the |frame|. The |name| of length |namelen| is header name.
+ * The |value| of length |valuelen| is header value. The |flags| is
+ * bitwise OR of one or more of :type:`nghttp2_nv_flag`.
+ *
+ * If :enum:`NGHTTP2_NV_FLAG_NO_INDEX` is set in |flags|, the receiver
+ * must not index this name/value pair when forwarding it to the next
+ * hop.
+ *
+ * When this callback is invoked, ``frame->hd.type`` is either
+ * :enum:`NGHTTP2_HEADERS` or :enum:`NGHTTP2_PUSH_PROMISE`. After all
+ * header name/value pairs are processed with this callback, and no
+ * error has been detected, :type:`nghttp2_on_frame_recv_callback`
+ * will be invoked. If there is an error in decompression,
+ * :type:`nghttp2_on_frame_recv_callback` for the |frame| will not be
+ * invoked.
+ *
+ * The |name| may be ``NULL`` if the |namelen| is 0. The same thing
+ * can be said about the |value|.
+ *
+ * Please note that nghttp2 library does not perform any validity
+ * check against the |name| and the |value|. For example, the
+ * |namelen| could be 0, and/or the |value| contains ``0x0a`` or
+ * ``0x0d``. The application must check them if it matters. The
+ * helper function `nghttp2_check_header_name()` and
+ * `nghttp2_check_header_value()` provide simple validation against
+ * HTTP2 header field construction rule.
+ *
+ * One more thing to note is that the |value| may contain ``NULL``
+ * (``0x00``) characters. It is used to concatenate header values
+ * which share the same header field name. The application should
+ * split these values if it wants to get individual value. This
+ * concatenation is used in order to keep the ordering of headers.
+ *
+ * If the application uses `nghttp2_session_mem_recv()`, it can return
+ * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
+ * return without processing further input bytes. The memory pointed
+ * by |frame|, |name| and |value| parameters are retained until
+ * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
+ * The application must retain the input bytes which was used to
+ * produce these parameters, because it may refer to the memory region
+ * included in the input bytes.
+ *
+ * Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
+ * the stream by issuing RST_STREAM with
+ * :enum:`NGHTTP2_INTERNAL_ERROR`. In this case,
+ * :type:`nghttp2_on_frame_recv_callback` will not be invoked.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * It may return :enum:`NGHTTP2_ERR_PAUSE` or
+ * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. For other critical
+ * failures, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If
+ * the other nonzero value is returned, it is treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_header_callback)
+(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen,
+ const uint8_t *value, size_t valuelen,
+ uint8_t flags,
+ void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the library asks application how
+ * many padding bytes are required for the transmission of the
+ * |frame|. The application must choose the total length of payload
+ * including padded bytes in range [frame->hd.length, max_payloadlen],
+ * inclusive. Choosing number not in this range will be treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Returning
+ * ``frame->hd.length`` means no padding is added. Returning
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will make
+ * `nghttp2_session_send()` function immediately return
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef ssize_t (*nghttp2_select_padding_callback)
+(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ size_t max_payloadlen,
+ void *user_data);
+
+/**
+ * @struct
+ *
+ * Callback functions.
+ */
+typedef struct {
+ /**
+ * Callback function invoked when the |session| wants to send data
+ * to the remote peer. This callback is not necessary if the
+ * application uses solely `nghttp2_session_mem_send()` to serialize
+ * data to transmit.
+ */
+ nghttp2_send_callback send_callback;
+ /**
+ * Callback function invoked when the |session| wants to receive
+ * data from the remote peer. This callback is not necessary if the
+ * application uses solely `nghttp2_session_mem_recv()` to process
+ * received data.
+ */
+ nghttp2_recv_callback recv_callback;
+ /**
+ * Callback function invoked by `nghttp2_session_recv()` when a
+ * frame is received.
+ */
+ nghttp2_on_frame_recv_callback on_frame_recv_callback;
+ /**
+ * Callback function invoked by `nghttp2_session_recv()` when an
+ * invalid non-DATA frame is received.
+ */
+ nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback;
+ /**
+ * Callback function invoked when a chunk of data in DATA frame is
+ * received.
+ */
+ nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback;
+ /**
+ * Callback function invoked before a non-DATA frame is sent.
+ */
+ nghttp2_before_frame_send_callback before_frame_send_callback;
+ /**
+ * Callback function invoked after a frame is sent.
+ */
+ nghttp2_on_frame_send_callback on_frame_send_callback;
+ /**
+ * The callback function invoked when a non-DATA frame is not sent
+ * because of an error.
+ */
+ nghttp2_on_frame_not_send_callback on_frame_not_send_callback;
+ /**
+ * Callback function invoked when the stream is closed.
+ */
+ nghttp2_on_stream_close_callback on_stream_close_callback;
+ /**
+ * Callback function invoked when the received frame type is
+ * unknown.
+ */
+ nghttp2_on_unknown_frame_recv_callback on_unknown_frame_recv_callback;
+ /**
+ * Callback function invoked when the reception of header block in
+ * HEADERS or PUSH_PROMISE is started.
+ */
+ nghttp2_on_begin_headers_callback on_begin_headers_callback;
+ /**
+ * Callback function invoked when a header name/value pair is
+ * received.
+ */
+ nghttp2_on_header_callback on_header_callback;
+ /**
+ * Callback function invoked when the library asks application how
+ * many padding bytes are required for the transmission of the given
+ * frame.
+ */
+ nghttp2_select_padding_callback select_padding_callback;
+} nghttp2_session_callbacks;
+
+struct nghttp2_option;
+
+/**
+ * @struct
+ *
+ * Configuration options for :type:`nghttp2_session`. The details of
+ * this structure are intentionally hidden from the public API.
+ */
+typedef struct nghttp2_option nghttp2_option;
+
+/**
+ * @function
+ *
+ * Initializes |*option_ptr| with default values.
+ *
+ * When the application finished using this object, it can use
+ * `nghttp2_option_del()` to free its memory.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_option_new(nghttp2_option **option_ptr);
+
+/**
+ * @function
+ *
+ * Frees any resources allocated for |option|. If |option| is
+ * ``NULL``, this function does nothing.
+ */
+void nghttp2_option_del(nghttp2_option *option);
+
+/**
+ * @function
+ *
+ * This option prevents the library from sending WINDOW_UPDATE for a
+ * stream automatically. If this option is set to nonzero, the
+ * library won't send WINDOW_UPDATE for a stream and the application
+ * is responsible for sending WINDOW_UPDATE using
+ * `nghttp2_submit_window_update`. By default, this option is set to
+ * zero.
+ */
+void nghttp2_option_set_no_auto_stream_window_update(nghttp2_option *option,
+ int val);
+
+/**
+ * @function
+ *
+ * This option prevents the library from sending WINDOW_UPDATE for a
+ * connection automatically. If this option is set to nonzero, the
+ * library won't send WINDOW_UPDATE for a connection and the
+ * application is responsible for sending WINDOW_UPDATE with stream ID
+ * 0 using `nghttp2_submit_window_update`. By default, this option is
+ * set to zero.
+ */
+void nghttp2_option_set_no_auto_connection_window_update
+(nghttp2_option *option, int val);
+
+/**
+ * @function
+ *
+ * This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of
+ * remote endpoint as if it is received in SETTINGS frame. Without
+ * specifying this option, before the local endpoint receives
+ * SETTINGS_MAX_CONCURRENT_STREAMS in SETTINGS frame from remote
+ * endpoint, SETTINGS_MAX_CONCURRENT_STREAMS is unlimited. This may
+ * cause problem if local endpoint submits lots of requests initially
+ * and sending them at once to the remote peer may lead to the
+ * rejection of some requests. Specifying this option to the sensible
+ * value, say 100, may avoid this kind of issue. This value will be
+ * overwritten if the local endpoint receives
+ * SETTINGS_MAX_CONCURRENT_STREAMS from the remote endpoint.
+ */
+void nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
+ uint32_t val);
+
+/**
+ * @function
+ *
+ * Initializes |*session_ptr| for client use. The all members of
+ * |callbacks| are copied to |*session_ptr|. Therefore |*session_ptr|
+ * does not store |callbacks|. The |user_data| is an arbitrary user
+ * supplied data, which will be passed to the callback functions.
+ *
+ * The :member:`nghttp2_session_callbacks.send_callback` must be
+ * specified. If the application code uses `nghttp2_session_recv()`,
+ * the :member:`nghttp2_session_callbacks.recv_callback` must be
+ * specified. The other members of |callbacks| can be ``NULL``.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_session_client_new(nghttp2_session **session_ptr,
+ const nghttp2_session_callbacks *callbacks,
+ void *user_data);
+
+/**
+ * @function
+ *
+ * Initializes |*session_ptr| for server use. The all members of
+ * |callbacks| are copied to |*session_ptr|. Therefore |*session_ptr|
+ * does not store |callbacks|. The |user_data| is an arbitrary user
+ * supplied data, which will be passed to the callback functions.
+ *
+ * The :member:`nghttp2_session_callbacks.send_callback` must be
+ * specified. If the application code uses `nghttp2_session_recv()`,
+ * the :member:`nghttp2_session_callbacks.recv_callback` must be
+ * specified. The other members of |callbacks| can be ``NULL``.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_session_server_new(nghttp2_session **session_ptr,
+ const nghttp2_session_callbacks *callbacks,
+ void *user_data);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_session_client_new()`, but with additional options
+ * specified in the |option|.
+ *
+ * The |option| can be ``NULL`` and the call is equivalent to
+ * `nghttp2_session_client_new()`.
+ *
+ * This function does not take ownership |option|. The application is
+ * responsible for freeing |option| if it finishes using the object.
+ *
+ * The library code does not refer to |option| after this function
+ * returns.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_session_client_new2(nghttp2_session **session_ptr,
+ const nghttp2_session_callbacks *callbacks,
+ void *user_data,
+ const nghttp2_option *option);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_session_server_new()`, but with additional options
+ * specified in the |option|.
+ *
+ * The |option| can be ``NULL`` and the call is equivalent to
+ * `nghttp2_session_server_new()`.
+ *
+ * This function does not take ownership |option|. The application is
+ * responsible for freeing |option| if it finishes using the object.
+ *
+ * The library code does not refer to |option| after this function
+ * returns.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_session_server_new2(nghttp2_session **session_ptr,
+ const nghttp2_session_callbacks *callbacks,
+ void *user_data,
+ const nghttp2_option *option);
+
+/**
+ * @function
+ *
+ * Frees any resources allocated for |session|. If |session| is
+ * ``NULL``, this function does nothing.
+ */
+void nghttp2_session_del(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Sends pending frames to the remote peer.
+ *
+ * This function retrieves the highest prioritized frame from the
+ * outbound queue and sends it to the remote peer. It does this as
+ * many as possible until the user callback
+ * :member:`nghttp2_session_callbacks.send_callback` returns
+ * :enum:`NGHTTP2_ERR_WOULDBLOCK` or the outbound queue becomes empty.
+ * This function calls several callback functions which are passed
+ * when initializing the |session|. Here is the simple time chart
+ * which tells when each callback is invoked:
+ *
+ * 1. Get the next frame to send from outbound queue.
+ * 2. Prepare transmission of the frame.
+ * 3. If the control frame cannot be sent because some preconditions
+ * are not met (e.g., request HEADERS cannot be sent after GOAWAY),
+ * :member:`nghttp2_session_callbacks.on_frame_not_send_callback`
+ * is invoked. Abort the following steps.
+ * 4. If the frame is HEADERS, PUSH_PROMISE or DATA,
+ * :member:`nghttp2_session_callbacks.select_padding_callback` is
+ * invoked.
+ * 5. If the frame is request HEADERS, the stream is opened here.
+ * 6. :member:`nghttp2_session_callbacks.before_frame_send_callback` is
+ * invoked.
+ * 7. :member:`nghttp2_session_callbacks.send_callback` is invoked one
+ * or more times to send the frame.
+ * 8. :member:`nghttp2_session_callbacks.on_frame_send_callback` is
+ * invoked.
+ * 9. If the transmission of the frame triggers closure of the stream,
+ * the stream is closed and
+ * :member:`nghttp2_session_callbacks.on_stream_close_callback` is
+ * invoked.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * The callback function failed.
+ */
+int nghttp2_session_send(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the serialized data to send.
+ *
+ * This function behaves like `nghttp2_session_send()` except that it
+ * does not use :member:`nghttp2_session_callbacks.send_callback` to
+ * transmit data. Instead, it assigns the pointer to the serialized
+ * data to the |*data_ptr| and returns its length. The other
+ * callbacks are called in the same way as they are in
+ * `nghttp2_session_send()`.
+ *
+ * If no data is available to send, this function returns 0.
+ *
+ * This function may not return all serialized data in one invocation.
+ * To get all data, call this function repeatedly until it returns 0
+ * or one of negative error codes.
+ *
+ * The assigned |*data_ptr| is valid until the next call of
+ * `nghttp2_session_mem_send()` or `nghttp2_session_send()`.
+ *
+ * The caller must send all data before sending the next chunk of
+ * data.
+ *
+ * This function returns the length of the data pointed by the
+ * |*data_ptr| if it succeeds, or one of the following negative error
+ * codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+ssize_t nghttp2_session_mem_send(nghttp2_session *session,
+ const uint8_t **data_ptr);
+
+/**
+ * @function
+ *
+ * Receives frames from the remote peer.
+ *
+ * This function receives as many frames as possible until the user
+ * callback :member:`nghttp2_session_callbacks.recv_callback` returns
+ * :enum:`NGHTTP2_ERR_WOULDBLOCK`. This function calls several
+ * callback functions which are passed when initializing the
+ * |session|. Here is the simple time chart which tells when each
+ * callback is invoked:
+ *
+ * 1. :member:`nghttp2_session_callbacks.recv_callback` is invoked one
+ * or more times to receive frame header.
+ * 2. If the frame is DATA frame:
+ *
+ * 1. :member:`nghttp2_session_callbacks.recv_callback` is invoked
+ * to receive DATA payload. For each chunk of data,
+ * :member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`
+ * is invoked.
+ * 2. If one DATA frame is completely received,
+ * :member:`nghttp2_session_callbacks.on_frame_recv_callback` is
+ * invoked. If the reception of the frame triggers the
+ * closure of the stream,
+ * :member:`nghttp2_session_callbacks.on_stream_close_callback`
+ * is invoked.
+ *
+ * 3. If the frame is the control frame:
+ *
+ * 1. :member:`nghttp2_session_callbacks.recv_callback` is invoked
+ * one or more times to receive whole frame.
+ *
+ * 2. If the received frame is valid, then following actions are
+ * taken. If the frame is either HEADERS or PUSH_PROMISE,
+ * :member:`nghttp2_session_callbacks.on_begin_headers_callback`
+ * is invoked. Then
+ * :member:`nghttp2_session_callbacks.on_header_callback` is
+ * invoked for each header name/value pair. After all name/value
+ * pairs are emitted successfully,
+ * :member:`nghttp2_session_callbacks.on_frame_recv_callback` is
+ * invoked. For other frames,
+ * :member:`nghttp2_session_callbacks.on_frame_recv_callback` is
+ * invoked.
+ * If the reception of the frame triggers the closure of the
+ * stream,
+ * :member:`nghttp2_session_callbacks.on_stream_close_callback`
+ * is invoked.
+ * 3. If the received frame is unpacked but is interpreted as
+ * invalid,
+ * :member:`nghttp2_session_callbacks.on_invalid_frame_recv_callback`
+ * is invoked.
+ * 4. If the received frame type is unknown,
+ * :member:`nghttp2_session_callbacks.on_unknown_frame_recv_callback`
+ * is invoked.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_EOF`
+ * The remote peer did shutdown on the connection.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * The callback function failed.
+ */
+int nghttp2_session_recv(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Processes data |in| as an input from the remote endpoint. The
+ * |inlen| indicates the number of bytes in the |in|.
+ *
+ * This function behaves like `nghttp2_session_recv()` except that it
+ * does not use :member:`nghttp2_session_callbacks.recv_callback` to
+ * receive data; the |in| is the only data for the invocation of this
+ * function. If all bytes are processed, this function returns. The
+ * other callbacks are called in the same way as they are in
+ * `nghttp2_session_recv()`.
+ *
+ * In the current implementation, this function always tries to
+ * processes all input data unless either an error occurs or
+ * :enum:`NGHTTP2_ERR_PAUSE` is returned from
+ * :member:`nghttp2_session_callbacks.on_header_callback` or
+ * :member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`.
+ * If :enum:`NGHTTP2_ERR_PAUSE` is used, the return value includes the
+ * number of bytes which was used to produce the data or frame for the
+ * callback.
+ *
+ * This function returns the number of processed bytes, or one of the
+ * following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * The callback function failed.
+ */
+ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
+ const uint8_t *in, size_t inlen);
+
+/**
+ * @function
+ *
+ * Puts back previously deferred DATA frame in the stream |stream_id|
+ * to the outbound queue.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The stream does not exist; or no deferred data exist; or data
+ * was deferred by flow control.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns nonzero value if |session| wants to receive data from the
+ * remote peer.
+ *
+ * If both `nghttp2_session_want_read()` and
+ * `nghttp2_session_want_write()` return 0, the application should
+ * drop the connection.
+ */
+int nghttp2_session_want_read(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns nonzero value if |session| wants to send data to the remote
+ * peer.
+ *
+ * If both `nghttp2_session_want_read()` and
+ * `nghttp2_session_want_write()` return 0, the application should
+ * drop the connection.
+ */
+int nghttp2_session_want_write(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns stream_user_data for the stream |stream_id|. The
+ * stream_user_data is provided by `nghttp2_submit_request()`,
+ * `nghttp2_submit_headers()` or
+ * `nghttp2_session_set_stream_user_data()`. Unless it is set using
+ * `nghttp2_session_set_stream_user_data()`, if the stream is
+ * initiated by the remote endpoint, stream_user_data is always
+ * ``NULL``. If the stream does not exist, this function returns
+ * ``NULL``.
+ */
+void* nghttp2_session_get_stream_user_data(nghttp2_session *session,
+ int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Sets the |stream_user_data| to the stream denoted by the
+ * |stream_id|. If a stream user data is already set to the stream,
+ * it is replaced with the |stream_user_data|. It is valid to specify
+ * ``NULL`` in the |stream_user_data|, which nullifies the associated
+ * data pointer.
+ *
+ * It is valid to set the |stream_user_data| to the stream reserved by
+ * PUSH_PROMISE frame.
+ *
+ * This function returns 0 if it succeeds, or one of following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The stream does not exist
+ */
+int nghttp2_session_set_stream_user_data(nghttp2_session *session,
+ int32_t stream_id,
+ void *stream_user_data);
+
+/**
+ * @function
+ *
+ * Returns the number of frames in the outbound queue. This does not
+ * include the deferred DATA frames.
+ */
+size_t nghttp2_session_get_outbound_queue_size(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the number of DATA payload in bytes received without
+ * WINDOW_UPDATE transmission for the stream |stream_id|. The local
+ * (receive) window size can be adjusted by
+ * `nghttp2_submit_window_update()`. This function takes into account
+ * that and returns effective data length. In particular, if the
+ * local window size is reduced by submitting negative
+ * window_size_increment with `nghttp2_submit_window_update()`, this
+ * function returns the number of bytes less than actually received.
+ *
+ * This function returns -1 if it fails.
+ */
+int32_t nghttp2_session_get_stream_effective_recv_data_length
+(nghttp2_session *session, int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns the local (receive) window size for the stream |stream_id|.
+ * The local window size can be adjusted by
+ * `nghttp2_submit_window_update()`. This function takes into account
+ * that and returns effective window size.
+ *
+ * This function returns -1 if it fails.
+ */
+int32_t nghttp2_session_get_stream_effective_local_window_size
+(nghttp2_session *session, int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns the number of DATA payload in bytes received without
+ * WINDOW_UPDATE transmission for a connection. The local (receive)
+ * window size can be adjusted by `nghttp2_submit_window_update()`.
+ * This function takes into account that and returns effective data
+ * length. In particular, if the local window size is reduced by
+ * submitting negative window_size_increment with
+ * `nghttp2_submit_window_update()`, this function returns the number
+ * of bytes less than actually received.
+ *
+ * This function returns -1 if it fails.
+ */
+int32_t nghttp2_session_get_effective_recv_data_length
+(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the local (receive) window size for a connection. The
+ * local window size can be adjusted by
+ * `nghttp2_submit_window_update()`. This function takes into account
+ * that and returns effective window size.
+ *
+ * This function returns -1 if it fails.
+ */
+int32_t nghttp2_session_get_effective_local_window_size
+(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the remote window size for a given stream |stream_id|.
+ * This is the amount of flow-controlled payload (e.g., DATA) that the
+ * local endpoint can send without WINDOW_UPDATE.
+ *
+ * This function returns -1 if it fails.
+ */
+int32_t nghttp2_session_get_stream_remote_window_size(nghttp2_session* session,
+ int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Signals the session so that the connection should be terminated.
+ *
+ * GOAWAY frame with the given |error_code| will be submitted if it
+ * has not been transmitted. After the transmission, both
+ * `nghttp2_session_want_read()` and `nghttp2_session_want_write()`
+ * return 0. If GOAWAY frame has already transmitted at the time when
+ * this function is invoked, `nghttp2_session_want_read()` and
+ * `nghttp2_session_want_write()` returns 0 immediately after this
+ * function succeeds.
+ *
+ * This function should be called when the connection should be
+ * terminated after sending GOAWAY. If the remaining streams should
+ * be processed after GOAWAY, use `nghttp2_submit_goaway()` instead.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_session_terminate_session(nghttp2_session *session,
+ nghttp2_error_code error_code);
+
+/**
+ * @function
+ *
+ * Returns the value of SETTINGS |id| notified by a remote endpoint.
+ */
+uint32_t nghttp2_session_get_remote_settings(nghttp2_session *session,
+ nghttp2_settings_id id);
+
+/**
+ * @function
+ *
+ * Performs post-process of HTTP Upgrade request. This function can
+ * be called from both client and server, but the behavior is very
+ * different in each other.
+ *
+ * If called from client side, the |settings_payload| must be the
+ * value sent in ``HTTP2-Settings`` header field and must be decoded
+ * by base64url decoder. The |settings_payloadlen| is the length of
+ * |settings_payload|. The |settings_payload| is unpacked and its
+ * setting values will be submitted using `nghttp2_submit_settings()`.
+ * This means that the client application code does not need to submit
+ * SETTINGS by itself. The stream with stream ID=1 is opened and the
+ * |stream_user_data| is used for its stream_user_data. The opened
+ * stream becomes half-closed (local) state.
+ *
+ * If called from server side, the |settings_payload| must be the
+ * value received in ``HTTP2-Settings`` header field and must be
+ * decoded by base64url decoder. The |settings_payloadlen| is the
+ * length of |settings_payload|. It is treated as if the SETTINGS
+ * frame with that payload is received. Thus, callback functions for
+ * the reception of SETTINGS frame will be invoked. The stream with
+ * stream ID=1 is opened. The |stream_user_data| is ignored. The
+ * opened stream becomes half-closed (remote).
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The |settings_payload| is badly formed.
+ * :enum:`NGHTTP2_ERR_PROTO`
+ * The stream ID 1 is already used or closed; or is not available.
+ */
+int nghttp2_session_upgrade(nghttp2_session *session,
+ const uint8_t *settings_payload,
+ size_t settings_payloadlen,
+ void *stream_user_data);
+
+/**
+ * @function
+ *
+ * Serializes the SETTINGS values |iv| in the |buf|. The size of the
+ * |buf| is specified by |buflen|. The number of entries in the |iv|
+ * array is given by |niv|. The required space in |buf| for the |niv|
+ * entries is ``8*niv`` bytes and if the given buffer is too small, an
+ * error is returned. This function is used mainly for creating a
+ * SETTINGS payload to be sent with the ``HTTP2-Settings`` header
+ * field in an HTTP Upgrade request. The data written in |buf| is NOT
+ * base64url encoded and the application is responsible for encoding.
+ *
+ * This function returns the number of bytes written in |buf|, or one
+ * of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The |iv| contains duplicate settings ID or invalid value.
+ *
+ * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * The provided |buflen| size is too small to hold the output.
+ */
+ssize_t nghttp2_pack_settings_payload(uint8_t *buf,
+ size_t buflen,
+ const nghttp2_settings_entry *iv,
+ size_t niv);
+
+/**
+ * @function
+ *
+ * Returns string describing the |lib_error_code|. The
+ * |lib_error_code| must be one of the :enum:`nghttp2_error`.
+ */
+const char* nghttp2_strerror(int lib_error_code);
+
+/**
+ * @function
+ *
+ * Initializes |pri_spec| with the |stream_id| of the stream to depend
+ * on with |weight| and its exclusive flag. If |exclusive| is
+ * nonzero, exclusive flag is set.
+ *
+ * The |weight| must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
+ * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.
+ */
+void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec,
+ int32_t stream_id, int32_t weight,
+ int exclusive);
+
+/**
+ * @function
+ *
+ * Initializes |pri_spec| with the default values. The default values
+ * are: stream_id = 0, weight = :macro:`NGHTTP2_DEFAULT_WEIGHT` and
+ * exclusive = 0.
+ */
+void nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the |pri_spec| is filled with default values.
+ */
+int nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
+
+/**
+ * @function
+ *
+ * Submits HEADERS frame and optionally one or more DATA frames.
+ *
+ * The |pri_spec| is priority specification of this request. ``NULL``
+ * means the default priority (see
+ * `nghttp2_priority_spec_default_init()`). To specify the priority,
+ * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
+ * this function will copy its data members.
+ *
+ * The `pri_spec->weight` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
+ * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. If `pri_spec->weight` is
+ * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :enum:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
+ * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements. The value is opaque sequence of bytes and
+ * therefore can contain NULL byte (0x0). If the application requires
+ * that the ordering of values for a single header field name
+ * appearing in different header fields, it has to concatenate them
+ * using NULL byte (0x0) before passing them to this function.
+ *
+ * HTTP/2 specification has requirement about header fields in the
+ * request HEADERS. See the specification for more details.
+ *
+ * This function creates copies of all name/value pairs in |nva|. It
+ * also lower-cases all names in |nva|.
+ *
+ * If |data_prd| is not ``NULL``, it provides data which will be sent
+ * in subsequent DATA frames. In this case, a method that allows
+ * request message bodies
+ * (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9) must
+ * be specified with ``:method`` key in |nva| (e.g. ``POST``). This
+ * function does not take ownership of the |data_prd|. The function
+ * copies the members of the |data_prd|. If |data_prd| is ``NULL``,
+ * HEADERS have END_STREAM set. The |stream_user_data| is data
+ * associated to the stream opened by this request and can be an
+ * arbitrary pointer, which can be retrieved later by
+ * `nghttp2_session_get_stream_user_data()`.
+ *
+ * This function returns assigned stream ID if it succeeds, or one of
+ * the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * No stream ID is available because maximum stream ID was
+ * reached.
+ */
+int32_t nghttp2_submit_request(nghttp2_session *session,
+ const nghttp2_priority_spec *pri_spec,
+ const nghttp2_nv *nva, size_t nvlen,
+ const nghttp2_data_provider *data_prd,
+ void *stream_user_data);
+
+/**
+ * @function
+ *
+ * Submits response HEADERS frame and optionally one or more DATA
+ * frames against the stream |stream_id|.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements. The value is opaque sequence of bytes and
+ * therefore can contain NULL byte (0x0). If the application requires
+ * that the ordering of values for a single header field name
+ * appearing in different header fields, it has to concatenate them
+ * using NULL byte (0x0) before passing them to this function.
+ *
+ * HTTP/2 specification has requirement about header fields in the
+ * response HEADERS. See the specification for more details.
+ *
+ * This function creates copies of all name/value pairs in |nva|. It
+ * also lower-cases all names in |nva|.
+ *
+ * If |data_prd| is not ``NULL``, it provides data which will be sent
+ * in subsequent DATA frames. This function does not take ownership
+ * of the |data_prd|. The function copies the members of the
+ * |data_prd|. If |data_prd| is ``NULL``, HEADERS will have
+ * END_STREAM flag set.
+ *
+ * This method can be used as normal HTTP response and push response.
+ * When pushing a resource using this function, the |session| must be
+ * configured using `nghttp2_session_server_new()` or its variants and
+ * the target stream denoted by the |stream_id| must be reserved using
+ * `nghttp2_submit_push_promise()`.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_submit_response(nghttp2_session *session,
+ int32_t stream_id,
+ const nghttp2_nv *nva, size_t nvlen,
+ const nghttp2_data_provider *data_prd);
+
+/**
+ * @function
+ *
+ * Submits HEADERS frame. The |flags| is bitwise OR of the
+ * following values:
+ *
+ * * :enum:`NGHTTP2_FLAG_END_STREAM`
+ *
+ * If |flags| includes :enum:`NGHTTP2_FLAG_END_STREAM`, this frame has
+ * END_STREAM flag set.
+ *
+ * The library handles the CONTINUATION frame internally and it
+ * correctly sets END_HEADERS to the last sequence of the PUSH_PROMISE
+ * or CONTINUATION frame.
+ *
+ * If the |stream_id| is -1, this frame is assumed as request (i.e.,
+ * request HEADERS frame which opens new stream). In this case, the
+ * assigned stream ID will be returned. Otherwise, specify stream ID
+ * in |stream_id|.
+ *
+ * The |pri_spec| is priority specification of this request. ``NULL``
+ * means the default priority (see
+ * `nghttp2_priority_spec_default_init()`). To specify the priority,
+ * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
+ * this function will copy its data members.
+ *
+ * The `pri_spec->weight` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
+ * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. If `pri_spec->weight` is
+ * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :enum:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
+ * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements. The value is opaque sequence of bytes and
+ * therefore can contain NULL byte (0x0). If the application requires
+ * that the ordering of values for a single header field name
+ * appearing in different header fields, it has to concatenate them
+ * using NULL byte (0x0) before passing them to this function.
+ *
+ * This function creates copies of all name/value pairs in |nva|. It
+ * also lower-cases all names in |nva|.
+ *
+ * The |stream_user_data| is a pointer to an arbitrary data which is
+ * associated to the stream this frame will open. Therefore it is
+ * only used if this frame opens streams, in other words, it changes
+ * stream state from idle or reserved to open.
+ *
+ * This function is low-level in a sense that the application code can
+ * specify flags directly. For usual HTTP request,
+ * `nghttp2_submit_request()` is useful.
+ *
+ * This function returns newly assigned stream ID if it succeeds and
+ * |stream_id| is -1. Otherwise, this function returns 0 if it
+ * succeeds, or one of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * No stream ID is available because maximum stream ID was
+ * reached.
+ */
+int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const nghttp2_priority_spec *pri_spec,
+ const nghttp2_nv *nva, size_t nvlen,
+ void *stream_user_data);
+
+/**
+ * @function
+ *
+ * Submits one or more DATA frames to the stream |stream_id|. The
+ * data to be sent are provided by |data_prd|. If |flags| contains
+ * :enum:`NGHTTP2_FLAG_END_STREAM`, the last DATA frame has END_STREAM
+ * flag set. If |flags| contains :enum:`NGHTTP2_FLAG_END_SEGMENT`,
+ * the last DATA frame has END_SEGMENT flag set.
+ *
+ * This function does not take ownership of the |data_prd|. The
+ * function copies the members of the |data_prd|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ * DATA has been already submitted and not fully processed yet.
+ */
+int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const nghttp2_data_provider *data_prd);
+
+/**
+ * @function
+ *
+ * Submits PRIORITY frame to change the priority of stream |stream_id|
+ * to the priority specification |pri_spec|.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * The |pri_spec| is priority specification of this request. ``NULL``
+ * is not allowed for this function. To specify the priority, use
+ * `nghttp2_priority_spec_init()`. This function will copy its data
+ * members.
+ *
+ * The `pri_spec->weight` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
+ * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. If `pri_spec->weight` is
+ * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :enum:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
+ * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The |pri_spec| is NULL; or trying to depend on itself.
+ */
+int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const nghttp2_priority_spec *pri_spec);
+
+/**
+ * @function
+ *
+ * Submits RST_STREAM frame to cancel/reject the stream |stream_id|
+ * with the error code |error_code|.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ nghttp2_error_code error_code);
+
+/**
+ * @function
+ *
+ * Stores local settings and submits SETTINGS frame. The |iv| is the
+ * pointer to the array of :type:`nghttp2_settings_entry`. The |niv|
+ * indicates the number of :type:`nghttp2_settings_entry`.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * This function does not take ownership of the |iv|. This function
+ * copies all the elements in the |iv|.
+ *
+ * While updating individual stream's local window size, if the window
+ * size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE,
+ * RST_STREAM is issued against such a stream.
+ *
+ * SETTINGS with :enum:`NGHTTP2_FLAG_ACK` is automatically submitted
+ * by the library and application could not send it at its will.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The |iv| contains invalid value (e.g., initial window size
+ * strictly greater than (1 << 31) - 1.
+ * :enum:`NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS`
+ * There is already another in-flight SETTINGS. Note that the
+ * current implementation only allows 1 in-flight SETTINGS frame
+ * without ACK flag set.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
+ const nghttp2_settings_entry *iv, size_t niv);
+
+
+/**
+ * @function
+ *
+ * Submits PUSH_PROMISE frame.
+ *
+ * The |flags| is currently ignored. The library handles the
+ * CONTINUATION frame internally and it correctly sets END_HEADERS to
+ * the last sequence of the PUSH_PROMISE or CONTINUATION frame.
+ *
+ * The |stream_id| must be client initiated stream ID.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements. The value is opaque sequence of bytes and
+ * therefore can contain NULL byte (0x0). If the application requires
+ * that the ordering of values for a single header field name
+ * appearing in different header fields, it has to concatenate them
+ * using NULL byte (0x0) before passing them to this function.
+ *
+ * This function creates copies of all name/value pairs in |nva|. It
+ * also lower-cases all names in |nva|.
+ *
+ * The |promised_stream_user_data| is a pointer to an arbitrary data
+ * which is associated to the promised stream this frame will open and
+ * make it in reserved state. It is available using
+ * `nghttp2_session_get_stream_user_data()`. The application can
+ * access it in :type:`nghttp2_before_frame_send_callback` and
+ * :type:`nghttp2_on_frame_send_callback` of this frame.
+ *
+ * The client side is not allowed to use this function.
+ *
+ * This function returns assigned promised stream ID if it succeeds,
+ * or one of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_PROTO`
+ * This function was invoked when |session| is initialized as
+ * client.
+ * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * No stream ID is available because maximum stream ID was
+ * reached.
+ */
+int32_t nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const nghttp2_nv *nva, size_t nvlen,
+ void *promised_stream_user_data);
+
+/**
+ * @function
+ *
+ * Submits PING frame. You don't have to send PING back when you
+ * received PING frame. The library automatically submits PING frame
+ * in this case.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * If the |opaque_data| is non ``NULL``, then it should point to the 8
+ * bytes array of memory to specify opaque data to send with PING
+ * frame. If the |opaque_data| is ``NULL``, zero-cleared 8 bytes will
+ * be sent as opaque data.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
+ uint8_t *opaque_data);
+
+/**
+ * @function
+ *
+ * Submits GOAWAY frame with the error code |error_code|.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * If the |opaque_data| is not ``NULL`` and |opaque_data_len| is not
+ * zero, those data will be sent as additional debug data. The
+ * library makes a copy of the memory region pointed by |opaque_data|
+ * with the length |opaque_data_len|, so the caller does not need to
+ * keep this memory after the return of this function. If the
+ * |opaque_data_len| is 0, the |opaque_data| could be ``NULL``.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ * The |opaque_data_len| is too large.
+ */
+int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags,
+ nghttp2_error_code error_code,
+ const uint8_t *opaque_data, size_t opaque_data_len);
+
+/**
+ * @function
+ *
+ * Submits WINDOW_UPDATE frame.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * If the |window_size_increment| is positive, the WINDOW_UPDATE with
+ * that value as window_size_increment is queued. If the
+ * |window_size_increment| is larger than the received bytes from the
+ * remote endpoint, the local window size is increased by that
+ * difference.
+ *
+ * If the |window_size_increment| is negative, the local window size
+ * is decreased by -|window_size_increment|. If
+ * :enum:`NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE` (or
+ * :enum:`NGHTTP2_OPT_NO_AUTO_CONNECTION_WINDOW_UPDATE` if |stream_id|
+ * is 0) is not set and the library decided that the WINDOW_UPDATE
+ * should be submitted, then WINDOW_UPDATE is queued with the current
+ * received bytes count.
+ *
+ * If the |window_size_increment| is 0, the function does nothing and
+ * returns 0.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_FLOW_CONTROL`
+ * The local window size overflow or gets negative.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ int32_t window_size_increment);
+
+/**
+ * @function
+ *
+ * Submits ALTSVC frame with given parameters.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * Only the server can send the ALTSVC frame. If |session| is
+ * initialized as client, this function fails and returns
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ *
+ * If the |protocol_id_len| is 0, the |protocol_id| could be ``NULL``.
+ *
+ * If the |host_len| is 0, the |host| could be ``NULL``.
+ *
+ * If the |origin_len| is 0, the |origin| could be ``NULL``.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_PROTO`
+ * The function is invoked with |session| which was initialized as
+ * client.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The combined length of |protocol_id_len|, |host_len| and
+ * |origin_len| is is too large.
+ */
+int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ uint32_t max_age, uint16_t port,
+ const uint8_t *protocol_id, size_t protocol_id_len,
+ const uint8_t *host, size_t host_len,
+ const uint8_t *origin, size_t origin_len);
+
+/**
+ * @function
+ *
+ * Compares ``lhs->name`` of length ``lhs->namelen`` bytes and
+ * ``rhs->name`` of length ``rhs->namelen`` bytes. Returns negative
+ * integer if ``lhs->name`` is found to be less than ``rhs->name``; or
+ * returns positive integer if ``lhs->name`` is found to be greater
+ * than ``rhs->name``; or returns 0 otherwise.
+ */
+int nghttp2_nv_compare_name(const nghttp2_nv *lhs, const nghttp2_nv *rhs);
+
+/**
+ * @function
+ *
+ * A helper function for dealing with NPN in client side or ALPN in
+ * server side. The |in| contains peer's protocol list in preferable
+ * order. The format of |in| is length-prefixed and not
+ * null-terminated. For example, ``HTTP-draft-04/2.0`` and
+ * ``http/1.1`` stored in |in| like this::
+ *
+ * in[0] = 17
+ * in[1..17] = "HTTP-draft-04/2.0"
+ * in[18] = 8
+ * in[19..26] = "http/1.1"
+ * inlen = 27
+ *
+ * The selection algorithm is as follows:
+ *
+ * 1. If peer's list contains HTTP/2 protocol the library supports,
+ * it is selected and returns 1. The following step is not taken.
+ *
+ * 2. If peer's list contains ``http/1.1``, this function selects
+ * ``http/1.1`` and returns 0. The following step is not taken.
+ *
+ * 3. This function selects nothing and returns -1 (So called
+ * non-overlap case). In this case, |out| and |outlen| are left
+ * untouched.
+ *
+ * Selecting ``HTTP-draft-04/2.0`` means that ``HTTP-draft-04/2.0`` is
+ * written into |*out| and its length (which is 17) is assigned to
+ * |*outlen|.
+ *
+ * For ALPN, refer to
+ * https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-05
+ *
+ * See http://technotes.googlecode.com/git/nextprotoneg.html for more
+ * details about NPN.
+ *
+ * For NPN, to use this method you should do something like::
+ *
+ * static int select_next_proto_cb(SSL* ssl,
+ * unsigned char **out,
+ * unsigned char *outlen,
+ * const unsigned char *in,
+ * unsigned int inlen,
+ * void *arg)
+ * {
+ * int rv;
+ * rv = nghttp2_select_next_protocol(out, outlen, in, inlen);
+ * if(rv == 1) {
+ * ((MyType*)arg)->http2_selected = 1;
+ * }
+ * return SSL_TLSEXT_ERR_OK;
+ * }
+ * ...
+ * SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, my_obj);
+ *
+ */
+int nghttp2_select_next_protocol(unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen);
+
+/**
+ * @function
+ *
+ * Returns a pointer to a nghttp2_info struct with version information
+ * about the run-time library in use. The |least_version| argument
+ * can be set to a 24 bit numerical value for the least accepted
+ * version number and if the condition is not met, this function will
+ * return a ``NULL``. Pass in 0 to skip the version checking.
+ */
+nghttp2_info *nghttp2_version(int least_version);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the :type:`nghttp2_error` library error code
+ * |lib_error| is fatal.
+ */
+int nghttp2_is_fatal(int lib_error);
+
+/**
+ * @function
+ *
+ * Returns nonzero if HTTP header field name |name| of length |len| is
+ * valid according to
+ * http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-25#section-3.2
+ *
+ * Because this is a header field name in HTTP2, the upper cased alphabet
+ * is treated as error.
+ */
+int nghttp2_check_header_name(const uint8_t *name, size_t len);
+
+/**
+ * @function
+ *
+ * Returns nonzero if HTTP header field value |value| of length |len|
+ * is valid according to
+ * http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-25#section-3.2
+ *
+ * Because this is HTTP2 header field value, it can contain NULL
+ * character (0x00).
+ */
+int nghttp2_check_header_value(const uint8_t *value, size_t len);
+
+/* HPACK API */
+
+struct nghttp2_hd_deflater;
+
+/**
+ * @struct
+ *
+ * HPACK deflater object.
+ */
+typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
+
+/**
+ * @function
+ *
+ * Initializes |*deflater_ptr| for deflating name/values pairs.
+ *
+ * The |deflate_hd_table_bufsize_max| is the upper bound of header
+ * table size the deflater will use.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
+ size_t deflate_hd_table_bufsize_max);
+
+/**
+ * @function
+ *
+ * Deallocates any resources allocated for |deflater|.
+ */
+void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
+
+/**
+ * @function
+ *
+ * Sets the availability of reference set in the |deflater|. If
+ * |no_refset| is nonzero, the deflater will first emit "Reference Set
+ * Emptying" in the each subsequent invocation of
+ * `nghttp2_hd_deflate_hd()` to clear up reference set. By default,
+ * the deflater uses reference set.
+ */
+void nghttp2_hd_deflate_set_no_refset(nghttp2_hd_deflater *deflater,
+ uint8_t no_refset);
+
+/**
+ * @function
+ *
+ * Changes header table size of the |deflater| to
+ * |settings_hd_table_bufsize_max| bytes. This may trigger eviction
+ * in the dynamic table.
+ *
+ * The |settings_hd_table_bufsize_max| should be the value received in
+ * SETTINGS_HEADER_TABLE_SIZE.
+ *
+ * The deflater never uses more memory than
+ * ``deflate_hd_table_bufsize_max`` bytes specified in
+ * `nghttp2_hd_deflate_new()`. Therefore, if
+ * |settings_hd_table_bufsize_max| > ``deflate_hd_table_bufsize_max``,
+ * resulting maximum table size becomes
+ * ``deflate_hd_table_bufsize_max``.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
+ size_t settings_hd_table_bufsize_max);
+
+/**
+ * @function
+ *
+ * Deflates the |nva|, which has the |nvlen| name/value pairs, into
+ * the |buf| of length |buflen|.
+ *
+ * If |buf| is not large enough to store the deflated header block,
+ * this function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The
+ * caller should use `nghttp2_hd_deflate_bound()` to know the upper
+ * bound of buffer size required to deflate given header name/value
+ * pairs.
+ *
+ * Once this function fails, subsequent call of this function always
+ * returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
+ *
+ * After this function returns, it is safe to delete the |nva|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * Deflation process has failed.
+ * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * The provided |buflen| size is too small to hold the output.
+ */
+ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
+ uint8_t *buf, size_t buflen,
+ nghttp2_nv *nva, size_t nvlen);
+
+/**
+ * @function
+ *
+ * Returns an upper bound on the compressed size after deflation of
+ * |nva| of length |nvlen|.
+ */
+size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
+ const nghttp2_nv *nva, size_t nvlen);
+
+struct nghttp2_hd_inflater;
+
+/**
+ * @struct
+ *
+ * HPACK inflater object.
+ */
+typedef struct nghttp2_hd_inflater nghttp2_hd_inflater;
+
+/**
+ * @function
+ *
+ * Initializes |*inflater_ptr| for inflating name/values pairs.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+WS_DLL_PUBLIC int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
+
+/**
+ * @function
+ *
+ * Deallocates any resources allocated for |inflater|.
+ */
+void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
+
+/**
+ * @function
+ *
+ * Changes header table size in the |inflater|. This may trigger
+ * eviction in the dynamic table.
+ *
+ * The |settings_hd_table_bufsize_max| should be the value transmitted
+ * in SETTINGS_HEADER_TABLE_SIZE.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
+ size_t settings_hd_table_bufsize_max);
+
+/**
+ * @enum
+ *
+ * The flags for header inflation.
+ */
+typedef enum {
+ /**
+ * No flag set.
+ */
+ NGHTTP2_HD_INFLATE_NONE = 0,
+ /**
+ * Indicates all headers were inflated.
+ */
+ NGHTTP2_HD_INFLATE_FINAL = 0x01,
+ /**
+ * Indicates a header was emitted.
+ */
+ NGHTTP2_HD_INFLATE_EMIT = 0x02
+} nghttp2_hd_inflate_flag;
+
+/**
+ * @function
+ *
+ * Inflates name/value block stored in |in| with length |inlen|. This
+ * function performs decompression. For each successful emission of
+ * header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
+ * |*inflate_flags| and name/value pair is assigned to the |nv_out|
+ * and the function returns. The caller must not free the members of
+ * |nv_out|.
+ *
+ * The |nv_out| may include pointers to the memory region in the |in|.
+ * The caller must retain the |in| while the |nv_out| is used.
+ *
+ * The application should call this function repeatedly until the
+ * ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and
+ * return value is non-negative. This means the all input values are
+ * processed successfully. Then the application must call
+ * `nghttp2_hd_inflate_end_headers()` to prepare for the next header
+ * block input.
+ *
+ * The caller can feed complete compressed header block. It also can
+ * feed it in several chunks. The caller must set |in_final| to
+ * nonzero if the given input is the last block of the compressed
+ * header.
+ *
+ * This function returns the number of bytes processed if it succeeds,
+ * or one of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * Inflation process has failed.
+ * :enum:`NGHTTP2_ERR_BUFFER_ERROR`
+ * The heder field name or value is too large.
+ *
+ * Example follows::
+ *
+ * int inflate_header_block(nghttp2_hd_inflater *hd_inflater,
+ * uint8_t *in, size_t inlen, int final)
+ * {
+ * int rv;
+ *
+ * for(;;) {
+ * nghttp2_nv nv;
+ * int inflate_flags = 0;
+ *
+ * rv = nghttp2_hd_inflate_hd(hd_inflater, &nv, &inflate_flags,
+ * in, inlen, final);
+ *
+ * if(rv < 0) {
+ * fprintf(stderr, "inflate failed with error code %d", rv);
+ * return -1;
+ * }
+ *
+ * in += rv;
+ * inlen -= rv;
+ *
+ * if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
+ * fwrite(nv.name, nv.namelen, 1, stderr);
+ * fprintf(stderr, ": ");
+ * fwrite(nv.value, nv.valuelen, 1, stderr);
+ * fprintf(stderr, "\n");
+ * }
+ * if(inflate_flags & NGHTTP2_HD_INFLATE_FINAL) {
+ * nghttp2_hd_inflate_end_headers(hd_inflater);
+ * break;
+ * }
+ * if((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 &&
+ * inlen == 0) {
+ * break;
+ * }
+ * }
+ *
+ * return 0;
+ * }
+ *
+ */
+WS_DLL_PUBLIC ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
+ nghttp2_nv *nv_out, int *inflate_flags,
+ uint8_t *in, size_t inlen, int in_final);
+
+/**
+ * @function
+ *
+ * Signals the end of decompression for one header block.
+ *
+ * This function returns 0 if it succeeds. Currently this function
+ * always succeeds.
+ */
+WS_DLL_PUBLIC int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NGHTTP2_H */
diff --git a/wsutil/nghttp2/nghttp2/nghttp2ver.h b/wsutil/nghttp2/nghttp2/nghttp2ver.h
new file mode 100644
index 0000000000..325427644e
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2/nghttp2ver.h
@@ -0,0 +1,42 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2VER_H
+#define NGHTTP2VER_H
+
+/**
+ * @macro
+ * Version number of the nghttp2 library release
+ */
+#define NGHTTP2_VERSION "0.5.0-DEV"
+
+/**
+ * @macro
+ * Numerical representation of the version number of the nghttp2 library
+ * release. This is a 24 bit number with 8 bits for major number, 8 bits
+ * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
+ */
+#define NGHTTP2_VERSION_NUM 0x000500
+
+#endif /* NGHTTP2VER_H */
diff --git a/wsutil/nghttp2/nghttp2_buf.c b/wsutil/nghttp2/nghttp2_buf.c
new file mode 100644
index 0000000000..fcc5eb1ed0
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_buf.c
@@ -0,0 +1,477 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_buf.h"
+
+#include <stdio.h>
+
+#include "nghttp2_helper.h"
+
+void nghttp2_buf_init(nghttp2_buf *buf)
+{
+ buf->begin = NULL;
+ buf->end = NULL;
+ buf->pos = NULL;
+ buf->last = NULL;
+ buf->mark = NULL;
+}
+
+int nghttp2_buf_init2(nghttp2_buf *buf, size_t initial)
+{
+ nghttp2_buf_init(buf);
+ return nghttp2_buf_reserve(buf, initial);
+}
+
+void nghttp2_buf_free(nghttp2_buf *buf)
+{
+ free(buf->begin);
+}
+
+int nghttp2_buf_reserve(nghttp2_buf *buf, size_t new_cap)
+{
+ uint8_t *ptr;
+ size_t cap;
+
+ cap = nghttp2_buf_cap(buf);
+
+ if(cap >= new_cap) {
+ return 0;
+ }
+
+ new_cap = nghttp2_max(new_cap, cap * 2);
+
+ ptr = (uint8_t *)realloc(buf->begin, new_cap);
+ if(ptr == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ buf->pos = ptr + (buf->pos - buf->begin);
+ buf->last = ptr + (buf->last - buf->begin);
+ buf->mark = ptr + (buf->mark - buf->begin);
+ buf->begin = ptr;
+ buf->end = ptr + new_cap;
+
+ return 0;
+}
+
+int nghttp2_buf_pos_reserve(nghttp2_buf *buf, size_t new_rel_cap)
+{
+ return nghttp2_buf_reserve(buf, nghttp2_buf_pos_offset(buf) + new_rel_cap);
+}
+
+int nghttp2_buf_last_reserve(nghttp2_buf *buf, size_t new_rel_cap)
+{
+ return nghttp2_buf_reserve(buf, nghttp2_buf_last_offset(buf) + new_rel_cap);
+}
+
+void nghttp2_buf_reset(nghttp2_buf *buf)
+{
+ buf->pos = buf->last = buf->mark = buf->begin;
+}
+
+void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len)
+{
+ buf->begin = buf->pos = buf->last = buf->mark = begin;
+ buf->end = begin + len;
+}
+
+static int buf_chain_new(nghttp2_buf_chain **chain, size_t chunk_length)
+{
+ int rv;
+
+ *chain = (nghttp2_buf_chain *)malloc(sizeof(nghttp2_buf_chain));
+ if(*chain == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ (*chain)->next = NULL;
+
+ rv = nghttp2_buf_init2(&(*chain)->buf, chunk_length);
+ if(rv != 0) {
+ free(*chain);
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ return 0;
+}
+
+static void buf_chain_del(nghttp2_buf_chain *chain)
+{
+ nghttp2_buf_free(&chain->buf);
+ free(chain);
+}
+
+int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length,
+ size_t max_chunk)
+{
+ return nghttp2_bufs_init2(bufs, chunk_length, max_chunk, 0);
+}
+
+int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length,
+ size_t max_chunk, size_t offset)
+{
+ return nghttp2_bufs_init3(bufs, chunk_length, max_chunk, max_chunk, offset);
+}
+
+int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length,
+ size_t max_chunk, size_t chunk_keep, size_t offset)
+{
+ int rv;
+ nghttp2_buf_chain *chain;
+
+ if(chunk_keep == 0 || max_chunk < chunk_keep || chunk_length < offset) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ rv = buf_chain_new(&chain, chunk_length);
+ if(rv != 0) {
+ return rv;
+ }
+
+ bufs->offset = offset;
+
+ bufs->head = chain;
+ bufs->cur = bufs->head;
+
+ nghttp2_buf_shift_right(&bufs->cur->buf, offset);
+
+ bufs->chunk_length = chunk_length;
+ bufs->chunk_used = 1;
+ bufs->max_chunk = max_chunk;
+ bufs->chunk_keep = chunk_keep;
+
+ return 0;
+}
+
+void nghttp2_bufs_free(nghttp2_bufs *bufs)
+{
+ nghttp2_buf_chain *chain, *next_chain;
+
+ for(chain = bufs->head; chain;) {
+ next_chain = chain->next;
+
+ buf_chain_del(chain);
+
+ chain = next_chain;
+ }
+}
+
+int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len)
+{
+ nghttp2_buf_chain *chain;
+
+ chain = (nghttp2_buf_chain *)malloc(sizeof(nghttp2_buf_chain));
+ if(chain == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ chain->next = NULL;
+
+ nghttp2_buf_wrap_init(&chain->buf, begin, len);
+
+ bufs->offset = 0;
+
+ bufs->head = chain;
+ bufs->cur = bufs->head;
+
+ bufs->chunk_length = len;
+ bufs->chunk_used = 1;
+ bufs->max_chunk = 1;
+ bufs->chunk_keep = 1;
+
+ return 0;
+}
+
+void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs)
+{
+ free(bufs->head);
+}
+
+void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs)
+{
+ nghttp2_buf_chain *ci;
+
+ for(ci = bufs->cur; ci; ci = ci->next) {
+ if(nghttp2_buf_len(&ci->buf) == 0) {
+ return;
+ } else {
+ bufs->cur = ci;
+ }
+ }
+}
+
+ssize_t nghttp2_bufs_len(nghttp2_bufs *bufs)
+{
+ nghttp2_buf_chain *ci;
+ ssize_t len;
+
+ len = 0;
+ for(ci = bufs->head; ci; ci = ci->next) {
+ len += nghttp2_buf_len(&ci->buf);
+ }
+
+ return len;
+}
+
+static int bufs_avail(nghttp2_bufs *bufs)
+{
+ return nghttp2_buf_avail(&bufs->cur->buf) +
+ (bufs->chunk_length - bufs->offset) * (bufs->max_chunk - bufs->chunk_used);
+}
+
+static int bufs_alloc_chain(nghttp2_bufs *bufs)
+{
+ int rv;
+ nghttp2_buf_chain *chain;
+
+ if(bufs->cur->next) {
+ bufs->cur = bufs->cur->next;
+
+ return 0;
+ }
+
+ if(bufs->max_chunk == bufs->chunk_used) {
+ return NGHTTP2_ERR_BUFFER_ERROR;
+ }
+
+ rv = buf_chain_new(&chain, bufs->chunk_length);
+ if(rv != 0) {
+ return rv;
+ }
+
+ DEBUGF(fprintf(stderr,
+ "new buffer %zu bytes allocated for bufs %p, used %zu\n",
+ bufs->chunk_length, bufs, bufs->chunk_used));
+
+ ++bufs->chunk_used;
+
+ bufs->cur->next = chain;
+ bufs->cur = chain;
+
+ nghttp2_buf_shift_right(&bufs->cur->buf, bufs->offset);
+
+ return 0;
+}
+
+int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len)
+{
+ int rv;
+ size_t nwrite;
+ nghttp2_buf *buf;
+ const uint8_t *p;
+
+ if(bufs_avail(bufs) < (ssize_t)len) {
+ return NGHTTP2_ERR_BUFFER_ERROR;
+ }
+
+ p = (const uint8_t *)data;
+
+ while(len) {
+ buf = &bufs->cur->buf;
+
+ nwrite = nghttp2_min((size_t)nghttp2_buf_avail(buf), len);
+ if(nwrite == 0) {
+ rv = bufs_alloc_chain(bufs);
+ if(rv != 0) {
+ return rv;
+ }
+ continue;
+ }
+
+ buf->last = nghttp2_cpymem(buf->last, p, nwrite);
+ p += len;
+ len -= nwrite;
+ }
+
+ return 0;
+}
+
+static int bufs_ensure_addb(nghttp2_bufs *bufs)
+{
+ int rv;
+ nghttp2_buf *buf;
+
+ buf = &bufs->cur->buf;
+
+ if(nghttp2_buf_avail(buf) > 0) {
+ return 0;
+ }
+
+ rv = bufs_alloc_chain(bufs);
+ if(rv != 0) {
+ return rv;
+ }
+
+ return 0;
+}
+
+int nghttp2_bufs_addb(nghttp2_bufs *bufs, uint8_t b)
+{
+ int rv;
+
+ rv = bufs_ensure_addb(bufs);
+ if(rv != 0) {
+ return rv;
+ }
+
+ *bufs->cur->buf.last++ = b;
+
+ return 0;
+}
+
+int nghttp2_bufs_addb_hold(nghttp2_bufs *bufs, uint8_t b)
+{
+ int rv;
+
+ rv = bufs_ensure_addb(bufs);
+ if(rv != 0) {
+ return rv;
+ }
+
+ *bufs->cur->buf.last = b;
+
+ return 0;
+}
+
+int nghttp2_bufs_orb(nghttp2_bufs *bufs, uint8_t b)
+{
+ int rv;
+
+ rv = bufs_ensure_addb(bufs);
+ if(rv != 0) {
+ return rv;
+ }
+
+ *bufs->cur->buf.last++ |= b;
+
+ return 0;
+}
+
+int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b)
+{
+ int rv;
+
+ rv = bufs_ensure_addb(bufs);
+ if(rv != 0) {
+ return rv;
+ }
+
+ *bufs->cur->buf.last |= b;
+
+ return 0;
+}
+
+ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out)
+{
+ size_t len;
+ nghttp2_buf_chain *chain;
+ nghttp2_buf *buf;
+ uint8_t *res;
+ nghttp2_buf resbuf;
+
+ len = 0;
+
+ for(chain = bufs->head; chain; chain = chain->next) {
+ len += nghttp2_buf_len(&chain->buf);
+ }
+
+ if(!len) {
+ res = NULL;
+ } else {
+ res = (uint8_t *)malloc(len);
+
+ if(res == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+ }
+
+ nghttp2_buf_wrap_init(&resbuf, res, len);
+
+ for(chain = bufs->head; chain; chain = chain->next) {
+ buf = &chain->buf;
+
+ if(resbuf.last) {
+ resbuf.last = nghttp2_cpymem(resbuf.last,
+ buf->pos, nghttp2_buf_len(buf));
+ }
+
+ nghttp2_buf_reset(buf);
+ nghttp2_buf_shift_right(&chain->buf, bufs->offset);
+ }
+
+ bufs->cur = bufs->head;
+
+ *out = res;
+
+ return len;
+}
+
+void nghttp2_bufs_reset(nghttp2_bufs *bufs)
+{
+ nghttp2_buf_chain *chain, *ci;
+ size_t k;
+
+ k = bufs->chunk_keep;
+
+ for(ci = bufs->head; ci; ci = ci->next) {
+ nghttp2_buf_reset(&ci->buf);
+ nghttp2_buf_shift_right(&ci->buf, bufs->offset);
+
+ if(--k == 0) {
+ break;
+ }
+ }
+
+ if(ci) {
+ chain = ci->next;
+ ci->next = NULL;
+
+ for(ci = chain; ci;) {
+ chain = ci->next;
+
+ buf_chain_del(ci);
+
+ ci = chain;
+ }
+
+ bufs->chunk_used = bufs->chunk_keep;
+ }
+
+ bufs->cur = bufs->head;
+}
+
+int nghttp2_bufs_advance(nghttp2_bufs *bufs)
+{
+ return bufs_alloc_chain(bufs);
+}
+
+int nghttp2_bufs_next_present(nghttp2_bufs *bufs)
+{
+ nghttp2_buf_chain *chain;
+
+ chain = bufs->cur->next;
+
+ return chain && nghttp2_buf_len(&chain->buf);
+}
+
diff --git a/wsutil/nghttp2/nghttp2_buf.h b/wsutil/nghttp2/nghttp2_buf.h
new file mode 100644
index 0000000000..3d940d8522
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_buf.h
@@ -0,0 +1,371 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_BUF_H
+#define NGHTTP2_BUF_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <wsutil/nghttp2/nghttp2/nghttp2.h>
+
+#include "nghttp2_int.h"
+
+typedef struct {
+ /* This points to the beginning of the buffer. The effective range
+ of buffer is [begin, end). */
+ uint8_t *begin;
+ /* This points to the memory one byte beyond the end of the
+ buffer. */
+ uint8_t *end;
+ /* The position indicator for effective start of the buffer. pos <=
+ last must be hold. */
+ uint8_t *pos;
+ /* The position indicator for effective one beyond of the end of the
+ buffer. last <= end must be hold. */
+ uint8_t *last;
+ /* Mark arbitrary position in buffer [begin, end) */
+ uint8_t *mark;
+} nghttp2_buf;
+
+#define nghttp2_buf_len(BUF) ((ssize_t)((BUF)->last - (BUF)->pos))
+#define nghttp2_buf_avail(BUF) ((ssize_t)((BUF)->end - (BUF)->last))
+#define nghttp2_buf_mark_avail(BUF) ((ssize_t)((BUF)->mark - (BUF)->last))
+#define nghttp2_buf_cap(BUF) ((ssize_t)((BUF)->end - (BUF)->begin))
+
+#define nghttp2_buf_pos_offset(BUF) ((ssize_t)((BUF)->pos - (BUF)->begin))
+#define nghttp2_buf_last_offset(BUF) ((ssize_t)((BUF)->last - (BUF)->begin))
+
+#define nghttp2_buf_shift_right(BUF, AMT) \
+ do { \
+ (BUF)->pos += AMT; \
+ (BUF)->last += AMT; \
+ } while(0)
+
+#define nghttp2_buf_shift_left(BUF, AMT) \
+ do { \
+ (BUF)->pos -= AMT; \
+ (BUF)->last -= AMT; \
+ } while(0)
+
+/*
+ * Initializes the |buf|. No memory is allocated in this function. Use
+ * nghttp2_buf_reserve() or nghttp2_buf_reserve2() to allocate memory.
+ */
+void nghttp2_buf_init(nghttp2_buf *buf);
+
+
+/*
+ * Initializes the |buf| and allocates at least |initial| bytes of
+ * memory.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory
+ */
+int nghttp2_buf_init2(nghttp2_buf *buf, size_t initial);
+
+/*
+ * Frees buffer in |buf|.
+ */
+void nghttp2_buf_free(nghttp2_buf *buf);
+
+/*
+ * Extends buffer so that nghttp2_buf_cap() returns at least
+ * |new_cap|. If extensions took place, buffer pointers in |buf| will
+ * change.
+ *
+ * This function returns 0 if it succeeds, or one of the followings
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory
+ */
+int nghttp2_buf_reserve(nghttp2_buf *buf, size_t new_cap);
+
+/*
+ * This function behaves like nghttp2_buf_reserve(), but new capacity
+ * is calculated as nghttp2_buf_pos_offset(buf) + new_rel_cap. In
+ * other words, this function reserves memory at least |new_rel_cap|
+ * bytes from buf->pos.
+ */
+int nghttp2_buf_pos_reserve(nghttp2_buf *buf, size_t new_rel_cap);
+
+/*
+ * This function behaves like nghttp2_buf_reserve(), but new capacity
+ * is calculated as nghttp2_buf_last_offset(buf) + new_rel_cap. In
+ * other words, this function reserves memory at least |new_rel_cap|
+ * bytes from buf->last.
+ */
+int nghttp2_buf_last_reserve(nghttp2_buf *buf, size_t new_rel_cap);
+
+/*
+ * Resets pos, last, mark member of |buf| to buf->begin.
+ */
+void nghttp2_buf_reset(nghttp2_buf *buf);
+
+/*
+ * Initializes |buf| using supplied buffer |begin| of length
+ * |len|. Semantically, the application should not call *_reserve() or
+ * nghttp2_free() functions for |buf|.
+ */
+void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len);
+
+struct nghttp2_buf_chain;
+
+typedef struct nghttp2_buf_chain nghttp2_buf_chain;
+
+/* Chains 2 buffers */
+struct nghttp2_buf_chain {
+ /* Points to the subsequent buffer. NULL if there is no such
+ buffer. */
+ nghttp2_buf_chain *next;
+ nghttp2_buf buf;
+};
+
+typedef struct {
+ /* Points to the first buffer */
+ nghttp2_buf_chain *head;
+ /* Buffer pointer where write occurs. */
+ nghttp2_buf_chain *cur;
+ /* The buffer capacity of each buf */
+ size_t chunk_length;
+ /* The maximum number of nghttp2_buf_chain */
+ size_t max_chunk;
+ /* The number of nghttp2_buf_chain allocated */
+ size_t chunk_used;
+ /* The number of nghttp2_buf_chain to keep on reset */
+ size_t chunk_keep;
+ /* pos offset from begin in each buffers. On initialization and
+ reset, buf->pos and buf->last are positioned at buf->begin +
+ offset. */
+ size_t offset;
+} nghttp2_bufs;
+
+/*
+ * This is the same as calling nghttp2_bufs_init2 with the given
+ * arguments and offset = 0.
+ */
+int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length,
+ size_t max_chunk);
+
+/*
+ * This is the same as calling nghttp2_bufs_init3 with the given
+ * arguments and chunk_keep = max_chunk.
+ */
+int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length,
+ size_t max_chunk, size_t offset);
+
+/*
+ * Initializes |bufs|. Each buffer size is given in the
+ * |chunk_length|. The maximum number of buffers is given in the
+ * |max_chunk|. On reset, first |chunk_keep| buffers are kept and
+ * remaining buffers are deleted. Each buffer will have bufs->pos and
+ * bufs->last shifted to left by |offset| bytes on creation and reset.
+ *
+ * This function allocates first buffer. bufs->head and bufs->cur
+ * will point to the first buffer after this call.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ * chunk_keep is 0; or max_chunk < chunk_keep; or offset is too
+ * long.
+ */
+int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length,
+ size_t max_chunk, size_t chunk_keep, size_t offset);
+
+/*
+ * Frees any related resources to the |bufs|.
+ */
+void nghttp2_bufs_free(nghttp2_bufs *bufs);
+
+/*
+ * Initializes |bufs| using supplied buffer |begin| of length |len|.
+ * The first buffer bufs->head uses buffer |begin|. The buffer size
+ * is fixed and no allocate extra chunk buffer is allocated. In other
+ * words, max_chunk = chunk_keep = 1. To free the resource allocated
+ * for |bufs|, use nghttp2_bufs_wrap_free().
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ */
+int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len);
+
+/*
+ * Frees any related resource to the |bufs|. This function does not
+ * free supplied buffer provided in nghttp2_bufs_wrap_init().
+ */
+void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs);
+
+/*
+ * Appends the |data| of length |len| to the |bufs|. The write starts
+ * at bufs->cur->buf.last. A new buffers will be allocated to store
+ * all data.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ * Out of buffer space.
+ */
+int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len);
+
+/*
+ * Appends a single byte |b| to the |bufs|. The write starts at
+ * bufs->cur->buf.last. A new buffers will be allocated to store all
+ * data.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ * Out of buffer space.
+ */
+int nghttp2_bufs_addb(nghttp2_bufs *bufs, uint8_t b);
+
+/*
+ * Behaves like nghttp2_bufs_addb(), but this does not update
+ * buf->last pointer.
+ */
+int nghttp2_bufs_addb_hold(nghttp2_bufs *bufs, uint8_t b);
+
+#define nghttp2_bufs_fast_addb(BUFS, B) \
+ do { \
+ *(BUFS)->cur->buf.last++ = B; \
+ } while(0)
+
+#define nghttp2_bufs_fast_addb_hold(BUFS, B) \
+ do { \
+ *(BUFS)->cur->buf.last = B; \
+ } while(0)
+
+/*
+ * Performs bitwise-OR of |b| at bufs->cur->buf.last. A new buffers
+ * will be allocated if necessary.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ * Out of buffer space.
+ */
+int nghttp2_bufs_orb(nghttp2_bufs *bufs, uint8_t b);
+
+/*
+ * Behaves like nghttp2_bufs_orb(), but does not update buf->last
+ * pointer.
+ */
+int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
+
+#define nghttp2_bufs_fast_orb(BUFS, B) \
+ do { \
+ *(BUFS)->cur->buf.last++ |= B; \
+ } while(0)
+
+#define nghttp2_bufs_fast_orb_hold(BUFS, B) \
+ do { \
+ *(BUFS)->cur->buf.last |= B; \
+ } while(0)
+
+/*
+ * Copies all data stored in |bufs| to the contagious buffer. This
+ * function allocates the contagious memory to store all data in
+ * |bufs| and assigns it to |*out|.
+ *
+ * On successful return, nghttp2_bufs_len(bufs) returns 0, just like
+ * after calling nghttp2_bufs_reset().
+
+ * This function returns the length of copied data and assigns the
+ * pointer to copied data to |*out| if it succeeds, or one of the
+ * following negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory
+ */
+ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
+
+/*
+ * Resets |bufs| and makes the buffers empty.
+ */
+void nghttp2_bufs_reset(nghttp2_bufs *bufs);
+
+/*
+ * Moves bufs->cur to bufs->cur->next. If resulting bufs->cur is
+ * NULL, this function allocates new buffers and bufs->cur points to
+ * it.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory
+ * NGHTTP2_ERR_BUFFER_ERROR
+ * Out of buffer space.
+ */
+int nghttp2_bufs_advance(nghttp2_bufs *bufs);
+
+/* Sets bufs->cur to bufs->head */
+#define nghttp2_bufs_rewind(BUFS) \
+ do { \
+ (BUFS)->cur = (BUFS)->head; \
+ } while(0)
+
+/*
+ * Move bufs->cur, from the current position, using next member, to
+ * the last buf which has nghttp2_buf_len(buf) > 0 without seeing buf
+ * which satisfies nghttp2_buf_len(buf) == 0. If
+ * nghttp2_buf_len(&bufs->cur->buf) == 0 or bufs->cur->next is NULL,
+ * bufs->cur is unchanged.
+ */
+void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs);
+
+/*
+ * Returns nonzero if bufs->cur->next is not emtpy.
+ */
+int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
+
+#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
+
+/*
+ * Returns the buffer length of |bufs|.
+ */
+ssize_t nghttp2_bufs_len(nghttp2_bufs *bufs);
+
+#endif /* NGHTTP2_BUF_H */
diff --git a/wsutil/nghttp2/nghttp2_hd.c b/wsutil/nghttp2/nghttp2_hd.c
new file mode 100644
index 0000000000..f4d3a80335
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_hd.c
@@ -0,0 +1,2056 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_hd.h"
+
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "nghttp2_helper.h"
+#include "nghttp2_int.h"
+
+/* Make scalar initialization form of nghttp2_nv */
+#define MAKE_STATIC_ENT(I, N, V, NH, VH) \
+ { { { (uint8_t*)N, (uint8_t*)V, sizeof(N) - 1, sizeof(V) - 1, 0 }, \
+ NH, VH, 1, NGHTTP2_HD_FLAG_NONE }, I }
+
+/* Sorted by hash(name) and its table index */
+static nghttp2_hd_static_entry static_table[] = {
+ MAKE_STATIC_ENT(20, "age", "", 96511u, 0u),
+ MAKE_STATIC_ENT(59, "via", "", 116750u, 0u),
+ MAKE_STATIC_ENT(32, "date", "", 3076014u, 0u),
+ MAKE_STATIC_ENT(33, "etag", "", 3123477u, 0u),
+ MAKE_STATIC_ENT(36, "from", "", 3151786u, 0u),
+ MAKE_STATIC_ENT(37, "host", "", 3208616u, 0u),
+ MAKE_STATIC_ENT(44, "link", "", 3321850u, 0u),
+ MAKE_STATIC_ENT(58, "vary", "", 3612210u, 0u),
+ MAKE_STATIC_ENT(38, "if-match", "", 34533653u, 0u),
+ MAKE_STATIC_ENT(41, "if-range", "", 39145613u, 0u),
+ MAKE_STATIC_ENT(3, ":path", "/", 56997727u, 47u),
+ MAKE_STATIC_ENT(4, ":path", "/index.html", 56997727u, 2144181430u),
+ MAKE_STATIC_ENT(21, "allow", "", 92906313u, 0u),
+ MAKE_STATIC_ENT(49, "range", "", 108280125u, 0u),
+ MAKE_STATIC_ENT(14, "accept-charset", "", 124285319u, 0u),
+ MAKE_STATIC_ENT(43, "last-modified", "", 150043680u, 0u),
+ MAKE_STATIC_ENT(48, "proxy-authorization", "", 329532250u, 0u),
+ MAKE_STATIC_ENT(57, "user-agent", "", 486342275u, 0u),
+ MAKE_STATIC_ENT(40, "if-none-match", "", 646073760u, 0u),
+ MAKE_STATIC_ENT(30, "content-type", "", 785670158u, 0u),
+ MAKE_STATIC_ENT(16, "accept-language", "", 802785917u, 0u),
+ MAKE_STATIC_ENT(50, "referer", "", 1085069613u, 0u),
+ MAKE_STATIC_ENT(51, "refresh", "", 1085444827u, 0u),
+ MAKE_STATIC_ENT(55, "strict-transport-security", "", 1153852136u, 0u),
+ MAKE_STATIC_ENT(54, "set-cookie", "", 1237214767u, 0u),
+ MAKE_STATIC_ENT(56, "transfer-encoding", "", 1274458357u, 0u),
+ MAKE_STATIC_ENT(17, "accept-ranges", "", 1397189435u, 0u),
+ MAKE_STATIC_ENT(42, "if-unmodified-since", "", 1454068927u, 0u),
+ MAKE_STATIC_ENT(46, "max-forwards", "", 1619948695u, 0u),
+ MAKE_STATIC_ENT(45, "location", "", 1901043637u, 0u),
+ MAKE_STATIC_ENT(52, "retry-after", "", 1933352567u, 0u),
+ MAKE_STATIC_ENT(25, "content-encoding", "", 2095084583u, 0u),
+ MAKE_STATIC_ENT(28, "content-location", "", 2284906121u, 0u),
+ MAKE_STATIC_ENT(39, "if-modified-since", "", 2302095846u, 0u),
+ MAKE_STATIC_ENT(18, "accept", "", 2871506184u, 0u),
+ MAKE_STATIC_ENT(29, "content-range", "", 2878374633u, 0u),
+ MAKE_STATIC_ENT(22, "authorization", "", 2909397113u, 0u),
+ MAKE_STATIC_ENT(31, "cookie", "", 2940209764u, 0u),
+ MAKE_STATIC_ENT(0, ":authority", "", 2962729033u, 0u),
+ MAKE_STATIC_ENT(35, "expires", "", 2985731892u, 0u),
+ MAKE_STATIC_ENT(34, "expect", "", 3005803609u, 0u),
+ MAKE_STATIC_ENT(24, "content-disposition", "", 3027699811u, 0u),
+ MAKE_STATIC_ENT(26, "content-language", "", 3065240108u, 0u),
+ MAKE_STATIC_ENT(1, ":method", "GET", 3153018267u, 70454u),
+ MAKE_STATIC_ENT(2, ":method", "POST", 3153018267u, 2461856u),
+ MAKE_STATIC_ENT(27, "content-length", "", 3162187450u, 0u),
+ MAKE_STATIC_ENT(19, "access-control-allow-origin", "", 3297999203u, 0u),
+ MAKE_STATIC_ENT(5, ":scheme", "http", 3322585695u, 3213448u),
+ MAKE_STATIC_ENT(6, ":scheme", "https", 3322585695u, 99617003u),
+ MAKE_STATIC_ENT(7, ":status", "200", 3338091692u, 49586u),
+ MAKE_STATIC_ENT(8, ":status", "204", 3338091692u, 49590u),
+ MAKE_STATIC_ENT(9, ":status", "206", 3338091692u, 49592u),
+ MAKE_STATIC_ENT(10, ":status", "304", 3338091692u, 50551u),
+ MAKE_STATIC_ENT(11, ":status", "400", 3338091692u, 51508u),
+ MAKE_STATIC_ENT(12, ":status", "404", 3338091692u, 51512u),
+ MAKE_STATIC_ENT(13, ":status", "500", 3338091692u, 52469u),
+ MAKE_STATIC_ENT(53, "server", "", 3389140803u, 0u),
+ MAKE_STATIC_ENT(47, "proxy-authenticate", "", 3993199572u, 0u),
+ MAKE_STATIC_ENT(60, "www-authenticate", "", 4051929931u, 0u),
+ MAKE_STATIC_ENT(23, "cache-control", "", 4086191634u, 0u),
+ MAKE_STATIC_ENT(15, "accept-encoding", "", 4127597688u, 0u),
+};
+
+/* Index to the position in static_table */
+const size_t static_table_index[] = {
+ 38, 43, 44, 10, 11, 47, 48, 49, 50, 51, 52, 53, 54, 55, 14, 60,
+ 20, 26, 34, 46, 0 , 12, 36, 59, 41, 31, 42, 45, 32, 35, 19, 37,
+ 2 , 3 , 40, 39, 4 , 5 , 8 , 33, 18, 9 , 27, 15, 6 , 29, 28, 57,
+ 16, 13, 21, 22, 30, 56, 24, 23, 25, 17, 7 , 1 , 58
+};
+
+static const size_t STATIC_TABLE_LENGTH =
+ sizeof(static_table)/sizeof(static_table[0]);
+
+static int memeq(const void *s1, const void *s2, size_t n)
+{
+ const uint8_t *a = (const uint8_t*)s1, *b = (const uint8_t*)s2;
+ uint8_t c = 0;
+ while(n > 0) {
+ c |= (*a++) ^ (*b++);
+ --n;
+ }
+ return c == 0;
+}
+
+static uint32_t hash(const uint8_t *s, size_t n)
+{
+ uint32_t h = 0;
+ while(n > 0) {
+ h = h * 31 + *s++;
+ --n;
+ }
+ return h;
+}
+
+typedef struct {
+ nghttp2_nv *nva;
+ size_t nvacap;
+ size_t nvlen;
+} nghttp2_nva_out;
+
+int nghttp2_hd_entry_init(nghttp2_hd_entry *ent, uint8_t flags,
+ uint8_t *name, size_t namelen,
+ uint8_t *value, size_t valuelen)
+{
+ int rv = 0;
+
+ /* Since nghttp2_hd_entry is used for indexing, ent->nv.flags always
+ NGHTTP2_NV_FLAG_NONE */
+ ent->nv.flags = NGHTTP2_NV_FLAG_NONE;
+
+ if((flags & NGHTTP2_HD_FLAG_NAME_ALLOC) &&
+ (flags & NGHTTP2_HD_FLAG_NAME_GIFT) == 0) {
+ if(namelen == 0) {
+ /* We should not allow empty header field name */
+ ent->nv.name = NULL;
+ } else {
+ ent->nv.name = (uint8_t *)nghttp2_memdup(name, namelen);
+ if(ent->nv.name == NULL) {
+ rv = NGHTTP2_ERR_NOMEM;
+ goto fail;
+ }
+ }
+ } else {
+ ent->nv.name = name;
+ }
+ if((flags & NGHTTP2_HD_FLAG_VALUE_ALLOC) &&
+ (flags & NGHTTP2_HD_FLAG_VALUE_GIFT) == 0) {
+ if(valuelen == 0) {
+ ent->nv.value = NULL;
+ } else {
+ ent->nv.value = (uint8_t *)nghttp2_memdup(value, valuelen);
+ if(ent->nv.value == NULL) {
+ rv = NGHTTP2_ERR_NOMEM;
+ goto fail2;
+ }
+ }
+ } else {
+ ent->nv.value = value;
+ }
+ ent->nv.namelen = namelen;
+ ent->nv.valuelen = valuelen;
+ ent->ref = 1;
+ ent->flags = flags;
+ if(ent->nv.name) {
+ ent->name_hash = hash(ent->nv.name, ent->nv.namelen);
+ } else {
+ ent->name_hash = 0;
+ }
+ if(ent->nv.value) {
+ ent->value_hash = hash(ent->nv.value, ent->nv.valuelen);
+ } else {
+ ent->value_hash = 0;
+ }
+ return 0;
+
+ fail2:
+ if(flags & NGHTTP2_HD_FLAG_NAME_ALLOC) {
+ free(ent->nv.name);
+ }
+ fail:
+ return rv;
+}
+
+void nghttp2_hd_entry_free(nghttp2_hd_entry *ent)
+{
+ assert(ent->ref == 0);
+ if(ent->flags & NGHTTP2_HD_FLAG_NAME_ALLOC) {
+ free(ent->nv.name);
+ }
+ if(ent->flags & NGHTTP2_HD_FLAG_VALUE_ALLOC) {
+ free(ent->nv.value);
+ }
+}
+
+static int hd_ringbuf_init(nghttp2_hd_ringbuf *ringbuf, size_t bufsize)
+{
+ size_t size;
+ for(size = 1; size < bufsize; size <<= 1);
+ ringbuf->buffer = (nghttp2_hd_entry **)malloc(sizeof(nghttp2_hd_entry*)*size);
+ if(ringbuf->buffer == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+ ringbuf->mask = size - 1;
+ ringbuf->first = 0;
+ ringbuf->len = 0;
+ return 0;
+}
+
+static nghttp2_hd_entry* hd_ringbuf_get(nghttp2_hd_ringbuf *ringbuf,
+ size_t index)
+{
+ assert(index < ringbuf->len);
+ return ringbuf->buffer[(ringbuf->first + index) & ringbuf->mask];
+}
+
+static int hd_ringbuf_reserve(nghttp2_hd_ringbuf *ringbuf, size_t bufsize)
+{
+ size_t i;
+ size_t size;
+ nghttp2_hd_entry **buffer;
+
+ if(ringbuf->mask + 1 >= bufsize) {
+ return 0;
+ }
+ for(size = 1; size < bufsize; size <<= 1);
+ buffer = (nghttp2_hd_entry **)malloc(sizeof(nghttp2_hd_entry*) * size);
+ if(buffer == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+ for(i = 0; i < ringbuf->len; ++i) {
+ buffer[i] = hd_ringbuf_get(ringbuf, i);
+ }
+ free(ringbuf->buffer);
+ ringbuf->buffer = buffer;
+ ringbuf->mask = size - 1;
+ ringbuf->first = 0;
+ return 0;
+}
+
+static void hd_ringbuf_free(nghttp2_hd_ringbuf *ringbuf)
+{
+ size_t i;
+ if(ringbuf == NULL) {
+ return;
+ }
+ for(i = 0; i < ringbuf->len; ++i) {
+ nghttp2_hd_entry *ent = hd_ringbuf_get(ringbuf, i);
+ --ent->ref;
+ nghttp2_hd_entry_free(ent);
+ free(ent);
+ }
+ free(ringbuf->buffer);
+}
+
+static size_t hd_ringbuf_push_front(nghttp2_hd_ringbuf *ringbuf,
+ nghttp2_hd_entry *ent)
+{
+ assert(ringbuf->len <= ringbuf->mask);
+ ringbuf->buffer[--ringbuf->first & ringbuf->mask] = ent;
+ ++ringbuf->len;
+ return 0;
+}
+
+static void hd_ringbuf_pop_back(nghttp2_hd_ringbuf *ringbuf)
+{
+ assert(ringbuf->len > 0);
+ --ringbuf->len;
+}
+
+static int hd_context_init(nghttp2_hd_context *context,
+ nghttp2_hd_role role)
+{
+ int rv;
+ context->role = role;
+ context->bad = 0;
+ context->hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
+ rv = hd_ringbuf_init
+ (&context->hd_table,
+ context->hd_table_bufsize_max/NGHTTP2_HD_ENTRY_OVERHEAD);
+ if(rv != 0) {
+ return rv;
+ }
+
+ context->hd_table_bufsize = 0;
+ return 0;
+}
+
+static void hd_context_free(nghttp2_hd_context *context)
+{
+ hd_ringbuf_free(&context->hd_table);
+}
+
+int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater)
+{
+ return nghttp2_hd_deflate_init2(deflater,
+ NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE);
+}
+
+int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
+ size_t deflate_hd_table_bufsize_max)
+{
+ int rv;
+ rv = hd_context_init(&deflater->ctx, NGHTTP2_HD_ROLE_DEFLATE);
+ if(rv != 0) {
+ return rv;
+ }
+ deflater->no_refset = 0;
+
+ if(deflate_hd_table_bufsize_max < NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE) {
+ deflater->notify_table_size_change = 1;
+ deflater->ctx.hd_table_bufsize_max = deflate_hd_table_bufsize_max;
+ } else {
+ deflater->notify_table_size_change = 0;
+ }
+
+ deflater->deflate_hd_table_bufsize_max = deflate_hd_table_bufsize_max;
+
+ return 0;
+}
+
+int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater)
+{
+ int rv;
+
+ rv = hd_context_init(&inflater->ctx, NGHTTP2_HD_ROLE_INFLATE);
+ if(rv != 0) {
+ goto fail;
+ }
+
+ inflater->settings_hd_table_bufsize_max =
+ NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
+
+ inflater->ent_keep = NULL;
+ inflater->name_keep = NULL;
+ inflater->value_keep = NULL;
+ inflater->end_headers_index = 0;
+
+ inflater->opcode = NGHTTP2_HD_OPCODE_NONE;
+ inflater->state = NGHTTP2_HD_STATE_OPCODE;
+
+ rv = nghttp2_bufs_init(&inflater->namebufs, NGHTTP2_HD_MAX_NAME, 1);
+
+ if(rv != 0) {
+ goto namebuf_fail;
+ }
+
+ rv = nghttp2_bufs_init(&inflater->valuebufs, NGHTTP2_HD_MAX_VALUE / 2, 2);
+
+ if(rv != 0) {
+ goto valuebuf_fail;
+ }
+
+ inflater->huffman_encoded = 0;
+ inflater->index = 0;
+ inflater->left = 0;
+ inflater->index_required = 0;
+ inflater->no_index = 0;
+ inflater->ent_name = NULL;
+
+ return 0;
+
+ valuebuf_fail:
+ nghttp2_bufs_free(&inflater->namebufs);
+ namebuf_fail:
+ hd_context_free(&inflater->ctx);
+ fail:
+ return rv;
+}
+
+static void hd_inflate_keep_free(nghttp2_hd_inflater *inflater)
+{
+ if(inflater->ent_keep) {
+ if(inflater->ent_keep->ref == 0) {
+ nghttp2_hd_entry_free(inflater->ent_keep);
+ free(inflater->ent_keep);
+ }
+ inflater->ent_keep = NULL;
+ }
+ free(inflater->name_keep);
+ free(inflater->value_keep);
+ inflater->name_keep = NULL;
+ inflater->value_keep = NULL;
+}
+
+void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater)
+{
+ hd_context_free(&deflater->ctx);
+}
+
+void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater)
+{
+ hd_inflate_keep_free(inflater);
+ nghttp2_bufs_free(&inflater->namebufs);
+ nghttp2_bufs_free(&inflater->valuebufs);
+ hd_context_free(&inflater->ctx);
+}
+
+void nghttp2_hd_deflate_set_no_refset(nghttp2_hd_deflater *deflater,
+ uint8_t no_refset)
+{
+ deflater->no_refset = no_refset;
+}
+
+static size_t entry_room(size_t namelen, size_t valuelen)
+{
+ return NGHTTP2_HD_ENTRY_OVERHEAD + namelen + valuelen;
+}
+
+static int emit_indexed_header(nghttp2_nv *nv_out, nghttp2_hd_entry *ent)
+{
+ DEBUGF(fprintf(stderr, "inflatehd: header emission: "));
+ DEBUGF(fwrite(ent->nv.name, ent->nv.namelen, 1, stderr));
+ DEBUGF(fprintf(stderr, ": "));
+ DEBUGF(fwrite(ent->nv.value, ent->nv.valuelen, 1, stderr));
+ DEBUGF(fprintf(stderr, "\n"));
+ /* ent->ref may be 0. This happens if the careless stupid encoder
+ emits literal block larger than header table capacity with
+ indexing. */
+ ent->flags |= NGHTTP2_HD_FLAG_EMIT;
+ *nv_out = ent->nv;
+ return 0;
+}
+
+static int emit_literal_header(nghttp2_nv *nv_out, nghttp2_nv *nv)
+{
+ DEBUGF(fprintf(stderr, "inflatehd: header emission: "));
+ DEBUGF(fwrite(nv->name, nv->namelen, 1, stderr));
+ DEBUGF(fprintf(stderr, ": "));
+ DEBUGF(fwrite(nv->value, nv->valuelen, 1, stderr));
+ DEBUGF(fprintf(stderr, "\n"));
+ *nv_out = *nv;
+ return 0;
+}
+
+static size_t count_encoded_length(size_t n, int prefix)
+{
+ size_t k = (1 << prefix) - 1;
+ size_t len = 0;
+ if(n >= k) {
+ n -= k;
+ ++len;
+ } else {
+ return 1;
+ }
+ do {
+ ++len;
+ if(n >= 128) {
+ n >>= 7;
+ } else {
+ break;
+ }
+ } while(n);
+ return len;
+}
+
+static size_t encode_length(uint8_t *buf, size_t n, int prefix)
+{
+ size_t k = (1 << prefix) - 1;
+ size_t len = 0;
+ *buf &= ~k;
+ if(n >= k) {
+ *buf++ |= k;
+ n -= k;
+ ++len;
+ } else {
+ *buf++ |= n;
+ return 1;
+ }
+ do {
+ ++len;
+ if(n >= 128) {
+ *buf++ = (1 << 7) | (n & 0x7f);
+ n >>= 7;
+ } else {
+ *buf++ = n;
+ break;
+ }
+ } while(n);
+ return len;
+}
+
+/*
+ * Decodes |prefx| prefixed integer stored from |in|. The |last|
+ * represents the 1 beyond the last of the valid contiguous memory
+ * region from |in|. The decoded integer must be strictly less than 1
+ * << 16.
+ *
+ * If the |initial| is nonzero, it is used as a initial value, this
+ * function assumes the |in| starts with intermediate data.
+ *
+ * An entire integer is decoded successfully, decoded, the |*final| is
+ * set to nonzero.
+ *
+ * This function returns the next byte of read byte. This function
+ * stores the decoded integer in |*res| if it succeed, including
+ * partial decoding, or stores -1 in |*res|, indicating decoding
+ * error.
+ */
+static uint8_t* decode_length(ssize_t *res, int *final, ssize_t initial,
+ uint8_t *in, uint8_t *last, int prefix)
+{
+ int k = (1 << prefix) - 1, r;
+ ssize_t n = initial;
+ *final = 0;
+ if(n == 0) {
+ if((*in & k) == k) {
+ n = k;
+ } else {
+ *res = (*in) & k;
+ *final = 1;
+ return in + 1;
+ }
+ if(++in == last) {
+ *res = n;
+ return in;
+ }
+ }
+ for(r = 0; in != last; ++in, r += 7) {
+ n += (*in & 0x7f) << r;
+ if(n >= (1 << 16)) {
+ *res = -1;
+ return in + 1;
+ }
+ if((*in & (1 << 7)) == 0) {
+ break;
+ }
+ }
+ if(in == last) {
+ *res = n;
+ return in;
+ }
+ if(*in & (1 << 7)) {
+ *res = -1;
+ return in + 1;
+ }
+ *res = n;
+ *final = 1;
+ return in + 1;
+}
+
+static int emit_clear_refset(nghttp2_bufs *bufs)
+{
+ int rv;
+
+ DEBUGF(fprintf(stderr, "deflatehd: emit clear refset\n"));
+
+ rv = nghttp2_bufs_addb(bufs, 0x30u);
+ if(rv != 0) {
+ return rv;
+ }
+
+ return 0;
+}
+
+static int emit_table_size(nghttp2_bufs *bufs, size_t table_size)
+{
+ int rv;
+ uint8_t *bufp;
+ size_t blocklen;
+ uint8_t sb[16];
+
+ DEBUGF(fprintf(stderr, "deflatehd: emit table_size=%zu\n", table_size));
+
+ blocklen = count_encoded_length(table_size, 4);
+
+ if(sizeof(sb) < blocklen) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+
+ bufp = sb;
+
+ *bufp = 0x20u;
+
+ encode_length(bufp, table_size, 4);
+
+ rv = nghttp2_bufs_add(bufs, sb, blocklen);
+ if(rv != 0) {
+ return rv;
+ }
+
+ return 0;
+}
+
+static int emit_indexed_block(nghttp2_bufs *bufs, size_t index)
+{
+ int rv;
+ size_t blocklen;
+ uint8_t sb[16];
+ uint8_t *bufp;
+
+ blocklen = count_encoded_length(index + 1, 7);
+
+ DEBUGF(fprintf(stderr, "deflatehd: emit indexed index=%zu, %zu bytes\n",
+ index, blocklen));
+
+ if(sizeof(sb) < blocklen) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+
+ bufp = sb;
+ *bufp = 0x80u;
+ encode_length(bufp, index + 1, 7);
+
+ rv = nghttp2_bufs_add(bufs, sb, blocklen);
+ if(rv != 0) {
+ return rv;
+ }
+
+ return 0;
+}
+
+static int emit_string(nghttp2_bufs *bufs,
+ size_t enclen, int huffman,
+ const uint8_t *str, size_t len)
+{
+ size_t rv;
+ uint8_t sb[16];
+ uint8_t *bufp;
+ size_t blocklen;
+
+ blocklen = count_encoded_length(enclen, 7);
+
+ DEBUGF(fprintf(stderr,
+ "deflatehd: emit string str="));
+ DEBUGF(fwrite(str, len, 1, stderr));
+ DEBUGF(fprintf(stderr, ", length=%zu, huffman=%d, encoded_length=%zu\n",
+ len, huffman, enclen));
+
+ if(sizeof(sb) < blocklen) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+
+ bufp = sb;
+ *bufp = huffman ? 1 << 7 : 0;
+ encode_length(bufp, enclen, 7);
+
+ rv = nghttp2_bufs_add(bufs, sb, blocklen);
+ if(rv != 0) {
+ return rv;
+ }
+
+ if(huffman) {
+ rv = nghttp2_hd_huff_encode(bufs, str, len);
+ } else {
+ assert(enclen == len);
+ rv = nghttp2_bufs_add(bufs, str, len);
+ }
+
+ return rv;
+}
+
+static uint8_t pack_first_byte(int inc_indexing, int no_index)
+{
+ if(inc_indexing) {
+ return 0x40u;
+ }
+
+ if(no_index) {
+ return 0x10u;
+ }
+
+ return 0;
+}
+
+static int emit_indname_block(nghttp2_bufs *bufs, size_t index,
+ nghttp2_nv *nv,
+ int inc_indexing)
+{
+ int rv;
+ uint8_t *bufp;
+ size_t encvallen;
+ size_t blocklen;
+ int huffman;
+ uint8_t sb[16];
+ size_t prefixlen;
+ int no_index;
+
+ no_index = (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) != 0;
+
+ if(inc_indexing) {
+ prefixlen = 6;
+ } else {
+ prefixlen = 4;
+ }
+
+ DEBUGF(fprintf(stderr,
+ "deflatehd: emit indname index=%zu, valuelen=%zu, "
+ "indexing=%d, no_index=%d\n",
+ index, nv->valuelen, inc_indexing, no_index));
+
+ encvallen = nghttp2_hd_huff_encode_count(nv->value, nv->valuelen);
+ blocklen = count_encoded_length(index + 1, prefixlen);
+ huffman = encvallen < nv->valuelen;
+
+ if(!huffman) {
+ encvallen = nv->valuelen;
+ }
+
+ if(sizeof(sb) < blocklen) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+
+ bufp = sb;
+
+ *bufp = pack_first_byte(inc_indexing, no_index);
+
+ encode_length(bufp, index + 1, prefixlen);
+
+ rv = nghttp2_bufs_add(bufs, sb, blocklen);
+ if(rv != 0) {
+ return rv;
+ }
+
+ rv = emit_string(bufs, encvallen, huffman, nv->value, nv->valuelen);
+ if(rv != 0) {
+ return rv;
+ }
+
+ return 0;
+}
+
+static int emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
+ int inc_indexing)
+{
+ int rv;
+ size_t encnamelen;
+ size_t encvallen;
+ int name_huffman;
+ int value_huffman;
+ int no_index;
+
+ no_index = (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) != 0;
+
+ DEBUGF(fprintf(stderr,
+ "deflatehd: emit newname namelen=%zu, valuelen=%zu, "
+ "indexing=%d, no_index=%d\n",
+ nv->namelen, nv->valuelen, inc_indexing, no_index));
+
+ encnamelen = nghttp2_hd_huff_encode_count(nv->name, nv->namelen);
+ encvallen = nghttp2_hd_huff_encode_count(nv->value, nv->valuelen);
+ name_huffman = encnamelen < nv->namelen;
+ value_huffman = encvallen < nv->valuelen;
+
+ if(!name_huffman) {
+ encnamelen = nv->namelen;
+ }
+ if(!value_huffman) {
+ encvallen = nv->valuelen;
+ }
+
+ rv = nghttp2_bufs_addb(bufs, pack_first_byte(inc_indexing, no_index));
+ if(rv != 0) {
+ return rv;
+ }
+
+ rv = emit_string(bufs, encnamelen, name_huffman, nv->name, nv->namelen);
+ if(rv != 0) {
+ return rv;
+ }
+
+ rv = emit_string(bufs, encvallen, value_huffman, nv->value, nv->valuelen);
+ if(rv != 0) {
+ return rv;
+ }
+
+ return 0;
+}
+
+/*
+ * Emit common header with |index| by toggle off and on (thus 2
+ * indexed representation emissions).
+ */
+static int emit_implicit(nghttp2_bufs *bufs, size_t index)
+{
+ int i, rv;
+
+ for(i = 0; i < 2; ++i) {
+ rv = emit_indexed_block(bufs, index);
+ if(rv != 0) {
+ return rv;
+ }
+ }
+ return 0;
+}
+
+static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
+ nghttp2_bufs *bufs,
+ nghttp2_nv *nv,
+ uint8_t entry_flags)
+{
+ int rv;
+ nghttp2_hd_entry *new_ent;
+ size_t room;
+
+ room = entry_room(nv->namelen, nv->valuelen);
+
+ while(context->hd_table_bufsize + room > context->hd_table_bufsize_max &&
+ context->hd_table.len > 0) {
+
+ size_t index = context->hd_table.len - 1;
+ nghttp2_hd_entry* ent = hd_ringbuf_get(&context->hd_table, index);
+
+ context->hd_table_bufsize -= entry_room(ent->nv.namelen, ent->nv.valuelen);
+ if(context->role == NGHTTP2_HD_ROLE_DEFLATE) {
+ if(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) {
+ /* Emit common header just before it slips away from the
+ table. If we don't do this, we have to emit it in literal
+ representation which hurts compression. */
+ rv = emit_implicit(bufs, index);
+ if(rv != 0) {
+ return NULL;
+ }
+ }
+ }
+ DEBUGF(fprintf(stderr, "hpack: remove item from header table: "));
+ DEBUGF(fwrite(ent->nv.name, ent->nv.namelen, 1, stderr));
+ DEBUGF(fprintf(stderr, ": "));
+ DEBUGF(fwrite(ent->nv.value, ent->nv.valuelen, 1, stderr));
+ DEBUGF(fprintf(stderr, "\n"));
+ hd_ringbuf_pop_back(&context->hd_table);
+ if(--ent->ref == 0) {
+ nghttp2_hd_entry_free(ent);
+ free(ent);
+ }
+ }
+
+ new_ent = (nghttp2_hd_entry *)malloc(sizeof(nghttp2_hd_entry));
+ if(new_ent == NULL) {
+ return NULL;
+ }
+
+ rv = nghttp2_hd_entry_init(new_ent, entry_flags,
+ nv->name, nv->namelen, nv->value, nv->valuelen);
+ if(rv != 0) {
+ free(new_ent);
+ return NULL;
+ }
+
+ if(room > context->hd_table_bufsize_max) {
+ /* The entry taking more than NGHTTP2_HD_MAX_BUFFER_SIZE is
+ immediately evicted. */
+ --new_ent->ref;
+ } else {
+ context->hd_table_bufsize += room;
+ hd_ringbuf_push_front(&context->hd_table, new_ent);
+
+ new_ent->flags |= NGHTTP2_HD_FLAG_REFSET;
+ }
+ return new_ent;
+}
+
+static int name_eq(const nghttp2_nv *a, const nghttp2_nv *b)
+{
+ return a->namelen == b->namelen && memeq(a->name, b->name, a->namelen);
+}
+
+static int value_eq(const nghttp2_nv *a, const nghttp2_nv *b)
+{
+ return a->valuelen == b->valuelen && memeq(a->value, b->value, a->valuelen);
+}
+
+typedef struct {
+ ssize_t index;
+ /* Nonzero if both name and value are matched. */
+ uint8_t name_value_match;
+} search_result;
+
+static search_result search_hd_table(nghttp2_hd_context *context,
+ nghttp2_nv *nv)
+{
+ search_result res = { -1, 0 };
+ size_t i;
+ uint32_t name_hash = hash(nv->name, nv->namelen);
+ uint32_t value_hash = hash(nv->value, nv->valuelen);
+ ssize_t left = -1, right = STATIC_TABLE_LENGTH;
+ int use_index = (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) == 0;
+
+ if(use_index) {
+ for(i = 0; i < context->hd_table.len; ++i) {
+ nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, i);
+ if(ent->name_hash == name_hash && name_eq(&ent->nv, nv)) {
+ if(res.index == -1) {
+ res.index = i;
+ }
+ if(ent->value_hash == value_hash && value_eq(&ent->nv, nv)) {
+ res.index = i;
+ res.name_value_match = 1;
+ return res;
+ }
+ }
+ }
+ }
+
+ while(right - left > 1) {
+ ssize_t mid = (left + right) / 2;
+ nghttp2_hd_entry *ent = &static_table[mid].ent;
+ if(ent->name_hash < name_hash) {
+ left = mid;
+ } else {
+ right = mid;
+ }
+ }
+
+ for(i = right; i < STATIC_TABLE_LENGTH; ++i) {
+ nghttp2_hd_entry *ent = &static_table[i].ent;
+ if(ent->name_hash != name_hash) {
+ break;
+ }
+ if(name_eq(&ent->nv, nv)) {
+ if(res.index == -1) {
+ res.index = context->hd_table.len + static_table[i].index;
+ }
+ if(use_index &&
+ ent->value_hash == value_hash && value_eq(&ent->nv, nv)) {
+ res.index = context->hd_table.len + static_table[i].index;
+ res.name_value_match = 1;
+ return res;
+ }
+ }
+ }
+ return res;
+}
+
+static void hd_context_shrink_table_size(nghttp2_hd_context *context)
+{
+ while(context->hd_table_bufsize > context->hd_table_bufsize_max &&
+ context->hd_table.len > 0) {
+ size_t index = context->hd_table.len - 1;
+ nghttp2_hd_entry* ent = hd_ringbuf_get(&context->hd_table, index);
+ context->hd_table_bufsize -= entry_room(ent->nv.namelen, ent->nv.valuelen);
+ hd_ringbuf_pop_back(&context->hd_table);
+ if(--ent->ref == 0) {
+ nghttp2_hd_entry_free(ent);
+ free(ent);
+ }
+ }
+}
+
+int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
+ size_t settings_hd_table_bufsize_max)
+{
+ int rv;
+ size_t next_bufsize = nghttp2_min(settings_hd_table_bufsize_max,
+ deflater->deflate_hd_table_bufsize_max);
+ rv = hd_ringbuf_reserve
+ (&deflater->ctx.hd_table, next_bufsize / NGHTTP2_HD_ENTRY_OVERHEAD);
+ if(rv != 0) {
+ return rv;
+ }
+
+ deflater->ctx.hd_table_bufsize_max = next_bufsize;
+
+ deflater->notify_table_size_change = 1;
+
+ hd_context_shrink_table_size(&deflater->ctx);
+ return 0;
+}
+
+int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
+ size_t settings_hd_table_bufsize_max)
+{
+ int rv;
+
+ rv = hd_ringbuf_reserve
+ (&inflater->ctx.hd_table,
+ settings_hd_table_bufsize_max / NGHTTP2_HD_ENTRY_OVERHEAD);
+ if(rv != 0) {
+ return rv;
+ }
+ inflater->settings_hd_table_bufsize_max = settings_hd_table_bufsize_max;
+ inflater->ctx.hd_table_bufsize_max = settings_hd_table_bufsize_max;
+ hd_context_shrink_table_size(&inflater->ctx);
+ return 0;
+}
+
+static void clear_refset(nghttp2_hd_context *context)
+{
+ size_t i;
+ for(i = 0; i < context->hd_table.len; ++i) {
+ nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, i);
+ ent->flags &= ~NGHTTP2_HD_FLAG_REFSET;
+ }
+}
+
+int check_index_range(nghttp2_hd_context *context, size_t index)
+{
+ return index < context->hd_table.len + STATIC_TABLE_LENGTH;
+}
+
+static int get_max_index(nghttp2_hd_context *context)
+{
+ return context->hd_table.len + STATIC_TABLE_LENGTH - 1;
+}
+
+nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context,
+ size_t index)
+{
+ assert(check_index_range(context, index));
+ if(index < context->hd_table.len) {
+ return hd_ringbuf_get(&context->hd_table, index);
+ } else {
+ return
+ &static_table[static_table_index[index - context->hd_table.len]].ent;
+ }
+}
+
+#define name_match(NV, NAME) \
+ (nv->namelen == sizeof(NAME) - 1 && memeq(nv->name, NAME, sizeof(NAME) - 1))
+
+static int hd_deflate_should_indexing(nghttp2_hd_deflater *deflater,
+ const nghttp2_nv *nv)
+{
+ if((nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) ||
+ entry_room(nv->namelen, nv->valuelen) >
+ deflater->ctx.hd_table_bufsize_max * 3 / 4) {
+ return 0;
+ }
+#ifdef NGHTTP2_XHD
+ return !name_match(nv, NGHTTP2_XHD);
+#else /* !NGHTTP2_XHD */
+ return
+ !name_match(nv, "set-cookie") &&
+ !name_match(nv, "content-length") &&
+ !name_match(nv, "location") &&
+ !name_match(nv, "etag") &&
+ !name_match(nv, ":path");
+#endif /* !NGHTTP2_XHD */
+}
+
+static int deflate_nv(nghttp2_hd_deflater *deflater,
+ nghttp2_bufs *bufs, nghttp2_nv *nv)
+{
+ int rv;
+ nghttp2_hd_entry *ent;
+ search_result res;
+
+ DEBUGF(fprintf(stderr, "deflatehd: deflating "));
+ DEBUGF(fwrite(nv->name, nv->namelen, 1, stderr));
+ DEBUGF(fprintf(stderr, ": "));
+ DEBUGF(fwrite(nv->value, nv->valuelen, 1, stderr));
+ DEBUGF(fprintf(stderr, "\n"));
+
+ res = search_hd_table(&deflater->ctx, nv);
+
+ if(res.index != -1 && res.name_value_match) {
+ size_t index = res.index;
+
+ DEBUGF(fprintf(stderr, "deflatehd: name/value match index=%zd\n",
+ res.index));
+
+ ent = nghttp2_hd_table_get(&deflater->ctx, index);
+ if(index >= deflater->ctx.hd_table.len) {
+ nghttp2_hd_entry *new_ent;
+
+ /* It is important to first add entry to the header table and
+ let eviction go. If NGHTTP2_HD_FLAG_IMPLICIT_EMIT entry is
+ evicted, it must be emitted before the |nv|. */
+ new_ent = add_hd_table_incremental(&deflater->ctx, bufs, &ent->nv,
+ NGHTTP2_HD_FLAG_NONE);
+ if(!new_ent) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+ if(new_ent->ref == 0) {
+ nghttp2_hd_entry_free(new_ent);
+ free(new_ent);
+ new_ent = NULL;
+ } else {
+ /* new_ent->ref > 0 means that new_ent is in the reference
+ set */
+ new_ent->flags |= NGHTTP2_HD_FLAG_EMIT;
+ }
+ rv = emit_indexed_block(bufs, index);
+ if(rv != 0) {
+ return rv;
+ }
+ } else if((ent->flags & NGHTTP2_HD_FLAG_REFSET) == 0) {
+ ent->flags |= NGHTTP2_HD_FLAG_REFSET | NGHTTP2_HD_FLAG_EMIT;
+ rv = emit_indexed_block(bufs, index);
+ if(rv != 0) {
+ return rv;
+ }
+ } else {
+ int num_emits = 0;
+ if(ent->flags & NGHTTP2_HD_FLAG_EMIT) {
+ /* occurrences of the same indexed representation. Emit index
+ twice. */
+ num_emits = 2;
+ } else if(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) {
+ /* ent was implicitly emitted because it is the common
+ header field. To support occurrences of the same indexed
+ representation, we have to emit 4 times. This is because
+ "implicitly emitted" means actually not emitted at
+ all. So first 2 emits performs 1st header appears in the
+ reference set. And another 2 emits are done for 2nd
+ (current) header. */
+ ent->flags ^= NGHTTP2_HD_FLAG_IMPLICIT_EMIT;
+ ent->flags |= NGHTTP2_HD_FLAG_EMIT;
+ num_emits = 4;
+ } else {
+ /* This is common header and not emitted in the current
+ run. Just mark IMPLICIT_EMIT, in the hope that we are not
+ required to emit anything for this. We will emit toggle
+ off/on for this entry if it is removed from the header
+ table. */
+ ent->flags |= NGHTTP2_HD_FLAG_IMPLICIT_EMIT;
+ }
+ for(; num_emits > 0; --num_emits) {
+ rv = emit_indexed_block(bufs, index);
+ if(rv != 0) {
+ return rv;
+ }
+ }
+ }
+ } else {
+ ssize_t index = -1;
+ int incidx = 0;
+ if(res.index != -1) {
+ DEBUGF(fprintf(stderr, "deflatehd: name match index=%zd\n",
+ res.index));
+
+ index = res.index;
+ }
+ if(hd_deflate_should_indexing(deflater, nv)) {
+ nghttp2_hd_entry *new_ent;
+ if(index >= (ssize_t)deflater->ctx.hd_table.len) {
+ nghttp2_nv nv_indname;
+ nv_indname = *nv;
+ nv_indname.name = nghttp2_hd_table_get(&deflater->ctx, index)->nv.name;
+ new_ent = add_hd_table_incremental(&deflater->ctx, bufs, &nv_indname,
+ NGHTTP2_HD_FLAG_VALUE_ALLOC);
+ } else {
+ new_ent = add_hd_table_incremental(&deflater->ctx, bufs, nv,
+ NGHTTP2_HD_FLAG_NAME_ALLOC |
+ NGHTTP2_HD_FLAG_VALUE_ALLOC);
+ }
+ if(!new_ent) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+ if(new_ent->ref == 0) {
+ nghttp2_hd_entry_free(new_ent);
+ free(new_ent);
+ } else {
+ /* new_ent->ref > 0 means that new_ent is in the reference
+ set. */
+ new_ent->flags |= NGHTTP2_HD_FLAG_EMIT;
+ }
+ incidx = 1;
+ }
+ if(index == -1) {
+ rv = emit_newname_block(bufs, nv, incidx);
+ } else {
+ rv = emit_indname_block(bufs, index, nv, incidx);
+ }
+ if(rv != 0) {
+ return rv;
+ }
+ }
+ return 0;
+}
+
+static int deflate_post_process_hd_entry(nghttp2_hd_entry *ent,
+ size_t index,
+ nghttp2_bufs *bufs)
+{
+ int rv;
+
+ if((ent->flags & NGHTTP2_HD_FLAG_REFSET) &&
+ (ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) == 0 &&
+ (ent->flags & NGHTTP2_HD_FLAG_EMIT) == 0) {
+ /* This entry is not present in the current header set and must
+ be removed. */
+ ent->flags ^= NGHTTP2_HD_FLAG_REFSET;
+
+ rv = emit_indexed_block(bufs, index);
+ if(rv != 0) {
+ return rv;
+ }
+ }
+
+ ent->flags &= ~(NGHTTP2_HD_FLAG_EMIT | NGHTTP2_HD_FLAG_IMPLICIT_EMIT);
+
+ return 0;
+}
+
+int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
+ nghttp2_bufs *bufs,
+ nghttp2_nv *nv, size_t nvlen)
+{
+ size_t i;
+ int rv = 0;
+
+ if(deflater->ctx.bad) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+
+ if(deflater->notify_table_size_change) {
+
+ deflater->notify_table_size_change = 0;
+
+ rv = emit_table_size(bufs, deflater->ctx.hd_table_bufsize_max);
+
+ if(rv != 0) {
+ goto fail;
+ }
+ }
+
+ if(deflater->no_refset) {
+ rv = emit_clear_refset(bufs);
+ if(rv != 0) {
+ goto fail;
+ }
+ clear_refset(&deflater->ctx);
+ }
+ for(i = 0; i < nvlen; ++i) {
+ rv = deflate_nv(deflater, bufs, &nv[i]);
+ if(rv != 0) {
+ goto fail;
+ }
+ }
+
+ DEBUGF(fprintf(stderr,
+ "deflatehd: all input name/value pairs were deflated\n"));
+
+ for(i = 0; i < deflater->ctx.hd_table.len; ++i) {
+ nghttp2_hd_entry *ent = hd_ringbuf_get(&deflater->ctx.hd_table, i);
+
+ rv = deflate_post_process_hd_entry(ent, i, bufs);
+ if(rv != 0) {
+ goto fail;
+ }
+ }
+
+ return 0;
+ fail:
+ DEBUGF(fprintf(stderr, "deflatehd: error return %d\n", rv));
+
+ deflater->ctx.bad = 1;
+ return rv;
+}
+
+ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
+ uint8_t *buf, size_t buflen,
+ nghttp2_nv *nv, size_t nvlen)
+{
+ nghttp2_bufs bufs;
+ int rv;
+
+ rv = nghttp2_bufs_wrap_init(&bufs, buf, buflen);
+
+ if(rv != 0) {
+ return rv;
+ }
+
+ rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs, nv, nvlen);
+
+ buflen = nghttp2_bufs_len(&bufs);
+
+ nghttp2_bufs_wrap_free(&bufs);
+
+ if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
+ return NGHTTP2_ERR_INSUFF_BUFSIZE;
+ }
+
+ if(rv != 0) {
+ return rv;
+ }
+
+ return buflen;
+}
+
+size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
+ const nghttp2_nv *nva, size_t nvlen)
+{
+ size_t n;
+ size_t i;
+
+ /* Possible Reference Set Emptying */
+ n = 1;
+
+ /* Possible Maximum Header Table Size Change. Encoding (1u << 31) -
+ 1 using 4 bit prefix requires 6 bytes. */
+ n += 6;
+
+ /* Use Literal Header Field without indexing - New Name, since it is
+ most space consuming format. Also we choose the less one between
+ non-huffman and huffman, so using literal byte count is
+ sufficient for upper bound.
+
+ Encoding (1u << 31) - 1 using 7 bit prefix requires 6 bytes. We
+ need 2 of this for |nvlen| header fields. */
+ n += 6 * 2 * nvlen;
+
+ for(i = 0; i < nvlen; ++i) {
+ n += nva[i].namelen + nva[i].valuelen;
+ }
+
+ /* Add possible reference set toggle off */
+ n += deflater->ctx.hd_table.len;
+
+ return n;
+}
+
+int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
+ size_t deflate_hd_table_bufsize_max)
+{
+ *deflater_ptr = (nghttp2_hd_deflater *)malloc(sizeof(nghttp2_hd_deflater));
+
+ if(*deflater_ptr == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ return nghttp2_hd_deflate_init2(*deflater_ptr, deflate_hd_table_bufsize_max);
+}
+
+void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater)
+{
+ nghttp2_hd_deflate_free(deflater);
+
+ free(deflater);
+}
+
+static void hd_inflate_set_huffman_encoded(nghttp2_hd_inflater *inflater,
+ const uint8_t *in)
+{
+ inflater->huffman_encoded = (*in & (1 << 7)) != 0;
+}
+
+/*
+ * Decodes the integer from the range [in, last). The result is
+ * assigned to |inflater->left|. If the |inflater->left| is 0, then
+ * it performs variable integer decoding from scratch. Otherwise, it
+ * uses the |inflater->left| as the initial value and continues to
+ * decode assuming that [in, last) begins with intermediary sequence.
+ *
+ * This function returns the number of bytes read if it succeeds, or
+ * one of the following negative error codes:
+ *
+ * NGHTTP2_ERR_HEADER_COMP
+ * Integer decoding failed
+ */
+static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater,
+ int *rfin,
+ uint8_t *in, uint8_t *last,
+ int prefix, size_t maxlen)
+{
+ uint8_t *nin;
+ *rfin = 0;
+ nin = decode_length(&inflater->left, rfin, inflater->left, in, last, prefix);
+ if(inflater->left == -1) {
+ DEBUGF(fprintf(stderr, "inflatehd: invalid integer\n"));
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+ if((size_t)inflater->left > maxlen) {
+ DEBUGF(fprintf(stderr,
+ "inflatehd: integer exceeded the maximum value %zu\n",
+ maxlen));
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+ return nin - in;
+}
+
+/*
+ * Reads |inflater->left| bytes from the range [in, last) and performs
+ * huffman decoding against them and pushes the result into the
+ * |buffer|.
+ *
+ * This function returns the number of bytes read if it succeeds, or
+ * one of the following negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory
+ * NGHTTP2_ERR_HEADER_COMP
+ * Huffman decoding failed
+ * NGHTTP2_ERR_BUFFER_ERROR
+ * Out of buffer space.
+ */
+static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
+ nghttp2_bufs *bufs,
+ uint8_t *in, uint8_t *last)
+{
+ int rv;
+ int final = 0;
+ if(last - in >= inflater->left) {
+ last = in + inflater->left;
+ final = 1;
+ }
+ rv = nghttp2_hd_huff_decode(&inflater->huff_decode_ctx, bufs,
+ in, last - in, final);
+
+ if(rv < 0) {
+ DEBUGF(fprintf(stderr, "inflatehd: huffman decoding failed\n"));
+ return rv;
+ }
+ inflater->left -= rv;
+ return rv;
+}
+
+/*
+ * Reads |inflater->left| bytes from the range [in, last) and copies
+ * them into the |buffer|.
+ *
+ * This function returns the number of bytes read if it succeeds, or
+ * one of the following negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory
+ * NGHTTP2_ERR_HEADER_COMP
+ * Header decompression failed
+ * NGHTTP2_ERR_BUFFER_ERROR
+ * Out of buffer space.
+ */
+static ssize_t hd_inflate_read(nghttp2_hd_inflater *inflater,
+ nghttp2_bufs *bufs,
+ uint8_t *in, uint8_t *last)
+{
+ int rv;
+ size_t len = nghttp2_min(last - in, inflater->left);
+ rv = nghttp2_bufs_add(bufs, in, len);
+ if(rv != 0) {
+ return rv;
+ }
+ inflater->left -= len;
+ return len;
+}
+
+/*
+ * Finalize indexed header representation reception. If header is
+ * emitted, |*nv_out| is filled with that value and 0 is returned. If
+ * no header is emitted, 1 is returned.
+ *
+ * This function returns either 0 or 1 if it succeeds, or one of the
+ * following negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory
+ */
+static int hd_inflate_commit_indexed(nghttp2_hd_inflater *inflater,
+ nghttp2_nv *nv_out)
+{
+ nghttp2_hd_entry *ent = nghttp2_hd_table_get(&inflater->ctx, inflater->index);
+ if(inflater->index >= inflater->ctx.hd_table.len) {
+ nghttp2_hd_entry *new_ent;
+ new_ent = add_hd_table_incremental(&inflater->ctx, NULL, &ent->nv,
+ NGHTTP2_HD_FLAG_NONE);
+ if(!new_ent) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+ /* new_ent->ref == 0 may be hold */
+ emit_indexed_header(nv_out, new_ent);
+ inflater->ent_keep = new_ent;
+ return 0;
+ }
+ ent->flags ^= NGHTTP2_HD_FLAG_REFSET;
+ if(ent->flags & NGHTTP2_HD_FLAG_REFSET) {
+ emit_indexed_header(nv_out, ent);
+ return 0;
+ }
+ DEBUGF(fprintf(stderr, "inflatehd: toggle off item: "));
+ DEBUGF(fwrite(ent->nv.name, ent->nv.namelen, 1, stderr));
+ DEBUGF(fprintf(stderr, ": "));
+ DEBUGF(fwrite(ent->nv.value, ent->nv.valuelen, 1, stderr));
+ DEBUGF(fprintf(stderr, "\n"));
+ return 1;
+}
+
+static int hd_inflate_remove_bufs(nghttp2_hd_inflater *inflater,
+ nghttp2_nv *nv, int value_only)
+{
+ ssize_t rv;
+
+ if(value_only) {
+ nv->name = NULL;
+ } else {
+ rv = nghttp2_bufs_remove(&inflater->namebufs, &nv->name);
+
+ if(rv < 0) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ nv->namelen = rv;
+ }
+
+ rv = nghttp2_bufs_remove(&inflater->valuebufs, &nv->value);
+ if(rv < 0) {
+ free(nv->name);
+
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ nv->valuelen = rv;
+
+ return 0;
+}
+
+/*
+ * Finalize literal header representation - new name- reception. If
+ * header is emitted, |*nv_out| is filled with that value and 0 is
+ * returned.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory
+ */
+static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
+ nghttp2_nv *nv_out)
+{
+ int rv;
+ nghttp2_nv nv;
+
+ rv = hd_inflate_remove_bufs(inflater, &nv, 0 /* name and value */);
+ if(rv != 0) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ if(inflater->no_index) {
+ nv.flags = NGHTTP2_NV_FLAG_NO_INDEX;
+ } else {
+ nv.flags = NGHTTP2_NV_FLAG_NONE;
+ }
+
+ if(inflater->index_required) {
+ nghttp2_hd_entry *new_ent;
+ uint8_t ent_flags;
+
+ ent_flags =
+ NGHTTP2_HD_FLAG_NAME_ALLOC | NGHTTP2_HD_FLAG_VALUE_ALLOC |
+ NGHTTP2_HD_FLAG_NAME_GIFT | NGHTTP2_HD_FLAG_VALUE_GIFT;
+
+ new_ent = add_hd_table_incremental(&inflater->ctx, NULL, &nv, ent_flags);
+
+ if(new_ent) {
+ emit_indexed_header(nv_out, new_ent);
+ inflater->ent_keep = new_ent;
+
+ return 0;
+ }
+
+ free(nv.name);
+ free(nv.value);
+
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ emit_literal_header(nv_out, &nv);
+
+ inflater->name_keep = nv.name;
+ inflater->value_keep = nv.value;
+
+ return 0;
+}
+
+/*
+ * Finalize literal header representation - indexed name-
+ * reception. If header is emitted, |*nv_out| is filled with that
+ * value and 0 is returned.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory
+ */
+static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
+ nghttp2_nv *nv_out)
+{
+ int rv;
+ nghttp2_nv nv;
+
+ rv = hd_inflate_remove_bufs(inflater, &nv, 1 /* value only */);
+ if(rv != 0) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ if(inflater->no_index) {
+ nv.flags = NGHTTP2_NV_FLAG_NO_INDEX;
+ } else {
+ nv.flags = NGHTTP2_NV_FLAG_NONE;
+ }
+
+ nv.name = inflater->ent_name->nv.name;
+ nv.namelen = inflater->ent_name->nv.namelen;
+
+ if(inflater->index_required) {
+ nghttp2_hd_entry *new_ent;
+ uint8_t ent_flags;
+ int static_name;
+
+ ent_flags = NGHTTP2_HD_FLAG_VALUE_ALLOC | NGHTTP2_HD_FLAG_VALUE_GIFT;
+ static_name = inflater->index >= inflater->ctx.hd_table.len;
+
+ if(!static_name) {
+ ent_flags |= NGHTTP2_HD_FLAG_NAME_ALLOC;
+ /* For entry in static table, we must not touch ref, because it
+ is shared by threads */
+ ++inflater->ent_name->ref;
+ }
+
+ new_ent = add_hd_table_incremental(&inflater->ctx, NULL, &nv, ent_flags);
+
+ if(!static_name && --inflater->ent_name->ref == 0) {
+ nghttp2_hd_entry_free(inflater->ent_name);
+ free(inflater->ent_name);
+ }
+
+ inflater->ent_name = NULL;
+
+ if(new_ent) {
+ emit_indexed_header(nv_out, new_ent);
+
+ inflater->ent_keep = new_ent;
+
+ return 0;
+ }
+
+ free(nv.value);
+
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ emit_literal_header(nv_out, &nv);
+
+ inflater->value_keep = nv.value;
+
+ return 0;
+}
+
+ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
+ nghttp2_nv *nv_out, int *inflate_flags,
+ uint8_t *in, size_t inlen, int in_final)
+{
+ ssize_t rv = 0;
+ uint8_t *first = in;
+ uint8_t *last = in + inlen;
+ int rfin = 0;
+
+ if(inflater->ctx.bad) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+
+ DEBUGF(fprintf(stderr, "inflatehd: start state=%d\n",
+ inflater->state));
+ hd_inflate_keep_free(inflater);
+ *inflate_flags = NGHTTP2_HD_INFLATE_NONE;
+ for(; in != last;) {
+ switch(inflater->state) {
+ case NGHTTP2_HD_STATE_OPCODE:
+ if((*in & 0xf0u) == 0x20u) {
+ DEBUGF(fprintf(stderr, "inflatehd: header table size change\n"));
+ inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
+ inflater->state = NGHTTP2_HD_STATE_READ_TABLE_SIZE;
+ } else if((*in & 0xf0u) == 0x30u) {
+ if(*in != 0x30u) {
+ rv = NGHTTP2_ERR_HEADER_COMP;
+ goto fail;
+ }
+
+ DEBUGF(fprintf(stderr, "inflatehd: clearing reference set\n"));
+ inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
+ inflater->state = NGHTTP2_HD_STATE_CLEAR_REFSET;
+ ++in;
+ } else if(*in & 0x80u) {
+ DEBUGF(fprintf(stderr, "inflatehd: indexed repr\n"));
+ inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
+ inflater->state = NGHTTP2_HD_STATE_READ_INDEX;
+ } else {
+ if(*in == 0x40u || *in == 0 || *in == 0x10u) {
+ DEBUGF(fprintf(stderr,
+ "inflatehd: literal header repr - new name\n"));
+ inflater->opcode = NGHTTP2_HD_OPCODE_NEWNAME;
+ inflater->state = NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN;
+ } else {
+ DEBUGF(fprintf(stderr,
+ "inflatehd: literal header repr - indexed name\n"));
+ inflater->opcode = NGHTTP2_HD_OPCODE_INDNAME;
+ inflater->state = NGHTTP2_HD_STATE_READ_INDEX;
+ }
+ inflater->index_required = (*in & 0x40) != 0;
+ inflater->no_index = (*in & 0x10u) != 0;
+ DEBUGF(fprintf(stderr,
+ "inflatehd: indexing required=%d, no_index=%d\n",
+ inflater->index_required,
+ inflater->no_index));
+ if(inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) {
+ ++in;
+ }
+ }
+ inflater->left = 0;
+ break;
+ case NGHTTP2_HD_STATE_CLEAR_REFSET:
+ clear_refset(&inflater->ctx);
+ inflater->state = NGHTTP2_HD_STATE_OPCODE;
+
+ break;
+ case NGHTTP2_HD_STATE_READ_TABLE_SIZE:
+ rfin = 0;
+ rv = hd_inflate_read_len(inflater, &rfin, in, last, 4,
+ inflater->settings_hd_table_bufsize_max);
+ if(rv < 0) {
+ goto fail;
+ }
+ in += rv;
+ if(!rfin) {
+ goto almost_ok;
+ }
+ DEBUGF(fprintf(stderr, "inflatehd: table_size=%zd\n", inflater->left));
+ inflater->ctx.hd_table_bufsize_max = inflater->left;
+ hd_context_shrink_table_size(&inflater->ctx);
+ inflater->state = NGHTTP2_HD_STATE_OPCODE;
+ break;
+ case NGHTTP2_HD_STATE_READ_INDEX: {
+ size_t prefixlen;
+
+ if(inflater->opcode == NGHTTP2_HD_OPCODE_INDEXED) {
+ prefixlen = 7;
+ } else if(inflater->index_required) {
+ prefixlen = 6;
+ } else {
+ prefixlen = 4;
+ }
+
+ rfin = 0;
+ rv = hd_inflate_read_len(inflater, &rfin, in, last, prefixlen,
+ get_max_index(&inflater->ctx) + 1);
+ if(rv < 0) {
+ goto fail;
+ }
+
+ in += rv;
+
+ if(inflater->left == 0) {
+ rv = NGHTTP2_ERR_HEADER_COMP;
+ goto fail;
+ }
+
+ if(!rfin) {
+ goto almost_ok;
+ }
+ DEBUGF(fprintf(stderr, "inflatehd: index=%zd\n", inflater->left));
+ if(inflater->opcode == NGHTTP2_HD_OPCODE_INDEXED) {
+ inflater->index = inflater->left;
+ assert(inflater->index > 0);
+ --inflater->index;
+ rv = hd_inflate_commit_indexed(inflater, nv_out);
+ if(rv < 0) {
+ goto fail;
+ }
+ inflater->state = NGHTTP2_HD_STATE_OPCODE;
+ /* If rv == 1, no header was emitted */
+ if(rv == 0) {
+ *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
+ return in - first;
+ }
+ } else {
+ inflater->index = inflater->left;
+ assert(inflater->index > 0);
+ --inflater->index;
+ inflater->ent_name = nghttp2_hd_table_get(&inflater->ctx,
+ inflater->index);
+ inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN;
+ }
+ break;
+ }
+ case NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN:
+ hd_inflate_set_huffman_encoded(inflater, in);
+ inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN;
+ inflater->left = 0;
+ DEBUGF(fprintf(stderr, "inflatehd: huffman encoded=%d\n",
+ inflater->huffman_encoded != 0));
+ /* Fall through */
+ case NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN:
+ rfin = 0;
+ rv = hd_inflate_read_len(inflater, &rfin, in, last, 7,
+ NGHTTP2_HD_MAX_NAME);
+ if(rv < 0) {
+ goto fail;
+ }
+ in += rv;
+ if(!rfin) {
+ DEBUGF(fprintf(stderr,
+ "inflatehd: integer not fully decoded. current=%zd\n",
+ inflater->left));
+
+ goto almost_ok;
+ }
+
+ if(inflater->huffman_encoded) {
+ nghttp2_hd_huff_decode_context_init(&inflater->huff_decode_ctx);
+
+ inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF;
+ } else {
+ inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAME;
+ }
+ break;
+ case NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF:
+ rv = hd_inflate_read_huff(inflater, &inflater->namebufs, in, last);
+ if(rv < 0) {
+ goto fail;
+ }
+
+ in += rv;
+
+ DEBUGF(fprintf(stderr, "inflatehd: %zd bytes read\n", rv));
+
+ if(inflater->left) {
+ DEBUGF(fprintf(stderr,
+ "inflatehd: still %zd bytes to go\n", inflater->left));
+
+ goto almost_ok;
+ }
+
+ inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN;
+
+ break;
+ case NGHTTP2_HD_STATE_NEWNAME_READ_NAME:
+ rv = hd_inflate_read(inflater, &inflater->namebufs, in, last);
+ if(rv < 0) {
+ goto fail;
+ }
+
+ in += rv;
+
+ DEBUGF(fprintf(stderr, "inflatehd: %zd bytes read\n", rv));
+ if(inflater->left) {
+ DEBUGF(fprintf(stderr,
+ "inflatehd: still %zd bytes to go\n", inflater->left));
+
+ goto almost_ok;
+ }
+
+ inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN;
+
+ break;
+ case NGHTTP2_HD_STATE_CHECK_VALUELEN:
+ hd_inflate_set_huffman_encoded(inflater, in);
+ inflater->state = NGHTTP2_HD_STATE_READ_VALUELEN;
+ inflater->left = 0;
+ DEBUGF(fprintf(stderr, "inflatehd: huffman encoded=%d\n",
+ inflater->huffman_encoded != 0));
+ /* Fall through */
+ case NGHTTP2_HD_STATE_READ_VALUELEN:
+ rfin = 0;
+ rv = hd_inflate_read_len(inflater, &rfin, in, last, 7,
+ NGHTTP2_HD_MAX_VALUE);
+ if(rv < 0) {
+ goto fail;
+ }
+
+ in += rv;
+
+ if(!rfin) {
+ goto almost_ok;
+ }
+
+ DEBUGF(fprintf(stderr, "inflatehd: valuelen=%zd\n", inflater->left));
+ if(inflater->left == 0) {
+ if(inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) {
+ rv = hd_inflate_commit_newname(inflater, nv_out);
+ } else {
+ rv = hd_inflate_commit_indname(inflater, nv_out);
+ }
+ if(rv != 0) {
+ goto fail;
+ }
+ inflater->state = NGHTTP2_HD_STATE_OPCODE;
+ *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
+ return in - first;
+ }
+
+ if(inflater->huffman_encoded) {
+ nghttp2_hd_huff_decode_context_init(&inflater->huff_decode_ctx);
+
+ inflater->state = NGHTTP2_HD_STATE_READ_VALUEHUFF;
+ } else {
+ inflater->state = NGHTTP2_HD_STATE_READ_VALUE;
+ }
+ break;
+ case NGHTTP2_HD_STATE_READ_VALUEHUFF:
+ rv = hd_inflate_read_huff(inflater, &inflater->valuebufs, in, last);
+ if(rv < 0) {
+ goto fail;
+ }
+
+ in += rv;
+
+ DEBUGF(fprintf(stderr, "inflatehd: %zd bytes read\n", rv));
+
+ if(inflater->left) {
+ DEBUGF(fprintf(stderr,
+ "inflatehd: still %zd bytes to go\n", inflater->left));
+
+ goto almost_ok;
+ }
+
+ if(inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) {
+ rv = hd_inflate_commit_newname(inflater, nv_out);
+ } else {
+ rv = hd_inflate_commit_indname(inflater, nv_out);
+ }
+
+ if(rv != 0) {
+ goto fail;
+ }
+
+ inflater->state = NGHTTP2_HD_STATE_OPCODE;
+ *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
+
+ return in - first;
+ case NGHTTP2_HD_STATE_READ_VALUE:
+ rv = hd_inflate_read(inflater, &inflater->valuebufs, in, last);
+ if(rv < 0) {
+ DEBUGF(fprintf(stderr, "inflatehd: value read failure %zd: %s\n",
+ rv, nghttp2_strerror(rv)));
+ goto fail;
+ }
+
+ in += rv;
+
+ DEBUGF(fprintf(stderr, "inflatehd: %zd bytes read\n", rv));
+
+ if(inflater->left) {
+ DEBUGF(fprintf(stderr,
+ "inflatehd: still %zd bytes to go\n", inflater->left));
+ goto almost_ok;
+ }
+
+ if(inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) {
+ rv = hd_inflate_commit_newname(inflater, nv_out);
+ } else {
+ rv = hd_inflate_commit_indname(inflater, nv_out);
+ }
+
+ if(rv != 0) {
+ goto fail;
+ }
+
+ inflater->state = NGHTTP2_HD_STATE_OPCODE;
+ *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
+
+ return in - first;
+ }
+ }
+
+ assert(in == last);
+
+ DEBUGF(fprintf(stderr, "inflatehd: all input bytes were processed\n"));
+
+ if(in_final) {
+ DEBUGF(fprintf(stderr, "inflatehd: in_final set\n"));
+
+ if(inflater->state != NGHTTP2_HD_STATE_OPCODE) {
+ DEBUGF(fprintf(stderr, "inflatehd: unacceptable state=%d\n",
+ inflater->state));
+ rv = NGHTTP2_ERR_HEADER_COMP;
+
+ goto fail;
+ }
+ for(; inflater->end_headers_index < inflater->ctx.hd_table.len;
+ ++inflater->end_headers_index) {
+ nghttp2_hd_entry *ent;
+ ent = hd_ringbuf_get(&inflater->ctx.hd_table,
+ inflater->end_headers_index);
+
+ if((ent->flags & NGHTTP2_HD_FLAG_REFSET) &&
+ (ent->flags & NGHTTP2_HD_FLAG_EMIT) == 0) {
+ emit_indexed_header(nv_out, ent);
+ *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
+ return in - first;
+ }
+ ent->flags &= ~NGHTTP2_HD_FLAG_EMIT;
+ }
+ *inflate_flags |= NGHTTP2_HD_INFLATE_FINAL;
+ }
+ return in - first;
+
+ almost_ok:
+ if(in_final && inflater->state != NGHTTP2_HD_STATE_OPCODE) {
+ DEBUGF(fprintf(stderr, "inflatehd: input ended prematurely\n"));
+
+ rv = NGHTTP2_ERR_HEADER_COMP;
+
+ goto fail;
+ }
+ return in - first;
+
+ fail:
+ DEBUGF(fprintf(stderr, "inflatehd: error return %zd\n", rv));
+
+ inflater->ctx.bad = 1;
+ return rv;
+}
+
+int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater)
+{
+ hd_inflate_keep_free(inflater);
+ inflater->end_headers_index = 0;
+ return 0;
+}
+
+int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr)
+{
+ *inflater_ptr = (nghttp2_hd_inflater *)malloc(sizeof(nghttp2_hd_inflater));
+
+ if(*inflater_ptr == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ return nghttp2_hd_inflate_init(*inflater_ptr);
+}
+
+void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater)
+{
+ nghttp2_hd_inflate_free(inflater);
+
+ free(inflater);
+}
+
+int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
+ nghttp2_nv *nv, int inc_indexing)
+{
+
+ return emit_indname_block(bufs, index, nv, inc_indexing);
+}
+
+int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
+ int inc_indexing)
+{
+ return emit_newname_block(bufs, nv, inc_indexing);
+}
+
+int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size)
+{
+ return emit_table_size(bufs, table_size);
+}
diff --git a/wsutil/nghttp2/nghttp2_hd.h b/wsutil/nghttp2/nghttp2_hd.h
new file mode 100644
index 0000000000..c8eef8ffd4
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_hd.h
@@ -0,0 +1,353 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_HD_H
+#define NGHTTP2_HD_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <wsutil/nghttp2/nghttp2/nghttp2.h>
+
+#include "nghttp2_hd_huffman.h"
+#include "nghttp2_buf.h"
+
+#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
+#define NGHTTP2_HD_ENTRY_OVERHEAD 32
+
+/* The maximum value length of name/value pair. This is not specified
+ by the spec. We just chose the arbitrary size */
+#define NGHTTP2_HD_MAX_NAME 256
+#define NGHTTP2_HD_MAX_VALUE 8192
+
+/* Default size of maximum table buffer size for encoder. Even if
+ remote decoder notifies larger buffer size for its decoding,
+ encoder only uses the memory up to this value. */
+#define NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE (1 << 12)
+
+typedef enum {
+ NGHTTP2_HD_ROLE_DEFLATE,
+ NGHTTP2_HD_ROLE_INFLATE
+} nghttp2_hd_role;
+
+typedef enum {
+ NGHTTP2_HD_FLAG_NONE = 0,
+ /* Indicates name was dynamically allocated and must be freed */
+ NGHTTP2_HD_FLAG_NAME_ALLOC = 1,
+ /* Indicates value was dynamically allocated and must be freed */
+ NGHTTP2_HD_FLAG_VALUE_ALLOC = 1 << 1,
+ /* Indicates that the entry is in the reference set */
+ NGHTTP2_HD_FLAG_REFSET = 1 << 2,
+ /* Indicates that the entry is emitted in the current header
+ processing. */
+ NGHTTP2_HD_FLAG_EMIT = 1 << 3,
+ NGHTTP2_HD_FLAG_IMPLICIT_EMIT = 1 << 4,
+ /* Indicates that the name was gifted to the entry and no copying
+ necessary. */
+ NGHTTP2_HD_FLAG_NAME_GIFT = 1 << 5,
+ /* Indicates that the value was gifted to the entry and no copying
+ necessary. */
+ NGHTTP2_HD_FLAG_VALUE_GIFT = 1 << 6
+} nghttp2_hd_flags;
+
+typedef struct {
+ nghttp2_nv nv;
+ uint32_t name_hash;
+ uint32_t value_hash;
+ /* Reference count */
+ uint8_t ref;
+ uint8_t flags;
+} nghttp2_hd_entry;
+
+typedef struct {
+ nghttp2_hd_entry ent;
+ size_t index;
+} nghttp2_hd_static_entry;
+
+typedef struct {
+ nghttp2_hd_entry **buffer;
+ size_t mask;
+ size_t first;
+ size_t len;
+} nghttp2_hd_ringbuf;
+
+typedef enum {
+ NGHTTP2_HD_OPCODE_NONE,
+ NGHTTP2_HD_OPCODE_INDEXED,
+ NGHTTP2_HD_OPCODE_NEWNAME,
+ NGHTTP2_HD_OPCODE_INDNAME
+} nghttp2_hd_opcode;
+
+typedef enum {
+ NGHTTP2_HD_STATE_OPCODE,
+ NGHTTP2_HD_STATE_CLEAR_REFSET,
+ NGHTTP2_HD_STATE_READ_TABLE_SIZE,
+ NGHTTP2_HD_STATE_READ_INDEX,
+ NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN,
+ NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN,
+ NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF,
+ NGHTTP2_HD_STATE_NEWNAME_READ_NAME,
+ NGHTTP2_HD_STATE_CHECK_VALUELEN,
+ NGHTTP2_HD_STATE_READ_VALUELEN,
+ NGHTTP2_HD_STATE_READ_VALUEHUFF,
+ NGHTTP2_HD_STATE_READ_VALUE
+} nghttp2_hd_inflate_state;
+
+typedef struct {
+ /* dynamic header table */
+ nghttp2_hd_ringbuf hd_table;
+ /* Abstract buffer size of hd_table as described in the spec. This
+ is the sum of length of name/value in hd_table +
+ NGHTTP2_HD_ENTRY_OVERHEAD bytes overhead per each entry. */
+ size_t hd_table_bufsize;
+ /* The effective header table size. */
+ size_t hd_table_bufsize_max;
+ /* Role of this context; deflate or infalte */
+ nghttp2_hd_role role;
+ /* If inflate/deflate error occurred, this value is set to 1 and
+ further invocation of inflate/deflate will fail with
+ NGHTTP2_ERR_HEADER_COMP. */
+ uint8_t bad;
+} nghttp2_hd_context;
+
+struct nghttp2_hd_deflater {
+ nghttp2_hd_context ctx;
+ /* The upper limit of the header table size the deflater accepts. */
+ size_t deflate_hd_table_bufsize_max;
+ /* Set to this nonzero to clear reference set on each deflation each
+ time. */
+ uint8_t no_refset;
+ /* If nonzero, send header table size using encoding context update
+ in the next deflate process */
+ uint8_t notify_table_size_change;
+};
+
+struct nghttp2_hd_inflater {
+ nghttp2_hd_context ctx;
+ /* header name buffer */
+ nghttp2_bufs namebufs;
+ /* header value buffer */
+ nghttp2_bufs valuebufs;
+ /* Stores current state of huffman decoding */
+ nghttp2_hd_huff_decode_context huff_decode_ctx;
+ /* Pointer to the nghttp2_hd_entry which is used current header
+ emission. This is required because in some cases the
+ ent_keep->ref == 0 and we have to keep track of it. */
+ nghttp2_hd_entry *ent_keep;
+ /* Pointers to the name/value pair which are used current header
+ emission. They are usually used to keep track of malloc'ed memory
+ for huffman decoding. */
+ uint8_t *name_keep, *value_keep;
+ /* Pointers to the name/value pair which is referred as indexed
+ name. This entry must be in header table. */
+ nghttp2_hd_entry *ent_name;
+ /* The number of bytes to read */
+ ssize_t left;
+ /* The index in indexed repr or indexed name */
+ size_t index;
+ /* The index of header table to toggle off the entry from reference
+ set at the end of decompression. */
+ size_t end_headers_index;
+ /* The maximum header table size the inflater supports. This is the
+ same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
+ size_t settings_hd_table_bufsize_max;
+ nghttp2_hd_opcode opcode;
+ nghttp2_hd_inflate_state state;
+ /* nonzero if string is huffman encoded */
+ uint8_t huffman_encoded;
+ /* nonzero if deflater requires that current entry is indexed */
+ uint8_t index_required;
+ /* nonzero if deflater requires that current entry must not be
+ indexed */
+ uint8_t no_index;
+};
+
+/*
+ * Initializes the |ent| members. If NGHTTP2_HD_FLAG_NAME_ALLOC bit
+ * set in the |flags|, the content pointed by the |name| with length
+ * |namelen| is copied. Likewise, if NGHTTP2_HD_FLAG_VALUE_ALLOC bit
+ * set in the |flags|, the content pointed by the |value| with length
+ * |valuelen| is copied.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ */
+int nghttp2_hd_entry_init(nghttp2_hd_entry *ent, uint8_t flags,
+ uint8_t *name, size_t namelen,
+ uint8_t *value, size_t valuelen);
+
+void nghttp2_hd_entry_free(nghttp2_hd_entry *ent);
+
+/*
+ * Initializes |deflater| for deflating name/values pairs.
+ *
+ * The encoder only uses up to
+ * NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE bytes for header table
+ * even if the larger value is specified later in
+ * nghttp2_hd_change_table_size().
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ */
+int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater);
+
+/*
+ * Initializes |deflater| for deflating name/values pairs.
+ *
+ * The encoder only uses up to |deflate_hd_table_bufsize_max| bytes
+ * for header table even if the larger value is specified later in
+ * nghttp2_hd_change_table_size().
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ */
+int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
+ size_t deflate_hd_table_bufsize_max);
+
+/*
+ * Deallocates any resources allocated for |deflater|.
+ */
+void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater);
+
+/*
+ * Deflates the |nva|, which has the |nvlen| name/value pairs, into
+ * the |bufs|.
+ *
+ * This function expands |bufs| as necessary to store the result. If
+ * buffers is full and the process still requires more space, this
+ * funtion fails and returns NGHTTP2_ERR_HEADER_COMP.
+ *
+ * After this function returns, it is safe to delete the |nva|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ * NGHTTP2_ERR_HEADER_COMP
+ * Deflation process has failed.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ * Out of buffer space.
+ */
+int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
+ nghttp2_bufs *bufs,
+ nghttp2_nv *nva, size_t nvlen);
+
+/*
+ * Initializes |inflater| for inflating name/values pairs.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ */
+int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater);
+
+/*
+ * Deallocates any resources allocated for |inflater|.
+ */
+void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
+
+/* For unittesting purpose */
+int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
+ nghttp2_nv *nv, int inc_indexing);
+
+/* For unittesting purpose */
+int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
+ int inc_indexing);
+
+/* For unittesting purpose */
+int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
+
+/* For unittesting purpose */
+nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context,
+ size_t index);
+
+/* Huffman encoding/decoding functions */
+
+/*
+ * Counts the required bytes to encode |src| with length |len|.
+ *
+ * This function returns the number of required bytes to encode given
+ * data, including padding of prefix of terminal symbol code. This
+ * function always succeeds.
+ */
+size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len);
+
+/*
+ * Encodes the given data |src| with length |srclen| to the |bufs|.
+ * This function expands extra buffers in |bufs| if necessary.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ * Out of buffer space.
+ */
+int nghttp2_hd_huff_encode(nghttp2_bufs *bufs,
+ const uint8_t *src, size_t srclen);
+
+void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
+
+/*
+ * Decodes the given data |src| with length |srclen|. The |ctx| must
+ * be initialized by nghttp2_hd_huff_decode_context_init(). The result
+ * will be added to |dest|. This function may expand |dest| as
+ * needed. The caller is responsible to release the memory of |dest|
+ * by calling nghttp2_bufs_free() or export its content using
+ * nghttp2_bufs_remove().
+ *
+ * The caller must set the |final| to nonzero if the given input is
+ * the final block.
+ *
+ * This function returns the number of read bytes from the |in|.
+ *
+ * If this function fails, it returns one of the following negative
+ * return codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ * Maximum buffer capacity size exceeded.
+ * NGHTTP2_ERR_HEADER_COMP
+ * Decoding process has failed.
+ */
+ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
+ nghttp2_bufs *bufs,
+ const uint8_t *src, size_t srclen, int final);
+
+#endif /* NGHTTP2_HD_H */
diff --git a/wsutil/nghttp2/nghttp2_hd_huffman.c b/wsutil/nghttp2/nghttp2_hd_huffman.c
new file mode 100644
index 0000000000..4fe3a07d42
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_hd_huffman.c
@@ -0,0 +1,205 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_hd_huffman.h"
+
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "nghttp2_hd.h"
+
+extern const nghttp2_huff_sym huff_sym_table[];
+extern const nghttp2_huff_decode huff_decode_table[][16];
+
+/*
+ * 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;
+
+ for(;;) {
+ if(rembits > nbits) {
+ if(*avail_ptr) {
+ nghttp2_bufs_fast_orb_hold(bufs, sym->code << (rembits - nbits));
+ } else {
+ rv = nghttp2_bufs_orb_hold(bufs, sym->code << (rembits - nbits));
+ if(rv != 0) {
+ return rv;
+ }
+
+ *avail_ptr = nghttp2_bufs_cur_avail(bufs);
+ }
+
+ rembits -= nbits;
+
+ break;
+ }
+
+ if(*avail_ptr) {
+ nghttp2_bufs_fast_orb(bufs, sym->code >> (nbits - rembits));
+ --*avail_ptr;
+ } else {
+ rv = nghttp2_bufs_orb(bufs, sym->code >> (nbits - rembits));
+ if(rv != 0) {
+ return rv;
+ }
+
+ *avail_ptr = nghttp2_bufs_cur_avail(bufs);
+ }
+
+ nbits -= rembits;
+ rembits = 8;
+
+ if(nbits == 0) {
+ break;
+ }
+
+ if(*avail_ptr) {
+ nghttp2_bufs_fast_addb_hold(bufs, 0);
+ } else {
+ rv = nghttp2_bufs_addb_hold(bufs, 0);
+ if(rv != 0) {
+ return rv;
+ }
+
+ *avail_ptr = nghttp2_bufs_cur_avail(bufs);
+ }
+ }
+ return rembits;
+}
+
+size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len)
+{
+ size_t i;
+ size_t nbits = 0;
+
+ for(i = 0; i < len; ++i) {
+ nbits += huff_sym_table[src[i]].nbits;
+ }
+ /* pad the prefix of EOS (256) */
+ return (nbits + 7) / 8;
+}
+
+int nghttp2_hd_huff_encode(nghttp2_bufs *bufs,
+ const uint8_t *src, size_t srclen)
+{
+ int rv;
+ int rembits = 8;
+ size_t i;
+ size_t avail;
+
+ 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);
+ }
+ }
+ rembits = huff_encode_sym(bufs, &avail, rembits, sym);
+ if(rembits < 0) {
+ return rembits;
+ }
+ }
+ /* 256 is special terminal symbol, pad with its prefix */
+ if(rembits < 8) {
+ const nghttp2_huff_sym *sym = &huff_sym_table[256];
+
+ /* Caution we no longer adjust avail here */
+ if(avail) {
+ nghttp2_bufs_fast_orb(bufs, sym->code >> (sym->nbits - rembits));
+ } else {
+ rv = nghttp2_bufs_orb(bufs, sym->code >> (sym->nbits - rembits));
+ 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;
+}
+
+ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
+ nghttp2_bufs *bufs,
+ const uint8_t *src, size_t srclen, int final)
+{
+ size_t i, j;
+ int rv;
+ size_t avail;
+
+ avail = nghttp2_bufs_cur_avail(bufs);
+
+ /* We use the decoding algorithm described in
+ http://graphics.ics.uci.edu/pub/Prefix.pdf */
+ for(i = 0; i < srclen; ++i) {
+ uint8_t in = src[i] >> 4;
+ for(j = 0; j < 2; ++j) {
+ const nghttp2_huff_decode *t = &huff_decode_table[ctx->state][in];
+ if(t->state == -1) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+ if(t->flags & NGHTTP2_HUFF_SYM) {
+ if(avail) {
+ nghttp2_bufs_fast_addb(bufs, t->sym);
+ --avail;
+ } else {
+ rv = nghttp2_bufs_addb(bufs, t->sym);
+ if(rv != 0) {
+ return rv;
+ }
+ avail = nghttp2_bufs_cur_avail(bufs);
+ }
+ }
+ ctx->state = t->state;
+ ctx->accept = (t->flags & NGHTTP2_HUFF_ACCEPTED) != 0;
+ in = src[i] & 0xf;
+ }
+ }
+ if(final && !ctx->accept) {
+ return NGHTTP2_ERR_HEADER_COMP;
+ }
+ return i;
+}
diff --git a/wsutil/nghttp2/nghttp2_hd_huffman.h b/wsutil/nghttp2/nghttp2_hd_huffman.h
new file mode 100644
index 0000000000..b870bddfc0
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_hd_huffman.h
@@ -0,0 +1,70 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_HD_HUFFMAN_H
+#define NGHTTP2_HD_HUFFMAN_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <wsutil/nghttp2/nghttp2/nghttp2.h>
+
+typedef enum {
+ /* FSA accepts this state as the end of huffman encoding
+ sequence. */
+ NGHTTP2_HUFF_ACCEPTED = 1,
+ /* This state emits symbol */
+ NGHTTP2_HUFF_SYM = (1 << 1)
+} nghttp2_huff_decode_flag;
+
+typedef struct {
+ /* huffman decoding state, which is actually the node ID of internal
+ huffman tree */
+ int16_t state;
+ /* bitwise OR of zero or more of the nghttp2_huff_decode_flag */
+ uint8_t flags;
+ /* symbol if NGHTTP2_HUFF_SYM flag set */
+ uint8_t sym;
+} nghttp2_huff_decode;
+
+typedef nghttp2_huff_decode huff_decode_table_type[16];
+
+typedef struct {
+ /* Current huffman decoding state. We stripped leaf nodes, so the
+ value range is [0..255], inclusive. */
+ int16_t state;
+ /* nonzero if we can say that the decoding process succeeds at this
+ state */
+ uint8_t accept;
+} nghttp2_hd_huff_decode_context;
+
+typedef struct {
+ /* The number of bits in this code */
+ uint32_t nbits;
+ /* Huffman code aligned to LSB */
+ uint32_t code;
+} nghttp2_huff_sym;
+
+#endif /* NGHTTP2_HD_HUFFMAN_H */
diff --git a/wsutil/nghttp2/nghttp2_hd_huffman_data.c b/wsutil/nghttp2/nghttp2_hd_huffman_data.c
new file mode 100644
index 0000000000..d9d534f1b9
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_hd_huffman_data.c
@@ -0,0 +1,5152 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_hd_huffman.h"
+
+const nghttp2_huff_sym huff_sym_table[] = {
+ { 26, 0x3ffffbau },
+ { 26, 0x3ffffbbu },
+ { 26, 0x3ffffbcu },
+ { 26, 0x3ffffbdu },
+ { 26, 0x3ffffbeu },
+ { 26, 0x3ffffbfu },
+ { 26, 0x3ffffc0u },
+ { 26, 0x3ffffc1u },
+ { 26, 0x3ffffc2u },
+ { 26, 0x3ffffc3u },
+ { 26, 0x3ffffc4u },
+ { 26, 0x3ffffc5u },
+ { 26, 0x3ffffc6u },
+ { 26, 0x3ffffc7u },
+ { 26, 0x3ffffc8u },
+ { 26, 0x3ffffc9u },
+ { 26, 0x3ffffcau },
+ { 26, 0x3ffffcbu },
+ { 26, 0x3ffffccu },
+ { 26, 0x3ffffcdu },
+ { 26, 0x3ffffceu },
+ { 26, 0x3ffffcfu },
+ { 26, 0x3ffffd0u },
+ { 26, 0x3ffffd1u },
+ { 26, 0x3ffffd2u },
+ { 26, 0x3ffffd3u },
+ { 26, 0x3ffffd4u },
+ { 26, 0x3ffffd5u },
+ { 26, 0x3ffffd6u },
+ { 26, 0x3ffffd7u },
+ { 26, 0x3ffffd8u },
+ { 26, 0x3ffffd9u },
+ { 5, 0x6u },
+ { 13, 0x1ffcu },
+ { 9, 0x1f0u },
+ { 14, 0x3ffcu },
+ { 15, 0x7ffcu },
+ { 6, 0x1eu },
+ { 7, 0x64u },
+ { 13, 0x1ffdu },
+ { 10, 0x3fau },
+ { 9, 0x1f1u },
+ { 10, 0x3fbu },
+ { 10, 0x3fcu },
+ { 7, 0x65u },
+ { 7, 0x66u },
+ { 6, 0x1fu },
+ { 5, 0x7u },
+ { 4, 0x0u },
+ { 4, 0x1u },
+ { 4, 0x2u },
+ { 5, 0x8u },
+ { 6, 0x20u },
+ { 6, 0x21u },
+ { 6, 0x22u },
+ { 6, 0x23u },
+ { 6, 0x24u },
+ { 6, 0x25u },
+ { 6, 0x26u },
+ { 8, 0xecu },
+ { 17, 0x1fffcu },
+ { 6, 0x27u },
+ { 15, 0x7ffdu },
+ { 10, 0x3fdu },
+ { 15, 0x7ffeu },
+ { 7, 0x67u },
+ { 8, 0xedu },
+ { 8, 0xeeu },
+ { 7, 0x68u },
+ { 8, 0xefu },
+ { 7, 0x69u },
+ { 7, 0x6au },
+ { 9, 0x1f2u },
+ { 8, 0xf0u },
+ { 9, 0x1f3u },
+ { 9, 0x1f4u },
+ { 9, 0x1f5u },
+ { 7, 0x6bu },
+ { 7, 0x6cu },
+ { 8, 0xf1u },
+ { 8, 0xf2u },
+ { 9, 0x1f6u },
+ { 9, 0x1f7u },
+ { 7, 0x6du },
+ { 6, 0x28u },
+ { 8, 0xf3u },
+ { 9, 0x1f8u },
+ { 9, 0x1f9u },
+ { 8, 0xf4u },
+ { 9, 0x1fau },
+ { 9, 0x1fbu },
+ { 11, 0x7fcu },
+ { 26, 0x3ffffdau },
+ { 11, 0x7fdu },
+ { 14, 0x3ffdu },
+ { 7, 0x6eu },
+ { 18, 0x3fffeu },
+ { 5, 0x9u },
+ { 7, 0x6fu },
+ { 5, 0xau },
+ { 6, 0x29u },
+ { 5, 0xbu },
+ { 7, 0x70u },
+ { 6, 0x2au },
+ { 6, 0x2bu },
+ { 5, 0xcu },
+ { 8, 0xf5u },
+ { 8, 0xf6u },
+ { 6, 0x2cu },
+ { 6, 0x2du },
+ { 6, 0x2eu },
+ { 5, 0xdu },
+ { 6, 0x2fu },
+ { 9, 0x1fcu },
+ { 6, 0x30u },
+ { 6, 0x31u },
+ { 5, 0xeu },
+ { 7, 0x71u },
+ { 7, 0x72u },
+ { 7, 0x73u },
+ { 7, 0x74u },
+ { 7, 0x75u },
+ { 8, 0xf7u },
+ { 17, 0x1fffdu },
+ { 12, 0xffcu },
+ { 17, 0x1fffeu },
+ { 12, 0xffdu },
+ { 26, 0x3ffffdbu },
+ { 26, 0x3ffffdcu },
+ { 26, 0x3ffffddu },
+ { 26, 0x3ffffdeu },
+ { 26, 0x3ffffdfu },
+ { 26, 0x3ffffe0u },
+ { 26, 0x3ffffe1u },
+ { 26, 0x3ffffe2u },
+ { 26, 0x3ffffe3u },
+ { 26, 0x3ffffe4u },
+ { 26, 0x3ffffe5u },
+ { 26, 0x3ffffe6u },
+ { 26, 0x3ffffe7u },
+ { 26, 0x3ffffe8u },
+ { 26, 0x3ffffe9u },
+ { 26, 0x3ffffeau },
+ { 26, 0x3ffffebu },
+ { 26, 0x3ffffecu },
+ { 26, 0x3ffffedu },
+ { 26, 0x3ffffeeu },
+ { 26, 0x3ffffefu },
+ { 26, 0x3fffff0u },
+ { 26, 0x3fffff1u },
+ { 26, 0x3fffff2u },
+ { 26, 0x3fffff3u },
+ { 26, 0x3fffff4u },
+ { 26, 0x3fffff5u },
+ { 26, 0x3fffff6u },
+ { 26, 0x3fffff7u },
+ { 26, 0x3fffff8u },
+ { 26, 0x3fffff9u },
+ { 26, 0x3fffffau },
+ { 26, 0x3fffffbu },
+ { 26, 0x3fffffcu },
+ { 26, 0x3fffffdu },
+ { 26, 0x3fffffeu },
+ { 26, 0x3ffffffu },
+ { 25, 0x1ffff80u },
+ { 25, 0x1ffff81u },
+ { 25, 0x1ffff82u },
+ { 25, 0x1ffff83u },
+ { 25, 0x1ffff84u },
+ { 25, 0x1ffff85u },
+ { 25, 0x1ffff86u },
+ { 25, 0x1ffff87u },
+ { 25, 0x1ffff88u },
+ { 25, 0x1ffff89u },
+ { 25, 0x1ffff8au },
+ { 25, 0x1ffff8bu },
+ { 25, 0x1ffff8cu },
+ { 25, 0x1ffff8du },
+ { 25, 0x1ffff8eu },
+ { 25, 0x1ffff8fu },
+ { 25, 0x1ffff90u },
+ { 25, 0x1ffff91u },
+ { 25, 0x1ffff92u },
+ { 25, 0x1ffff93u },
+ { 25, 0x1ffff94u },
+ { 25, 0x1ffff95u },
+ { 25, 0x1ffff96u },
+ { 25, 0x1ffff97u },
+ { 25, 0x1ffff98u },
+ { 25, 0x1ffff99u },
+ { 25, 0x1ffff9au },
+ { 25, 0x1ffff9bu },
+ { 25, 0x1ffff9cu },
+ { 25, 0x1ffff9du },
+ { 25, 0x1ffff9eu },
+ { 25, 0x1ffff9fu },
+ { 25, 0x1ffffa0u },
+ { 25, 0x1ffffa1u },
+ { 25, 0x1ffffa2u },
+ { 25, 0x1ffffa3u },
+ { 25, 0x1ffffa4u },
+ { 25, 0x1ffffa5u },
+ { 25, 0x1ffffa6u },
+ { 25, 0x1ffffa7u },
+ { 25, 0x1ffffa8u },
+ { 25, 0x1ffffa9u },
+ { 25, 0x1ffffaau },
+ { 25, 0x1ffffabu },
+ { 25, 0x1ffffacu },
+ { 25, 0x1ffffadu },
+ { 25, 0x1ffffaeu },
+ { 25, 0x1ffffafu },
+ { 25, 0x1ffffb0u },
+ { 25, 0x1ffffb1u },
+ { 25, 0x1ffffb2u },
+ { 25, 0x1ffffb3u },
+ { 25, 0x1ffffb4u },
+ { 25, 0x1ffffb5u },
+ { 25, 0x1ffffb6u },
+ { 25, 0x1ffffb7u },
+ { 25, 0x1ffffb8u },
+ { 25, 0x1ffffb9u },
+ { 25, 0x1ffffbau },
+ { 25, 0x1ffffbbu },
+ { 25, 0x1ffffbcu },
+ { 25, 0x1ffffbdu },
+ { 25, 0x1ffffbeu },
+ { 25, 0x1ffffbfu },
+ { 25, 0x1ffffc0u },
+ { 25, 0x1ffffc1u },
+ { 25, 0x1ffffc2u },
+ { 25, 0x1ffffc3u },
+ { 25, 0x1ffffc4u },
+ { 25, 0x1ffffc5u },
+ { 25, 0x1ffffc6u },
+ { 25, 0x1ffffc7u },
+ { 25, 0x1ffffc8u },
+ { 25, 0x1ffffc9u },
+ { 25, 0x1ffffcau },
+ { 25, 0x1ffffcbu },
+ { 25, 0x1ffffccu },
+ { 25, 0x1ffffcdu },
+ { 25, 0x1ffffceu },
+ { 25, 0x1ffffcfu },
+ { 25, 0x1ffffd0u },
+ { 25, 0x1ffffd1u },
+ { 25, 0x1ffffd2u },
+ { 25, 0x1ffffd3u },
+ { 25, 0x1ffffd4u },
+ { 25, 0x1ffffd5u },
+ { 25, 0x1ffffd6u },
+ { 25, 0x1ffffd7u },
+ { 25, 0x1ffffd8u },
+ { 25, 0x1ffffd9u },
+ { 25, 0x1ffffdau },
+ { 25, 0x1ffffdbu },
+ { 25, 0x1ffffdcu }
+};
+
+const nghttp2_huff_decode huff_decode_table[][16] = {
+ /* 0 */
+ {
+ {0, 0x03, 48},
+ {0, 0x03, 49},
+ {0, 0x03, 50},
+ {5, 0x00, 0},
+ {8, 0x00, 0},
+ {9, 0x00, 0},
+ {11, 0x00, 0},
+ {12, 0x00, 0},
+ {17, 0x00, 0},
+ {20, 0x00, 0},
+ {24, 0x00, 0},
+ {27, 0x00, 0},
+ {32, 0x00, 0},
+ {37, 0x00, 0},
+ {45, 0x00, 0},
+ {54, 0x01, 0},
+ },
+ /* 1 */
+ {
+ {1, 0x02, 48},
+ {14, 0x03, 48},
+ {1, 0x02, 49},
+ {14, 0x03, 49},
+ {1, 0x02, 50},
+ {14, 0x03, 50},
+ {0, 0x03, 32},
+ {0, 0x03, 47},
+ {0, 0x03, 51},
+ {0, 0x03, 97},
+ {0, 0x03, 99},
+ {0, 0x03, 101},
+ {0, 0x03, 105},
+ {0, 0x03, 111},
+ {0, 0x03, 116},
+ {13, 0x00, 0},
+ },
+ /* 2 */
+ {
+ {2, 0x02, 48},
+ {6, 0x02, 48},
+ {15, 0x02, 48},
+ {30, 0x03, 48},
+ {2, 0x02, 49},
+ {6, 0x02, 49},
+ {15, 0x02, 49},
+ {30, 0x03, 49},
+ {2, 0x02, 50},
+ {6, 0x02, 50},
+ {15, 0x02, 50},
+ {30, 0x03, 50},
+ {1, 0x02, 32},
+ {14, 0x03, 32},
+ {1, 0x02, 47},
+ {14, 0x03, 47},
+ },
+ /* 3 */
+ {
+ {3, 0x02, 48},
+ {4, 0x02, 48},
+ {7, 0x02, 48},
+ {10, 0x02, 48},
+ {16, 0x02, 48},
+ {23, 0x02, 48},
+ {31, 0x02, 48},
+ {44, 0x03, 48},
+ {3, 0x02, 49},
+ {4, 0x02, 49},
+ {7, 0x02, 49},
+ {10, 0x02, 49},
+ {16, 0x02, 49},
+ {23, 0x02, 49},
+ {31, 0x02, 49},
+ {44, 0x03, 49},
+ },
+ /* 4 */
+ {
+ {3, 0x02, 50},
+ {4, 0x02, 50},
+ {7, 0x02, 50},
+ {10, 0x02, 50},
+ {16, 0x02, 50},
+ {23, 0x02, 50},
+ {31, 0x02, 50},
+ {44, 0x03, 50},
+ {2, 0x02, 32},
+ {6, 0x02, 32},
+ {15, 0x02, 32},
+ {30, 0x03, 32},
+ {2, 0x02, 47},
+ {6, 0x02, 47},
+ {15, 0x02, 47},
+ {30, 0x03, 47},
+ },
+ /* 5 */
+ {
+ {3, 0x02, 32},
+ {4, 0x02, 32},
+ {7, 0x02, 32},
+ {10, 0x02, 32},
+ {16, 0x02, 32},
+ {23, 0x02, 32},
+ {31, 0x02, 32},
+ {44, 0x03, 32},
+ {3, 0x02, 47},
+ {4, 0x02, 47},
+ {7, 0x02, 47},
+ {10, 0x02, 47},
+ {16, 0x02, 47},
+ {23, 0x02, 47},
+ {31, 0x02, 47},
+ {44, 0x03, 47},
+ },
+ /* 6 */
+ {
+ {1, 0x02, 51},
+ {14, 0x03, 51},
+ {1, 0x02, 97},
+ {14, 0x03, 97},
+ {1, 0x02, 99},
+ {14, 0x03, 99},
+ {1, 0x02, 101},
+ {14, 0x03, 101},
+ {1, 0x02, 105},
+ {14, 0x03, 105},
+ {1, 0x02, 111},
+ {14, 0x03, 111},
+ {1, 0x02, 116},
+ {14, 0x03, 116},
+ {0, 0x03, 37},
+ {0, 0x03, 46},
+ },
+ /* 7 */
+ {
+ {2, 0x02, 51},
+ {6, 0x02, 51},
+ {15, 0x02, 51},
+ {30, 0x03, 51},
+ {2, 0x02, 97},
+ {6, 0x02, 97},
+ {15, 0x02, 97},
+ {30, 0x03, 97},
+ {2, 0x02, 99},
+ {6, 0x02, 99},
+ {15, 0x02, 99},
+ {30, 0x03, 99},
+ {2, 0x02, 101},
+ {6, 0x02, 101},
+ {15, 0x02, 101},
+ {30, 0x03, 101},
+ },
+ /* 8 */
+ {
+ {3, 0x02, 51},
+ {4, 0x02, 51},
+ {7, 0x02, 51},
+ {10, 0x02, 51},
+ {16, 0x02, 51},
+ {23, 0x02, 51},
+ {31, 0x02, 51},
+ {44, 0x03, 51},
+ {3, 0x02, 97},
+ {4, 0x02, 97},
+ {7, 0x02, 97},
+ {10, 0x02, 97},
+ {16, 0x02, 97},
+ {23, 0x02, 97},
+ {31, 0x02, 97},
+ {44, 0x03, 97},
+ },
+ /* 9 */
+ {
+ {3, 0x02, 99},
+ {4, 0x02, 99},
+ {7, 0x02, 99},
+ {10, 0x02, 99},
+ {16, 0x02, 99},
+ {23, 0x02, 99},
+ {31, 0x02, 99},
+ {44, 0x03, 99},
+ {3, 0x02, 101},
+ {4, 0x02, 101},
+ {7, 0x02, 101},
+ {10, 0x02, 101},
+ {16, 0x02, 101},
+ {23, 0x02, 101},
+ {31, 0x02, 101},
+ {44, 0x03, 101},
+ },
+ /* 10 */
+ {
+ {2, 0x02, 105},
+ {6, 0x02, 105},
+ {15, 0x02, 105},
+ {30, 0x03, 105},
+ {2, 0x02, 111},
+ {6, 0x02, 111},
+ {15, 0x02, 111},
+ {30, 0x03, 111},
+ {2, 0x02, 116},
+ {6, 0x02, 116},
+ {15, 0x02, 116},
+ {30, 0x03, 116},
+ {1, 0x02, 37},
+ {14, 0x03, 37},
+ {1, 0x02, 46},
+ {14, 0x03, 46},
+ },
+ /* 11 */
+ {
+ {3, 0x02, 105},
+ {4, 0x02, 105},
+ {7, 0x02, 105},
+ {10, 0x02, 105},
+ {16, 0x02, 105},
+ {23, 0x02, 105},
+ {31, 0x02, 105},
+ {44, 0x03, 105},
+ {3, 0x02, 111},
+ {4, 0x02, 111},
+ {7, 0x02, 111},
+ {10, 0x02, 111},
+ {16, 0x02, 111},
+ {23, 0x02, 111},
+ {31, 0x02, 111},
+ {44, 0x03, 111},
+ },
+ /* 12 */
+ {
+ {3, 0x02, 116},
+ {4, 0x02, 116},
+ {7, 0x02, 116},
+ {10, 0x02, 116},
+ {16, 0x02, 116},
+ {23, 0x02, 116},
+ {31, 0x02, 116},
+ {44, 0x03, 116},
+ {2, 0x02, 37},
+ {6, 0x02, 37},
+ {15, 0x02, 37},
+ {30, 0x03, 37},
+ {2, 0x02, 46},
+ {6, 0x02, 46},
+ {15, 0x02, 46},
+ {30, 0x03, 46},
+ },
+ /* 13 */
+ {
+ {3, 0x02, 37},
+ {4, 0x02, 37},
+ {7, 0x02, 37},
+ {10, 0x02, 37},
+ {16, 0x02, 37},
+ {23, 0x02, 37},
+ {31, 0x02, 37},
+ {44, 0x03, 37},
+ {3, 0x02, 46},
+ {4, 0x02, 46},
+ {7, 0x02, 46},
+ {10, 0x02, 46},
+ {16, 0x02, 46},
+ {23, 0x02, 46},
+ {31, 0x02, 46},
+ {44, 0x03, 46},
+ },
+ /* 14 */
+ {
+ {18, 0x00, 0},
+ {19, 0x00, 0},
+ {21, 0x00, 0},
+ {22, 0x00, 0},
+ {25, 0x00, 0},
+ {26, 0x00, 0},
+ {28, 0x00, 0},
+ {29, 0x00, 0},
+ {33, 0x00, 0},
+ {34, 0x00, 0},
+ {38, 0x00, 0},
+ {41, 0x00, 0},
+ {46, 0x00, 0},
+ {49, 0x00, 0},
+ {55, 0x00, 0},
+ {62, 0x01, 0},
+ },
+ /* 15 */
+ {
+ {0, 0x03, 52},
+ {0, 0x03, 53},
+ {0, 0x03, 54},
+ {0, 0x03, 55},
+ {0, 0x03, 56},
+ {0, 0x03, 57},
+ {0, 0x03, 58},
+ {0, 0x03, 61},
+ {0, 0x03, 84},
+ {0, 0x03, 100},
+ {0, 0x03, 103},
+ {0, 0x03, 104},
+ {0, 0x03, 108},
+ {0, 0x03, 109},
+ {0, 0x03, 110},
+ {0, 0x03, 112},
+ },
+ /* 16 */
+ {
+ {1, 0x02, 52},
+ {14, 0x03, 52},
+ {1, 0x02, 53},
+ {14, 0x03, 53},
+ {1, 0x02, 54},
+ {14, 0x03, 54},
+ {1, 0x02, 55},
+ {14, 0x03, 55},
+ {1, 0x02, 56},
+ {14, 0x03, 56},
+ {1, 0x02, 57},
+ {14, 0x03, 57},
+ {1, 0x02, 58},
+ {14, 0x03, 58},
+ {1, 0x02, 61},
+ {14, 0x03, 61},
+ },
+ /* 17 */
+ {
+ {2, 0x02, 52},
+ {6, 0x02, 52},
+ {15, 0x02, 52},
+ {30, 0x03, 52},
+ {2, 0x02, 53},
+ {6, 0x02, 53},
+ {15, 0x02, 53},
+ {30, 0x03, 53},
+ {2, 0x02, 54},
+ {6, 0x02, 54},
+ {15, 0x02, 54},
+ {30, 0x03, 54},
+ {2, 0x02, 55},
+ {6, 0x02, 55},
+ {15, 0x02, 55},
+ {30, 0x03, 55},
+ },
+ /* 18 */
+ {
+ {3, 0x02, 52},
+ {4, 0x02, 52},
+ {7, 0x02, 52},
+ {10, 0x02, 52},
+ {16, 0x02, 52},
+ {23, 0x02, 52},
+ {31, 0x02, 52},
+ {44, 0x03, 52},
+ {3, 0x02, 53},
+ {4, 0x02, 53},
+ {7, 0x02, 53},
+ {10, 0x02, 53},
+ {16, 0x02, 53},
+ {23, 0x02, 53},
+ {31, 0x02, 53},
+ {44, 0x03, 53},
+ },
+ /* 19 */
+ {
+ {3, 0x02, 54},
+ {4, 0x02, 54},
+ {7, 0x02, 54},
+ {10, 0x02, 54},
+ {16, 0x02, 54},
+ {23, 0x02, 54},
+ {31, 0x02, 54},
+ {44, 0x03, 54},
+ {3, 0x02, 55},
+ {4, 0x02, 55},
+ {7, 0x02, 55},
+ {10, 0x02, 55},
+ {16, 0x02, 55},
+ {23, 0x02, 55},
+ {31, 0x02, 55},
+ {44, 0x03, 55},
+ },
+ /* 20 */
+ {
+ {2, 0x02, 56},
+ {6, 0x02, 56},
+ {15, 0x02, 56},
+ {30, 0x03, 56},
+ {2, 0x02, 57},
+ {6, 0x02, 57},
+ {15, 0x02, 57},
+ {30, 0x03, 57},
+ {2, 0x02, 58},
+ {6, 0x02, 58},
+ {15, 0x02, 58},
+ {30, 0x03, 58},
+ {2, 0x02, 61},
+ {6, 0x02, 61},
+ {15, 0x02, 61},
+ {30, 0x03, 61},
+ },
+ /* 21 */
+ {
+ {3, 0x02, 56},
+ {4, 0x02, 56},
+ {7, 0x02, 56},
+ {10, 0x02, 56},
+ {16, 0x02, 56},
+ {23, 0x02, 56},
+ {31, 0x02, 56},
+ {44, 0x03, 56},
+ {3, 0x02, 57},
+ {4, 0x02, 57},
+ {7, 0x02, 57},
+ {10, 0x02, 57},
+ {16, 0x02, 57},
+ {23, 0x02, 57},
+ {31, 0x02, 57},
+ {44, 0x03, 57},
+ },
+ /* 22 */
+ {
+ {3, 0x02, 58},
+ {4, 0x02, 58},
+ {7, 0x02, 58},
+ {10, 0x02, 58},
+ {16, 0x02, 58},
+ {23, 0x02, 58},
+ {31, 0x02, 58},
+ {44, 0x03, 58},
+ {3, 0x02, 61},
+ {4, 0x02, 61},
+ {7, 0x02, 61},
+ {10, 0x02, 61},
+ {16, 0x02, 61},
+ {23, 0x02, 61},
+ {31, 0x02, 61},
+ {44, 0x03, 61},
+ },
+ /* 23 */
+ {
+ {1, 0x02, 84},
+ {14, 0x03, 84},
+ {1, 0x02, 100},
+ {14, 0x03, 100},
+ {1, 0x02, 103},
+ {14, 0x03, 103},
+ {1, 0x02, 104},
+ {14, 0x03, 104},
+ {1, 0x02, 108},
+ {14, 0x03, 108},
+ {1, 0x02, 109},
+ {14, 0x03, 109},
+ {1, 0x02, 110},
+ {14, 0x03, 110},
+ {1, 0x02, 112},
+ {14, 0x03, 112},
+ },
+ /* 24 */
+ {
+ {2, 0x02, 84},
+ {6, 0x02, 84},
+ {15, 0x02, 84},
+ {30, 0x03, 84},
+ {2, 0x02, 100},
+ {6, 0x02, 100},
+ {15, 0x02, 100},
+ {30, 0x03, 100},
+ {2, 0x02, 103},
+ {6, 0x02, 103},
+ {15, 0x02, 103},
+ {30, 0x03, 103},
+ {2, 0x02, 104},
+ {6, 0x02, 104},
+ {15, 0x02, 104},
+ {30, 0x03, 104},
+ },
+ /* 25 */
+ {
+ {3, 0x02, 84},
+ {4, 0x02, 84},
+ {7, 0x02, 84},
+ {10, 0x02, 84},
+ {16, 0x02, 84},
+ {23, 0x02, 84},
+ {31, 0x02, 84},
+ {44, 0x03, 84},
+ {3, 0x02, 100},
+ {4, 0x02, 100},
+ {7, 0x02, 100},
+ {10, 0x02, 100},
+ {16, 0x02, 100},
+ {23, 0x02, 100},
+ {31, 0x02, 100},
+ {44, 0x03, 100},
+ },
+ /* 26 */
+ {
+ {3, 0x02, 103},
+ {4, 0x02, 103},
+ {7, 0x02, 103},
+ {10, 0x02, 103},
+ {16, 0x02, 103},
+ {23, 0x02, 103},
+ {31, 0x02, 103},
+ {44, 0x03, 103},
+ {3, 0x02, 104},
+ {4, 0x02, 104},
+ {7, 0x02, 104},
+ {10, 0x02, 104},
+ {16, 0x02, 104},
+ {23, 0x02, 104},
+ {31, 0x02, 104},
+ {44, 0x03, 104},
+ },
+ /* 27 */
+ {
+ {2, 0x02, 108},
+ {6, 0x02, 108},
+ {15, 0x02, 108},
+ {30, 0x03, 108},
+ {2, 0x02, 109},
+ {6, 0x02, 109},
+ {15, 0x02, 109},
+ {30, 0x03, 109},
+ {2, 0x02, 110},
+ {6, 0x02, 110},
+ {15, 0x02, 110},
+ {30, 0x03, 110},
+ {2, 0x02, 112},
+ {6, 0x02, 112},
+ {15, 0x02, 112},
+ {30, 0x03, 112},
+ },
+ /* 28 */
+ {
+ {3, 0x02, 108},
+ {4, 0x02, 108},
+ {7, 0x02, 108},
+ {10, 0x02, 108},
+ {16, 0x02, 108},
+ {23, 0x02, 108},
+ {31, 0x02, 108},
+ {44, 0x03, 108},
+ {3, 0x02, 109},
+ {4, 0x02, 109},
+ {7, 0x02, 109},
+ {10, 0x02, 109},
+ {16, 0x02, 109},
+ {23, 0x02, 109},
+ {31, 0x02, 109},
+ {44, 0x03, 109},
+ },
+ /* 29 */
+ {
+ {3, 0x02, 110},
+ {4, 0x02, 110},
+ {7, 0x02, 110},
+ {10, 0x02, 110},
+ {16, 0x02, 110},
+ {23, 0x02, 110},
+ {31, 0x02, 110},
+ {44, 0x03, 110},
+ {3, 0x02, 112},
+ {4, 0x02, 112},
+ {7, 0x02, 112},
+ {10, 0x02, 112},
+ {16, 0x02, 112},
+ {23, 0x02, 112},
+ {31, 0x02, 112},
+ {44, 0x03, 112},
+ },
+ /* 30 */
+ {
+ {0, 0x03, 114},
+ {0, 0x03, 115},
+ {35, 0x00, 0},
+ {36, 0x00, 0},
+ {39, 0x00, 0},
+ {40, 0x00, 0},
+ {42, 0x00, 0},
+ {43, 0x00, 0},
+ {47, 0x00, 0},
+ {48, 0x00, 0},
+ {50, 0x00, 0},
+ {51, 0x00, 0},
+ {56, 0x00, 0},
+ {59, 0x00, 0},
+ {63, 0x00, 0},
+ {70, 0x01, 0},
+ },
+ /* 31 */
+ {
+ {1, 0x02, 114},
+ {14, 0x03, 114},
+ {1, 0x02, 115},
+ {14, 0x03, 115},
+ {0, 0x03, 38},
+ {0, 0x03, 44},
+ {0, 0x03, 45},
+ {0, 0x03, 65},
+ {0, 0x03, 68},
+ {0, 0x03, 70},
+ {0, 0x03, 71},
+ {0, 0x03, 77},
+ {0, 0x03, 78},
+ {0, 0x03, 83},
+ {0, 0x03, 95},
+ {0, 0x03, 98},
+ },
+ /* 32 */
+ {
+ {2, 0x02, 114},
+ {6, 0x02, 114},
+ {15, 0x02, 114},
+ {30, 0x03, 114},
+ {2, 0x02, 115},
+ {6, 0x02, 115},
+ {15, 0x02, 115},
+ {30, 0x03, 115},
+ {1, 0x02, 38},
+ {14, 0x03, 38},
+ {1, 0x02, 44},
+ {14, 0x03, 44},
+ {1, 0x02, 45},
+ {14, 0x03, 45},
+ {1, 0x02, 65},
+ {14, 0x03, 65},
+ },
+ /* 33 */
+ {
+ {3, 0x02, 114},
+ {4, 0x02, 114},
+ {7, 0x02, 114},
+ {10, 0x02, 114},
+ {16, 0x02, 114},
+ {23, 0x02, 114},
+ {31, 0x02, 114},
+ {44, 0x03, 114},
+ {3, 0x02, 115},
+ {4, 0x02, 115},
+ {7, 0x02, 115},
+ {10, 0x02, 115},
+ {16, 0x02, 115},
+ {23, 0x02, 115},
+ {31, 0x02, 115},
+ {44, 0x03, 115},
+ },
+ /* 34 */
+ {
+ {2, 0x02, 38},
+ {6, 0x02, 38},
+ {15, 0x02, 38},
+ {30, 0x03, 38},
+ {2, 0x02, 44},
+ {6, 0x02, 44},
+ {15, 0x02, 44},
+ {30, 0x03, 44},
+ {2, 0x02, 45},
+ {6, 0x02, 45},
+ {15, 0x02, 45},
+ {30, 0x03, 45},
+ {2, 0x02, 65},
+ {6, 0x02, 65},
+ {15, 0x02, 65},
+ {30, 0x03, 65},
+ },
+ /* 35 */
+ {
+ {3, 0x02, 38},
+ {4, 0x02, 38},
+ {7, 0x02, 38},
+ {10, 0x02, 38},
+ {16, 0x02, 38},
+ {23, 0x02, 38},
+ {31, 0x02, 38},
+ {44, 0x03, 38},
+ {3, 0x02, 44},
+ {4, 0x02, 44},
+ {7, 0x02, 44},
+ {10, 0x02, 44},
+ {16, 0x02, 44},
+ {23, 0x02, 44},
+ {31, 0x02, 44},
+ {44, 0x03, 44},
+ },
+ /* 36 */
+ {
+ {3, 0x02, 45},
+ {4, 0x02, 45},
+ {7, 0x02, 45},
+ {10, 0x02, 45},
+ {16, 0x02, 45},
+ {23, 0x02, 45},
+ {31, 0x02, 45},
+ {44, 0x03, 45},
+ {3, 0x02, 65},
+ {4, 0x02, 65},
+ {7, 0x02, 65},
+ {10, 0x02, 65},
+ {16, 0x02, 65},
+ {23, 0x02, 65},
+ {31, 0x02, 65},
+ {44, 0x03, 65},
+ },
+ /* 37 */
+ {
+ {1, 0x02, 68},
+ {14, 0x03, 68},
+ {1, 0x02, 70},
+ {14, 0x03, 70},
+ {1, 0x02, 71},
+ {14, 0x03, 71},
+ {1, 0x02, 77},
+ {14, 0x03, 77},
+ {1, 0x02, 78},
+ {14, 0x03, 78},
+ {1, 0x02, 83},
+ {14, 0x03, 83},
+ {1, 0x02, 95},
+ {14, 0x03, 95},
+ {1, 0x02, 98},
+ {14, 0x03, 98},
+ },
+ /* 38 */
+ {
+ {2, 0x02, 68},
+ {6, 0x02, 68},
+ {15, 0x02, 68},
+ {30, 0x03, 68},
+ {2, 0x02, 70},
+ {6, 0x02, 70},
+ {15, 0x02, 70},
+ {30, 0x03, 70},
+ {2, 0x02, 71},
+ {6, 0x02, 71},
+ {15, 0x02, 71},
+ {30, 0x03, 71},
+ {2, 0x02, 77},
+ {6, 0x02, 77},
+ {15, 0x02, 77},
+ {30, 0x03, 77},
+ },
+ /* 39 */
+ {
+ {3, 0x02, 68},
+ {4, 0x02, 68},
+ {7, 0x02, 68},
+ {10, 0x02, 68},
+ {16, 0x02, 68},
+ {23, 0x02, 68},
+ {31, 0x02, 68},
+ {44, 0x03, 68},
+ {3, 0x02, 70},
+ {4, 0x02, 70},
+ {7, 0x02, 70},
+ {10, 0x02, 70},
+ {16, 0x02, 70},
+ {23, 0x02, 70},
+ {31, 0x02, 70},
+ {44, 0x03, 70},
+ },
+ /* 40 */
+ {
+ {3, 0x02, 71},
+ {4, 0x02, 71},
+ {7, 0x02, 71},
+ {10, 0x02, 71},
+ {16, 0x02, 71},
+ {23, 0x02, 71},
+ {31, 0x02, 71},
+ {44, 0x03, 71},
+ {3, 0x02, 77},
+ {4, 0x02, 77},
+ {7, 0x02, 77},
+ {10, 0x02, 77},
+ {16, 0x02, 77},
+ {23, 0x02, 77},
+ {31, 0x02, 77},
+ {44, 0x03, 77},
+ },
+ /* 41 */
+ {
+ {2, 0x02, 78},
+ {6, 0x02, 78},
+ {15, 0x02, 78},
+ {30, 0x03, 78},
+ {2, 0x02, 83},
+ {6, 0x02, 83},
+ {15, 0x02, 83},
+ {30, 0x03, 83},
+ {2, 0x02, 95},
+ {6, 0x02, 95},
+ {15, 0x02, 95},
+ {30, 0x03, 95},
+ {2, 0x02, 98},
+ {6, 0x02, 98},
+ {15, 0x02, 98},
+ {30, 0x03, 98},
+ },
+ /* 42 */
+ {
+ {3, 0x02, 78},
+ {4, 0x02, 78},
+ {7, 0x02, 78},
+ {10, 0x02, 78},
+ {16, 0x02, 78},
+ {23, 0x02, 78},
+ {31, 0x02, 78},
+ {44, 0x03, 78},
+ {3, 0x02, 83},
+ {4, 0x02, 83},
+ {7, 0x02, 83},
+ {10, 0x02, 83},
+ {16, 0x02, 83},
+ {23, 0x02, 83},
+ {31, 0x02, 83},
+ {44, 0x03, 83},
+ },
+ /* 43 */
+ {
+ {3, 0x02, 95},
+ {4, 0x02, 95},
+ {7, 0x02, 95},
+ {10, 0x02, 95},
+ {16, 0x02, 95},
+ {23, 0x02, 95},
+ {31, 0x02, 95},
+ {44, 0x03, 95},
+ {3, 0x02, 98},
+ {4, 0x02, 98},
+ {7, 0x02, 98},
+ {10, 0x02, 98},
+ {16, 0x02, 98},
+ {23, 0x02, 98},
+ {31, 0x02, 98},
+ {44, 0x03, 98},
+ },
+ /* 44 */
+ {
+ {0, 0x03, 102},
+ {0, 0x03, 117},
+ {0, 0x03, 118},
+ {0, 0x03, 119},
+ {0, 0x03, 120},
+ {0, 0x03, 121},
+ {52, 0x00, 0},
+ {53, 0x00, 0},
+ {57, 0x00, 0},
+ {58, 0x00, 0},
+ {60, 0x00, 0},
+ {61, 0x00, 0},
+ {64, 0x00, 0},
+ {67, 0x00, 0},
+ {71, 0x00, 0},
+ {74, 0x01, 0},
+ },
+ /* 45 */
+ {
+ {1, 0x02, 102},
+ {14, 0x03, 102},
+ {1, 0x02, 117},
+ {14, 0x03, 117},
+ {1, 0x02, 118},
+ {14, 0x03, 118},
+ {1, 0x02, 119},
+ {14, 0x03, 119},
+ {1, 0x02, 120},
+ {14, 0x03, 120},
+ {1, 0x02, 121},
+ {14, 0x03, 121},
+ {0, 0x03, 59},
+ {0, 0x03, 66},
+ {0, 0x03, 67},
+ {0, 0x03, 69},
+ },
+ /* 46 */
+ {
+ {2, 0x02, 102},
+ {6, 0x02, 102},
+ {15, 0x02, 102},
+ {30, 0x03, 102},
+ {2, 0x02, 117},
+ {6, 0x02, 117},
+ {15, 0x02, 117},
+ {30, 0x03, 117},
+ {2, 0x02, 118},
+ {6, 0x02, 118},
+ {15, 0x02, 118},
+ {30, 0x03, 118},
+ {2, 0x02, 119},
+ {6, 0x02, 119},
+ {15, 0x02, 119},
+ {30, 0x03, 119},
+ },
+ /* 47 */
+ {
+ {3, 0x02, 102},
+ {4, 0x02, 102},
+ {7, 0x02, 102},
+ {10, 0x02, 102},
+ {16, 0x02, 102},
+ {23, 0x02, 102},
+ {31, 0x02, 102},
+ {44, 0x03, 102},
+ {3, 0x02, 117},
+ {4, 0x02, 117},
+ {7, 0x02, 117},
+ {10, 0x02, 117},
+ {16, 0x02, 117},
+ {23, 0x02, 117},
+ {31, 0x02, 117},
+ {44, 0x03, 117},
+ },
+ /* 48 */
+ {
+ {3, 0x02, 118},
+ {4, 0x02, 118},
+ {7, 0x02, 118},
+ {10, 0x02, 118},
+ {16, 0x02, 118},
+ {23, 0x02, 118},
+ {31, 0x02, 118},
+ {44, 0x03, 118},
+ {3, 0x02, 119},
+ {4, 0x02, 119},
+ {7, 0x02, 119},
+ {10, 0x02, 119},
+ {16, 0x02, 119},
+ {23, 0x02, 119},
+ {31, 0x02, 119},
+ {44, 0x03, 119},
+ },
+ /* 49 */
+ {
+ {2, 0x02, 120},
+ {6, 0x02, 120},
+ {15, 0x02, 120},
+ {30, 0x03, 120},
+ {2, 0x02, 121},
+ {6, 0x02, 121},
+ {15, 0x02, 121},
+ {30, 0x03, 121},
+ {1, 0x02, 59},
+ {14, 0x03, 59},
+ {1, 0x02, 66},
+ {14, 0x03, 66},
+ {1, 0x02, 67},
+ {14, 0x03, 67},
+ {1, 0x02, 69},
+ {14, 0x03, 69},
+ },
+ /* 50 */
+ {
+ {3, 0x02, 120},
+ {4, 0x02, 120},
+ {7, 0x02, 120},
+ {10, 0x02, 120},
+ {16, 0x02, 120},
+ {23, 0x02, 120},
+ {31, 0x02, 120},
+ {44, 0x03, 120},
+ {3, 0x02, 121},
+ {4, 0x02, 121},
+ {7, 0x02, 121},
+ {10, 0x02, 121},
+ {16, 0x02, 121},
+ {23, 0x02, 121},
+ {31, 0x02, 121},
+ {44, 0x03, 121},
+ },
+ /* 51 */
+ {
+ {2, 0x02, 59},
+ {6, 0x02, 59},
+ {15, 0x02, 59},
+ {30, 0x03, 59},
+ {2, 0x02, 66},
+ {6, 0x02, 66},
+ {15, 0x02, 66},
+ {30, 0x03, 66},
+ {2, 0x02, 67},
+ {6, 0x02, 67},
+ {15, 0x02, 67},
+ {30, 0x03, 67},
+ {2, 0x02, 69},
+ {6, 0x02, 69},
+ {15, 0x02, 69},
+ {30, 0x03, 69},
+ },
+ /* 52 */
+ {
+ {3, 0x02, 59},
+ {4, 0x02, 59},
+ {7, 0x02, 59},
+ {10, 0x02, 59},
+ {16, 0x02, 59},
+ {23, 0x02, 59},
+ {31, 0x02, 59},
+ {44, 0x03, 59},
+ {3, 0x02, 66},
+ {4, 0x02, 66},
+ {7, 0x02, 66},
+ {10, 0x02, 66},
+ {16, 0x02, 66},
+ {23, 0x02, 66},
+ {31, 0x02, 66},
+ {44, 0x03, 66},
+ },
+ /* 53 */
+ {
+ {3, 0x02, 67},
+ {4, 0x02, 67},
+ {7, 0x02, 67},
+ {10, 0x02, 67},
+ {16, 0x02, 67},
+ {23, 0x02, 67},
+ {31, 0x02, 67},
+ {44, 0x03, 67},
+ {3, 0x02, 69},
+ {4, 0x02, 69},
+ {7, 0x02, 69},
+ {10, 0x02, 69},
+ {16, 0x02, 69},
+ {23, 0x02, 69},
+ {31, 0x02, 69},
+ {44, 0x03, 69},
+ },
+ /* 54 */
+ {
+ {0, 0x03, 73},
+ {0, 0x03, 79},
+ {0, 0x03, 80},
+ {0, 0x03, 85},
+ {0, 0x03, 88},
+ {0, 0x03, 106},
+ {0, 0x03, 107},
+ {0, 0x03, 122},
+ {65, 0x00, 0},
+ {66, 0x00, 0},
+ {68, 0x00, 0},
+ {69, 0x00, 0},
+ {72, 0x00, 0},
+ {73, 0x00, 0},
+ {75, 0x00, 0},
+ {77, 0x00, 0},
+ },
+ /* 55 */
+ {
+ {1, 0x02, 73},
+ {14, 0x03, 73},
+ {1, 0x02, 79},
+ {14, 0x03, 79},
+ {1, 0x02, 80},
+ {14, 0x03, 80},
+ {1, 0x02, 85},
+ {14, 0x03, 85},
+ {1, 0x02, 88},
+ {14, 0x03, 88},
+ {1, 0x02, 106},
+ {14, 0x03, 106},
+ {1, 0x02, 107},
+ {14, 0x03, 107},
+ {1, 0x02, 122},
+ {14, 0x03, 122},
+ },
+ /* 56 */
+ {
+ {2, 0x02, 73},
+ {6, 0x02, 73},
+ {15, 0x02, 73},
+ {30, 0x03, 73},
+ {2, 0x02, 79},
+ {6, 0x02, 79},
+ {15, 0x02, 79},
+ {30, 0x03, 79},
+ {2, 0x02, 80},
+ {6, 0x02, 80},
+ {15, 0x02, 80},
+ {30, 0x03, 80},
+ {2, 0x02, 85},
+ {6, 0x02, 85},
+ {15, 0x02, 85},
+ {30, 0x03, 85},
+ },
+ /* 57 */
+ {
+ {3, 0x02, 73},
+ {4, 0x02, 73},
+ {7, 0x02, 73},
+ {10, 0x02, 73},
+ {16, 0x02, 73},
+ {23, 0x02, 73},
+ {31, 0x02, 73},
+ {44, 0x03, 73},
+ {3, 0x02, 79},
+ {4, 0x02, 79},
+ {7, 0x02, 79},
+ {10, 0x02, 79},
+ {16, 0x02, 79},
+ {23, 0x02, 79},
+ {31, 0x02, 79},
+ {44, 0x03, 79},
+ },
+ /* 58 */
+ {
+ {3, 0x02, 80},
+ {4, 0x02, 80},
+ {7, 0x02, 80},
+ {10, 0x02, 80},
+ {16, 0x02, 80},
+ {23, 0x02, 80},
+ {31, 0x02, 80},
+ {44, 0x03, 80},
+ {3, 0x02, 85},
+ {4, 0x02, 85},
+ {7, 0x02, 85},
+ {10, 0x02, 85},
+ {16, 0x02, 85},
+ {23, 0x02, 85},
+ {31, 0x02, 85},
+ {44, 0x03, 85},
+ },
+ /* 59 */
+ {
+ {2, 0x02, 88},
+ {6, 0x02, 88},
+ {15, 0x02, 88},
+ {30, 0x03, 88},
+ {2, 0x02, 106},
+ {6, 0x02, 106},
+ {15, 0x02, 106},
+ {30, 0x03, 106},
+ {2, 0x02, 107},
+ {6, 0x02, 107},
+ {15, 0x02, 107},
+ {30, 0x03, 107},
+ {2, 0x02, 122},
+ {6, 0x02, 122},
+ {15, 0x02, 122},
+ {30, 0x03, 122},
+ },
+ /* 60 */
+ {
+ {3, 0x02, 88},
+ {4, 0x02, 88},
+ {7, 0x02, 88},
+ {10, 0x02, 88},
+ {16, 0x02, 88},
+ {23, 0x02, 88},
+ {31, 0x02, 88},
+ {44, 0x03, 88},
+ {3, 0x02, 106},
+ {4, 0x02, 106},
+ {7, 0x02, 106},
+ {10, 0x02, 106},
+ {16, 0x02, 106},
+ {23, 0x02, 106},
+ {31, 0x02, 106},
+ {44, 0x03, 106},
+ },
+ /* 61 */
+ {
+ {3, 0x02, 107},
+ {4, 0x02, 107},
+ {7, 0x02, 107},
+ {10, 0x02, 107},
+ {16, 0x02, 107},
+ {23, 0x02, 107},
+ {31, 0x02, 107},
+ {44, 0x03, 107},
+ {3, 0x02, 122},
+ {4, 0x02, 122},
+ {7, 0x02, 122},
+ {10, 0x02, 122},
+ {16, 0x02, 122},
+ {23, 0x02, 122},
+ {31, 0x02, 122},
+ {44, 0x03, 122},
+ },
+ /* 62 */
+ {
+ {0, 0x03, 34},
+ {0, 0x03, 41},
+ {0, 0x03, 72},
+ {0, 0x03, 74},
+ {0, 0x03, 75},
+ {0, 0x03, 76},
+ {0, 0x03, 81},
+ {0, 0x03, 82},
+ {0, 0x03, 86},
+ {0, 0x03, 87},
+ {0, 0x03, 89},
+ {0, 0x03, 90},
+ {0, 0x03, 113},
+ {76, 0x00, 0},
+ {78, 0x00, 0},
+ {79, 0x00, 0},
+ },
+ /* 63 */
+ {
+ {1, 0x02, 34},
+ {14, 0x03, 34},
+ {1, 0x02, 41},
+ {14, 0x03, 41},
+ {1, 0x02, 72},
+ {14, 0x03, 72},
+ {1, 0x02, 74},
+ {14, 0x03, 74},
+ {1, 0x02, 75},
+ {14, 0x03, 75},
+ {1, 0x02, 76},
+ {14, 0x03, 76},
+ {1, 0x02, 81},
+ {14, 0x03, 81},
+ {1, 0x02, 82},
+ {14, 0x03, 82},
+ },
+ /* 64 */
+ {
+ {2, 0x02, 34},
+ {6, 0x02, 34},
+ {15, 0x02, 34},
+ {30, 0x03, 34},
+ {2, 0x02, 41},
+ {6, 0x02, 41},
+ {15, 0x02, 41},
+ {30, 0x03, 41},
+ {2, 0x02, 72},
+ {6, 0x02, 72},
+ {15, 0x02, 72},
+ {30, 0x03, 72},
+ {2, 0x02, 74},
+ {6, 0x02, 74},
+ {15, 0x02, 74},
+ {30, 0x03, 74},
+ },
+ /* 65 */
+ {
+ {3, 0x02, 34},
+ {4, 0x02, 34},
+ {7, 0x02, 34},
+ {10, 0x02, 34},
+ {16, 0x02, 34},
+ {23, 0x02, 34},
+ {31, 0x02, 34},
+ {44, 0x03, 34},
+ {3, 0x02, 41},
+ {4, 0x02, 41},
+ {7, 0x02, 41},
+ {10, 0x02, 41},
+ {16, 0x02, 41},
+ {23, 0x02, 41},
+ {31, 0x02, 41},
+ {44, 0x03, 41},
+ },
+ /* 66 */
+ {
+ {3, 0x02, 72},
+ {4, 0x02, 72},
+ {7, 0x02, 72},
+ {10, 0x02, 72},
+ {16, 0x02, 72},
+ {23, 0x02, 72},
+ {31, 0x02, 72},
+ {44, 0x03, 72},
+ {3, 0x02, 74},
+ {4, 0x02, 74},
+ {7, 0x02, 74},
+ {10, 0x02, 74},
+ {16, 0x02, 74},
+ {23, 0x02, 74},
+ {31, 0x02, 74},
+ {44, 0x03, 74},
+ },
+ /* 67 */
+ {
+ {2, 0x02, 75},
+ {6, 0x02, 75},
+ {15, 0x02, 75},
+ {30, 0x03, 75},
+ {2, 0x02, 76},
+ {6, 0x02, 76},
+ {15, 0x02, 76},
+ {30, 0x03, 76},
+ {2, 0x02, 81},
+ {6, 0x02, 81},
+ {15, 0x02, 81},
+ {30, 0x03, 81},
+ {2, 0x02, 82},
+ {6, 0x02, 82},
+ {15, 0x02, 82},
+ {30, 0x03, 82},
+ },
+ /* 68 */
+ {
+ {3, 0x02, 75},
+ {4, 0x02, 75},
+ {7, 0x02, 75},
+ {10, 0x02, 75},
+ {16, 0x02, 75},
+ {23, 0x02, 75},
+ {31, 0x02, 75},
+ {44, 0x03, 75},
+ {3, 0x02, 76},
+ {4, 0x02, 76},
+ {7, 0x02, 76},
+ {10, 0x02, 76},
+ {16, 0x02, 76},
+ {23, 0x02, 76},
+ {31, 0x02, 76},
+ {44, 0x03, 76},
+ },
+ /* 69 */
+ {
+ {3, 0x02, 81},
+ {4, 0x02, 81},
+ {7, 0x02, 81},
+ {10, 0x02, 81},
+ {16, 0x02, 81},
+ {23, 0x02, 81},
+ {31, 0x02, 81},
+ {44, 0x03, 81},
+ {3, 0x02, 82},
+ {4, 0x02, 82},
+ {7, 0x02, 82},
+ {10, 0x02, 82},
+ {16, 0x02, 82},
+ {23, 0x02, 82},
+ {31, 0x02, 82},
+ {44, 0x03, 82},
+ },
+ /* 70 */
+ {
+ {1, 0x02, 86},
+ {14, 0x03, 86},
+ {1, 0x02, 87},
+ {14, 0x03, 87},
+ {1, 0x02, 89},
+ {14, 0x03, 89},
+ {1, 0x02, 90},
+ {14, 0x03, 90},
+ {1, 0x02, 113},
+ {14, 0x03, 113},
+ {0, 0x03, 40},
+ {0, 0x03, 42},
+ {0, 0x03, 43},
+ {0, 0x03, 63},
+ {80, 0x00, 0},
+ {81, 0x00, 0},
+ },
+ /* 71 */
+ {
+ {2, 0x02, 86},
+ {6, 0x02, 86},
+ {15, 0x02, 86},
+ {30, 0x03, 86},
+ {2, 0x02, 87},
+ {6, 0x02, 87},
+ {15, 0x02, 87},
+ {30, 0x03, 87},
+ {2, 0x02, 89},
+ {6, 0x02, 89},
+ {15, 0x02, 89},
+ {30, 0x03, 89},
+ {2, 0x02, 90},
+ {6, 0x02, 90},
+ {15, 0x02, 90},
+ {30, 0x03, 90},
+ },
+ /* 72 */
+ {
+ {3, 0x02, 86},
+ {4, 0x02, 86},
+ {7, 0x02, 86},
+ {10, 0x02, 86},
+ {16, 0x02, 86},
+ {23, 0x02, 86},
+ {31, 0x02, 86},
+ {44, 0x03, 86},
+ {3, 0x02, 87},
+ {4, 0x02, 87},
+ {7, 0x02, 87},
+ {10, 0x02, 87},
+ {16, 0x02, 87},
+ {23, 0x02, 87},
+ {31, 0x02, 87},
+ {44, 0x03, 87},
+ },
+ /* 73 */
+ {
+ {3, 0x02, 89},
+ {4, 0x02, 89},
+ {7, 0x02, 89},
+ {10, 0x02, 89},
+ {16, 0x02, 89},
+ {23, 0x02, 89},
+ {31, 0x02, 89},
+ {44, 0x03, 89},
+ {3, 0x02, 90},
+ {4, 0x02, 90},
+ {7, 0x02, 90},
+ {10, 0x02, 90},
+ {16, 0x02, 90},
+ {23, 0x02, 90},
+ {31, 0x02, 90},
+ {44, 0x03, 90},
+ },
+ /* 74 */
+ {
+ {2, 0x02, 113},
+ {6, 0x02, 113},
+ {15, 0x02, 113},
+ {30, 0x03, 113},
+ {1, 0x02, 40},
+ {14, 0x03, 40},
+ {1, 0x02, 42},
+ {14, 0x03, 42},
+ {1, 0x02, 43},
+ {14, 0x03, 43},
+ {1, 0x02, 63},
+ {14, 0x03, 63},
+ {0, 0x03, 91},
+ {0, 0x03, 93},
+ {82, 0x00, 0},
+ {83, 0x00, 0},
+ },
+ /* 75 */
+ {
+ {3, 0x02, 113},
+ {4, 0x02, 113},
+ {7, 0x02, 113},
+ {10, 0x02, 113},
+ {16, 0x02, 113},
+ {23, 0x02, 113},
+ {31, 0x02, 113},
+ {44, 0x03, 113},
+ {2, 0x02, 40},
+ {6, 0x02, 40},
+ {15, 0x02, 40},
+ {30, 0x03, 40},
+ {2, 0x02, 42},
+ {6, 0x02, 42},
+ {15, 0x02, 42},
+ {30, 0x03, 42},
+ },
+ /* 76 */
+ {
+ {3, 0x02, 40},
+ {4, 0x02, 40},
+ {7, 0x02, 40},
+ {10, 0x02, 40},
+ {16, 0x02, 40},
+ {23, 0x02, 40},
+ {31, 0x02, 40},
+ {44, 0x03, 40},
+ {3, 0x02, 42},
+ {4, 0x02, 42},
+ {7, 0x02, 42},
+ {10, 0x02, 42},
+ {16, 0x02, 42},
+ {23, 0x02, 42},
+ {31, 0x02, 42},
+ {44, 0x03, 42},
+ },
+ /* 77 */
+ {
+ {2, 0x02, 43},
+ {6, 0x02, 43},
+ {15, 0x02, 43},
+ {30, 0x03, 43},
+ {2, 0x02, 63},
+ {6, 0x02, 63},
+ {15, 0x02, 63},
+ {30, 0x03, 63},
+ {1, 0x02, 91},
+ {14, 0x03, 91},
+ {1, 0x02, 93},
+ {14, 0x03, 93},
+ {0, 0x03, 124},
+ {0, 0x03, 126},
+ {84, 0x00, 0},
+ {85, 0x00, 0},
+ },
+ /* 78 */
+ {
+ {3, 0x02, 43},
+ {4, 0x02, 43},
+ {7, 0x02, 43},
+ {10, 0x02, 43},
+ {16, 0x02, 43},
+ {23, 0x02, 43},
+ {31, 0x02, 43},
+ {44, 0x03, 43},
+ {3, 0x02, 63},
+ {4, 0x02, 63},
+ {7, 0x02, 63},
+ {10, 0x02, 63},
+ {16, 0x02, 63},
+ {23, 0x02, 63},
+ {31, 0x02, 63},
+ {44, 0x03, 63},
+ },
+ /* 79 */
+ {
+ {2, 0x02, 91},
+ {6, 0x02, 91},
+ {15, 0x02, 91},
+ {30, 0x03, 91},
+ {2, 0x02, 93},
+ {6, 0x02, 93},
+ {15, 0x02, 93},
+ {30, 0x03, 93},
+ {1, 0x02, 124},
+ {14, 0x03, 124},
+ {1, 0x02, 126},
+ {14, 0x03, 126},
+ {0, 0x03, 33},
+ {0, 0x03, 39},
+ {86, 0x00, 0},
+ {87, 0x00, 0},
+ },
+ /* 80 */
+ {
+ {3, 0x02, 91},
+ {4, 0x02, 91},
+ {7, 0x02, 91},
+ {10, 0x02, 91},
+ {16, 0x02, 91},
+ {23, 0x02, 91},
+ {31, 0x02, 91},
+ {44, 0x03, 91},
+ {3, 0x02, 93},
+ {4, 0x02, 93},
+ {7, 0x02, 93},
+ {10, 0x02, 93},
+ {16, 0x02, 93},
+ {23, 0x02, 93},
+ {31, 0x02, 93},
+ {44, 0x03, 93},
+ },
+ /* 81 */
+ {
+ {2, 0x02, 124},
+ {6, 0x02, 124},
+ {15, 0x02, 124},
+ {30, 0x03, 124},
+ {2, 0x02, 126},
+ {6, 0x02, 126},
+ {15, 0x02, 126},
+ {30, 0x03, 126},
+ {1, 0x02, 33},
+ {14, 0x03, 33},
+ {1, 0x02, 39},
+ {14, 0x03, 39},
+ {0, 0x03, 35},
+ {0, 0x03, 94},
+ {88, 0x00, 0},
+ {89, 0x00, 0},
+ },
+ /* 82 */
+ {
+ {3, 0x02, 124},
+ {4, 0x02, 124},
+ {7, 0x02, 124},
+ {10, 0x02, 124},
+ {16, 0x02, 124},
+ {23, 0x02, 124},
+ {31, 0x02, 124},
+ {44, 0x03, 124},
+ {3, 0x02, 126},
+ {4, 0x02, 126},
+ {7, 0x02, 126},
+ {10, 0x02, 126},
+ {16, 0x02, 126},
+ {23, 0x02, 126},
+ {31, 0x02, 126},
+ {44, 0x03, 126},
+ },
+ /* 83 */
+ {
+ {2, 0x02, 33},
+ {6, 0x02, 33},
+ {15, 0x02, 33},
+ {30, 0x03, 33},
+ {2, 0x02, 39},
+ {6, 0x02, 39},
+ {15, 0x02, 39},
+ {30, 0x03, 39},
+ {1, 0x02, 35},
+ {14, 0x03, 35},
+ {1, 0x02, 94},
+ {14, 0x03, 94},
+ {0, 0x03, 36},
+ {0, 0x03, 62},
+ {0, 0x03, 64},
+ {90, 0x00, 0},
+ },
+ /* 84 */
+ {
+ {3, 0x02, 33},
+ {4, 0x02, 33},
+ {7, 0x02, 33},
+ {10, 0x02, 33},
+ {16, 0x02, 33},
+ {23, 0x02, 33},
+ {31, 0x02, 33},
+ {44, 0x03, 33},
+ {3, 0x02, 39},
+ {4, 0x02, 39},
+ {7, 0x02, 39},
+ {10, 0x02, 39},
+ {16, 0x02, 39},
+ {23, 0x02, 39},
+ {31, 0x02, 39},
+ {44, 0x03, 39},
+ },
+ /* 85 */
+ {
+ {2, 0x02, 35},
+ {6, 0x02, 35},
+ {15, 0x02, 35},
+ {30, 0x03, 35},
+ {2, 0x02, 94},
+ {6, 0x02, 94},
+ {15, 0x02, 94},
+ {30, 0x03, 94},
+ {1, 0x02, 36},
+ {14, 0x03, 36},
+ {1, 0x02, 62},
+ {14, 0x03, 62},
+ {1, 0x02, 64},
+ {14, 0x03, 64},
+ {91, 0x00, 0},
+ {92, 0x00, 0},
+ },
+ /* 86 */
+ {
+ {3, 0x02, 35},
+ {4, 0x02, 35},
+ {7, 0x02, 35},
+ {10, 0x02, 35},
+ {16, 0x02, 35},
+ {23, 0x02, 35},
+ {31, 0x02, 35},
+ {44, 0x03, 35},
+ {3, 0x02, 94},
+ {4, 0x02, 94},
+ {7, 0x02, 94},
+ {10, 0x02, 94},
+ {16, 0x02, 94},
+ {23, 0x02, 94},
+ {31, 0x02, 94},
+ {44, 0x03, 94},
+ },
+ /* 87 */
+ {
+ {2, 0x02, 36},
+ {6, 0x02, 36},
+ {15, 0x02, 36},
+ {30, 0x03, 36},
+ {2, 0x02, 62},
+ {6, 0x02, 62},
+ {15, 0x02, 62},
+ {30, 0x03, 62},
+ {2, 0x02, 64},
+ {6, 0x02, 64},
+ {15, 0x02, 64},
+ {30, 0x03, 64},
+ {0, 0x03, 60},
+ {0, 0x03, 123},
+ {0, 0x03, 125},
+ {93, 0x00, 0},
+ },
+ /* 88 */
+ {
+ {3, 0x02, 36},
+ {4, 0x02, 36},
+ {7, 0x02, 36},
+ {10, 0x02, 36},
+ {16, 0x02, 36},
+ {23, 0x02, 36},
+ {31, 0x02, 36},
+ {44, 0x03, 36},
+ {3, 0x02, 62},
+ {4, 0x02, 62},
+ {7, 0x02, 62},
+ {10, 0x02, 62},
+ {16, 0x02, 62},
+ {23, 0x02, 62},
+ {31, 0x02, 62},
+ {44, 0x03, 62},
+ },
+ /* 89 */
+ {
+ {3, 0x02, 64},
+ {4, 0x02, 64},
+ {7, 0x02, 64},
+ {10, 0x02, 64},
+ {16, 0x02, 64},
+ {23, 0x02, 64},
+ {31, 0x02, 64},
+ {44, 0x03, 64},
+ {1, 0x02, 60},
+ {14, 0x03, 60},
+ {1, 0x02, 123},
+ {14, 0x03, 123},
+ {1, 0x02, 125},
+ {14, 0x03, 125},
+ {0, 0x03, 96},
+ {94, 0x00, 0},
+ },
+ /* 90 */
+ {
+ {2, 0x02, 60},
+ {6, 0x02, 60},
+ {15, 0x02, 60},
+ {30, 0x03, 60},
+ {2, 0x02, 123},
+ {6, 0x02, 123},
+ {15, 0x02, 123},
+ {30, 0x03, 123},
+ {2, 0x02, 125},
+ {6, 0x02, 125},
+ {15, 0x02, 125},
+ {30, 0x03, 125},
+ {1, 0x02, 96},
+ {14, 0x03, 96},
+ {95, 0x00, 0},
+ {158, 0x00, 0},
+ },
+ /* 91 */
+ {
+ {3, 0x02, 60},
+ {4, 0x02, 60},
+ {7, 0x02, 60},
+ {10, 0x02, 60},
+ {16, 0x02, 60},
+ {23, 0x02, 60},
+ {31, 0x02, 60},
+ {44, 0x03, 60},
+ {3, 0x02, 123},
+ {4, 0x02, 123},
+ {7, 0x02, 123},
+ {10, 0x02, 123},
+ {16, 0x02, 123},
+ {23, 0x02, 123},
+ {31, 0x02, 123},
+ {44, 0x03, 123},
+ },
+ /* 92 */
+ {
+ {3, 0x02, 125},
+ {4, 0x02, 125},
+ {7, 0x02, 125},
+ {10, 0x02, 125},
+ {16, 0x02, 125},
+ {23, 0x02, 125},
+ {31, 0x02, 125},
+ {44, 0x03, 125},
+ {2, 0x02, 96},
+ {6, 0x02, 96},
+ {15, 0x02, 96},
+ {30, 0x03, 96},
+ {96, 0x00, 0},
+ {127, 0x00, 0},
+ {159, 0x00, 0},
+ {193, 0x00, 0},
+ },
+ /* 93 */
+ {
+ {3, 0x02, 96},
+ {4, 0x02, 96},
+ {7, 0x02, 96},
+ {10, 0x02, 96},
+ {16, 0x02, 96},
+ {23, 0x02, 96},
+ {31, 0x02, 96},
+ {44, 0x03, 96},
+ {97, 0x00, 0},
+ {112, 0x00, 0},
+ {128, 0x00, 0},
+ {143, 0x00, 0},
+ {160, 0x00, 0},
+ {175, 0x00, 0},
+ {194, 0x00, 0},
+ {225, 0x00, 0},
+ },
+ /* 94 */
+ {
+ {98, 0x00, 0},
+ {105, 0x00, 0},
+ {113, 0x00, 0},
+ {120, 0x00, 0},
+ {129, 0x00, 0},
+ {136, 0x00, 0},
+ {144, 0x00, 0},
+ {151, 0x00, 0},
+ {161, 0x00, 0},
+ {168, 0x00, 0},
+ {176, 0x00, 0},
+ {183, 0x00, 0},
+ {195, 0x00, 0},
+ {210, 0x00, 0},
+ {226, 0x00, 0},
+ {241, 0x00, 0},
+ },
+ /* 95 */
+ {
+ {99, 0x00, 0},
+ {102, 0x00, 0},
+ {106, 0x00, 0},
+ {109, 0x00, 0},
+ {114, 0x00, 0},
+ {117, 0x00, 0},
+ {121, 0x00, 0},
+ {124, 0x00, 0},
+ {130, 0x00, 0},
+ {133, 0x00, 0},
+ {137, 0x00, 0},
+ {140, 0x00, 0},
+ {145, 0x00, 0},
+ {148, 0x00, 0},
+ {152, 0x00, 0},
+ {155, 0x00, 0},
+ },
+ /* 96 */
+ {
+ {100, 0x00, 0},
+ {101, 0x00, 0},
+ {103, 0x00, 0},
+ {104, 0x00, 0},
+ {107, 0x00, 0},
+ {108, 0x00, 0},
+ {110, 0x00, 0},
+ {111, 0x00, 0},
+ {115, 0x00, 0},
+ {116, 0x00, 0},
+ {118, 0x00, 0},
+ {119, 0x00, 0},
+ {122, 0x00, 0},
+ {123, 0x00, 0},
+ {125, 0x00, 0},
+ {126, 0x00, 0},
+ },
+ /* 97 */
+ {
+ {0, 0x03, 164},
+ {0, 0x03, 165},
+ {0, 0x03, 166},
+ {0, 0x03, 167},
+ {0, 0x03, 168},
+ {0, 0x03, 169},
+ {0, 0x03, 170},
+ {0, 0x03, 171},
+ {0, 0x03, 172},
+ {0, 0x03, 173},
+ {0, 0x03, 174},
+ {0, 0x03, 175},
+ {0, 0x03, 176},
+ {0, 0x03, 177},
+ {0, 0x03, 178},
+ {0, 0x03, 179},
+ },
+ /* 98 */
+ {
+ {1, 0x02, 164},
+ {14, 0x03, 164},
+ {1, 0x02, 165},
+ {14, 0x03, 165},
+ {1, 0x02, 166},
+ {14, 0x03, 166},
+ {1, 0x02, 167},
+ {14, 0x03, 167},
+ {1, 0x02, 168},
+ {14, 0x03, 168},
+ {1, 0x02, 169},
+ {14, 0x03, 169},
+ {1, 0x02, 170},
+ {14, 0x03, 170},
+ {1, 0x02, 171},
+ {14, 0x03, 171},
+ },
+ /* 99 */
+ {
+ {2, 0x02, 164},
+ {6, 0x02, 164},
+ {15, 0x02, 164},
+ {30, 0x03, 164},
+ {2, 0x02, 165},
+ {6, 0x02, 165},
+ {15, 0x02, 165},
+ {30, 0x03, 165},
+ {2, 0x02, 166},
+ {6, 0x02, 166},
+ {15, 0x02, 166},
+ {30, 0x03, 166},
+ {2, 0x02, 167},
+ {6, 0x02, 167},
+ {15, 0x02, 167},
+ {30, 0x03, 167},
+ },
+ /* 100 */
+ {
+ {3, 0x02, 164},
+ {4, 0x02, 164},
+ {7, 0x02, 164},
+ {10, 0x02, 164},
+ {16, 0x02, 164},
+ {23, 0x02, 164},
+ {31, 0x02, 164},
+ {44, 0x03, 164},
+ {3, 0x02, 165},
+ {4, 0x02, 165},
+ {7, 0x02, 165},
+ {10, 0x02, 165},
+ {16, 0x02, 165},
+ {23, 0x02, 165},
+ {31, 0x02, 165},
+ {44, 0x03, 165},
+ },
+ /* 101 */
+ {
+ {3, 0x02, 166},
+ {4, 0x02, 166},
+ {7, 0x02, 166},
+ {10, 0x02, 166},
+ {16, 0x02, 166},
+ {23, 0x02, 166},
+ {31, 0x02, 166},
+ {44, 0x03, 166},
+ {3, 0x02, 167},
+ {4, 0x02, 167},
+ {7, 0x02, 167},
+ {10, 0x02, 167},
+ {16, 0x02, 167},
+ {23, 0x02, 167},
+ {31, 0x02, 167},
+ {44, 0x03, 167},
+ },
+ /* 102 */
+ {
+ {2, 0x02, 168},
+ {6, 0x02, 168},
+ {15, 0x02, 168},
+ {30, 0x03, 168},
+ {2, 0x02, 169},
+ {6, 0x02, 169},
+ {15, 0x02, 169},
+ {30, 0x03, 169},
+ {2, 0x02, 170},
+ {6, 0x02, 170},
+ {15, 0x02, 170},
+ {30, 0x03, 170},
+ {2, 0x02, 171},
+ {6, 0x02, 171},
+ {15, 0x02, 171},
+ {30, 0x03, 171},
+ },
+ /* 103 */
+ {
+ {3, 0x02, 168},
+ {4, 0x02, 168},
+ {7, 0x02, 168},
+ {10, 0x02, 168},
+ {16, 0x02, 168},
+ {23, 0x02, 168},
+ {31, 0x02, 168},
+ {44, 0x03, 168},
+ {3, 0x02, 169},
+ {4, 0x02, 169},
+ {7, 0x02, 169},
+ {10, 0x02, 169},
+ {16, 0x02, 169},
+ {23, 0x02, 169},
+ {31, 0x02, 169},
+ {44, 0x03, 169},
+ },
+ /* 104 */
+ {
+ {3, 0x02, 170},
+ {4, 0x02, 170},
+ {7, 0x02, 170},
+ {10, 0x02, 170},
+ {16, 0x02, 170},
+ {23, 0x02, 170},
+ {31, 0x02, 170},
+ {44, 0x03, 170},
+ {3, 0x02, 171},
+ {4, 0x02, 171},
+ {7, 0x02, 171},
+ {10, 0x02, 171},
+ {16, 0x02, 171},
+ {23, 0x02, 171},
+ {31, 0x02, 171},
+ {44, 0x03, 171},
+ },
+ /* 105 */
+ {
+ {1, 0x02, 172},
+ {14, 0x03, 172},
+ {1, 0x02, 173},
+ {14, 0x03, 173},
+ {1, 0x02, 174},
+ {14, 0x03, 174},
+ {1, 0x02, 175},
+ {14, 0x03, 175},
+ {1, 0x02, 176},
+ {14, 0x03, 176},
+ {1, 0x02, 177},
+ {14, 0x03, 177},
+ {1, 0x02, 178},
+ {14, 0x03, 178},
+ {1, 0x02, 179},
+ {14, 0x03, 179},
+ },
+ /* 106 */
+ {
+ {2, 0x02, 172},
+ {6, 0x02, 172},
+ {15, 0x02, 172},
+ {30, 0x03, 172},
+ {2, 0x02, 173},
+ {6, 0x02, 173},
+ {15, 0x02, 173},
+ {30, 0x03, 173},
+ {2, 0x02, 174},
+ {6, 0x02, 174},
+ {15, 0x02, 174},
+ {30, 0x03, 174},
+ {2, 0x02, 175},
+ {6, 0x02, 175},
+ {15, 0x02, 175},
+ {30, 0x03, 175},
+ },
+ /* 107 */
+ {
+ {3, 0x02, 172},
+ {4, 0x02, 172},
+ {7, 0x02, 172},
+ {10, 0x02, 172},
+ {16, 0x02, 172},
+ {23, 0x02, 172},
+ {31, 0x02, 172},
+ {44, 0x03, 172},
+ {3, 0x02, 173},
+ {4, 0x02, 173},
+ {7, 0x02, 173},
+ {10, 0x02, 173},
+ {16, 0x02, 173},
+ {23, 0x02, 173},
+ {31, 0x02, 173},
+ {44, 0x03, 173},
+ },
+ /* 108 */
+ {
+ {3, 0x02, 174},
+ {4, 0x02, 174},
+ {7, 0x02, 174},
+ {10, 0x02, 174},
+ {16, 0x02, 174},
+ {23, 0x02, 174},
+ {31, 0x02, 174},
+ {44, 0x03, 174},
+ {3, 0x02, 175},
+ {4, 0x02, 175},
+ {7, 0x02, 175},
+ {10, 0x02, 175},
+ {16, 0x02, 175},
+ {23, 0x02, 175},
+ {31, 0x02, 175},
+ {44, 0x03, 175},
+ },
+ /* 109 */
+ {
+ {2, 0x02, 176},
+ {6, 0x02, 176},
+ {15, 0x02, 176},
+ {30, 0x03, 176},
+ {2, 0x02, 177},
+ {6, 0x02, 177},
+ {15, 0x02, 177},
+ {30, 0x03, 177},
+ {2, 0x02, 178},
+ {6, 0x02, 178},
+ {15, 0x02, 178},
+ {30, 0x03, 178},
+ {2, 0x02, 179},
+ {6, 0x02, 179},
+ {15, 0x02, 179},
+ {30, 0x03, 179},
+ },
+ /* 110 */
+ {
+ {3, 0x02, 176},
+ {4, 0x02, 176},
+ {7, 0x02, 176},
+ {10, 0x02, 176},
+ {16, 0x02, 176},
+ {23, 0x02, 176},
+ {31, 0x02, 176},
+ {44, 0x03, 176},
+ {3, 0x02, 177},
+ {4, 0x02, 177},
+ {7, 0x02, 177},
+ {10, 0x02, 177},
+ {16, 0x02, 177},
+ {23, 0x02, 177},
+ {31, 0x02, 177},
+ {44, 0x03, 177},
+ },
+ /* 111 */
+ {
+ {3, 0x02, 178},
+ {4, 0x02, 178},
+ {7, 0x02, 178},
+ {10, 0x02, 178},
+ {16, 0x02, 178},
+ {23, 0x02, 178},
+ {31, 0x02, 178},
+ {44, 0x03, 178},
+ {3, 0x02, 179},
+ {4, 0x02, 179},
+ {7, 0x02, 179},
+ {10, 0x02, 179},
+ {16, 0x02, 179},
+ {23, 0x02, 179},
+ {31, 0x02, 179},
+ {44, 0x03, 179},
+ },
+ /* 112 */
+ {
+ {0, 0x03, 180},
+ {0, 0x03, 181},
+ {0, 0x03, 182},
+ {0, 0x03, 183},
+ {0, 0x03, 184},
+ {0, 0x03, 185},
+ {0, 0x03, 186},
+ {0, 0x03, 187},
+ {0, 0x03, 188},
+ {0, 0x03, 189},
+ {0, 0x03, 190},
+ {0, 0x03, 191},
+ {0, 0x03, 192},
+ {0, 0x03, 193},
+ {0, 0x03, 194},
+ {0, 0x03, 195},
+ },
+ /* 113 */
+ {
+ {1, 0x02, 180},
+ {14, 0x03, 180},
+ {1, 0x02, 181},
+ {14, 0x03, 181},
+ {1, 0x02, 182},
+ {14, 0x03, 182},
+ {1, 0x02, 183},
+ {14, 0x03, 183},
+ {1, 0x02, 184},
+ {14, 0x03, 184},
+ {1, 0x02, 185},
+ {14, 0x03, 185},
+ {1, 0x02, 186},
+ {14, 0x03, 186},
+ {1, 0x02, 187},
+ {14, 0x03, 187},
+ },
+ /* 114 */
+ {
+ {2, 0x02, 180},
+ {6, 0x02, 180},
+ {15, 0x02, 180},
+ {30, 0x03, 180},
+ {2, 0x02, 181},
+ {6, 0x02, 181},
+ {15, 0x02, 181},
+ {30, 0x03, 181},
+ {2, 0x02, 182},
+ {6, 0x02, 182},
+ {15, 0x02, 182},
+ {30, 0x03, 182},
+ {2, 0x02, 183},
+ {6, 0x02, 183},
+ {15, 0x02, 183},
+ {30, 0x03, 183},
+ },
+ /* 115 */
+ {
+ {3, 0x02, 180},
+ {4, 0x02, 180},
+ {7, 0x02, 180},
+ {10, 0x02, 180},
+ {16, 0x02, 180},
+ {23, 0x02, 180},
+ {31, 0x02, 180},
+ {44, 0x03, 180},
+ {3, 0x02, 181},
+ {4, 0x02, 181},
+ {7, 0x02, 181},
+ {10, 0x02, 181},
+ {16, 0x02, 181},
+ {23, 0x02, 181},
+ {31, 0x02, 181},
+ {44, 0x03, 181},
+ },
+ /* 116 */
+ {
+ {3, 0x02, 182},
+ {4, 0x02, 182},
+ {7, 0x02, 182},
+ {10, 0x02, 182},
+ {16, 0x02, 182},
+ {23, 0x02, 182},
+ {31, 0x02, 182},
+ {44, 0x03, 182},
+ {3, 0x02, 183},
+ {4, 0x02, 183},
+ {7, 0x02, 183},
+ {10, 0x02, 183},
+ {16, 0x02, 183},
+ {23, 0x02, 183},
+ {31, 0x02, 183},
+ {44, 0x03, 183},
+ },
+ /* 117 */
+ {
+ {2, 0x02, 184},
+ {6, 0x02, 184},
+ {15, 0x02, 184},
+ {30, 0x03, 184},
+ {2, 0x02, 185},
+ {6, 0x02, 185},
+ {15, 0x02, 185},
+ {30, 0x03, 185},
+ {2, 0x02, 186},
+ {6, 0x02, 186},
+ {15, 0x02, 186},
+ {30, 0x03, 186},
+ {2, 0x02, 187},
+ {6, 0x02, 187},
+ {15, 0x02, 187},
+ {30, 0x03, 187},
+ },
+ /* 118 */
+ {
+ {3, 0x02, 184},
+ {4, 0x02, 184},
+ {7, 0x02, 184},
+ {10, 0x02, 184},
+ {16, 0x02, 184},
+ {23, 0x02, 184},
+ {31, 0x02, 184},
+ {44, 0x03, 184},
+ {3, 0x02, 185},
+ {4, 0x02, 185},
+ {7, 0x02, 185},
+ {10, 0x02, 185},
+ {16, 0x02, 185},
+ {23, 0x02, 185},
+ {31, 0x02, 185},
+ {44, 0x03, 185},
+ },
+ /* 119 */
+ {
+ {3, 0x02, 186},
+ {4, 0x02, 186},
+ {7, 0x02, 186},
+ {10, 0x02, 186},
+ {16, 0x02, 186},
+ {23, 0x02, 186},
+ {31, 0x02, 186},
+ {44, 0x03, 186},
+ {3, 0x02, 187},
+ {4, 0x02, 187},
+ {7, 0x02, 187},
+ {10, 0x02, 187},
+ {16, 0x02, 187},
+ {23, 0x02, 187},
+ {31, 0x02, 187},
+ {44, 0x03, 187},
+ },
+ /* 120 */
+ {
+ {1, 0x02, 188},
+ {14, 0x03, 188},
+ {1, 0x02, 189},
+ {14, 0x03, 189},
+ {1, 0x02, 190},
+ {14, 0x03, 190},
+ {1, 0x02, 191},
+ {14, 0x03, 191},
+ {1, 0x02, 192},
+ {14, 0x03, 192},
+ {1, 0x02, 193},
+ {14, 0x03, 193},
+ {1, 0x02, 194},
+ {14, 0x03, 194},
+ {1, 0x02, 195},
+ {14, 0x03, 195},
+ },
+ /* 121 */
+ {
+ {2, 0x02, 188},
+ {6, 0x02, 188},
+ {15, 0x02, 188},
+ {30, 0x03, 188},
+ {2, 0x02, 189},
+ {6, 0x02, 189},
+ {15, 0x02, 189},
+ {30, 0x03, 189},
+ {2, 0x02, 190},
+ {6, 0x02, 190},
+ {15, 0x02, 190},
+ {30, 0x03, 190},
+ {2, 0x02, 191},
+ {6, 0x02, 191},
+ {15, 0x02, 191},
+ {30, 0x03, 191},
+ },
+ /* 122 */
+ {
+ {3, 0x02, 188},
+ {4, 0x02, 188},
+ {7, 0x02, 188},
+ {10, 0x02, 188},
+ {16, 0x02, 188},
+ {23, 0x02, 188},
+ {31, 0x02, 188},
+ {44, 0x03, 188},
+ {3, 0x02, 189},
+ {4, 0x02, 189},
+ {7, 0x02, 189},
+ {10, 0x02, 189},
+ {16, 0x02, 189},
+ {23, 0x02, 189},
+ {31, 0x02, 189},
+ {44, 0x03, 189},
+ },
+ /* 123 */
+ {
+ {3, 0x02, 190},
+ {4, 0x02, 190},
+ {7, 0x02, 190},
+ {10, 0x02, 190},
+ {16, 0x02, 190},
+ {23, 0x02, 190},
+ {31, 0x02, 190},
+ {44, 0x03, 190},
+ {3, 0x02, 191},
+ {4, 0x02, 191},
+ {7, 0x02, 191},
+ {10, 0x02, 191},
+ {16, 0x02, 191},
+ {23, 0x02, 191},
+ {31, 0x02, 191},
+ {44, 0x03, 191},
+ },
+ /* 124 */
+ {
+ {2, 0x02, 192},
+ {6, 0x02, 192},
+ {15, 0x02, 192},
+ {30, 0x03, 192},
+ {2, 0x02, 193},
+ {6, 0x02, 193},
+ {15, 0x02, 193},
+ {30, 0x03, 193},
+ {2, 0x02, 194},
+ {6, 0x02, 194},
+ {15, 0x02, 194},
+ {30, 0x03, 194},
+ {2, 0x02, 195},
+ {6, 0x02, 195},
+ {15, 0x02, 195},
+ {30, 0x03, 195},
+ },
+ /* 125 */
+ {
+ {3, 0x02, 192},
+ {4, 0x02, 192},
+ {7, 0x02, 192},
+ {10, 0x02, 192},
+ {16, 0x02, 192},
+ {23, 0x02, 192},
+ {31, 0x02, 192},
+ {44, 0x03, 192},
+ {3, 0x02, 193},
+ {4, 0x02, 193},
+ {7, 0x02, 193},
+ {10, 0x02, 193},
+ {16, 0x02, 193},
+ {23, 0x02, 193},
+ {31, 0x02, 193},
+ {44, 0x03, 193},
+ },
+ /* 126 */
+ {
+ {3, 0x02, 194},
+ {4, 0x02, 194},
+ {7, 0x02, 194},
+ {10, 0x02, 194},
+ {16, 0x02, 194},
+ {23, 0x02, 194},
+ {31, 0x02, 194},
+ {44, 0x03, 194},
+ {3, 0x02, 195},
+ {4, 0x02, 195},
+ {7, 0x02, 195},
+ {10, 0x02, 195},
+ {16, 0x02, 195},
+ {23, 0x02, 195},
+ {31, 0x02, 195},
+ {44, 0x03, 195},
+ },
+ /* 127 */
+ {
+ {131, 0x00, 0},
+ {132, 0x00, 0},
+ {134, 0x00, 0},
+ {135, 0x00, 0},
+ {138, 0x00, 0},
+ {139, 0x00, 0},
+ {141, 0x00, 0},
+ {142, 0x00, 0},
+ {146, 0x00, 0},
+ {147, 0x00, 0},
+ {149, 0x00, 0},
+ {150, 0x00, 0},
+ {153, 0x00, 0},
+ {154, 0x00, 0},
+ {156, 0x00, 0},
+ {157, 0x00, 0},
+ },
+ /* 128 */
+ {
+ {0, 0x03, 196},
+ {0, 0x03, 197},
+ {0, 0x03, 198},
+ {0, 0x03, 199},
+ {0, 0x03, 200},
+ {0, 0x03, 201},
+ {0, 0x03, 202},
+ {0, 0x03, 203},
+ {0, 0x03, 204},
+ {0, 0x03, 205},
+ {0, 0x03, 206},
+ {0, 0x03, 207},
+ {0, 0x03, 208},
+ {0, 0x03, 209},
+ {0, 0x03, 210},
+ {0, 0x03, 211},
+ },
+ /* 129 */
+ {
+ {1, 0x02, 196},
+ {14, 0x03, 196},
+ {1, 0x02, 197},
+ {14, 0x03, 197},
+ {1, 0x02, 198},
+ {14, 0x03, 198},
+ {1, 0x02, 199},
+ {14, 0x03, 199},
+ {1, 0x02, 200},
+ {14, 0x03, 200},
+ {1, 0x02, 201},
+ {14, 0x03, 201},
+ {1, 0x02, 202},
+ {14, 0x03, 202},
+ {1, 0x02, 203},
+ {14, 0x03, 203},
+ },
+ /* 130 */
+ {
+ {2, 0x02, 196},
+ {6, 0x02, 196},
+ {15, 0x02, 196},
+ {30, 0x03, 196},
+ {2, 0x02, 197},
+ {6, 0x02, 197},
+ {15, 0x02, 197},
+ {30, 0x03, 197},
+ {2, 0x02, 198},
+ {6, 0x02, 198},
+ {15, 0x02, 198},
+ {30, 0x03, 198},
+ {2, 0x02, 199},
+ {6, 0x02, 199},
+ {15, 0x02, 199},
+ {30, 0x03, 199},
+ },
+ /* 131 */
+ {
+ {3, 0x02, 196},
+ {4, 0x02, 196},
+ {7, 0x02, 196},
+ {10, 0x02, 196},
+ {16, 0x02, 196},
+ {23, 0x02, 196},
+ {31, 0x02, 196},
+ {44, 0x03, 196},
+ {3, 0x02, 197},
+ {4, 0x02, 197},
+ {7, 0x02, 197},
+ {10, 0x02, 197},
+ {16, 0x02, 197},
+ {23, 0x02, 197},
+ {31, 0x02, 197},
+ {44, 0x03, 197},
+ },
+ /* 132 */
+ {
+ {3, 0x02, 198},
+ {4, 0x02, 198},
+ {7, 0x02, 198},
+ {10, 0x02, 198},
+ {16, 0x02, 198},
+ {23, 0x02, 198},
+ {31, 0x02, 198},
+ {44, 0x03, 198},
+ {3, 0x02, 199},
+ {4, 0x02, 199},
+ {7, 0x02, 199},
+ {10, 0x02, 199},
+ {16, 0x02, 199},
+ {23, 0x02, 199},
+ {31, 0x02, 199},
+ {44, 0x03, 199},
+ },
+ /* 133 */
+ {
+ {2, 0x02, 200},
+ {6, 0x02, 200},
+ {15, 0x02, 200},
+ {30, 0x03, 200},
+ {2, 0x02, 201},
+ {6, 0x02, 201},
+ {15, 0x02, 201},
+ {30, 0x03, 201},
+ {2, 0x02, 202},
+ {6, 0x02, 202},
+ {15, 0x02, 202},
+ {30, 0x03, 202},
+ {2, 0x02, 203},
+ {6, 0x02, 203},
+ {15, 0x02, 203},
+ {30, 0x03, 203},
+ },
+ /* 134 */
+ {
+ {3, 0x02, 200},
+ {4, 0x02, 200},
+ {7, 0x02, 200},
+ {10, 0x02, 200},
+ {16, 0x02, 200},
+ {23, 0x02, 200},
+ {31, 0x02, 200},
+ {44, 0x03, 200},
+ {3, 0x02, 201},
+ {4, 0x02, 201},
+ {7, 0x02, 201},
+ {10, 0x02, 201},
+ {16, 0x02, 201},
+ {23, 0x02, 201},
+ {31, 0x02, 201},
+ {44, 0x03, 201},
+ },
+ /* 135 */
+ {
+ {3, 0x02, 202},
+ {4, 0x02, 202},
+ {7, 0x02, 202},
+ {10, 0x02, 202},
+ {16, 0x02, 202},
+ {23, 0x02, 202},
+ {31, 0x02, 202},
+ {44, 0x03, 202},
+ {3, 0x02, 203},
+ {4, 0x02, 203},
+ {7, 0x02, 203},
+ {10, 0x02, 203},
+ {16, 0x02, 203},
+ {23, 0x02, 203},
+ {31, 0x02, 203},
+ {44, 0x03, 203},
+ },
+ /* 136 */
+ {
+ {1, 0x02, 204},
+ {14, 0x03, 204},
+ {1, 0x02, 205},
+ {14, 0x03, 205},
+ {1, 0x02, 206},
+ {14, 0x03, 206},
+ {1, 0x02, 207},
+ {14, 0x03, 207},
+ {1, 0x02, 208},
+ {14, 0x03, 208},
+ {1, 0x02, 209},
+ {14, 0x03, 209},
+ {1, 0x02, 210},
+ {14, 0x03, 210},
+ {1, 0x02, 211},
+ {14, 0x03, 211},
+ },
+ /* 137 */
+ {
+ {2, 0x02, 204},
+ {6, 0x02, 204},
+ {15, 0x02, 204},
+ {30, 0x03, 204},
+ {2, 0x02, 205},
+ {6, 0x02, 205},
+ {15, 0x02, 205},
+ {30, 0x03, 205},
+ {2, 0x02, 206},
+ {6, 0x02, 206},
+ {15, 0x02, 206},
+ {30, 0x03, 206},
+ {2, 0x02, 207},
+ {6, 0x02, 207},
+ {15, 0x02, 207},
+ {30, 0x03, 207},
+ },
+ /* 138 */
+ {
+ {3, 0x02, 204},
+ {4, 0x02, 204},
+ {7, 0x02, 204},
+ {10, 0x02, 204},
+ {16, 0x02, 204},
+ {23, 0x02, 204},
+ {31, 0x02, 204},
+ {44, 0x03, 204},
+ {3, 0x02, 205},
+ {4, 0x02, 205},
+ {7, 0x02, 205},
+ {10, 0x02, 205},
+ {16, 0x02, 205},
+ {23, 0x02, 205},
+ {31, 0x02, 205},
+ {44, 0x03, 205},
+ },
+ /* 139 */
+ {
+ {3, 0x02, 206},
+ {4, 0x02, 206},
+ {7, 0x02, 206},
+ {10, 0x02, 206},
+ {16, 0x02, 206},
+ {23, 0x02, 206},
+ {31, 0x02, 206},
+ {44, 0x03, 206},
+ {3, 0x02, 207},
+ {4, 0x02, 207},
+ {7, 0x02, 207},
+ {10, 0x02, 207},
+ {16, 0x02, 207},
+ {23, 0x02, 207},
+ {31, 0x02, 207},
+ {44, 0x03, 207},
+ },
+ /* 140 */
+ {
+ {2, 0x02, 208},
+ {6, 0x02, 208},
+ {15, 0x02, 208},
+ {30, 0x03, 208},
+ {2, 0x02, 209},
+ {6, 0x02, 209},
+ {15, 0x02, 209},
+ {30, 0x03, 209},
+ {2, 0x02, 210},
+ {6, 0x02, 210},
+ {15, 0x02, 210},
+ {30, 0x03, 210},
+ {2, 0x02, 211},
+ {6, 0x02, 211},
+ {15, 0x02, 211},
+ {30, 0x03, 211},
+ },
+ /* 141 */
+ {
+ {3, 0x02, 208},
+ {4, 0x02, 208},
+ {7, 0x02, 208},
+ {10, 0x02, 208},
+ {16, 0x02, 208},
+ {23, 0x02, 208},
+ {31, 0x02, 208},
+ {44, 0x03, 208},
+ {3, 0x02, 209},
+ {4, 0x02, 209},
+ {7, 0x02, 209},
+ {10, 0x02, 209},
+ {16, 0x02, 209},
+ {23, 0x02, 209},
+ {31, 0x02, 209},
+ {44, 0x03, 209},
+ },
+ /* 142 */
+ {
+ {3, 0x02, 210},
+ {4, 0x02, 210},
+ {7, 0x02, 210},
+ {10, 0x02, 210},
+ {16, 0x02, 210},
+ {23, 0x02, 210},
+ {31, 0x02, 210},
+ {44, 0x03, 210},
+ {3, 0x02, 211},
+ {4, 0x02, 211},
+ {7, 0x02, 211},
+ {10, 0x02, 211},
+ {16, 0x02, 211},
+ {23, 0x02, 211},
+ {31, 0x02, 211},
+ {44, 0x03, 211},
+ },
+ /* 143 */
+ {
+ {0, 0x03, 212},
+ {0, 0x03, 213},
+ {0, 0x03, 214},
+ {0, 0x03, 215},
+ {0, 0x03, 216},
+ {0, 0x03, 217},
+ {0, 0x03, 218},
+ {0, 0x03, 219},
+ {0, 0x03, 220},
+ {0, 0x03, 221},
+ {0, 0x03, 222},
+ {0, 0x03, 223},
+ {0, 0x03, 224},
+ {0, 0x03, 225},
+ {0, 0x03, 226},
+ {0, 0x03, 227},
+ },
+ /* 144 */
+ {
+ {1, 0x02, 212},
+ {14, 0x03, 212},
+ {1, 0x02, 213},
+ {14, 0x03, 213},
+ {1, 0x02, 214},
+ {14, 0x03, 214},
+ {1, 0x02, 215},
+ {14, 0x03, 215},
+ {1, 0x02, 216},
+ {14, 0x03, 216},
+ {1, 0x02, 217},
+ {14, 0x03, 217},
+ {1, 0x02, 218},
+ {14, 0x03, 218},
+ {1, 0x02, 219},
+ {14, 0x03, 219},
+ },
+ /* 145 */
+ {
+ {2, 0x02, 212},
+ {6, 0x02, 212},
+ {15, 0x02, 212},
+ {30, 0x03, 212},
+ {2, 0x02, 213},
+ {6, 0x02, 213},
+ {15, 0x02, 213},
+ {30, 0x03, 213},
+ {2, 0x02, 214},
+ {6, 0x02, 214},
+ {15, 0x02, 214},
+ {30, 0x03, 214},
+ {2, 0x02, 215},
+ {6, 0x02, 215},
+ {15, 0x02, 215},
+ {30, 0x03, 215},
+ },
+ /* 146 */
+ {
+ {3, 0x02, 212},
+ {4, 0x02, 212},
+ {7, 0x02, 212},
+ {10, 0x02, 212},
+ {16, 0x02, 212},
+ {23, 0x02, 212},
+ {31, 0x02, 212},
+ {44, 0x03, 212},
+ {3, 0x02, 213},
+ {4, 0x02, 213},
+ {7, 0x02, 213},
+ {10, 0x02, 213},
+ {16, 0x02, 213},
+ {23, 0x02, 213},
+ {31, 0x02, 213},
+ {44, 0x03, 213},
+ },
+ /* 147 */
+ {
+ {3, 0x02, 214},
+ {4, 0x02, 214},
+ {7, 0x02, 214},
+ {10, 0x02, 214},
+ {16, 0x02, 214},
+ {23, 0x02, 214},
+ {31, 0x02, 214},
+ {44, 0x03, 214},
+ {3, 0x02, 215},
+ {4, 0x02, 215},
+ {7, 0x02, 215},
+ {10, 0x02, 215},
+ {16, 0x02, 215},
+ {23, 0x02, 215},
+ {31, 0x02, 215},
+ {44, 0x03, 215},
+ },
+ /* 148 */
+ {
+ {2, 0x02, 216},
+ {6, 0x02, 216},
+ {15, 0x02, 216},
+ {30, 0x03, 216},
+ {2, 0x02, 217},
+ {6, 0x02, 217},
+ {15, 0x02, 217},
+ {30, 0x03, 217},
+ {2, 0x02, 218},
+ {6, 0x02, 218},
+ {15, 0x02, 218},
+ {30, 0x03, 218},
+ {2, 0x02, 219},
+ {6, 0x02, 219},
+ {15, 0x02, 219},
+ {30, 0x03, 219},
+ },
+ /* 149 */
+ {
+ {3, 0x02, 216},
+ {4, 0x02, 216},
+ {7, 0x02, 216},
+ {10, 0x02, 216},
+ {16, 0x02, 216},
+ {23, 0x02, 216},
+ {31, 0x02, 216},
+ {44, 0x03, 216},
+ {3, 0x02, 217},
+ {4, 0x02, 217},
+ {7, 0x02, 217},
+ {10, 0x02, 217},
+ {16, 0x02, 217},
+ {23, 0x02, 217},
+ {31, 0x02, 217},
+ {44, 0x03, 217},
+ },
+ /* 150 */
+ {
+ {3, 0x02, 218},
+ {4, 0x02, 218},
+ {7, 0x02, 218},
+ {10, 0x02, 218},
+ {16, 0x02, 218},
+ {23, 0x02, 218},
+ {31, 0x02, 218},
+ {44, 0x03, 218},
+ {3, 0x02, 219},
+ {4, 0x02, 219},
+ {7, 0x02, 219},
+ {10, 0x02, 219},
+ {16, 0x02, 219},
+ {23, 0x02, 219},
+ {31, 0x02, 219},
+ {44, 0x03, 219},
+ },
+ /* 151 */
+ {
+ {1, 0x02, 220},
+ {14, 0x03, 220},
+ {1, 0x02, 221},
+ {14, 0x03, 221},
+ {1, 0x02, 222},
+ {14, 0x03, 222},
+ {1, 0x02, 223},
+ {14, 0x03, 223},
+ {1, 0x02, 224},
+ {14, 0x03, 224},
+ {1, 0x02, 225},
+ {14, 0x03, 225},
+ {1, 0x02, 226},
+ {14, 0x03, 226},
+ {1, 0x02, 227},
+ {14, 0x03, 227},
+ },
+ /* 152 */
+ {
+ {2, 0x02, 220},
+ {6, 0x02, 220},
+ {15, 0x02, 220},
+ {30, 0x03, 220},
+ {2, 0x02, 221},
+ {6, 0x02, 221},
+ {15, 0x02, 221},
+ {30, 0x03, 221},
+ {2, 0x02, 222},
+ {6, 0x02, 222},
+ {15, 0x02, 222},
+ {30, 0x03, 222},
+ {2, 0x02, 223},
+ {6, 0x02, 223},
+ {15, 0x02, 223},
+ {30, 0x03, 223},
+ },
+ /* 153 */
+ {
+ {3, 0x02, 220},
+ {4, 0x02, 220},
+ {7, 0x02, 220},
+ {10, 0x02, 220},
+ {16, 0x02, 220},
+ {23, 0x02, 220},
+ {31, 0x02, 220},
+ {44, 0x03, 220},
+ {3, 0x02, 221},
+ {4, 0x02, 221},
+ {7, 0x02, 221},
+ {10, 0x02, 221},
+ {16, 0x02, 221},
+ {23, 0x02, 221},
+ {31, 0x02, 221},
+ {44, 0x03, 221},
+ },
+ /* 154 */
+ {
+ {3, 0x02, 222},
+ {4, 0x02, 222},
+ {7, 0x02, 222},
+ {10, 0x02, 222},
+ {16, 0x02, 222},
+ {23, 0x02, 222},
+ {31, 0x02, 222},
+ {44, 0x03, 222},
+ {3, 0x02, 223},
+ {4, 0x02, 223},
+ {7, 0x02, 223},
+ {10, 0x02, 223},
+ {16, 0x02, 223},
+ {23, 0x02, 223},
+ {31, 0x02, 223},
+ {44, 0x03, 223},
+ },
+ /* 155 */
+ {
+ {2, 0x02, 224},
+ {6, 0x02, 224},
+ {15, 0x02, 224},
+ {30, 0x03, 224},
+ {2, 0x02, 225},
+ {6, 0x02, 225},
+ {15, 0x02, 225},
+ {30, 0x03, 225},
+ {2, 0x02, 226},
+ {6, 0x02, 226},
+ {15, 0x02, 226},
+ {30, 0x03, 226},
+ {2, 0x02, 227},
+ {6, 0x02, 227},
+ {15, 0x02, 227},
+ {30, 0x03, 227},
+ },
+ /* 156 */
+ {
+ {3, 0x02, 224},
+ {4, 0x02, 224},
+ {7, 0x02, 224},
+ {10, 0x02, 224},
+ {16, 0x02, 224},
+ {23, 0x02, 224},
+ {31, 0x02, 224},
+ {44, 0x03, 224},
+ {3, 0x02, 225},
+ {4, 0x02, 225},
+ {7, 0x02, 225},
+ {10, 0x02, 225},
+ {16, 0x02, 225},
+ {23, 0x02, 225},
+ {31, 0x02, 225},
+ {44, 0x03, 225},
+ },
+ /* 157 */
+ {
+ {3, 0x02, 226},
+ {4, 0x02, 226},
+ {7, 0x02, 226},
+ {10, 0x02, 226},
+ {16, 0x02, 226},
+ {23, 0x02, 226},
+ {31, 0x02, 226},
+ {44, 0x03, 226},
+ {3, 0x02, 227},
+ {4, 0x02, 227},
+ {7, 0x02, 227},
+ {10, 0x02, 227},
+ {16, 0x02, 227},
+ {23, 0x02, 227},
+ {31, 0x02, 227},
+ {44, 0x03, 227},
+ },
+ /* 158 */
+ {
+ {162, 0x00, 0},
+ {165, 0x00, 0},
+ {169, 0x00, 0},
+ {172, 0x00, 0},
+ {177, 0x00, 0},
+ {180, 0x00, 0},
+ {184, 0x00, 0},
+ {187, 0x00, 0},
+ {196, 0x00, 0},
+ {203, 0x00, 0},
+ {211, 0x00, 0},
+ {218, 0x00, 0},
+ {227, 0x00, 0},
+ {234, 0x00, 0},
+ {242, 0x00, 0},
+ {249, 0x00, 0},
+ },
+ /* 159 */
+ {
+ {163, 0x00, 0},
+ {164, 0x00, 0},
+ {166, 0x00, 0},
+ {167, 0x00, 0},
+ {170, 0x00, 0},
+ {171, 0x00, 0},
+ {173, 0x00, 0},
+ {174, 0x00, 0},
+ {178, 0x00, 0},
+ {179, 0x00, 0},
+ {181, 0x00, 0},
+ {182, 0x00, 0},
+ {185, 0x00, 0},
+ {186, 0x00, 0},
+ {188, 0x00, 0},
+ {190, 0x00, 0},
+ },
+ /* 160 */
+ {
+ {0, 0x03, 228},
+ {0, 0x03, 229},
+ {0, 0x03, 230},
+ {0, 0x03, 231},
+ {0, 0x03, 232},
+ {0, 0x03, 233},
+ {0, 0x03, 234},
+ {0, 0x03, 235},
+ {0, 0x03, 236},
+ {0, 0x03, 237},
+ {0, 0x03, 238},
+ {0, 0x03, 239},
+ {0, 0x03, 240},
+ {0, 0x03, 241},
+ {0, 0x03, 242},
+ {0, 0x03, 243},
+ },
+ /* 161 */
+ {
+ {1, 0x02, 228},
+ {14, 0x03, 228},
+ {1, 0x02, 229},
+ {14, 0x03, 229},
+ {1, 0x02, 230},
+ {14, 0x03, 230},
+ {1, 0x02, 231},
+ {14, 0x03, 231},
+ {1, 0x02, 232},
+ {14, 0x03, 232},
+ {1, 0x02, 233},
+ {14, 0x03, 233},
+ {1, 0x02, 234},
+ {14, 0x03, 234},
+ {1, 0x02, 235},
+ {14, 0x03, 235},
+ },
+ /* 162 */
+ {
+ {2, 0x02, 228},
+ {6, 0x02, 228},
+ {15, 0x02, 228},
+ {30, 0x03, 228},
+ {2, 0x02, 229},
+ {6, 0x02, 229},
+ {15, 0x02, 229},
+ {30, 0x03, 229},
+ {2, 0x02, 230},
+ {6, 0x02, 230},
+ {15, 0x02, 230},
+ {30, 0x03, 230},
+ {2, 0x02, 231},
+ {6, 0x02, 231},
+ {15, 0x02, 231},
+ {30, 0x03, 231},
+ },
+ /* 163 */
+ {
+ {3, 0x02, 228},
+ {4, 0x02, 228},
+ {7, 0x02, 228},
+ {10, 0x02, 228},
+ {16, 0x02, 228},
+ {23, 0x02, 228},
+ {31, 0x02, 228},
+ {44, 0x03, 228},
+ {3, 0x02, 229},
+ {4, 0x02, 229},
+ {7, 0x02, 229},
+ {10, 0x02, 229},
+ {16, 0x02, 229},
+ {23, 0x02, 229},
+ {31, 0x02, 229},
+ {44, 0x03, 229},
+ },
+ /* 164 */
+ {
+ {3, 0x02, 230},
+ {4, 0x02, 230},
+ {7, 0x02, 230},
+ {10, 0x02, 230},
+ {16, 0x02, 230},
+ {23, 0x02, 230},
+ {31, 0x02, 230},
+ {44, 0x03, 230},
+ {3, 0x02, 231},
+ {4, 0x02, 231},
+ {7, 0x02, 231},
+ {10, 0x02, 231},
+ {16, 0x02, 231},
+ {23, 0x02, 231},
+ {31, 0x02, 231},
+ {44, 0x03, 231},
+ },
+ /* 165 */
+ {
+ {2, 0x02, 232},
+ {6, 0x02, 232},
+ {15, 0x02, 232},
+ {30, 0x03, 232},
+ {2, 0x02, 233},
+ {6, 0x02, 233},
+ {15, 0x02, 233},
+ {30, 0x03, 233},
+ {2, 0x02, 234},
+ {6, 0x02, 234},
+ {15, 0x02, 234},
+ {30, 0x03, 234},
+ {2, 0x02, 235},
+ {6, 0x02, 235},
+ {15, 0x02, 235},
+ {30, 0x03, 235},
+ },
+ /* 166 */
+ {
+ {3, 0x02, 232},
+ {4, 0x02, 232},
+ {7, 0x02, 232},
+ {10, 0x02, 232},
+ {16, 0x02, 232},
+ {23, 0x02, 232},
+ {31, 0x02, 232},
+ {44, 0x03, 232},
+ {3, 0x02, 233},
+ {4, 0x02, 233},
+ {7, 0x02, 233},
+ {10, 0x02, 233},
+ {16, 0x02, 233},
+ {23, 0x02, 233},
+ {31, 0x02, 233},
+ {44, 0x03, 233},
+ },
+ /* 167 */
+ {
+ {3, 0x02, 234},
+ {4, 0x02, 234},
+ {7, 0x02, 234},
+ {10, 0x02, 234},
+ {16, 0x02, 234},
+ {23, 0x02, 234},
+ {31, 0x02, 234},
+ {44, 0x03, 234},
+ {3, 0x02, 235},
+ {4, 0x02, 235},
+ {7, 0x02, 235},
+ {10, 0x02, 235},
+ {16, 0x02, 235},
+ {23, 0x02, 235},
+ {31, 0x02, 235},
+ {44, 0x03, 235},
+ },
+ /* 168 */
+ {
+ {1, 0x02, 236},
+ {14, 0x03, 236},
+ {1, 0x02, 237},
+ {14, 0x03, 237},
+ {1, 0x02, 238},
+ {14, 0x03, 238},
+ {1, 0x02, 239},
+ {14, 0x03, 239},
+ {1, 0x02, 240},
+ {14, 0x03, 240},
+ {1, 0x02, 241},
+ {14, 0x03, 241},
+ {1, 0x02, 242},
+ {14, 0x03, 242},
+ {1, 0x02, 243},
+ {14, 0x03, 243},
+ },
+ /* 169 */
+ {
+ {2, 0x02, 236},
+ {6, 0x02, 236},
+ {15, 0x02, 236},
+ {30, 0x03, 236},
+ {2, 0x02, 237},
+ {6, 0x02, 237},
+ {15, 0x02, 237},
+ {30, 0x03, 237},
+ {2, 0x02, 238},
+ {6, 0x02, 238},
+ {15, 0x02, 238},
+ {30, 0x03, 238},
+ {2, 0x02, 239},
+ {6, 0x02, 239},
+ {15, 0x02, 239},
+ {30, 0x03, 239},
+ },
+ /* 170 */
+ {
+ {3, 0x02, 236},
+ {4, 0x02, 236},
+ {7, 0x02, 236},
+ {10, 0x02, 236},
+ {16, 0x02, 236},
+ {23, 0x02, 236},
+ {31, 0x02, 236},
+ {44, 0x03, 236},
+ {3, 0x02, 237},
+ {4, 0x02, 237},
+ {7, 0x02, 237},
+ {10, 0x02, 237},
+ {16, 0x02, 237},
+ {23, 0x02, 237},
+ {31, 0x02, 237},
+ {44, 0x03, 237},
+ },
+ /* 171 */
+ {
+ {3, 0x02, 238},
+ {4, 0x02, 238},
+ {7, 0x02, 238},
+ {10, 0x02, 238},
+ {16, 0x02, 238},
+ {23, 0x02, 238},
+ {31, 0x02, 238},
+ {44, 0x03, 238},
+ {3, 0x02, 239},
+ {4, 0x02, 239},
+ {7, 0x02, 239},
+ {10, 0x02, 239},
+ {16, 0x02, 239},
+ {23, 0x02, 239},
+ {31, 0x02, 239},
+ {44, 0x03, 239},
+ },
+ /* 172 */
+ {
+ {2, 0x02, 240},
+ {6, 0x02, 240},
+ {15, 0x02, 240},
+ {30, 0x03, 240},
+ {2, 0x02, 241},
+ {6, 0x02, 241},
+ {15, 0x02, 241},
+ {30, 0x03, 241},
+ {2, 0x02, 242},
+ {6, 0x02, 242},
+ {15, 0x02, 242},
+ {30, 0x03, 242},
+ {2, 0x02, 243},
+ {6, 0x02, 243},
+ {15, 0x02, 243},
+ {30, 0x03, 243},
+ },
+ /* 173 */
+ {
+ {3, 0x02, 240},
+ {4, 0x02, 240},
+ {7, 0x02, 240},
+ {10, 0x02, 240},
+ {16, 0x02, 240},
+ {23, 0x02, 240},
+ {31, 0x02, 240},
+ {44, 0x03, 240},
+ {3, 0x02, 241},
+ {4, 0x02, 241},
+ {7, 0x02, 241},
+ {10, 0x02, 241},
+ {16, 0x02, 241},
+ {23, 0x02, 241},
+ {31, 0x02, 241},
+ {44, 0x03, 241},
+ },
+ /* 174 */
+ {
+ {3, 0x02, 242},
+ {4, 0x02, 242},
+ {7, 0x02, 242},
+ {10, 0x02, 242},
+ {16, 0x02, 242},
+ {23, 0x02, 242},
+ {31, 0x02, 242},
+ {44, 0x03, 242},
+ {3, 0x02, 243},
+ {4, 0x02, 243},
+ {7, 0x02, 243},
+ {10, 0x02, 243},
+ {16, 0x02, 243},
+ {23, 0x02, 243},
+ {31, 0x02, 243},
+ {44, 0x03, 243},
+ },
+ /* 175 */
+ {
+ {0, 0x03, 244},
+ {0, 0x03, 245},
+ {0, 0x03, 246},
+ {0, 0x03, 247},
+ {0, 0x03, 248},
+ {0, 0x03, 249},
+ {0, 0x03, 250},
+ {0, 0x03, 251},
+ {0, 0x03, 252},
+ {0, 0x03, 253},
+ {0, 0x03, 254},
+ {0, 0x03, 255},
+ {-1, 0x00, 0},
+ {189, 0x00, 0},
+ {191, 0x00, 0},
+ {192, 0x00, 0},
+ },
+ /* 176 */
+ {
+ {1, 0x02, 244},
+ {14, 0x03, 244},
+ {1, 0x02, 245},
+ {14, 0x03, 245},
+ {1, 0x02, 246},
+ {14, 0x03, 246},
+ {1, 0x02, 247},
+ {14, 0x03, 247},
+ {1, 0x02, 248},
+ {14, 0x03, 248},
+ {1, 0x02, 249},
+ {14, 0x03, 249},
+ {1, 0x02, 250},
+ {14, 0x03, 250},
+ {1, 0x02, 251},
+ {14, 0x03, 251},
+ },
+ /* 177 */
+ {
+ {2, 0x02, 244},
+ {6, 0x02, 244},
+ {15, 0x02, 244},
+ {30, 0x03, 244},
+ {2, 0x02, 245},
+ {6, 0x02, 245},
+ {15, 0x02, 245},
+ {30, 0x03, 245},
+ {2, 0x02, 246},
+ {6, 0x02, 246},
+ {15, 0x02, 246},
+ {30, 0x03, 246},
+ {2, 0x02, 247},
+ {6, 0x02, 247},
+ {15, 0x02, 247},
+ {30, 0x03, 247},
+ },
+ /* 178 */
+ {
+ {3, 0x02, 244},
+ {4, 0x02, 244},
+ {7, 0x02, 244},
+ {10, 0x02, 244},
+ {16, 0x02, 244},
+ {23, 0x02, 244},
+ {31, 0x02, 244},
+ {44, 0x03, 244},
+ {3, 0x02, 245},
+ {4, 0x02, 245},
+ {7, 0x02, 245},
+ {10, 0x02, 245},
+ {16, 0x02, 245},
+ {23, 0x02, 245},
+ {31, 0x02, 245},
+ {44, 0x03, 245},
+ },
+ /* 179 */
+ {
+ {3, 0x02, 246},
+ {4, 0x02, 246},
+ {7, 0x02, 246},
+ {10, 0x02, 246},
+ {16, 0x02, 246},
+ {23, 0x02, 246},
+ {31, 0x02, 246},
+ {44, 0x03, 246},
+ {3, 0x02, 247},
+ {4, 0x02, 247},
+ {7, 0x02, 247},
+ {10, 0x02, 247},
+ {16, 0x02, 247},
+ {23, 0x02, 247},
+ {31, 0x02, 247},
+ {44, 0x03, 247},
+ },
+ /* 180 */
+ {
+ {2, 0x02, 248},
+ {6, 0x02, 248},
+ {15, 0x02, 248},
+ {30, 0x03, 248},
+ {2, 0x02, 249},
+ {6, 0x02, 249},
+ {15, 0x02, 249},
+ {30, 0x03, 249},
+ {2, 0x02, 250},
+ {6, 0x02, 250},
+ {15, 0x02, 250},
+ {30, 0x03, 250},
+ {2, 0x02, 251},
+ {6, 0x02, 251},
+ {15, 0x02, 251},
+ {30, 0x03, 251},
+ },
+ /* 181 */
+ {
+ {3, 0x02, 248},
+ {4, 0x02, 248},
+ {7, 0x02, 248},
+ {10, 0x02, 248},
+ {16, 0x02, 248},
+ {23, 0x02, 248},
+ {31, 0x02, 248},
+ {44, 0x03, 248},
+ {3, 0x02, 249},
+ {4, 0x02, 249},
+ {7, 0x02, 249},
+ {10, 0x02, 249},
+ {16, 0x02, 249},
+ {23, 0x02, 249},
+ {31, 0x02, 249},
+ {44, 0x03, 249},
+ },
+ /* 182 */
+ {
+ {3, 0x02, 250},
+ {4, 0x02, 250},
+ {7, 0x02, 250},
+ {10, 0x02, 250},
+ {16, 0x02, 250},
+ {23, 0x02, 250},
+ {31, 0x02, 250},
+ {44, 0x03, 250},
+ {3, 0x02, 251},
+ {4, 0x02, 251},
+ {7, 0x02, 251},
+ {10, 0x02, 251},
+ {16, 0x02, 251},
+ {23, 0x02, 251},
+ {31, 0x02, 251},
+ {44, 0x03, 251},
+ },
+ /* 183 */
+ {
+ {1, 0x02, 252},
+ {14, 0x03, 252},
+ {1, 0x02, 253},
+ {14, 0x03, 253},
+ {1, 0x02, 254},
+ {14, 0x03, 254},
+ {1, 0x02, 255},
+ {14, 0x03, 255},
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {0, 0x03, 0},
+ {0, 0x03, 1},
+ {0, 0x03, 2},
+ {0, 0x03, 3},
+ {0, 0x03, 4},
+ {0, 0x03, 5},
+ },
+ /* 184 */
+ {
+ {2, 0x02, 252},
+ {6, 0x02, 252},
+ {15, 0x02, 252},
+ {30, 0x03, 252},
+ {2, 0x02, 253},
+ {6, 0x02, 253},
+ {15, 0x02, 253},
+ {30, 0x03, 253},
+ {2, 0x02, 254},
+ {6, 0x02, 254},
+ {15, 0x02, 254},
+ {30, 0x03, 254},
+ {2, 0x02, 255},
+ {6, 0x02, 255},
+ {15, 0x02, 255},
+ {30, 0x03, 255},
+ },
+ /* 185 */
+ {
+ {3, 0x02, 252},
+ {4, 0x02, 252},
+ {7, 0x02, 252},
+ {10, 0x02, 252},
+ {16, 0x02, 252},
+ {23, 0x02, 252},
+ {31, 0x02, 252},
+ {44, 0x03, 252},
+ {3, 0x02, 253},
+ {4, 0x02, 253},
+ {7, 0x02, 253},
+ {10, 0x02, 253},
+ {16, 0x02, 253},
+ {23, 0x02, 253},
+ {31, 0x02, 253},
+ {44, 0x03, 253},
+ },
+ /* 186 */
+ {
+ {3, 0x02, 254},
+ {4, 0x02, 254},
+ {7, 0x02, 254},
+ {10, 0x02, 254},
+ {16, 0x02, 254},
+ {23, 0x02, 254},
+ {31, 0x02, 254},
+ {44, 0x03, 254},
+ {3, 0x02, 255},
+ {4, 0x02, 255},
+ {7, 0x02, 255},
+ {10, 0x02, 255},
+ {16, 0x02, 255},
+ {23, 0x02, 255},
+ {31, 0x02, 255},
+ {44, 0x03, 255},
+ },
+ /* 187 */
+ {
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {1, 0x02, 0},
+ {14, 0x03, 0},
+ {1, 0x02, 1},
+ {14, 0x03, 1},
+ {1, 0x02, 2},
+ {14, 0x03, 2},
+ {1, 0x02, 3},
+ {14, 0x03, 3},
+ {1, 0x02, 4},
+ {14, 0x03, 4},
+ {1, 0x02, 5},
+ {14, 0x03, 5},
+ },
+ /* 188 */
+ {
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {-1, 0x00, 0},
+ {2, 0x02, 0},
+ {6, 0x02, 0},
+ {15, 0x02, 0},
+ {30, 0x03, 0},
+ {2, 0x02, 1},
+ {6, 0x02, 1},
+ {15, 0x02, 1},
+ {30, 0x03, 1},
+ },
+ /* 189 */
+ {
+ {3, 0x02, 0},
+ {4, 0x02, 0},
+ {7, 0x02, 0},
+ {10, 0x02, 0},
+ {16, 0x02, 0},
+ {23, 0x02, 0},
+ {31, 0x02, 0},
+ {44, 0x03, 0},
+ {3, 0x02, 1},
+ {4, 0x02, 1},
+ {7, 0x02, 1},
+ {10, 0x02, 1},
+ {16, 0x02, 1},
+ {23, 0x02, 1},
+ {31, 0x02, 1},
+ {44, 0x03, 1},
+ },
+ /* 190 */
+ {
+ {2, 0x02, 2},
+ {6, 0x02, 2},
+ {15, 0x02, 2},
+ {30, 0x03, 2},
+ {2, 0x02, 3},
+ {6, 0x02, 3},
+ {15, 0x02, 3},
+ {30, 0x03, 3},
+ {2, 0x02, 4},
+ {6, 0x02, 4},
+ {15, 0x02, 4},
+ {30, 0x03, 4},
+ {2, 0x02, 5},
+ {6, 0x02, 5},
+ {15, 0x02, 5},
+ {30, 0x03, 5},
+ },
+ /* 191 */
+ {
+ {3, 0x02, 2},
+ {4, 0x02, 2},
+ {7, 0x02, 2},
+ {10, 0x02, 2},
+ {16, 0x02, 2},
+ {23, 0x02, 2},
+ {31, 0x02, 2},
+ {44, 0x03, 2},
+ {3, 0x02, 3},
+ {4, 0x02, 3},
+ {7, 0x02, 3},
+ {10, 0x02, 3},
+ {16, 0x02, 3},
+ {23, 0x02, 3},
+ {31, 0x02, 3},
+ {44, 0x03, 3},
+ },
+ /* 192 */
+ {
+ {3, 0x02, 4},
+ {4, 0x02, 4},
+ {7, 0x02, 4},
+ {10, 0x02, 4},
+ {16, 0x02, 4},
+ {23, 0x02, 4},
+ {31, 0x02, 4},
+ {44, 0x03, 4},
+ {3, 0x02, 5},
+ {4, 0x02, 5},
+ {7, 0x02, 5},
+ {10, 0x02, 5},
+ {16, 0x02, 5},
+ {23, 0x02, 5},
+ {31, 0x02, 5},
+ {44, 0x03, 5},
+ },
+ /* 193 */
+ {
+ {197, 0x00, 0},
+ {200, 0x00, 0},
+ {204, 0x00, 0},
+ {207, 0x00, 0},
+ {212, 0x00, 0},
+ {215, 0x00, 0},
+ {219, 0x00, 0},
+ {222, 0x00, 0},
+ {228, 0x00, 0},
+ {231, 0x00, 0},
+ {235, 0x00, 0},
+ {238, 0x00, 0},
+ {243, 0x00, 0},
+ {246, 0x00, 0},
+ {250, 0x00, 0},
+ {253, 0x00, 0},
+ },
+ /* 194 */
+ {
+ {198, 0x00, 0},
+ {199, 0x00, 0},
+ {201, 0x00, 0},
+ {202, 0x00, 0},
+ {205, 0x00, 0},
+ {206, 0x00, 0},
+ {208, 0x00, 0},
+ {209, 0x00, 0},
+ {213, 0x00, 0},
+ {214, 0x00, 0},
+ {216, 0x00, 0},
+ {217, 0x00, 0},
+ {220, 0x00, 0},
+ {221, 0x00, 0},
+ {223, 0x00, 0},
+ {224, 0x00, 0},
+ },
+ /* 195 */
+ {
+ {0, 0x03, 6},
+ {0, 0x03, 7},
+ {0, 0x03, 8},
+ {0, 0x03, 9},
+ {0, 0x03, 10},
+ {0, 0x03, 11},
+ {0, 0x03, 12},
+ {0, 0x03, 13},
+ {0, 0x03, 14},
+ {0, 0x03, 15},
+ {0, 0x03, 16},
+ {0, 0x03, 17},
+ {0, 0x03, 18},
+ {0, 0x03, 19},
+ {0, 0x03, 20},
+ {0, 0x03, 21},
+ },
+ /* 196 */
+ {
+ {1, 0x02, 6},
+ {14, 0x03, 6},
+ {1, 0x02, 7},
+ {14, 0x03, 7},
+ {1, 0x02, 8},
+ {14, 0x03, 8},
+ {1, 0x02, 9},
+ {14, 0x03, 9},
+ {1, 0x02, 10},
+ {14, 0x03, 10},
+ {1, 0x02, 11},
+ {14, 0x03, 11},
+ {1, 0x02, 12},
+ {14, 0x03, 12},
+ {1, 0x02, 13},
+ {14, 0x03, 13},
+ },
+ /* 197 */
+ {
+ {2, 0x02, 6},
+ {6, 0x02, 6},
+ {15, 0x02, 6},
+ {30, 0x03, 6},
+ {2, 0x02, 7},
+ {6, 0x02, 7},
+ {15, 0x02, 7},
+ {30, 0x03, 7},
+ {2, 0x02, 8},
+ {6, 0x02, 8},
+ {15, 0x02, 8},
+ {30, 0x03, 8},
+ {2, 0x02, 9},
+ {6, 0x02, 9},
+ {15, 0x02, 9},
+ {30, 0x03, 9},
+ },
+ /* 198 */
+ {
+ {3, 0x02, 6},
+ {4, 0x02, 6},
+ {7, 0x02, 6},
+ {10, 0x02, 6},
+ {16, 0x02, 6},
+ {23, 0x02, 6},
+ {31, 0x02, 6},
+ {44, 0x03, 6},
+ {3, 0x02, 7},
+ {4, 0x02, 7},
+ {7, 0x02, 7},
+ {10, 0x02, 7},
+ {16, 0x02, 7},
+ {23, 0x02, 7},
+ {31, 0x02, 7},
+ {44, 0x03, 7},
+ },
+ /* 199 */
+ {
+ {3, 0x02, 8},
+ {4, 0x02, 8},
+ {7, 0x02, 8},
+ {10, 0x02, 8},
+ {16, 0x02, 8},
+ {23, 0x02, 8},
+ {31, 0x02, 8},
+ {44, 0x03, 8},
+ {3, 0x02, 9},
+ {4, 0x02, 9},
+ {7, 0x02, 9},
+ {10, 0x02, 9},
+ {16, 0x02, 9},
+ {23, 0x02, 9},
+ {31, 0x02, 9},
+ {44, 0x03, 9},
+ },
+ /* 200 */
+ {
+ {2, 0x02, 10},
+ {6, 0x02, 10},
+ {15, 0x02, 10},
+ {30, 0x03, 10},
+ {2, 0x02, 11},
+ {6, 0x02, 11},
+ {15, 0x02, 11},
+ {30, 0x03, 11},
+ {2, 0x02, 12},
+ {6, 0x02, 12},
+ {15, 0x02, 12},
+ {30, 0x03, 12},
+ {2, 0x02, 13},
+ {6, 0x02, 13},
+ {15, 0x02, 13},
+ {30, 0x03, 13},
+ },
+ /* 201 */
+ {
+ {3, 0x02, 10},
+ {4, 0x02, 10},
+ {7, 0x02, 10},
+ {10, 0x02, 10},
+ {16, 0x02, 10},
+ {23, 0x02, 10},
+ {31, 0x02, 10},
+ {44, 0x03, 10},
+ {3, 0x02, 11},
+ {4, 0x02, 11},
+ {7, 0x02, 11},
+ {10, 0x02, 11},
+ {16, 0x02, 11},
+ {23, 0x02, 11},
+ {31, 0x02, 11},
+ {44, 0x03, 11},
+ },
+ /* 202 */
+ {
+ {3, 0x02, 12},
+ {4, 0x02, 12},
+ {7, 0x02, 12},
+ {10, 0x02, 12},
+ {16, 0x02, 12},
+ {23, 0x02, 12},
+ {31, 0x02, 12},
+ {44, 0x03, 12},
+ {3, 0x02, 13},
+ {4, 0x02, 13},
+ {7, 0x02, 13},
+ {10, 0x02, 13},
+ {16, 0x02, 13},
+ {23, 0x02, 13},
+ {31, 0x02, 13},
+ {44, 0x03, 13},
+ },
+ /* 203 */
+ {
+ {1, 0x02, 14},
+ {14, 0x03, 14},
+ {1, 0x02, 15},
+ {14, 0x03, 15},
+ {1, 0x02, 16},
+ {14, 0x03, 16},
+ {1, 0x02, 17},
+ {14, 0x03, 17},
+ {1, 0x02, 18},
+ {14, 0x03, 18},
+ {1, 0x02, 19},
+ {14, 0x03, 19},
+ {1, 0x02, 20},
+ {14, 0x03, 20},
+ {1, 0x02, 21},
+ {14, 0x03, 21},
+ },
+ /* 204 */
+ {
+ {2, 0x02, 14},
+ {6, 0x02, 14},
+ {15, 0x02, 14},
+ {30, 0x03, 14},
+ {2, 0x02, 15},
+ {6, 0x02, 15},
+ {15, 0x02, 15},
+ {30, 0x03, 15},
+ {2, 0x02, 16},
+ {6, 0x02, 16},
+ {15, 0x02, 16},
+ {30, 0x03, 16},
+ {2, 0x02, 17},
+ {6, 0x02, 17},
+ {15, 0x02, 17},
+ {30, 0x03, 17},
+ },
+ /* 205 */
+ {
+ {3, 0x02, 14},
+ {4, 0x02, 14},
+ {7, 0x02, 14},
+ {10, 0x02, 14},
+ {16, 0x02, 14},
+ {23, 0x02, 14},
+ {31, 0x02, 14},
+ {44, 0x03, 14},
+ {3, 0x02, 15},
+ {4, 0x02, 15},
+ {7, 0x02, 15},
+ {10, 0x02, 15},
+ {16, 0x02, 15},
+ {23, 0x02, 15},
+ {31, 0x02, 15},
+ {44, 0x03, 15},
+ },
+ /* 206 */
+ {
+ {3, 0x02, 16},
+ {4, 0x02, 16},
+ {7, 0x02, 16},
+ {10, 0x02, 16},
+ {16, 0x02, 16},
+ {23, 0x02, 16},
+ {31, 0x02, 16},
+ {44, 0x03, 16},
+ {3, 0x02, 17},
+ {4, 0x02, 17},
+ {7, 0x02, 17},
+ {10, 0x02, 17},
+ {16, 0x02, 17},
+ {23, 0x02, 17},
+ {31, 0x02, 17},
+ {44, 0x03, 17},
+ },
+ /* 207 */
+ {
+ {2, 0x02, 18},
+ {6, 0x02, 18},
+ {15, 0x02, 18},
+ {30, 0x03, 18},
+ {2, 0x02, 19},
+ {6, 0x02, 19},
+ {15, 0x02, 19},
+ {30, 0x03, 19},
+ {2, 0x02, 20},
+ {6, 0x02, 20},
+ {15, 0x02, 20},
+ {30, 0x03, 20},
+ {2, 0x02, 21},
+ {6, 0x02, 21},
+ {15, 0x02, 21},
+ {30, 0x03, 21},
+ },
+ /* 208 */
+ {
+ {3, 0x02, 18},
+ {4, 0x02, 18},
+ {7, 0x02, 18},
+ {10, 0x02, 18},
+ {16, 0x02, 18},
+ {23, 0x02, 18},
+ {31, 0x02, 18},
+ {44, 0x03, 18},
+ {3, 0x02, 19},
+ {4, 0x02, 19},
+ {7, 0x02, 19},
+ {10, 0x02, 19},
+ {16, 0x02, 19},
+ {23, 0x02, 19},
+ {31, 0x02, 19},
+ {44, 0x03, 19},
+ },
+ /* 209 */
+ {
+ {3, 0x02, 20},
+ {4, 0x02, 20},
+ {7, 0x02, 20},
+ {10, 0x02, 20},
+ {16, 0x02, 20},
+ {23, 0x02, 20},
+ {31, 0x02, 20},
+ {44, 0x03, 20},
+ {3, 0x02, 21},
+ {4, 0x02, 21},
+ {7, 0x02, 21},
+ {10, 0x02, 21},
+ {16, 0x02, 21},
+ {23, 0x02, 21},
+ {31, 0x02, 21},
+ {44, 0x03, 21},
+ },
+ /* 210 */
+ {
+ {0, 0x03, 22},
+ {0, 0x03, 23},
+ {0, 0x03, 24},
+ {0, 0x03, 25},
+ {0, 0x03, 26},
+ {0, 0x03, 27},
+ {0, 0x03, 28},
+ {0, 0x03, 29},
+ {0, 0x03, 30},
+ {0, 0x03, 31},
+ {0, 0x03, 92},
+ {0, 0x03, 127},
+ {0, 0x03, 128},
+ {0, 0x03, 129},
+ {0, 0x03, 130},
+ {0, 0x03, 131},
+ },
+ /* 211 */
+ {
+ {1, 0x02, 22},
+ {14, 0x03, 22},
+ {1, 0x02, 23},
+ {14, 0x03, 23},
+ {1, 0x02, 24},
+ {14, 0x03, 24},
+ {1, 0x02, 25},
+ {14, 0x03, 25},
+ {1, 0x02, 26},
+ {14, 0x03, 26},
+ {1, 0x02, 27},
+ {14, 0x03, 27},
+ {1, 0x02, 28},
+ {14, 0x03, 28},
+ {1, 0x02, 29},
+ {14, 0x03, 29},
+ },
+ /* 212 */
+ {
+ {2, 0x02, 22},
+ {6, 0x02, 22},
+ {15, 0x02, 22},
+ {30, 0x03, 22},
+ {2, 0x02, 23},
+ {6, 0x02, 23},
+ {15, 0x02, 23},
+ {30, 0x03, 23},
+ {2, 0x02, 24},
+ {6, 0x02, 24},
+ {15, 0x02, 24},
+ {30, 0x03, 24},
+ {2, 0x02, 25},
+ {6, 0x02, 25},
+ {15, 0x02, 25},
+ {30, 0x03, 25},
+ },
+ /* 213 */
+ {
+ {3, 0x02, 22},
+ {4, 0x02, 22},
+ {7, 0x02, 22},
+ {10, 0x02, 22},
+ {16, 0x02, 22},
+ {23, 0x02, 22},
+ {31, 0x02, 22},
+ {44, 0x03, 22},
+ {3, 0x02, 23},
+ {4, 0x02, 23},
+ {7, 0x02, 23},
+ {10, 0x02, 23},
+ {16, 0x02, 23},
+ {23, 0x02, 23},
+ {31, 0x02, 23},
+ {44, 0x03, 23},
+ },
+ /* 214 */
+ {
+ {3, 0x02, 24},
+ {4, 0x02, 24},
+ {7, 0x02, 24},
+ {10, 0x02, 24},
+ {16, 0x02, 24},
+ {23, 0x02, 24},
+ {31, 0x02, 24},
+ {44, 0x03, 24},
+ {3, 0x02, 25},
+ {4, 0x02, 25},
+ {7, 0x02, 25},
+ {10, 0x02, 25},
+ {16, 0x02, 25},
+ {23, 0x02, 25},
+ {31, 0x02, 25},
+ {44, 0x03, 25},
+ },
+ /* 215 */
+ {
+ {2, 0x02, 26},
+ {6, 0x02, 26},
+ {15, 0x02, 26},
+ {30, 0x03, 26},
+ {2, 0x02, 27},
+ {6, 0x02, 27},
+ {15, 0x02, 27},
+ {30, 0x03, 27},
+ {2, 0x02, 28},
+ {6, 0x02, 28},
+ {15, 0x02, 28},
+ {30, 0x03, 28},
+ {2, 0x02, 29},
+ {6, 0x02, 29},
+ {15, 0x02, 29},
+ {30, 0x03, 29},
+ },
+ /* 216 */
+ {
+ {3, 0x02, 26},
+ {4, 0x02, 26},
+ {7, 0x02, 26},
+ {10, 0x02, 26},
+ {16, 0x02, 26},
+ {23, 0x02, 26},
+ {31, 0x02, 26},
+ {44, 0x03, 26},
+ {3, 0x02, 27},
+ {4, 0x02, 27},
+ {7, 0x02, 27},
+ {10, 0x02, 27},
+ {16, 0x02, 27},
+ {23, 0x02, 27},
+ {31, 0x02, 27},
+ {44, 0x03, 27},
+ },
+ /* 217 */
+ {
+ {3, 0x02, 28},
+ {4, 0x02, 28},
+ {7, 0x02, 28},
+ {10, 0x02, 28},
+ {16, 0x02, 28},
+ {23, 0x02, 28},
+ {31, 0x02, 28},
+ {44, 0x03, 28},
+ {3, 0x02, 29},
+ {4, 0x02, 29},
+ {7, 0x02, 29},
+ {10, 0x02, 29},
+ {16, 0x02, 29},
+ {23, 0x02, 29},
+ {31, 0x02, 29},
+ {44, 0x03, 29},
+ },
+ /* 218 */
+ {
+ {1, 0x02, 30},
+ {14, 0x03, 30},
+ {1, 0x02, 31},
+ {14, 0x03, 31},
+ {1, 0x02, 92},
+ {14, 0x03, 92},
+ {1, 0x02, 127},
+ {14, 0x03, 127},
+ {1, 0x02, 128},
+ {14, 0x03, 128},
+ {1, 0x02, 129},
+ {14, 0x03, 129},
+ {1, 0x02, 130},
+ {14, 0x03, 130},
+ {1, 0x02, 131},
+ {14, 0x03, 131},
+ },
+ /* 219 */
+ {
+ {2, 0x02, 30},
+ {6, 0x02, 30},
+ {15, 0x02, 30},
+ {30, 0x03, 30},
+ {2, 0x02, 31},
+ {6, 0x02, 31},
+ {15, 0x02, 31},
+ {30, 0x03, 31},
+ {2, 0x02, 92},
+ {6, 0x02, 92},
+ {15, 0x02, 92},
+ {30, 0x03, 92},
+ {2, 0x02, 127},
+ {6, 0x02, 127},
+ {15, 0x02, 127},
+ {30, 0x03, 127},
+ },
+ /* 220 */
+ {
+ {3, 0x02, 30},
+ {4, 0x02, 30},
+ {7, 0x02, 30},
+ {10, 0x02, 30},
+ {16, 0x02, 30},
+ {23, 0x02, 30},
+ {31, 0x02, 30},
+ {44, 0x03, 30},
+ {3, 0x02, 31},
+ {4, 0x02, 31},
+ {7, 0x02, 31},
+ {10, 0x02, 31},
+ {16, 0x02, 31},
+ {23, 0x02, 31},
+ {31, 0x02, 31},
+ {44, 0x03, 31},
+ },
+ /* 221 */
+ {
+ {3, 0x02, 92},
+ {4, 0x02, 92},
+ {7, 0x02, 92},
+ {10, 0x02, 92},
+ {16, 0x02, 92},
+ {23, 0x02, 92},
+ {31, 0x02, 92},
+ {44, 0x03, 92},
+ {3, 0x02, 127},
+ {4, 0x02, 127},
+ {7, 0x02, 127},
+ {10, 0x02, 127},
+ {16, 0x02, 127},
+ {23, 0x02, 127},
+ {31, 0x02, 127},
+ {44, 0x03, 127},
+ },
+ /* 222 */
+ {
+ {2, 0x02, 128},
+ {6, 0x02, 128},
+ {15, 0x02, 128},
+ {30, 0x03, 128},
+ {2, 0x02, 129},
+ {6, 0x02, 129},
+ {15, 0x02, 129},
+ {30, 0x03, 129},
+ {2, 0x02, 130},
+ {6, 0x02, 130},
+ {15, 0x02, 130},
+ {30, 0x03, 130},
+ {2, 0x02, 131},
+ {6, 0x02, 131},
+ {15, 0x02, 131},
+ {30, 0x03, 131},
+ },
+ /* 223 */
+ {
+ {3, 0x02, 128},
+ {4, 0x02, 128},
+ {7, 0x02, 128},
+ {10, 0x02, 128},
+ {16, 0x02, 128},
+ {23, 0x02, 128},
+ {31, 0x02, 128},
+ {44, 0x03, 128},
+ {3, 0x02, 129},
+ {4, 0x02, 129},
+ {7, 0x02, 129},
+ {10, 0x02, 129},
+ {16, 0x02, 129},
+ {23, 0x02, 129},
+ {31, 0x02, 129},
+ {44, 0x03, 129},
+ },
+ /* 224 */
+ {
+ {3, 0x02, 130},
+ {4, 0x02, 130},
+ {7, 0x02, 130},
+ {10, 0x02, 130},
+ {16, 0x02, 130},
+ {23, 0x02, 130},
+ {31, 0x02, 130},
+ {44, 0x03, 130},
+ {3, 0x02, 131},
+ {4, 0x02, 131},
+ {7, 0x02, 131},
+ {10, 0x02, 131},
+ {16, 0x02, 131},
+ {23, 0x02, 131},
+ {31, 0x02, 131},
+ {44, 0x03, 131},
+ },
+ /* 225 */
+ {
+ {229, 0x00, 0},
+ {230, 0x00, 0},
+ {232, 0x00, 0},
+ {233, 0x00, 0},
+ {236, 0x00, 0},
+ {237, 0x00, 0},
+ {239, 0x00, 0},
+ {240, 0x00, 0},
+ {244, 0x00, 0},
+ {245, 0x00, 0},
+ {247, 0x00, 0},
+ {248, 0x00, 0},
+ {251, 0x00, 0},
+ {252, 0x00, 0},
+ {254, 0x00, 0},
+ {255, 0x00, 0},
+ },
+ /* 226 */
+ {
+ {0, 0x03, 132},
+ {0, 0x03, 133},
+ {0, 0x03, 134},
+ {0, 0x03, 135},
+ {0, 0x03, 136},
+ {0, 0x03, 137},
+ {0, 0x03, 138},
+ {0, 0x03, 139},
+ {0, 0x03, 140},
+ {0, 0x03, 141},
+ {0, 0x03, 142},
+ {0, 0x03, 143},
+ {0, 0x03, 144},
+ {0, 0x03, 145},
+ {0, 0x03, 146},
+ {0, 0x03, 147},
+ },
+ /* 227 */
+ {
+ {1, 0x02, 132},
+ {14, 0x03, 132},
+ {1, 0x02, 133},
+ {14, 0x03, 133},
+ {1, 0x02, 134},
+ {14, 0x03, 134},
+ {1, 0x02, 135},
+ {14, 0x03, 135},
+ {1, 0x02, 136},
+ {14, 0x03, 136},
+ {1, 0x02, 137},
+ {14, 0x03, 137},
+ {1, 0x02, 138},
+ {14, 0x03, 138},
+ {1, 0x02, 139},
+ {14, 0x03, 139},
+ },
+ /* 228 */
+ {
+ {2, 0x02, 132},
+ {6, 0x02, 132},
+ {15, 0x02, 132},
+ {30, 0x03, 132},
+ {2, 0x02, 133},
+ {6, 0x02, 133},
+ {15, 0x02, 133},
+ {30, 0x03, 133},
+ {2, 0x02, 134},
+ {6, 0x02, 134},
+ {15, 0x02, 134},
+ {30, 0x03, 134},
+ {2, 0x02, 135},
+ {6, 0x02, 135},
+ {15, 0x02, 135},
+ {30, 0x03, 135},
+ },
+ /* 229 */
+ {
+ {3, 0x02, 132},
+ {4, 0x02, 132},
+ {7, 0x02, 132},
+ {10, 0x02, 132},
+ {16, 0x02, 132},
+ {23, 0x02, 132},
+ {31, 0x02, 132},
+ {44, 0x03, 132},
+ {3, 0x02, 133},
+ {4, 0x02, 133},
+ {7, 0x02, 133},
+ {10, 0x02, 133},
+ {16, 0x02, 133},
+ {23, 0x02, 133},
+ {31, 0x02, 133},
+ {44, 0x03, 133},
+ },
+ /* 230 */
+ {
+ {3, 0x02, 134},
+ {4, 0x02, 134},
+ {7, 0x02, 134},
+ {10, 0x02, 134},
+ {16, 0x02, 134},
+ {23, 0x02, 134},
+ {31, 0x02, 134},
+ {44, 0x03, 134},
+ {3, 0x02, 135},
+ {4, 0x02, 135},
+ {7, 0x02, 135},
+ {10, 0x02, 135},
+ {16, 0x02, 135},
+ {23, 0x02, 135},
+ {31, 0x02, 135},
+ {44, 0x03, 135},
+ },
+ /* 231 */
+ {
+ {2, 0x02, 136},
+ {6, 0x02, 136},
+ {15, 0x02, 136},
+ {30, 0x03, 136},
+ {2, 0x02, 137},
+ {6, 0x02, 137},
+ {15, 0x02, 137},
+ {30, 0x03, 137},
+ {2, 0x02, 138},
+ {6, 0x02, 138},
+ {15, 0x02, 138},
+ {30, 0x03, 138},
+ {2, 0x02, 139},
+ {6, 0x02, 139},
+ {15, 0x02, 139},
+ {30, 0x03, 139},
+ },
+ /* 232 */
+ {
+ {3, 0x02, 136},
+ {4, 0x02, 136},
+ {7, 0x02, 136},
+ {10, 0x02, 136},
+ {16, 0x02, 136},
+ {23, 0x02, 136},
+ {31, 0x02, 136},
+ {44, 0x03, 136},
+ {3, 0x02, 137},
+ {4, 0x02, 137},
+ {7, 0x02, 137},
+ {10, 0x02, 137},
+ {16, 0x02, 137},
+ {23, 0x02, 137},
+ {31, 0x02, 137},
+ {44, 0x03, 137},
+ },
+ /* 233 */
+ {
+ {3, 0x02, 138},
+ {4, 0x02, 138},
+ {7, 0x02, 138},
+ {10, 0x02, 138},
+ {16, 0x02, 138},
+ {23, 0x02, 138},
+ {31, 0x02, 138},
+ {44, 0x03, 138},
+ {3, 0x02, 139},
+ {4, 0x02, 139},
+ {7, 0x02, 139},
+ {10, 0x02, 139},
+ {16, 0x02, 139},
+ {23, 0x02, 139},
+ {31, 0x02, 139},
+ {44, 0x03, 139},
+ },
+ /* 234 */
+ {
+ {1, 0x02, 140},
+ {14, 0x03, 140},
+ {1, 0x02, 141},
+ {14, 0x03, 141},
+ {1, 0x02, 142},
+ {14, 0x03, 142},
+ {1, 0x02, 143},
+ {14, 0x03, 143},
+ {1, 0x02, 144},
+ {14, 0x03, 144},
+ {1, 0x02, 145},
+ {14, 0x03, 145},
+ {1, 0x02, 146},
+ {14, 0x03, 146},
+ {1, 0x02, 147},
+ {14, 0x03, 147},
+ },
+ /* 235 */
+ {
+ {2, 0x02, 140},
+ {6, 0x02, 140},
+ {15, 0x02, 140},
+ {30, 0x03, 140},
+ {2, 0x02, 141},
+ {6, 0x02, 141},
+ {15, 0x02, 141},
+ {30, 0x03, 141},
+ {2, 0x02, 142},
+ {6, 0x02, 142},
+ {15, 0x02, 142},
+ {30, 0x03, 142},
+ {2, 0x02, 143},
+ {6, 0x02, 143},
+ {15, 0x02, 143},
+ {30, 0x03, 143},
+ },
+ /* 236 */
+ {
+ {3, 0x02, 140},
+ {4, 0x02, 140},
+ {7, 0x02, 140},
+ {10, 0x02, 140},
+ {16, 0x02, 140},
+ {23, 0x02, 140},
+ {31, 0x02, 140},
+ {44, 0x03, 140},
+ {3, 0x02, 141},
+ {4, 0x02, 141},
+ {7, 0x02, 141},
+ {10, 0x02, 141},
+ {16, 0x02, 141},
+ {23, 0x02, 141},
+ {31, 0x02, 141},
+ {44, 0x03, 141},
+ },
+ /* 237 */
+ {
+ {3, 0x02, 142},
+ {4, 0x02, 142},
+ {7, 0x02, 142},
+ {10, 0x02, 142},
+ {16, 0x02, 142},
+ {23, 0x02, 142},
+ {31, 0x02, 142},
+ {44, 0x03, 142},
+ {3, 0x02, 143},
+ {4, 0x02, 143},
+ {7, 0x02, 143},
+ {10, 0x02, 143},
+ {16, 0x02, 143},
+ {23, 0x02, 143},
+ {31, 0x02, 143},
+ {44, 0x03, 143},
+ },
+ /* 238 */
+ {
+ {2, 0x02, 144},
+ {6, 0x02, 144},
+ {15, 0x02, 144},
+ {30, 0x03, 144},
+ {2, 0x02, 145},
+ {6, 0x02, 145},
+ {15, 0x02, 145},
+ {30, 0x03, 145},
+ {2, 0x02, 146},
+ {6, 0x02, 146},
+ {15, 0x02, 146},
+ {30, 0x03, 146},
+ {2, 0x02, 147},
+ {6, 0x02, 147},
+ {15, 0x02, 147},
+ {30, 0x03, 147},
+ },
+ /* 239 */
+ {
+ {3, 0x02, 144},
+ {4, 0x02, 144},
+ {7, 0x02, 144},
+ {10, 0x02, 144},
+ {16, 0x02, 144},
+ {23, 0x02, 144},
+ {31, 0x02, 144},
+ {44, 0x03, 144},
+ {3, 0x02, 145},
+ {4, 0x02, 145},
+ {7, 0x02, 145},
+ {10, 0x02, 145},
+ {16, 0x02, 145},
+ {23, 0x02, 145},
+ {31, 0x02, 145},
+ {44, 0x03, 145},
+ },
+ /* 240 */
+ {
+ {3, 0x02, 146},
+ {4, 0x02, 146},
+ {7, 0x02, 146},
+ {10, 0x02, 146},
+ {16, 0x02, 146},
+ {23, 0x02, 146},
+ {31, 0x02, 146},
+ {44, 0x03, 146},
+ {3, 0x02, 147},
+ {4, 0x02, 147},
+ {7, 0x02, 147},
+ {10, 0x02, 147},
+ {16, 0x02, 147},
+ {23, 0x02, 147},
+ {31, 0x02, 147},
+ {44, 0x03, 147},
+ },
+ /* 241 */
+ {
+ {0, 0x03, 148},
+ {0, 0x03, 149},
+ {0, 0x03, 150},
+ {0, 0x03, 151},
+ {0, 0x03, 152},
+ {0, 0x03, 153},
+ {0, 0x03, 154},
+ {0, 0x03, 155},
+ {0, 0x03, 156},
+ {0, 0x03, 157},
+ {0, 0x03, 158},
+ {0, 0x03, 159},
+ {0, 0x03, 160},
+ {0, 0x03, 161},
+ {0, 0x03, 162},
+ {0, 0x03, 163},
+ },
+ /* 242 */
+ {
+ {1, 0x02, 148},
+ {14, 0x03, 148},
+ {1, 0x02, 149},
+ {14, 0x03, 149},
+ {1, 0x02, 150},
+ {14, 0x03, 150},
+ {1, 0x02, 151},
+ {14, 0x03, 151},
+ {1, 0x02, 152},
+ {14, 0x03, 152},
+ {1, 0x02, 153},
+ {14, 0x03, 153},
+ {1, 0x02, 154},
+ {14, 0x03, 154},
+ {1, 0x02, 155},
+ {14, 0x03, 155},
+ },
+ /* 243 */
+ {
+ {2, 0x02, 148},
+ {6, 0x02, 148},
+ {15, 0x02, 148},
+ {30, 0x03, 148},
+ {2, 0x02, 149},
+ {6, 0x02, 149},
+ {15, 0x02, 149},
+ {30, 0x03, 149},
+ {2, 0x02, 150},
+ {6, 0x02, 150},
+ {15, 0x02, 150},
+ {30, 0x03, 150},
+ {2, 0x02, 151},
+ {6, 0x02, 151},
+ {15, 0x02, 151},
+ {30, 0x03, 151},
+ },
+ /* 244 */
+ {
+ {3, 0x02, 148},
+ {4, 0x02, 148},
+ {7, 0x02, 148},
+ {10, 0x02, 148},
+ {16, 0x02, 148},
+ {23, 0x02, 148},
+ {31, 0x02, 148},
+ {44, 0x03, 148},
+ {3, 0x02, 149},
+ {4, 0x02, 149},
+ {7, 0x02, 149},
+ {10, 0x02, 149},
+ {16, 0x02, 149},
+ {23, 0x02, 149},
+ {31, 0x02, 149},
+ {44, 0x03, 149},
+ },
+ /* 245 */
+ {
+ {3, 0x02, 150},
+ {4, 0x02, 150},
+ {7, 0x02, 150},
+ {10, 0x02, 150},
+ {16, 0x02, 150},
+ {23, 0x02, 150},
+ {31, 0x02, 150},
+ {44, 0x03, 150},
+ {3, 0x02, 151},
+ {4, 0x02, 151},
+ {7, 0x02, 151},
+ {10, 0x02, 151},
+ {16, 0x02, 151},
+ {23, 0x02, 151},
+ {31, 0x02, 151},
+ {44, 0x03, 151},
+ },
+ /* 246 */
+ {
+ {2, 0x02, 152},
+ {6, 0x02, 152},
+ {15, 0x02, 152},
+ {30, 0x03, 152},
+ {2, 0x02, 153},
+ {6, 0x02, 153},
+ {15, 0x02, 153},
+ {30, 0x03, 153},
+ {2, 0x02, 154},
+ {6, 0x02, 154},
+ {15, 0x02, 154},
+ {30, 0x03, 154},
+ {2, 0x02, 155},
+ {6, 0x02, 155},
+ {15, 0x02, 155},
+ {30, 0x03, 155},
+ },
+ /* 247 */
+ {
+ {3, 0x02, 152},
+ {4, 0x02, 152},
+ {7, 0x02, 152},
+ {10, 0x02, 152},
+ {16, 0x02, 152},
+ {23, 0x02, 152},
+ {31, 0x02, 152},
+ {44, 0x03, 152},
+ {3, 0x02, 153},
+ {4, 0x02, 153},
+ {7, 0x02, 153},
+ {10, 0x02, 153},
+ {16, 0x02, 153},
+ {23, 0x02, 153},
+ {31, 0x02, 153},
+ {44, 0x03, 153},
+ },
+ /* 248 */
+ {
+ {3, 0x02, 154},
+ {4, 0x02, 154},
+ {7, 0x02, 154},
+ {10, 0x02, 154},
+ {16, 0x02, 154},
+ {23, 0x02, 154},
+ {31, 0x02, 154},
+ {44, 0x03, 154},
+ {3, 0x02, 155},
+ {4, 0x02, 155},
+ {7, 0x02, 155},
+ {10, 0x02, 155},
+ {16, 0x02, 155},
+ {23, 0x02, 155},
+ {31, 0x02, 155},
+ {44, 0x03, 155},
+ },
+ /* 249 */
+ {
+ {1, 0x02, 156},
+ {14, 0x03, 156},
+ {1, 0x02, 157},
+ {14, 0x03, 157},
+ {1, 0x02, 158},
+ {14, 0x03, 158},
+ {1, 0x02, 159},
+ {14, 0x03, 159},
+ {1, 0x02, 160},
+ {14, 0x03, 160},
+ {1, 0x02, 161},
+ {14, 0x03, 161},
+ {1, 0x02, 162},
+ {14, 0x03, 162},
+ {1, 0x02, 163},
+ {14, 0x03, 163},
+ },
+ /* 250 */
+ {
+ {2, 0x02, 156},
+ {6, 0x02, 156},
+ {15, 0x02, 156},
+ {30, 0x03, 156},
+ {2, 0x02, 157},
+ {6, 0x02, 157},
+ {15, 0x02, 157},
+ {30, 0x03, 157},
+ {2, 0x02, 158},
+ {6, 0x02, 158},
+ {15, 0x02, 158},
+ {30, 0x03, 158},
+ {2, 0x02, 159},
+ {6, 0x02, 159},
+ {15, 0x02, 159},
+ {30, 0x03, 159},
+ },
+ /* 251 */
+ {
+ {3, 0x02, 156},
+ {4, 0x02, 156},
+ {7, 0x02, 156},
+ {10, 0x02, 156},
+ {16, 0x02, 156},
+ {23, 0x02, 156},
+ {31, 0x02, 156},
+ {44, 0x03, 156},
+ {3, 0x02, 157},
+ {4, 0x02, 157},
+ {7, 0x02, 157},
+ {10, 0x02, 157},
+ {16, 0x02, 157},
+ {23, 0x02, 157},
+ {31, 0x02, 157},
+ {44, 0x03, 157},
+ },
+ /* 252 */
+ {
+ {3, 0x02, 158},
+ {4, 0x02, 158},
+ {7, 0x02, 158},
+ {10, 0x02, 158},
+ {16, 0x02, 158},
+ {23, 0x02, 158},
+ {31, 0x02, 158},
+ {44, 0x03, 158},
+ {3, 0x02, 159},
+ {4, 0x02, 159},
+ {7, 0x02, 159},
+ {10, 0x02, 159},
+ {16, 0x02, 159},
+ {23, 0x02, 159},
+ {31, 0x02, 159},
+ {44, 0x03, 159},
+ },
+ /* 253 */
+ {
+ {2, 0x02, 160},
+ {6, 0x02, 160},
+ {15, 0x02, 160},
+ {30, 0x03, 160},
+ {2, 0x02, 161},
+ {6, 0x02, 161},
+ {15, 0x02, 161},
+ {30, 0x03, 161},
+ {2, 0x02, 162},
+ {6, 0x02, 162},
+ {15, 0x02, 162},
+ {30, 0x03, 162},
+ {2, 0x02, 163},
+ {6, 0x02, 163},
+ {15, 0x02, 163},
+ {30, 0x03, 163},
+ },
+ /* 254 */
+ {
+ {3, 0x02, 160},
+ {4, 0x02, 160},
+ {7, 0x02, 160},
+ {10, 0x02, 160},
+ {16, 0x02, 160},
+ {23, 0x02, 160},
+ {31, 0x02, 160},
+ {44, 0x03, 160},
+ {3, 0x02, 161},
+ {4, 0x02, 161},
+ {7, 0x02, 161},
+ {10, 0x02, 161},
+ {16, 0x02, 161},
+ {23, 0x02, 161},
+ {31, 0x02, 161},
+ {44, 0x03, 161},
+ },
+ /* 255 */
+ {
+ {3, 0x02, 162},
+ {4, 0x02, 162},
+ {7, 0x02, 162},
+ {10, 0x02, 162},
+ {16, 0x02, 162},
+ {23, 0x02, 162},
+ {31, 0x02, 162},
+ {44, 0x03, 162},
+ {3, 0x02, 163},
+ {4, 0x02, 163},
+ {7, 0x02, 163},
+ {10, 0x02, 163},
+ {16, 0x02, 163},
+ {23, 0x02, 163},
+ {31, 0x02, 163},
+ {44, 0x03, 163},
+ },
+};
diff --git a/wsutil/nghttp2/nghttp2_helper.c b/wsutil/nghttp2/nghttp2_helper.c
new file mode 100644
index 0000000000..caf8bdb926
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_helper.c
@@ -0,0 +1,409 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_helper.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "nghttp2_net.h"
+
+void nghttp2_put_uint16be(uint8_t *buf, uint16_t n)
+{
+ uint16_t x = htons(n);
+ memcpy(buf, &x, sizeof(uint16_t));
+}
+
+void nghttp2_put_uint32be(uint8_t *buf, uint32_t n)
+{
+ uint32_t x = htonl(n);
+ memcpy(buf, &x, sizeof(uint32_t));
+}
+
+uint16_t nghttp2_get_uint16(const uint8_t *data)
+{
+ uint16_t n;
+ memcpy(&n, data, sizeof(uint16_t));
+ return ntohs(n);
+}
+
+uint32_t nghttp2_get_uint32(const uint8_t *data)
+{
+ uint32_t n;
+ memcpy(&n, data, sizeof(uint32_t));
+ return ntohl(n);
+}
+
+int nghttp2_reserve_buffer(uint8_t **buf_ptr, size_t *buflen_ptr,
+ size_t min_length)
+{
+ if(min_length > *buflen_ptr) {
+ uint8_t *temp;
+ min_length = (min_length+4095)/4096*4096;
+ temp = (uint8_t *)realloc(*buf_ptr, min_length);
+ if(temp == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ } else {
+ *buf_ptr = temp;
+ *buflen_ptr = min_length;
+ }
+ }
+ return 0;
+}
+
+void* nghttp2_memdup(const void* src, size_t n)
+{
+ void* dest;
+
+ if(n == 0) {
+ return NULL;
+ }
+
+ dest = malloc(n);
+ if(dest == NULL) {
+ return NULL;
+ }
+ memcpy(dest, src, n);
+ return dest;
+}
+
+void nghttp2_downcase(uint8_t *s, size_t len)
+{
+ size_t i;
+ for(i = 0; i < len; ++i) {
+ if('A' <= s[i] && s[i] <= 'Z') {
+ s[i] += 'a'-'A';
+ }
+ }
+}
+
+int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
+ int32_t *recv_window_size_ptr,
+ int32_t *recv_reduction_ptr,
+ int32_t *delta_ptr)
+{
+ if(*delta_ptr > 0) {
+ int32_t new_recv_window_size =
+ nghttp2_max(0, *recv_window_size_ptr) - *delta_ptr;
+ if(new_recv_window_size < 0) {
+ /* The delta size is strictly more than received bytes. Increase
+ local_window_size by that difference. */
+ int32_t recv_reduction_diff;
+ if(*local_window_size_ptr >
+ NGHTTP2_MAX_WINDOW_SIZE + new_recv_window_size) {
+ return NGHTTP2_ERR_FLOW_CONTROL;
+ }
+ *local_window_size_ptr -= new_recv_window_size;
+ /* If there is recv_reduction due to earlier window_size
+ reduction, we have to adjust it too. */
+ recv_reduction_diff = nghttp2_min(*recv_reduction_ptr,
+ -new_recv_window_size);
+ *recv_reduction_ptr -= recv_reduction_diff;
+ if(*recv_window_size_ptr < 0) {
+ *recv_window_size_ptr += recv_reduction_diff;
+ } else {
+ /* If *recv_window_size_ptr > 0, then those bytes are
+ considered to be backed to the remote peer (by
+ WINDOW_UPDATE with the adjusted *delta_ptr), so it is
+ effectively 0 now. */
+ *recv_window_size_ptr = recv_reduction_diff;
+ }
+ /* recv_reduction_diff must be paied from *delta_ptr, since it
+ was added in window size reduction (see below). */
+ *delta_ptr -= recv_reduction_diff;
+ } else {
+ *recv_window_size_ptr = new_recv_window_size;
+ }
+ return 0;
+ } else {
+ if(*local_window_size_ptr + *delta_ptr < 0 ||
+ *recv_window_size_ptr < INT32_MIN - *delta_ptr ||
+ *recv_reduction_ptr > INT32_MAX + *delta_ptr) {
+ return NGHTTP2_ERR_FLOW_CONTROL;
+ }
+ /* Decreasing local window size. Note that we achieve this without
+ noticing to the remote peer. To do this, we cut
+ recv_window_size by -delta. This means that we don't send
+ WINDOW_UPDATE for -delta bytes. */
+ *local_window_size_ptr += *delta_ptr;
+ *recv_window_size_ptr += *delta_ptr;
+ *recv_reduction_ptr -= *delta_ptr;
+ *delta_ptr = 0;
+ }
+ return 0;
+}
+
+int nghttp2_should_send_window_update(int32_t local_window_size,
+ int32_t recv_window_size)
+{
+ return recv_window_size >= local_window_size / 2;
+}
+
+const char* nghttp2_strerror(int error_code)
+{
+ switch(error_code) {
+ case 0:
+ return "Success";
+ case NGHTTP2_ERR_INVALID_ARGUMENT:
+ return "Invalid argument";
+ case NGHTTP2_ERR_BUFFER_ERROR:
+ return "Out of buffer space";
+ case NGHTTP2_ERR_UNSUPPORTED_VERSION:
+ return "Unsupported SPDY version";
+ case NGHTTP2_ERR_WOULDBLOCK:
+ return "Operation would block";
+ case NGHTTP2_ERR_PROTO:
+ return "Protocol error";
+ case NGHTTP2_ERR_INVALID_FRAME:
+ return "Invalid frame octets";
+ case NGHTTP2_ERR_EOF:
+ return "EOF";
+ case NGHTTP2_ERR_DEFERRED:
+ return "Data transfer deferred";
+ case NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE:
+ return "No more Stream ID available";
+ case NGHTTP2_ERR_STREAM_CLOSED:
+ return "Stream was already closed or invalid";
+ case NGHTTP2_ERR_STREAM_CLOSING:
+ return "Stream is closing";
+ case NGHTTP2_ERR_STREAM_SHUT_WR:
+ return "The transmission is not allowed for this stream";
+ case NGHTTP2_ERR_INVALID_STREAM_ID:
+ return "Stream ID is invalid";
+ case NGHTTP2_ERR_INVALID_STREAM_STATE:
+ return "Invalid stream state";
+ case NGHTTP2_ERR_DEFERRED_DATA_EXIST:
+ return "Another DATA frame has already been deferred";
+ case NGHTTP2_ERR_START_STREAM_NOT_ALLOWED:
+ return "request HEADERS is not allowed";
+ case NGHTTP2_ERR_GOAWAY_ALREADY_SENT:
+ return "GOAWAY has already been sent";
+ case NGHTTP2_ERR_INVALID_HEADER_BLOCK:
+ return "Invalid header block";
+ case NGHTTP2_ERR_INVALID_STATE:
+ return "Invalid state";
+ case NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE:
+ return "The user callback function failed due to the temporal error";
+ case NGHTTP2_ERR_FRAME_SIZE_ERROR:
+ return "The length of the frame is invalid";
+ case NGHTTP2_ERR_HEADER_COMP:
+ return "Header compression/decompression error";
+ case NGHTTP2_ERR_FLOW_CONTROL:
+ return "Flow control error";
+ case NGHTTP2_ERR_INSUFF_BUFSIZE:
+ return "Insufficient buffer size given to function";
+ case NGHTTP2_ERR_PAUSE:
+ return "Callback was paused by the application";
+ case NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS:
+ return "Too many inflight SETTINGS";
+ case NGHTTP2_ERR_PUSH_DISABLED:
+ return "Server push is disabled by peer";
+ case NGHTTP2_ERR_DATA_EXIST:
+ return "DATA frame already exists";
+ case NGHTTP2_ERR_NOMEM:
+ return "Out of memory";
+ case NGHTTP2_ERR_CALLBACK_FAILURE:
+ return "The user callback function failed";
+ default:
+ return "Unknown error code";
+ }
+}
+
+void nghttp2_free(void *ptr)
+{
+ free(ptr);
+}
+
+static int VALID_HD_NAME_CHARS[] = {
+ 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
+ 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
+ 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
+ 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
+ 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
+ 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
+ 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
+ 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
+ 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */,
+ 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
+ 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */,
+ 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
+ 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
+ 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
+ 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
+ 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */,
+ 0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */,
+ 0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */,
+ 0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */,
+ 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
+ 0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */,
+ 0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */,
+ 0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */,
+ 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */,
+ 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
+ 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
+ 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
+ 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
+ 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
+ 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
+ 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
+ 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
+ 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
+ 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
+ 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
+ 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
+ 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
+ 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
+ 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
+ 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
+ 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
+ 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
+ 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
+ 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
+ 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
+ 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
+ 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
+ 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
+ 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
+ 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
+ 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
+ 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
+ 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
+ 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
+ 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
+ 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
+ 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
+ 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
+ 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
+ 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
+ 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
+ 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
+ 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
+ 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
+};
+
+int nghttp2_check_header_name(const uint8_t *name, size_t len)
+{
+ const uint8_t *last;
+ if(len == 0) {
+ return 0;
+ }
+ if(*name == ':') {
+ if(len == 1) {
+ return 0;
+ }
+ ++name;
+ --len;
+ }
+ for(last = name + len; name != last; ++name) {
+ if(!VALID_HD_NAME_CHARS[*name]) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int VALID_HD_VALUE_CHARS[] = {
+ 1 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
+ 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
+ 0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */,
+ 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
+ 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
+ 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
+ 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
+ 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
+ 1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */,
+ 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
+ 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
+ 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */,
+ 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
+ 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
+ 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
+ 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */,
+ 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
+ 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
+ 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
+ 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
+ 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
+ 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
+ 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
+ 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */,
+ 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
+ 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
+ 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
+ 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
+ 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
+ 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
+ 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */,
+ 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */,
+ 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
+ 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
+ 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
+ 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
+ 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
+ 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
+ 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
+ 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
+ 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
+ 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
+ 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
+ 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
+ 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
+ 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
+ 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
+ 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
+ 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
+ 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
+ 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
+ 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
+ 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */,
+ 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */,
+ 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
+ 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */,
+ 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */,
+ 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */,
+ 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */,
+ 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
+ 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */,
+ 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */,
+ 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */,
+ 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */
+};
+
+int nghttp2_check_header_value(const uint8_t *value, size_t len)
+{
+ const uint8_t *last;
+ for(last = value + len; value != last; ++value) {
+ if(!VALID_HD_VALUE_CHARS[*value]) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+uint8_t* nghttp2_cpymem(uint8_t *dest, const void *src, size_t len)
+{
+ memcpy(dest, src, len);
+
+ return dest + len;
+}
diff --git a/wsutil/nghttp2/nghttp2_helper.h b/wsutil/nghttp2/nghttp2_helper.h
new file mode 100644
index 0000000000..e1a127f32c
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_helper.h
@@ -0,0 +1,135 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_HELPER_H
+#define NGHTTP2_HELPER_H
+
+
+# include <config.h>
+
+#include <wsutil/nghttp2/nghttp2/nghttp2.h>
+
+#define nghttp2_min(A, B) ((A) < (B) ? (A) : (B))
+#define nghttp2_max(A, B) ((A) > (B) ? (A) : (B))
+
+/*
+ * Copies 2 byte unsigned integer |n| in host byte order to |buf| in
+ * network byte order.
+ */
+void nghttp2_put_uint16be(uint8_t *buf, uint16_t n);
+
+/*
+ * Copies 4 byte unsigned integer |n| in host byte order to |buf| in
+ * network byte order.
+ */
+void nghttp2_put_uint32be(uint8_t *buf, uint32_t n);
+
+/*
+ * Retrieves 2 byte unsigned integer stored in |data| in network byte
+ * order and returns it in host byte order.
+ */
+uint16_t nghttp2_get_uint16(const uint8_t *data);
+
+/*
+ * Retrieves 4 byte unsigned integer stored in |data| in network byte
+ * order and returns it in host byte order.
+ */
+uint32_t nghttp2_get_uint32(const uint8_t *data);
+
+/*
+ * Ensures that buffer |*buf_ptr| with |*buflen_ptr| length has at
+ * least |min_length| bytes. If |min_length| > |*buflen_ptr|,
+ * allocates new buffer having at least |min_length| bytes and assigns
+ * its pointer to |*buf_ptr| and allocated number of bytes to
+ * |*buflen_ptr|. The memory pointed by |*buf_ptr| previously may
+ * change. No memory copy is done between old and new buffer.
+ * |*buf_ptr| and |*buflen_ptr| are only updated iff this function
+ * succeeds.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ */
+int nghttp2_reserve_buffer(uint8_t **buf_ptr, size_t *buflen_ptr,
+ size_t min_length);
+
+/*
+ * Allocates |n| bytes of memory and copy the memory region pointed by
+ * |src| with the length |n| bytes into it. Returns the allocated memory.
+ *
+ * This function returns pointer to allocated memory, or one of the
+ * following negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ */
+void* nghttp2_memdup(const void* src, size_t n);
+
+void nghttp2_downcase(uint8_t *s, size_t len);
+
+/*
+ * Adjusts |*local_window_size_ptr|, |*recv_window_size_ptr|,
+ * |*recv_reduction_ptr| with |*delta_ptr| which is the
+ * WINDOW_UPDATE's window_size_increment sent from local side. If
+ * |delta| is strictly larger than |*recv_window_size_ptr|,
+ * |*local_window_size_ptr| is increased by delta -
+ * *recv_window_size_ptr. If |delta| is negative,
+ * |*local_window_size_ptr| is decreased by delta.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_FLOW_CONTROL
+ * local_window_size overflow or gets negative.
+ */
+int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
+ int32_t *recv_window_size_ptr,
+ int32_t *recv_reduction_ptr,
+ int32_t *delta_ptr);
+
+/*
+ * Returns non-zero if the function decided that WINDOW_UPDATE should
+ * be sent.
+ */
+int nghttp2_should_send_window_update(int32_t local_window_size,
+ int32_t recv_window_size);
+
+/*
+ * Deallocates memory space pointed by |ptr|. This function exists for
+ * the application to free the memory space allocated by the library
+ * functions. Currently this function is hidden from the public API,
+ * but may be exposed as public API.
+ */
+void nghttp2_free(void *ptr);
+
+/*
+ * Copies the buffer |src| of length |len| to the destination pointed
+ * by the |dest|, assuming that the |dest| is at lest |len| bytes long
+ * . Returns dest + len.
+ */
+uint8_t* nghttp2_cpymem(uint8_t *dest, const void *src, size_t len);
+
+#endif /* NGHTTP2_HELPER_H */
diff --git a/wsutil/nghttp2/nghttp2_int.h b/wsutil/nghttp2/nghttp2_int.h
new file mode 100644
index 0000000000..da64940ccc
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_int.h
@@ -0,0 +1,50 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_INT_H
+#define NGHTTP2_INT_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+/* Macros, types and constants for internal use */
+
+#ifdef DEBUGBUILD
+#define DEBUGF(x) x
+#else
+#define DEBUGF(x) do { } while(0)
+#endif
+
+typedef int (*nghttp2_compar)(const void *lhs, const void *rhs);
+
+/* Internal error code. They must be in the range [-499, -100],
+ inclusive. */
+typedef enum {
+ NGHTTP2_ERR_CREDENTIAL_PENDING = -101,
+ NGHTTP2_ERR_IGN_HEADER_BLOCK = -103,
+ NGHTTP2_ERR_IGN_PAYLOAD = -104
+} nghttp2_internal_error;
+
+#endif /* NGHTTP2_INT_H */
diff --git a/wsutil/nghttp2/nghttp2_net.h b/wsutil/nghttp2/nghttp2_net.h
new file mode 100644
index 0000000000..621231efd7
--- /dev/null
+++ b/wsutil/nghttp2/nghttp2_net.h
@@ -0,0 +1,44 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_NET_H
+#define NGHTTP2_NET_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif /* HAVE_ARPA_INET_H */
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif /* HAVE_NETINET_IN_H */
+
+#ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+#endif /* HAVE_WINSOCK2_H */
+
+#endif /* NGHTTP2_NET_H */