Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
kelbon committed Oct 16, 2024
0 parents commit c68ba32
Show file tree
Hide file tree
Showing 22 changed files with 2,915 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
BasedOnStyle: Google
ColumnLimit : 110
AllowShortFunctionsOnASingleLine: false
AllowShortLambdasOnASingleLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
SortIncludes: false
4 changes: 4 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# These are supported funding model platforms

github: [kelbon]

37 changes: 37 additions & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: build_and_test

on: push

jobs:
build:
strategy:
matrix:
os: [ubuntu-22.04]
compiler: [g++-12, clang++-14]
cpp_standard: [20]
build_type: [Debug, Release]
runs-on: ${{matrix.os}}

steps:
- uses: actions/checkout@v2

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install ninja-build lld gcc-12 clang-14
sudo ln -sf /usr/local/bin/ld /usr/bin/lld
- name: Configure CMake
run: |
cmake . -DHPACK_ENABLE_TESTING=ON \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_STANDARD=${{matrix.cpp_standard}} \
-B build -G "Ninja"
- name: Build
run:
cmake --build build

- name: Test
run: |
cd build
ctest --output-on-failure -C ${{matrix.build_type}} -V
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/build*
/.cache
/.vscode
43 changes: 43 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
cmake_minimum_required(VERSION 3.05)
project(HPACK LANGUAGES CXX)

### options ###

option(HPACK_ENABLE_TESTING "enables testing" OFF)

### dependecies ###

include(cmake/get_cpm.cmake)

set(BOOST_INCLUDE_LIBRARIES intrusive)
CPMAddPackage(
NAME Boost
VERSION 1.84.0
URL https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.xz
OPTIONS "BOOST_ENABLE_CMAKE ON"
)
unset(BOOST_INCLUDE_LIBRARIES)
find_package(Boost 1.84 COMPONENTS intrusive REQUIRED)

### hpacklib ###

add_library(hpacklib STATIC
"${CMAKE_CURRENT_SOURCE_DIR}/src/decoder.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/dynamic_table.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/huffman.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/static_table.cpp")

target_include_directories(hpacklib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")

target_link_libraries(hpacklib PUBLIC Boost::intrusive)

set_target_properties(hpacklib PROPERTIES
CMAKE_CXX_EXTENSIONS OFF
LINKER_LANGUAGE CXX
CMAKE_CXX_STANDARD_REQUIRED ON
CXX_STANDARD 20)

if(HPACK_ENABLE_TESTING)
include(CTest)
add_subdirectory(tests)
endif()
24 changes: 24 additions & 0 deletions cmake/get_cpm.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors

set(CPM_DOWNLOAD_VERSION 0.40.2)
set(CPM_HASH_SUM "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d")

if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()

# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)

file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
)

include(${CPM_DOWNLOAD_LOCATION})
126 changes: 126 additions & 0 deletions include/hpack/basic_types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#pragma once

#include <cstdint>
#include <iterator>
#include <string_view>

#ifndef KELBON_HPACK_HANDLE_PROTOCOL_ERROR

#include <exception>

namespace hpack {
struct protocol_error : std::exception {};
} // namespace hpack

#define KELBON_HPACK_HANDLE_PROTOCOL_ERROR \
throw ::hpack::protocol_error { \
}
#endif

namespace hpack {

struct sym_info_t {
uint32_t bits;
uint8_t bit_count;
};
extern const sym_info_t huffman_table[257];

// uint16_t(-1) if not found
uint16_t huffman_decode_table_find(sym_info_t info);

// integer/string len
using size_type = uint32_t;
// header index
using index_type = uint32_t;
using byte_t = unsigned char;
using In = const byte_t*;

template <typename T>
concept Out = std::output_iterator<T, byte_t>;

[[noreturn]] inline void handle_protocol_error() {
KELBON_HPACK_HANDLE_PROTOCOL_ERROR;
}
[[noreturn]] inline void handle_size_error() {
KELBON_HPACK_HANDLE_PROTOCOL_ERROR;
}

namespace noexport {

template <typename T>
struct adapted_output_iterator {
T base_it;
mutable byte_t byte = 0;

using iterator_category = std::output_iterator_tag;
using value_type = byte_t;
using difference_type = std::ptrdiff_t;

constexpr value_type& operator*() const noexcept {
return byte;
}
constexpr adapted_output_iterator& operator++() {
*base_it = byte;
++base_it;
return *this;
}
constexpr adapted_output_iterator operator++(int) {
auto cpy = *this;
++(*this);
return cpy;
}
};

template <Out O>
auto adapt_output_iterator(O it) {
return adapted_output_iterator<O>(it);
}
template <typename T>
auto adapt_output_iterator(adapted_output_iterator<T> it) {
return it;
}

inline byte_t* adapt_output_iterator(byte_t* ptr) {
return ptr;
}
inline byte_t* adapt_output_iterator(std::byte* ptr) {
return reinterpret_cast<byte_t*>(ptr);
}
inline byte_t* adapt_output_iterator(char* ptr) {
return reinterpret_cast<byte_t*>(ptr);
}

template <typename Original, typename T>
Original unadapt(adapted_output_iterator<T> it) {
return Original(std::move(it.base_it));
}

template <typename Original>
Original unadapt(byte_t* ptr) {
static_assert(std::is_pointer_v<Original>);
return reinterpret_cast<Original>(ptr);
}

} // namespace noexport

struct table_entry {
std::string_view name; // empty if not found
std::string_view value; // empty if no

constexpr explicit operator bool() const noexcept {
return !name.empty();
}
auto operator<=>(const table_entry&) const = default;
};

struct find_result_t {
// not found by default
index_type header_name_index = 0;
bool value_indexed = false;

constexpr explicit operator bool() const noexcept {
return header_name_index != 0;
}
};

} // namespace hpack
Loading

0 comments on commit c68ba32

Please sign in to comment.