add source file

This commit is contained in:
Neucrack
2024-04-25 16:22:02 +08:00
parent ee323a029b
commit fdb6c6e927
1633 changed files with 386243 additions and 0 deletions

74
.gitignore vendored Normal file
View File

@@ -0,0 +1,74 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# python
*.pyc
__pycache__
.venv
*.egg-info
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
dl/extracted/*
dl/pkgs/*
dl/pkgs_info.json
build
dist
.vscode
.config
.config.old
.config.mk
!tools/vscode/vscode_*_debug/.vscode
out/
docs/api/
projects/MaixPy/docs/api/

36
Kconfig Normal file
View File

@@ -0,0 +1,36 @@
mainmenu "MaixCDK configuration, platform: ${PLATFORM}"
menu "SDK Components Configuration"
osource "${SDK_PATH}/components/*/Kconfig"
endmenu
menu "3rd party Components Configuration"
osource "${SDK_PATH}/components/3rd_party/*/Kconfig"
endmenu
menu "Extra Components Configuration"
osource "${MAIXCDK_EXTRA_COMPONENTS_PATH}/*/Kconfig"
# components released with python package format, installed by pip install maixcdk-xxxx
# site-package directory is `python -c "import site;print(site.getusersitepackages())"`
osource "${PY_PKG_COMPONENTS_PATH}/*/Kconfig"
osource "${PY_USR_PKG_COMPONENTS_PATH}/*/Kconfig"
endmenu
menu "Project Components Configuration"
osource "${PROJECT_PATH}/../components/*/Kconfig"
osource "${PROJECT_PATH}/*/Kconfig"
osource "${PROJECT_PATH}/components/*/Kconfig"
endmenu
config LIBS_LINK_STATIC
bool "Link libraries statically"
default n
help
Link libraries statically, link all code to one executable file.
config COMPONENTS_COMPILE_FROM_SOURCE
bool "All components compile from source instead of using prebuilt libraries or local libraries"
default n
help
All components compile from source instead of using prebuilt libraries or local libraries.

49
LICENSE Normal file
View File

@@ -0,0 +1,49 @@
------------------------- MaixCDK -------------------------
Apache 2.0 License
Copyright (c) 2023- Sipeed Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
------------------------- MaixCDK end -------------------------
----------------- c_cpp_project_framework -----------------
The project framework is based on c_cpp_project_framework(https://github.com/neutree/c_cpp_project_framework)
MIT License
Copyright (c) 2019- Neucrack(CZD666666@gmail.com)
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.
----------------- c_cpp_project_framework end -----------------
And more submodules see the LICENSE file in each submodule.

View File

@@ -1,3 +1,64 @@
MaixCDK
===
English | [中文](./README_ZH.md)
MaixCDK (Maix C/CPP Development Kit) is a C/C++ development kit that integrates practical functions such as AI, machine vision, and IoT, providing easy-to-use encapsulation for quickly building your own projects in vision, artificial intelligence, IoT, robotics, industrial cameras, and more.
It is also the C/C++ version of [MaixPy](https://github.com/sipeed/MaixPy).
## Features
* Supports hardware-accelerated execution of AI models, including common classification, detection, and segmentation algorithms.
* Supports common vision algorithms such as color block detection, QR code recognition, apriltag detection, line following, etc.
* Supports OpenCV.
* Provides interfaces for common peripheral operations (UART, I2C, SPI, GPIO, PWM, ADC, camera, display, etc.).
* Cross-platform support, including Linux and Sipeed Maix series development boards (see table below for specifics).
* Easy-to-use API with commonly used function examples.
* Simple environment setup with one-click compilation.
* Supports online debugging of programs.
* Corresponding Python version (MaixPy) with automatically synchronized API updates.
* Complete ecosystem including MaixCDK + MaixPy + MaixVision (code writing, real-time image viewing, etc.) + MaixHub (application store, sharing, communication, etc.).
For more information, refer to the [MaixPy](https://github.com/sipeed/MaixPy) introduction and documentation.
## Supported Devices
| Device | Support Status |
| ------ | -------------- |
| Linux | Partial |
| [Sipeed MaixCAM](https://wiki.sipeed.com/maixcam) | Full |
## Quick Start
Click to view the [Quick Start](./docs/doc/dev/quick_start.md) document, which includes instructions on how to quickly download code, compile, and run.
## MaixCDK Development Guidelines
To help developers quickly understand MaixCDK and maintain the quality of long-term updates, please read the [MaixCDK Development Guidelines and Guidelines](./docs/doc/convention/README.md) before writing or contributing code.
## More Documentation
In addition to the development guidelines above, the documentation also includes application documents, development notes, and more for reference.
The documents are written in `Markdown` format under the [docs](./docs) directory. You can directly view the `.md` files or generate a web version of the documentation using the [teedoc](https://github.com/teedoc/teedoc) tool.
```shell
pip install teedoc -U # Install teedoc via pip
cd docs # Navigate to the docs directory
teedoc install -i https://pypi.tuna.tsinghua.edu.cn/simple # Install teedoc plugins according to the documentation
teedoc serve # Start a local web service to preview
```
Then, access the documentation via `http://127.0.0.1:2333` in your browser.
> If you need to generate offline documentation, use the `teedoc build` command. The generated documents will be in the `out` directory. Use `python -m http.server` in the `out` directory to start a local web service for preview.
## FAQ
If you encounter any issues during compilation or usage, check the [FAQ](./docs/doc/faq.md) for potential solutions.
## Open Source License
MaixCDK is licensed under the Apache 2.0 open source license. See the [LICENSE](./LICENSE) file for details.

73
README_ZH.md Normal file
View File

@@ -0,0 +1,73 @@
MaixCDK
===================
[English](./README.md) | 中文
MaixCDK(Maix C/CPP Development Kit) 是集成了 AI + 机器视觉 + IOT 等实用功能的 C/C++ 开发套件简单易用的封装让你快速构建自己的视觉、人工智能、IOT、机器人、工业相机等项目。
也是 [MaixPy](https://github.com/sipeed/MaixPy) 的 C/C++ 版本。
## 特性
* 支持 AI 模型硬件加速运行,支持常见 分类、检测、分割算法。
* 支持常用视觉算法,比如 找色块、二维码、apriltag、巡线等等。
* 支持 OpenCV。
* 常用外设操作UART、IIC、SPI、GPIO、PWM、ADC、摄像头、屏幕等
* 多平台支持, 支持 LinuxSipeed Maix 系列开发板(具体看下方表格)。
* 简单易用的 API提供常用功能例程。
* 环境搭建简单,一键编译。
* 支持在线调试程序。
* 有对应的 Python 版本MaixPyAPI 自动同步更新。
* 完整生态, MaixCDK + MaixPy + MaixVision代码编写实时图像查看等 + MaixHub应用商店分享交流等
更多介绍可以看 [MaixPy](https://github.com/sipeed/MaixPy) 介绍和文档
## 支持的设备
| 设备名 | 支持状态 |
| ----- | ------- |
| Linux | 部分支持 |
| [Sipeed MaixCAM](https://wiki.sipeed.com/maixcam) | 完全支持 |
## 快速开始
点击查看 [快速开始](./docs/doc/dev/quick_start.md) 文档,里面包含了如何快速下载代码、编译、运行
## MaixCDK 开发准则
为帮助开发者快速了解 MaixCDK, 以及保持长期更新的质量,在 编写 或 贡献 代码前,请务必阅读 [MaixCDK 开发准则和指导](./docs/doc/convention/README.md)。
## 更多文档
出了上面的开发准则,文档里面还有应用文档,开发笔记等供查阅。
文档在[docs](./docs)目录下,使用`Markdown`格式编写,可以直接查看`.md`文件,
也可以使用[teedoc](https://github.com/teedoc/teedoc)工具生成网页版文档。
```shell
pip install teedoc -U # 用 pip 安装 teedoc
cd docs # 进入 docs 目录
teedoc install -i https://pypi.tuna.tsinghua.edu.cn/simple # 根据文档配置安装 teedoc 插件
teedoc serve # 启动一个本地网页服务用以预览
```
然后用浏览器访问`http://127.0.0.1:2333`即可看到文档。
> 如果需要生成离线文档,使用`teedoc build`命令,生成的文档在`out`目录下,
> 使用者在`out`目录下使用`python -m http.server`命令来启动一个本地网页服务用以预览。
## 常见问题
在编译或者使用时遇到问题,首先看下[FAQ](./docs/doc/faq.md)是否有解决方案。
## 开源协议
MaixCDK 采用 Apache 2.0 开源协议,详见 [LICENSE](./LICENSE) 文件。

View File

@@ -0,0 +1,85 @@
list(APPEND ADD_FILE_DOWNLOADS "{
'url': 'https://phoenixnap.dl.sourceforge.net/project/asio/asio/1.28.0%20%28Stable%29/asio-1.28.0.tar.gz',
'urls':[],
'sites': ['https://sourceforge.net/projects/asio/files/asio/1.28.0%20%28Stable%29/'],
'sha256sum': 'e854a53cc6fe599bdf830e3c607f1d22fe74eee892f64c81d3ca997a80ddca97',
'filename': 'asio-1.28.0.tar.gz',
'path': 'asio',
'check_files': ['asio-1.28.0']
}"
)
set(asio_root "${DL_EXTRACTED_PATH}/asio/asio-1.28.0")
list(APPEND ADD_INCLUDE "${asio_root}/include")
# append_srcs_dir(ADD_SRCS "${asio_root}/src")
list(APPEND ADD_DEFINITIONS -DASIO_STANDALONE=1)
################# Add include #################
# list(APPEND ADD_INCLUDE "${websocketpp_root}"
# )
# list(APPEND ADD_PRIVATE_INCLUDE "include_private")
###############################################
############## Add source files ###############
# list(APPEND ADD_SRCS "src/lib1.c"
# )
# aux_source_directory("inifile2/src" ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS component1)
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS m) # add system libs, pthread or m(math) lib for example
###############################################
############ Add static libs ##################
# if(CONFIG_COMPONENT1_INCLUDE_STATIC_LIB)
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
# endif()
###############################################
############ Add dynamic libs ##################
# list(APPEND ADD_DYNAMIC_LIB "lib/arch/v831/libmaix_nn.so"
# "lib/arch/v831/libmaix_cam.so"
# )
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
###############################################
############ Add static libs ##################
#### Update parent's variables like CMAKE_C_LINK_FLAGS
# set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group libmaix/libtest.a -ltest2 -Wl,--end-group" PARENT_SCOPE)
###############################################
######### Add files need to download #########
# list(APPEND ADD_FILE_DOWNLOADS "{
# 'url': 'https://*****/abcde.tar.xz',
# 'urls': [],
# 'sha256sum': '',
# 'filename': 'abcde.tar.xz',
# 'path': 'toolchains/xxxxx',
# 'check_files': []
# }"
# )
#
# then extracted file in ${DL_EXTRACTED_PATH}/toolchains/xxxxx,
# you can directly use then, for example use it in add_custom_command
##############################################
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
register_component()

0
components/3rd_party/asio/Kconfig vendored Normal file
View File

View File

@@ -0,0 +1,142 @@
############### Add include ###################
# list(APPEND ADD_INCLUDE "include"
# )
# list(APPEND ADD_PRIVATE_INCLUDE "")
###############################################
############ Add source files #################
# list(APPEND ADD_SRCS "src/main.c"
# "src/test.c"
# )
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test2.c")
# FILE(GLOB_RECURSE EXTRA_SRC "src/*.c")
# FILE(GLOB EXTRA_SRC "src/*.c")
# list(APPEND ADD_SRCS ${EXTRA_SRC})
# aux_source_directory(src ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
# set(ADD_ASM_SRCS "src/asm.S")
# list(APPEND ADD_SRCS ${ADD_ASM_SRCS})
# SET_PROPERTY(SOURCE ${ADD_ASM_SRCS} PROPERTY LANGUAGE C) # set .S ASM file as C language
# SET_SOURCE_FILES_PROPERTIES(${ADD_ASM_SRCS} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp -D BBBBB")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS basic)
# list(APPEND ADD_FILE_DEPENDS include/axx.h)
# set_property(SOURCE ${python_h_path} PROPERTY GENERATED 1)
# add_custom_command(OUTPUT include/axx.h
# COMMAND echo "" > include/axx.h
# COMMENT "Generating axx.h ..."
# )
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS pthread m) # add system libs, pthread and math lib for example here
# set (brotli_DIR brotli/lib/cmake/brotli4)
# find_package(brotli REQUIRED)
###############################################
############ Add static libs ##################
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
###############################################
############ Add dynamic libs ##################
# list(APPEND ADD_DYNAMIC_LIB "lib/arch/v831/libmaix_nn.so"
# "lib/arch/v831/libmaix_cam.so"
# )
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
###############################################
############ Add static libs ##################
#### Update parent's variables like CMAKE_C_LINK_FLAGS
# set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group libmaix/libtest.a -ltest2 -Wl,--end-group" PARENT_SCOPE)
###############################################
######### Add files need to download #########
# list(APPEND ADD_FILE_DOWNLOADS "{
# 'url': 'https://*****/abcde.tar.xz',
# 'urls': [], # backup urls, if url failed, will try urls
# 'sites': [], # download site, user can manually download file and put it into dl_path
# 'sha256sum': '',
# 'filename': 'abcde.tar.xz',
# 'path': 'toolchains/xxxxx',
# 'check_files': []
# }"
# )
#
# then extracted file in ${DL_EXTRACTED_PATH}/toolchains/xxxxx,
# you can directly use then, for example use it in add_custom_command
##############################################
set(version_str "${CONFIG_BROTLI_VERSION_MAJOR}.${CONFIG_BROTLI_VERSION_MINOR}.${CONFIG_BROTLI_VERSION_PATCH}")
# write build python version to CMAKE_BINARY_DIR/config/python_version.txt
# file(WRITE ${CMAKE_BINARY_DIR}/config/brotli_version.txt "${version_str}")
set(install_dir "${CMAKE_BINARY_DIR}/brotli_install")
set(include_dir "${install_dir}/include/brotli" "${install_dir}/include")
set(h_path "${install_dir}/include/brotli/decode.h")
set(lib_file "${install_dir}/lib/libbrotlidec.a" "${install_dir}/lib/libbrotlicommon.a" "${install_dir}/lib/libbrotlienc.a")
set(build_dir "${CMAKE_BINARY_DIR}/brotli_build")
list(APPEND ADD_INCLUDE ${include_dir})
list(APPEND ADD_STATIC_LIB ${lib_file})
set_property(SOURCE ${include_dir} PROPERTY GENERATED 1)
set_property(SOURCE ${h_path} PROPERTY GENERATED 1)
set_property(SOURCE ${lib_file} PROPERTY GENERATED 1)
set(brotli_url "https://master.dl.sourceforge.net/project/brotli.mirror/v${version_str}/v${version_str}.tar.gz?viasf=1")
set(brotli_filename "brotli-${version_str}.tar.gz")
set(brotli_unzip_path "${DL_EXTRACTED_PATH}/brotli_srcs")
set(brotli_src_path "${brotli_unzip_path}/google-brotli-${version_str}")
if(version_str EQUAL "1.1.0")
set(brotli_file_sha256sum "10973f4b4199eafa1d5735ef661ddb2ec2f97319ee9fd1824d4aabe08cff5265")
set(brotli_src_path "${brotli_unzip_path}/google-brotli-ed738e8")
else()
message(FATAL_ERROR "No brotli version ${version_str} support, please edit to add brotli support for this version")
endif()
list(APPEND ADD_FILE_DOWNLOADS "{
'url': '${brotli_url}',
'urls': [],
'sha256sum': '${brotli_file_sha256sum}',
'filename': '${brotli_filename}',
'path': 'brotli_srcs',
'check_files': ['google-brotli-${version_str}']
}"
)
if(PLATFORM_M2DOCK)
set(brotli_toolchain_file ${CMAKE_CURRENT_LIST_DIR}/toolchain_m2dock.cmake)
elseif(PLATFORM_MAIXCAM)
set(brotli_toolchain_file ${CMAKE_CURRENT_LIST_DIR}/toolchain_linux_cross.cmake)
elseif(PLATFORM_LINUX)
set(brotli_toolchain_file ${CMAKE_CURRENT_LIST_DIR}/toolchain_linux.cmake)
else()
message(FATAL_ERROR "No brotli toolchain config for this board, please edit to add brotli support for this board")
endif()
set(brotli_compile_cmd COMMAND mkdir -p ${build_dir} && cd ${build_dir} && SDK_PATH=${SDK_PATH} TOOLCHAIN_PATH=${CONFIG_TOOLCHAIN_PATH} TOOLCHAIN_PREFIX=${CONFIG_TOOLCHAIN_PREFIX} cmake -DBROTLI_DISABLE_TESTS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_TOOLCHAIN_FILE=${brotli_toolchain_file} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${install_dir} ${brotli_src_path} && make -j`nproc` install)
add_custom_command(OUTPUT ${h_path}
${brotli_compile_cmd}
COMMENT "Building brotli-${version_str} ..."
)
list(APPEND ADD_FILE_DEPENDS ${h_path})
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
register_component()

20
components/3rd_party/brotli/Kconfig vendored Normal file
View File

@@ -0,0 +1,20 @@
# BROTLI version major minor patch
menu "BROTLI version"
config BROTLI_VERSION_MAJOR
int "BROTLI package major version"
default 1
help
BROTLI package major version, 0 means auto select according to board
config BROTLI_VERSION_MINOR
int "BROTLI package minor version"
default 1
help
BROTLI package minor version
config BROTLI_VERSION_PATCH
int "BROTLI package patch version"
default 0
help
BROTLI package patch version
endmenu

View File

@@ -0,0 +1,26 @@
set(CMAKE_SYSTEM_NAME Linux)
# CMAKE_SYSTEM_PROCESSOR from command `uname -m`
execute_process(COMMAND uname -m OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR OUTPUT_STRIP_TRAILING_WHITESPACE)
# set(GNU_MACHINE "arm-openwrt-linux" CACHE STRING "GNU compiler triple")
# if(NOT CMAKE_INSTALL_PREFIX)
# set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/opencv4_install)
# endif()
# set(SDK_PATH $ENV{SDK_PATH}) # toolchain cmake file can not read var from cmake cmd's -D option, so use env var instead
# if(NOT TOOLCHAIN_PATH)
# if($ENV{TOOLCHAIN_PATH} STREQUAL "")
# set(TOOLCHAIN_PATH "${SDK_PATH}/dl/extracted/toolchains/m2dock/toolchain-sunxi-musl/toolchain/bin")
# else()
# set(TOOLCHAIN_PATH $ENV{TOOLCHAIN_PATH})
# endif()
# endif()
# set(prefix "arm-openwrt-linux-")
# set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/${prefix}gcc)
# set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/${prefix}g++)
# include("${CMAKE_CURRENT_LIST_DIR}/opencv4/platforms/linux/arm.toolchain.cmake")

View File

@@ -0,0 +1,22 @@
set(CMAKE_SYSTEM_NAME Linux)
set(toolchain $ENV{TOOLCHAIN_PATH})
set(prefix $ENV{TOOLCHAIN_PREFIX})
string(LENGTH "${toolchain}" toolchain_prefix_len)
math(EXPR toolchain_prefix_len "${toolchain_prefix_len} - 1")
string(SUBSTRING "${prefix}" 0 ${toolchain_prefix_len} prefix_no_minus)
# set(GNU_MACHINE "${prefix_no_minus}" CACHE STRING "GNU compiler triple")
execute_process(COMMAND ${toolchain}/${prefix}gcc -dumpmachine OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR)
string(REGEX REPLACE "([^-]+)-.*" "\\1" CMAKE_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_C_COMPILER ${toolchain}/${prefix}gcc)
set(CMAKE_CXX_COMPILER ${toolchain}/${prefix}g++)
# if ${toolchain}/../sysroot exists, set CMAKE_SYSROOT
if(EXISTS ${toolchain}/../sysroot)
set(CMAKE_SYSROOT ${toolchain}/../sysroot)
endif()

View File

@@ -0,0 +1,22 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(GNU_MACHINE "arm-openwrt-linux" CACHE STRING "GNU compiler triple")
if(NOT CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/freetype_install)
endif()
# toolchain path must the same as sdk_path/platforms/xxxx.yaml
set(SDK_PATH $ENV{SDK_PATH}) # toolchain cmake file can not read var from cmake cmd's -D option, so use env var instead
if(NOT TOOLCHAIN_PATH)
if($ENV{TOOLCHAIN_PATH} STREQUAL "")
set(TOOLCHAIN_PATH "${SDK_PATH}/dl/extracted/toolchains/m2dock/toolchain-sunxi-musl/toolchain/bin")
else()
set(TOOLCHAIN_PATH $ENV{TOOLCHAIN_PATH})
endif()
endif()
set(prefix "arm-openwrt-linux-")
set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/${prefix}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/${prefix}g++)

View File

@@ -0,0 +1,87 @@
list(APPEND ADD_REQUIREMENTS brotli openssl)
list(APPEND ADD_INCLUDE "cpp-httplib")
list(APPEND ADD_DEFINITIONS -DCPPHTTPLIB_OPENSSL_SUPPORT=1)
register_component()
# Config enable component2 or not in Kconfig
################# Add include #################
# list(APPEND ADD_INCLUDE "include"
# )
# list(APPEND ADD_PRIVATE_INCLUDE "include_private")
###############################################
############## Add source files ###############
# list(APPEND ADD_SRCS "src/lib2.c"
# )
# FILE(GLOB_RECURSE EXTRA_SRC "src/*.c")
# FILE(GLOB EXTRA_SRC "src/*.c")
# list(APPEND ADD_SRCS ${EXTRA_SRC})
# aux_source_directory(src ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
# set(ADD_ASM_SRCS "src/asm.S")
# list(APPEND ADD_SRCS ${ADD_ASM_SRCS})
# SET_PROPERTY(SOURCE ${ADD_ASM_SRCS} PROPERTY LANGUAGE C) # set .S ASM file as C language
# SET_SOURCE_FILES_PROPERTIES(${ADD_ASM_SRCS} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp -D BBBBB")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS basic ini)
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS pthread m) # add system libs, pthread and math lib for example here
# set (OpenCV_DIR opencv/lib/cmake/opencv4)
# find_package(OpenCV REQUIRED)
###############################################
############ Add static libs ##################
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
###############################################
############ Add dynamic libs ##################
# list(APPEND ADD_DYNAMIC_LIB "lib/arch/v831/libmaix_nn.so"
# "lib/arch/v831/libmaix_cam.so"
# )
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
###############################################
############ Add static libs ##################
#### Update parent's variables like CMAKE_C_LINK_FLAGS
# set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group libmaix/libtest.a -ltest2 -Wl,--end-group" PARENT_SCOPE)
###############################################
######### Add files need to download #########
# list(APPEND ADD_FILE_DOWNLOADS "{
# 'url': 'https://*****/abcde.tar.xz',
# 'urls': [], # backup urls, if url failed, will try urls
# 'sites': [], # download site, user can manually download file and put it into dl_path
# 'sha256sum': '',
# 'filename': 'abcde.tar.xz',
# 'path': 'toolchains/xxxxx',
# 'check_files': []
# }"
# )
#
# then extracted file in ${DL_EXTRACTED_PATH}/toolchains/xxxxx,
# you can directly use then, for example use it in add_custom_command
##############################################
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
# register_component()

View File

View File

@@ -0,0 +1,301 @@
#[[
Build options:
* BUILD_SHARED_LIBS (default off) builds as a shared library (if HTTPLIB_COMPILE is ON)
* HTTPLIB_USE_OPENSSL_IF_AVAILABLE (default on)
* HTTPLIB_USE_ZLIB_IF_AVAILABLE (default on)
* HTTPLIB_USE_BROTLI_IF_AVAILABLE (default on)
* HTTPLIB_REQUIRE_OPENSSL (default off)
* HTTPLIB_REQUIRE_ZLIB (default off)
* HTTPLIB_REQUIRE_BROTLI (default off)
* HTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN (default on)
* HTTPLIB_COMPILE (default off)
* HTTPLIB_INSTALL (default on)
* HTTPLIB_TEST (default off)
* BROTLI_USE_STATIC_LIBS - tells Cmake to use the static Brotli libs (only works if you have them installed).
* OPENSSL_USE_STATIC_LIBS - tells Cmake to use the static OpenSSL libs (only works if you have them installed).
-------------------------------------------------------------------------------
After installation with Cmake, a find_package(httplib COMPONENTS OpenSSL ZLIB Brotli) is available.
This creates a httplib::httplib target (if found and if listed components are supported).
It can be linked like so:
target_link_libraries(your_exe httplib::httplib)
The following will build & install for later use.
Linux/macOS:
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
sudo cmake --build . --target install
Windows:
mkdir build
cd build
cmake ..
runas /user:Administrator "cmake --build . --config Release --target install"
-------------------------------------------------------------------------------
These variables are available after you run find_package(httplib)
* HTTPLIB_HEADER_PATH - this is the full path to the installed header (e.g. /usr/include/httplib.h).
* HTTPLIB_IS_USING_OPENSSL - a bool for if OpenSSL support is enabled.
* HTTPLIB_IS_USING_ZLIB - a bool for if ZLIB support is enabled.
* HTTPLIB_IS_USING_BROTLI - a bool for if Brotli support is enabled.
* HTTPLIB_IS_USING_CERTS_FROM_MACOSX_KEYCHAIN - a bool for if support of loading system certs from the Apple Keychain is enabled.
* HTTPLIB_IS_COMPILED - a bool for if the library is compiled, or otherwise header-only.
* HTTPLIB_INCLUDE_DIR - the root path to httplib's header (e.g. /usr/include).
* HTTPLIB_LIBRARY - the full path to the library if compiled (e.g. /usr/lib/libhttplib.so).
* httplib_VERSION or HTTPLIB_VERSION - the project's version string.
* HTTPLIB_FOUND - a bool for if the target was found.
Want to use precompiled headers (Cmake feature since v3.16)?
It's as simple as doing the following (before linking):
target_precompile_headers(httplib::httplib INTERFACE "${HTTPLIB_HEADER_PATH}")
-------------------------------------------------------------------------------
ARCH_INDEPENDENT option of write_basic_package_version_file() requires Cmake v3.14
]]
cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR)
# Get the CPPHTTPLIB_VERSION value and use it as a version
# This gets the string with the CPPHTTPLIB_VERSION value from the header.
# This is so the maintainer doesn't actually need to update this manually.
file(STRINGS httplib.h _raw_version_string REGEX "CPPHTTPLIB_VERSION \"([0-9]+\\.[0-9]+\\.[0-9]+)\"")
# Extracts just the version string itself from the whole string contained in _raw_version_string
# since _raw_version_string would contain the entire line of code where it found the version string
string(REGEX MATCH "([0-9]+\\.?)+" _httplib_version "${_raw_version_string}")
project(httplib
VERSION ${_httplib_version}
LANGUAGES CXX
DESCRIPTION "A C++ header-only HTTP/HTTPS server and client library."
HOMEPAGE_URL "https://github.com/yhirose/cpp-httplib"
)
# Change as needed to set an OpenSSL minimum version.
# This is used in the installed Cmake config file.
set(_HTTPLIB_OPENSSL_MIN_VER "3.0.0")
# Lets you disable C++ exception during CMake configure time.
# The value is used in the install CMake config file.
option(HTTPLIB_NO_EXCEPTIONS "Disable the use of C++ exceptions" OFF)
# Allow for a build to require OpenSSL to pass, instead of just being optional
option(HTTPLIB_REQUIRE_OPENSSL "Requires OpenSSL to be found & linked, or fails build." OFF)
option(HTTPLIB_REQUIRE_ZLIB "Requires ZLIB to be found & linked, or fails build." OFF)
# Allow for a build to casually enable OpenSSL/ZLIB support, but silently continue if not found.
# Make these options so their automatic use can be specifically disabled (as needed)
option(HTTPLIB_USE_OPENSSL_IF_AVAILABLE "Uses OpenSSL (if available) to enable HTTPS support." ON)
option(HTTPLIB_USE_ZLIB_IF_AVAILABLE "Uses ZLIB (if available) to enable Zlib compression support." ON)
# Lets you compile the program as a regular library instead of header-only
option(HTTPLIB_COMPILE "If ON, uses a Python script to split the header into a compilable header & source file (requires Python v3)." OFF)
# Lets you disable the installation (useful when fetched from another CMake project)
option(HTTPLIB_INSTALL "Enables the installation target" ON)
option(HTTPLIB_TEST "Enables testing and builds tests" OFF)
option(HTTPLIB_REQUIRE_BROTLI "Requires Brotli to be found & linked, or fails build." OFF)
option(HTTPLIB_USE_BROTLI_IF_AVAILABLE "Uses Brotli (if available) to enable Brotli decompression support." ON)
option(HTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN "Enable feature to load system certs from the Apple Keychain." ON)
# Defaults to static library
option(BUILD_SHARED_LIBS "Build the library as a shared library instead of static. Has no effect if using header-only." OFF)
if (BUILD_SHARED_LIBS AND WIN32 AND HTTPLIB_COMPILE)
# Necessary for Windows if building shared libs
# See https://stackoverflow.com/a/40743080
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
# Set some variables that are used in-tree and while building based on our options
set(HTTPLIB_IS_COMPILED ${HTTPLIB_COMPILE})
set(HTTPLIB_IS_USING_CERTS_FROM_MACOSX_KEYCHAIN ${HTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN})
# Threads needed for <thread> on some systems, and for <pthread.h> on Linux
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
# Since Cmake v3.11, Crypto & SSL became optional when not specified as COMPONENTS.
if(HTTPLIB_REQUIRE_OPENSSL)
find_package(OpenSSL ${_HTTPLIB_OPENSSL_MIN_VER} COMPONENTS Crypto SSL REQUIRED)
set(HTTPLIB_IS_USING_OPENSSL TRUE)
elseif(HTTPLIB_USE_OPENSSL_IF_AVAILABLE)
find_package(OpenSSL ${_HTTPLIB_OPENSSL_MIN_VER} COMPONENTS Crypto SSL QUIET)
# Avoid a rare circumstance of not finding all components but the end-user did their
# own call for OpenSSL, which might trick us into thinking we'd otherwise have what we wanted
if (TARGET OpenSSL::SSL AND TARGET OpenSSL::Crypto)
set(HTTPLIB_IS_USING_OPENSSL ${OPENSSL_FOUND})
else()
set(HTTPLIB_IS_USING_OPENSSL FALSE)
endif()
endif()
if(HTTPLIB_REQUIRE_ZLIB)
find_package(ZLIB REQUIRED)
set(HTTPLIB_IS_USING_ZLIB TRUE)
elseif(HTTPLIB_USE_ZLIB_IF_AVAILABLE)
find_package(ZLIB QUIET)
# FindZLIB doesn't have a ZLIB_FOUND variable, so check the target.
if(TARGET ZLIB::ZLIB)
set(HTTPLIB_IS_USING_ZLIB TRUE)
endif()
endif()
# Adds our cmake folder to the search path for find_package
# This is so we can use our custom FindBrotli.cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if(HTTPLIB_REQUIRE_BROTLI)
find_package(Brotli COMPONENTS encoder decoder common REQUIRED)
set(HTTPLIB_IS_USING_BROTLI TRUE)
elseif(HTTPLIB_USE_BROTLI_IF_AVAILABLE)
find_package(Brotli COMPONENTS encoder decoder common QUIET)
set(HTTPLIB_IS_USING_BROTLI ${Brotli_FOUND})
endif()
# Used for default, common dirs that the end-user can change (if needed)
# like CMAKE_INSTALL_INCLUDEDIR or CMAKE_INSTALL_DATADIR
include(GNUInstallDirs)
if(HTTPLIB_COMPILE)
# Put the split script into the build dir
configure_file(split.py "${CMAKE_CURRENT_BINARY_DIR}/split.py"
COPYONLY
)
# Needs to be in the same dir as the python script
configure_file(httplib.h "${CMAKE_CURRENT_BINARY_DIR}/httplib.h"
COPYONLY
)
# Used outside of this if-else
set(_INTERFACE_OR_PUBLIC PUBLIC)
# Brings in the Python3_EXECUTABLE path we can use.
find_package(Python3 REQUIRED)
# Actually split the file
# Keeps the output in the build dir to not pollute the main dir
execute_process(COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/split.py"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
ERROR_VARIABLE _httplib_split_error
)
if(_httplib_split_error)
message(FATAL_ERROR "Failed when trying to split cpp-httplib with the Python script.\n${_httplib_split_error}")
endif()
# split.py puts output in "out"
set(_httplib_build_includedir "${CMAKE_CURRENT_BINARY_DIR}/out")
# This will automatically be either static or shared based on the value of BUILD_SHARED_LIBS
add_library(${PROJECT_NAME} "${_httplib_build_includedir}/httplib.cc")
target_sources(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${_httplib_build_includedir}/httplib.h>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/httplib.h>
)
set_target_properties(${PROJECT_NAME}
PROPERTIES
VERSION ${${PROJECT_NAME}_VERSION}
SOVERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}"
)
else()
# This is for header-only.
set(_INTERFACE_OR_PUBLIC INTERFACE)
add_library(${PROJECT_NAME} INTERFACE)
set(_httplib_build_includedir "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
# Lets you address the target with httplib::httplib
# Only useful if building in-tree, versus using it from an installation.
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
# Require C++11
target_compile_features(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC} cxx_std_11)
target_include_directories(${PROJECT_NAME} SYSTEM ${_INTERFACE_OR_PUBLIC}
$<BUILD_INTERFACE:${_httplib_build_includedir}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
# Always require threads
target_link_libraries(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
Threads::Threads
# Needed for Windows libs on Mingw, as the pragma comment(lib, "xyz") aren't triggered.
$<$<PLATFORM_ID:Windows>:ws2_32>
$<$<PLATFORM_ID:Windows>:crypt32>
# Needed for API from MacOS Security framework
"$<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>,$<BOOL:${HTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN}>>:-framework CoreFoundation -framework Security>"
# Can't put multiple targets in a single generator expression or it bugs out.
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:Brotli::common>
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:Brotli::encoder>
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:Brotli::decoder>
$<$<BOOL:${HTTPLIB_IS_USING_ZLIB}>:ZLIB::ZLIB>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:OpenSSL::SSL>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:OpenSSL::Crypto>
)
# Set the definitions to enable optional features
target_compile_definitions(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
$<$<BOOL:${HTTPLIB_NO_EXCEPTIONS}>:CPPHTTPLIB_NO_EXCEPTIONS>
$<$<BOOL:${HTTPLIB_IS_USING_BROTLI}>:CPPHTTPLIB_BROTLI_SUPPORT>
$<$<BOOL:${HTTPLIB_IS_USING_ZLIB}>:CPPHTTPLIB_ZLIB_SUPPORT>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:CPPHTTPLIB_OPENSSL_SUPPORT>
$<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>,$<BOOL:${HTTPLIB_IS_USING_CERTS_FROM_MACOSX_KEYCHAIN}>>:CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN>
)
# CMake configuration files installation directory
set(_TARGET_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
include(CMakePackageConfigHelpers)
# Configures the meta-file httplibConfig.cmake.in to replace variables with paths/values/etc.
configure_package_config_file("${PROJECT_NAME}Config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "${_TARGET_INSTALL_CMAKEDIR}"
# Passes the includedir install path
PATH_VARS CMAKE_INSTALL_FULL_INCLUDEDIR
)
if(HTTPLIB_COMPILE)
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
# Example: if you find_package(httplib 0.5.4)
# then anything >= 0.5.4 and < 0.6 is accepted
COMPATIBILITY SameMinorVersion
)
else()
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
# Example: if you find_package(httplib 0.5.4)
# then anything >= 0.5.4 and < 0.6 is accepted
COMPATIBILITY SameMinorVersion
# Tells Cmake that it's a header-only lib
# Mildly useful for end-users :)
ARCH_INDEPENDENT
)
endif()
if(HTTPLIB_INSTALL)
# Creates the export httplibTargets.cmake
# This is strictly what holds compilation requirements
# and linkage information (doesn't find deps though).
install(TARGETS ${PROJECT_NAME} EXPORT httplibTargets)
install(FILES "${_httplib_build_includedir}/httplib.h" TYPE INCLUDE)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
# Install it so it can be used later by the httplibConfig.cmake file.
# Put it in the same dir as our config file instead of a global path so we don't potentially stomp on other packages.
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindBrotli.cmake"
DESTINATION ${_TARGET_INSTALL_CMAKEDIR}
)
# NOTE: This path changes depending on if it's on Windows or Linux
install(EXPORT httplibTargets
# Puts the targets into the httplib namespace
# So this makes httplib::httplib linkable after doing find_package(httplib)
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${_TARGET_INSTALL_CMAKEDIR}
)
endif()
if(HTTPLIB_TEST)
include(CTest)
add_subdirectory(test)
endif()

View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2017 yhirose
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.

View File

@@ -0,0 +1,874 @@
cpp-httplib
===========
[![](https://github.com/yhirose/cpp-httplib/workflows/test/badge.svg)](https://github.com/yhirose/cpp-httplib/actions)
A C++11 single-file header-only cross platform HTTP/HTTPS library.
It's extremely easy to setup. Just include the **httplib.h** file in your code!
NOTE: This library uses 'blocking' socket I/O. If you are looking for a library with 'non-blocking' socket I/O, this is not the one that you want.
Simple examples
---------------
#### Server (Multi-threaded)
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"
// HTTP
httplib::Server svr;
// HTTPS
httplib::SSLServer svr;
svr.Get("/hi", [](const httplib::Request &, httplib::Response &res) {
res.set_content("Hello World!", "text/plain");
});
svr.listen("0.0.0.0", 8080);
```
#### Client
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"
// HTTP
httplib::Client cli("http://cpp-httplib-server.yhirose.repl.co");
// HTTPS
httplib::Client cli("https://cpp-httplib-server.yhirose.repl.co");
auto res = cli.Get("/hi");
res->status;
res->body;
```
SSL Support
-----------
SSL support is available with `CPPHTTPLIB_OPENSSL_SUPPORT`. `libssl` and `libcrypto` should be linked.
NOTE: cpp-httplib currently supports only version 3.0 or later. Please see [this page](https://www.openssl.org/policies/releasestrat.html) to get more information.
NOTE for macOS: cpp-httplib now can use system certs with `CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN`. `CoreFoundation` and `Security` should be linked with `-framework`.
```c++
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "path/to/httplib.h"
// Server
httplib::SSLServer svr("./cert.pem", "./key.pem");
// Client
httplib::Client cli("https://localhost:1234"); // scheme + host
httplib::SSLClient cli("localhost:1234"); // host
httplib::SSLClient cli("localhost", 1234); // host, port
// Use your CA bundle
cli.set_ca_cert_path("./ca-bundle.crt");
// Disable cert verification
cli.enable_server_certificate_verification(false);
```
NOTE: When using SSL, it seems impossible to avoid SIGPIPE in all cases, since on some operating systems, SIGPIPE can only be suppressed on a per-message basis, but there is no way to make the OpenSSL library do so for its internal communications. If your program needs to avoid being terminated on SIGPIPE, the only fully general way might be to set up a signal handler for SIGPIPE to handle or ignore it yourself.
Server
------
```c++
#include <httplib.h>
int main(void)
{
using namespace httplib;
Server svr;
svr.Get("/hi", [](const Request& req, Response& res) {
res.set_content("Hello World!", "text/plain");
});
// Match the request path against a regular expression
// and extract its captures
svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
auto numbers = req.matches[1];
res.set_content(numbers, "text/plain");
});
// Capture the second segment of the request path as "id" path param
svr.Get("/users/:id", [&](const Request& req, Response& res) {
auto user_id = req.path_params.at("id");
res.set_content(user_id, "text/plain");
});
// Extract values from HTTP headers and URL query params
svr.Get("/body-header-param", [](const Request& req, Response& res) {
if (req.has_header("Content-Length")) {
auto val = req.get_header_value("Content-Length");
}
if (req.has_param("key")) {
auto val = req.get_param_value("key");
}
res.set_content(req.body, "text/plain");
});
svr.Get("/stop", [&](const Request& req, Response& res) {
svr.stop();
});
svr.listen("localhost", 1234);
}
```
`Post`, `Put`, `Delete` and `Options` methods are also supported.
### Bind a socket to multiple interfaces and any available port
```cpp
int port = svr.bind_to_any_port("0.0.0.0");
svr.listen_after_bind();
```
### Static File Server
```cpp
// Mount / to ./www directory
auto ret = svr.set_mount_point("/", "./www");
if (!ret) {
// The specified base directory doesn't exist...
}
// Mount /public to ./www directory
ret = svr.set_mount_point("/public", "./www");
// Mount /public to ./www1 and ./www2 directories
ret = svr.set_mount_point("/public", "./www1"); // 1st order to search
ret = svr.set_mount_point("/public", "./www2"); // 2nd order to search
// Remove mount /
ret = svr.remove_mount_point("/");
// Remove mount /public
ret = svr.remove_mount_point("/public");
```
```cpp
// User defined file extension and MIME type mappings
svr.set_file_extension_and_mimetype_mapping("cc", "text/x-c");
svr.set_file_extension_and_mimetype_mapping("cpp", "text/x-c");
svr.set_file_extension_and_mimetype_mapping("hh", "text/x-h");
```
The followings are built-in mappings:
| Extension | MIME Type | Extension | MIME Type |
| :--------- | :-------------------------- | :--------- | :-------------------------- |
| css | text/css | mpga | audio/mpeg |
| csv | text/csv | weba | audio/webm |
| txt | text/plain | wav | audio/wave |
| vtt | text/vtt | otf | font/otf |
| html, htm | text/html | ttf | font/ttf |
| apng | image/apng | woff | font/woff |
| avif | image/avif | woff2 | font/woff2 |
| bmp | image/bmp | 7z | application/x-7z-compressed |
| gif | image/gif | atom | application/atom+xml |
| png | image/png | pdf | application/pdf |
| svg | image/svg+xml | mjs, js | application/javascript |
| webp | image/webp | json | application/json |
| ico | image/x-icon | rss | application/rss+xml |
| tif | image/tiff | tar | application/x-tar |
| tiff | image/tiff | xhtml, xht | application/xhtml+xml |
| jpeg, jpg | image/jpeg | xslt | application/xslt+xml |
| mp4 | video/mp4 | xml | application/xml |
| mpeg | video/mpeg | gz | application/gzip |
| webm | video/webm | zip | application/zip |
| mp3 | audio/mp3 | wasm | application/wasm |
NOTE: These static file server methods are not thread-safe.
### File request handler
```cpp
// The handler is called right before the response is sent to a client
svr.set_file_request_handler([](const Request &req, Response &res) {
...
});
```
### Logging
```cpp
svr.set_logger([](const auto& req, const auto& res) {
your_logger(req, res);
});
```
### Error handler
```cpp
svr.set_error_handler([](const auto& req, auto& res) {
auto fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
```
### Exception handler
The exception handler gets called if a user routing handler throws an error.
```cpp
svr.set_exception_handler([](const auto& req, auto& res, std::exception_ptr ep) {
auto fmt = "<h1>Error 500</h1><p>%s</p>";
char buf[BUFSIZ];
try {
std::rethrow_exception(ep);
} catch (std::exception &e) {
snprintf(buf, sizeof(buf), fmt, e.what());
} catch (...) { // See the following NOTE
snprintf(buf, sizeof(buf), fmt, "Unknown Exception");
}
res.set_content(buf, "text/html");
res.status = StatusCode::InternalServerError_500;
});
```
NOTE: if you don't provide the `catch (...)` block for a rethrown exception pointer, an uncaught exception will end up causing the server crash. Be careful!
### Pre routing handler
```cpp
svr.set_pre_routing_handler([](const auto& req, auto& res) {
if (req.path == "/hello") {
res.set_content("world", "text/html");
return Server::HandlerResponse::Handled;
}
return Server::HandlerResponse::Unhandled;
});
```
### Post routing handler
```cpp
svr.set_post_routing_handler([](const auto& req, auto& res) {
res.set_header("ADDITIONAL_HEADER", "value");
});
```
### 'multipart/form-data' POST data
```cpp
svr.Post("/multipart", [&](const auto& req, auto& res) {
auto size = req.files.size();
auto ret = req.has_file("name1");
const auto& file = req.get_file_value("name1");
// file.filename;
// file.content_type;
// file.content;
});
```
### Receive content with a content receiver
```cpp
svr.Post("/content_receiver",
[&](const Request &req, Response &res, const ContentReader &content_reader) {
if (req.is_multipart_form_data()) {
// NOTE: `content_reader` is blocking until every form data field is read
MultipartFormDataItems files;
content_reader(
[&](const MultipartFormData &file) {
files.push_back(file);
return true;
},
[&](const char *data, size_t data_length) {
files.back().content.append(data, data_length);
return true;
});
} else {
std::string body;
content_reader([&](const char *data, size_t data_length) {
body.append(data, data_length);
return true;
});
}
});
```
### Send content with the content provider
```cpp
const size_t DATA_CHUNK_SIZE = 4;
svr.Get("/stream", [&](const Request &req, Response &res) {
auto data = new std::string("abcdefg");
res.set_content_provider(
data->size(), // Content length
"text/plain", // Content type
[&, data](size_t offset, size_t length, DataSink &sink) {
const auto &d = *data;
sink.write(&d[offset], std::min(length, DATA_CHUNK_SIZE));
return true; // return 'false' if you want to cancel the process.
},
[data](bool success) { delete data; });
});
```
Without content length:
```cpp
svr.Get("/stream", [&](const Request &req, Response &res) {
res.set_content_provider(
"text/plain", // Content type
[&](size_t offset, DataSink &sink) {
if (/* there is still data */) {
std::vector<char> data;
// prepare data...
sink.write(data.data(), data.size());
} else {
sink.done(); // No more data
}
return true; // return 'false' if you want to cancel the process.
});
});
```
### Chunked transfer encoding
```cpp
svr.Get("/chunked", [&](const Request& req, Response& res) {
res.set_chunked_content_provider(
"text/plain",
[](size_t offset, DataSink &sink) {
sink.write("123", 3);
sink.write("345", 3);
sink.write("789", 3);
sink.done(); // No more data
return true; // return 'false' if you want to cancel the process.
}
);
});
```
With trailer:
```cpp
svr.Get("/chunked", [&](const Request& req, Response& res) {
res.set_header("Trailer", "Dummy1, Dummy2");
res.set_chunked_content_provider(
"text/plain",
[](size_t offset, DataSink &sink) {
sink.write("123", 3);
sink.write("345", 3);
sink.write("789", 3);
sink.done_with_trailer({
{"Dummy1", "DummyVal1"},
{"Dummy2", "DummyVal2"}
});
return true;
}
);
});
```
### 'Expect: 100-continue' handler
By default, the server sends a `100 Continue` response for an `Expect: 100-continue` header.
```cpp
// Send a '417 Expectation Failed' response.
svr.set_expect_100_continue_handler([](const Request &req, Response &res) {
return StatusCode::ExpectationFailed_417;
});
```
```cpp
// Send a final status without reading the message body.
svr.set_expect_100_continue_handler([](const Request &req, Response &res) {
return res.status = StatusCode::Unauthorized_401;
});
```
### Keep-Alive connection
```cpp
svr.set_keep_alive_max_count(2); // Default is 5
svr.set_keep_alive_timeout(10); // Default is 5
```
### Timeout
```c++
svr.set_read_timeout(5, 0); // 5 seconds
svr.set_write_timeout(5, 0); // 5 seconds
svr.set_idle_interval(0, 100000); // 100 milliseconds
```
### Set maximum payload length for reading a request body
```c++
svr.set_payload_max_length(1024 * 1024 * 512); // 512MB
```
NOTE: When the request body content type is 'www-form-urlencoded', the actual payload length shouldn't exceed `CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH`.
### Server-Sent Events
Please see [Server example](https://github.com/yhirose/cpp-httplib/blob/master/example/ssesvr.cc) and [Client example](https://github.com/yhirose/cpp-httplib/blob/master/example/ssecli.cc).
### Default thread pool support
`ThreadPool` is used as a **default** task queue, and the default thread count is 8, or `std::thread::hardware_concurrency()`. You can change it with `CPPHTTPLIB_THREAD_POOL_COUNT`.
If you want to set the thread count at runtime, there is no convenient way... But here is how.
```cpp
svr.new_task_queue = [] { return new ThreadPool(12); };
```
You can also provide an optional parameter to limit the maximum number
of pending requests, i.e. requests `accept()`ed by the listener but
still waiting to be serviced by worker threads.
```cpp
svr.new_task_queue = [] { return new ThreadPool(/*num_threads=*/12, /*max_queued_requests=*/18); };
```
Default limit is 0 (unlimited). Once the limit is reached, the listener
will shutdown the client connection.
### Override the default thread pool with yours
You can supply your own thread pool implementation according to your need.
```cpp
class YourThreadPoolTaskQueue : public TaskQueue {
public:
YourThreadPoolTaskQueue(size_t n) {
pool_.start_with_thread_count(n);
}
virtual bool enqueue(std::function<void()> fn) override {
/* Return true if the task was actually enqueued, or false
* if the caller must drop the corresponding connection. */
return pool_.enqueue(fn);
}
virtual void shutdown() override {
pool_.shutdown_gracefully();
}
private:
YourThreadPool pool_;
};
svr.new_task_queue = [] {
return new YourThreadPoolTaskQueue(12);
};
```
Client
------
```c++
#include <httplib.h>
#include <iostream>
int main(void)
{
httplib::Client cli("localhost", 1234);
if (auto res = cli.Get("/hi")) {
if (res->status == StatusCode::OK_200) {
std::cout << res->body << std::endl;
}
} else {
auto err = res.error();
std::cout << "HTTP error: " << httplib::to_string(err) << std::endl;
}
}
```
NOTE: Constructor with scheme-host-port string is now supported!
```c++
httplib::Client cli("localhost");
httplib::Client cli("localhost:8080");
httplib::Client cli("http://localhost");
httplib::Client cli("http://localhost:8080");
httplib::Client cli("https://localhost");
httplib::SSLClient cli("localhost");
```
### Error code
Here is the list of errors from `Result::error()`.
```c++
enum Error {
Success = 0,
Unknown,
Connection,
BindIPAddress,
Read,
Write,
ExceedRedirectCount,
Canceled,
SSLConnection,
SSLLoadingCerts,
SSLServerVerification,
UnsupportedMultipartBoundaryChars,
Compression,
ConnectionTimeout,
};
```
### GET with HTTP headers
```c++
httplib::Headers headers = {
{ "Accept-Encoding", "gzip, deflate" }
};
auto res = cli.Get("/hi", headers);
```
or
```c++
auto res = cli.Get("/hi", {{"Accept-Encoding", "gzip, deflate"}});
```
or
```c++
cli.set_default_headers({
{ "Accept-Encoding", "gzip, deflate" }
});
auto res = cli.Get("/hi");
```
### POST
```c++
res = cli.Post("/post", "text", "text/plain");
res = cli.Post("/person", "name=john1&note=coder", "application/x-www-form-urlencoded");
```
### POST with parameters
```c++
httplib::Params params;
params.emplace("name", "john");
params.emplace("note", "coder");
auto res = cli.Post("/post", params);
```
or
```c++
httplib::Params params{
{ "name", "john" },
{ "note", "coder" }
};
auto res = cli.Post("/post", params);
```
### POST with Multipart Form Data
```c++
httplib::MultipartFormDataItems items = {
{ "text1", "text default", "", "" },
{ "text2", "aωb", "", "" },
{ "file1", "h\ne\n\nl\nl\no\n", "hello.txt", "text/plain" },
{ "file2", "{\n \"world\", true\n}\n", "world.json", "application/json" },
{ "file3", "", "", "application/octet-stream" },
};
auto res = cli.Post("/multipart", items);
```
### PUT
```c++
res = cli.Put("/resource/foo", "text", "text/plain");
```
### DELETE
```c++
res = cli.Delete("/resource/foo");
```
### OPTIONS
```c++
res = cli.Options("*");
res = cli.Options("/resource/foo");
```
### Timeout
```c++
cli.set_connection_timeout(0, 300000); // 300 milliseconds
cli.set_read_timeout(5, 0); // 5 seconds
cli.set_write_timeout(5, 0); // 5 seconds
```
### Receive content with a content receiver
```c++
std::string body;
auto res = cli.Get("/large-data",
[&](const char *data, size_t data_length) {
body.append(data, data_length);
return true;
});
```
```cpp
std::string body;
auto res = cli.Get(
"/stream", Headers(),
[&](const Response &response) {
EXPECT_EQ(StatusCode::OK_200, response.status);
return true; // return 'false' if you want to cancel the request.
},
[&](const char *data, size_t data_length) {
body.append(data, data_length);
return true; // return 'false' if you want to cancel the request.
});
```
### Send content with a content provider
```cpp
std::string body = ...;
auto res = cli.Post(
"/stream", body.size(),
[](size_t offset, size_t length, DataSink &sink) {
sink.write(body.data() + offset, length);
return true; // return 'false' if you want to cancel the request.
},
"text/plain");
```
### Chunked transfer encoding
```cpp
auto res = cli.Post(
"/stream",
[](size_t offset, DataSink &sink) {
sink.os << "chunked data 1";
sink.os << "chunked data 2";
sink.os << "chunked data 3";
sink.done();
return true; // return 'false' if you want to cancel the request.
},
"text/plain");
```
### With Progress Callback
```cpp
httplib::Client cli(url, port);
// prints: 0 / 000 bytes => 50% complete
auto res = cli.Get("/", [](uint64_t len, uint64_t total) {
printf("%lld / %lld bytes => %d%% complete\n",
len, total,
(int)(len*100/total));
return true; // return 'false' if you want to cancel the request.
}
);
```
![progress](https://user-images.githubusercontent.com/236374/33138910-495c4ecc-cf86-11e7-8693-2fc6d09615c4.gif)
### Authentication
```cpp
// Basic Authentication
cli.set_basic_auth("user", "pass");
// Digest Authentication
cli.set_digest_auth("user", "pass");
// Bearer Token Authentication
cli.set_bearer_token_auth("token");
```
NOTE: OpenSSL is required for Digest Authentication.
### Proxy server support
```cpp
cli.set_proxy("host", port);
// Basic Authentication
cli.set_proxy_basic_auth("user", "pass");
// Digest Authentication
cli.set_proxy_digest_auth("user", "pass");
// Bearer Token Authentication
cli.set_proxy_bearer_token_auth("pass");
```
NOTE: OpenSSL is required for Digest Authentication.
### Range
```cpp
httplib::Client cli("httpbin.org");
auto res = cli.Get("/range/32", {
httplib::make_range_header({{1, 10}}) // 'Range: bytes=1-10'
});
// res->status should be 206.
// res->body should be "bcdefghijk".
```
```cpp
httplib::make_range_header({{1, 10}, {20, -1}}) // 'Range: bytes=1-10, 20-'
httplib::make_range_header({{100, 199}, {500, 599}}) // 'Range: bytes=100-199, 500-599'
httplib::make_range_header({{0, 0}, {-1, 1}}) // 'Range: bytes=0-0, -1'
```
### Keep-Alive connection
```cpp
httplib::Client cli("localhost", 1234);
cli.Get("/hello"); // with "Connection: close"
cli.set_keep_alive(true);
cli.Get("/world");
cli.set_keep_alive(false);
cli.Get("/last-request"); // with "Connection: close"
```
### Redirect
```cpp
httplib::Client cli("yahoo.com");
auto res = cli.Get("/");
res->status; // 301
cli.set_follow_location(true);
res = cli.Get("/");
res->status; // 200
```
### Use a specific network interface
NOTE: This feature is not available on Windows, yet.
```cpp
cli.set_interface("eth0"); // Interface name, IP address or host name
```
Compression
-----------
The server can apply compression to the following MIME type contents:
* all text types except text/event-stream
* image/svg+xml
* application/javascript
* application/json
* application/xml
* application/xhtml+xml
### Zlib Support
'gzip' compression is available with `CPPHTTPLIB_ZLIB_SUPPORT`. `libz` should be linked.
### Brotli Support
Brotli compression is available with `CPPHTTPLIB_BROTLI_SUPPORT`. Necessary libraries should be linked.
Please see https://github.com/google/brotli for more detail.
### Compress request body on client
```c++
cli.set_compress(true);
res = cli.Post("/resource/foo", "...", "text/plain");
```
### Compress response body on client
```c++
cli.set_decompress(false);
res = cli.Get("/resource/foo", {{"Accept-Encoding", "gzip, deflate, br"}});
res->body; // Compressed data
```
Use `poll` instead of `select`
------------------------------
`select` system call is used as default since it's more widely supported. If you want to let cpp-httplib use `poll` instead, you can do so with `CPPHTTPLIB_USE_POLL`.
Split httplib.h into .h and .cc
-------------------------------
```console
$ ./split.py -h
usage: split.py [-h] [-e EXTENSION] [-o OUT]
This script splits httplib.h into .h and .cc parts.
optional arguments:
-h, --help show this help message and exit
-e EXTENSION, --extension EXTENSION
extension of the implementation file (default: cc)
-o OUT, --out OUT where to write the files (default: out)
$ ./split.py
Wrote out/httplib.h and out/httplib.cc
```
NOTE
----
### g++
g++ 4.8 and below cannot build this library since `<regex>` in the versions are [broken](https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions).
### Windows
Include `httplib.h` before `Windows.h` or include `Windows.h` by defining `WIN32_LEAN_AND_MEAN` beforehand.
```cpp
#include <httplib.h>
#include <Windows.h>
```
```cpp
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <httplib.h>
```
NOTE: cpp-httplib officially supports only the latest Visual Studio. It might work with former versions of Visual Studio, but I can no longer verify it. Pull requests are always welcome for the older versions of Visual Studio unless they break the C++11 conformance.
NOTE: Windows 8 or lower, Visual Studio 2013 or lower, and Cygwin and MSYS2 including MinGW are neither supported nor tested.
License
-------
MIT license (© 2024 Yuji Hirose)
Special Thanks To
-----------------
[These folks](https://github.com/yhirose/cpp-httplib/graphs/contributors) made great contributions to polish this library to totally another level from a simple toy!

View File

@@ -0,0 +1,12 @@
FROM alpine as builder
WORKDIR /src/example
RUN apk add g++ make openssl-dev zlib-dev brotli-dev
COPY ./httplib.h /src
COPY ./example/hello.cc /src/example
COPY ./example/Makefile /src/example
RUN make hello
FROM alpine
RUN apk --no-cache add brotli libstdc++
COPY --from=builder /src/example/hello /bin/hello
CMD ["/bin/hello"]

View File

@@ -0,0 +1,59 @@
#CXX = clang++
CXXFLAGS = -O2 -std=c++11 -I.. -Wall -Wextra -pthread
PREFIX = /usr/local
#PREFIX = $(shell brew --prefix)
OPENSSL_DIR = $(PREFIX)/opt/openssl@3
OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I$(OPENSSL_DIR)/include -L$(OPENSSL_DIR)/lib -lssl -lcrypto
ifneq ($(OS), Windows_NT)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Darwin)
OPENSSL_SUPPORT += -framework CoreFoundation -framework Security
endif
endif
ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz
BROTLI_DIR = $(PREFIX)/opt/brotli
BROTLI_SUPPORT = -DCPPHTTPLIB_BROTLI_SUPPORT -I$(BROTLI_DIR)/include -L$(BROTLI_DIR)/lib -lbrotlicommon -lbrotlienc -lbrotlidec
all: server client hello simplecli simplesvr upload redirect ssesvr ssecli benchmark issue
server : server.cc ../httplib.h Makefile
$(CXX) -o server $(CXXFLAGS) server.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
client : client.cc ../httplib.h Makefile
$(CXX) -o client $(CXXFLAGS) client.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
hello : hello.cc ../httplib.h Makefile
$(CXX) -o hello $(CXXFLAGS) hello.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
simplecli : simplecli.cc ../httplib.h Makefile
$(CXX) -o simplecli $(CXXFLAGS) simplecli.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
simplesvr : simplesvr.cc ../httplib.h Makefile
$(CXX) -o simplesvr $(CXXFLAGS) simplesvr.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
upload : upload.cc ../httplib.h Makefile
$(CXX) -o upload $(CXXFLAGS) upload.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
redirect : redirect.cc ../httplib.h Makefile
$(CXX) -o redirect $(CXXFLAGS) redirect.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
ssesvr : ssesvr.cc ../httplib.h Makefile
$(CXX) -o ssesvr $(CXXFLAGS) ssesvr.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
ssecli : ssecli.cc ../httplib.h Makefile
$(CXX) -o ssecli $(CXXFLAGS) ssecli.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
benchmark : benchmark.cc ../httplib.h Makefile
$(CXX) -o benchmark $(CXXFLAGS) benchmark.cc $(OPENSSL_SUPPORT) $(ZLIB_SUPPORT) $(BROTLI_SUPPORT)
pem:
openssl genrsa 2048 > key.pem
openssl req -new -key key.pem | openssl x509 -days 3650 -req -signkey key.pem > cert.pem
clean:
rm server client hello simplecli simplesvr upload redirect ssesvr ssecli benchmark *.pem

View File

@@ -0,0 +1,33 @@
#include <chrono>
#include <httplib.h>
#include <iostream>
using namespace std;
struct StopWatch {
StopWatch(const string &label) : label_(label) {
start_ = chrono::system_clock::now();
}
~StopWatch() {
auto end = chrono::system_clock::now();
auto diff = end - start_;
auto count = chrono::duration_cast<chrono::milliseconds>(diff).count();
cout << label_ << ": " << count << " millisec." << endl;
}
string label_;
chrono::system_clock::time_point start_;
};
int main(void) {
string body(1024 * 5, 'a');
httplib::Client cli("httpbin.org", 80);
for (int i = 0; i < 3; i++) {
StopWatch sw(to_string(i).c_str());
auto res = cli.Post("/post", body, "application/octet-stream");
assert(res->status == httplib::StatusCode::OK_200);
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
//
// client.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <httplib.h>
#include <iostream>
#define CA_CERT_FILE "./ca-bundle.crt"
using namespace std;
int main(void) {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
httplib::SSLClient cli("localhost", 8080);
// httplib::SSLClient cli("google.com");
// httplib::SSLClient cli("www.youtube.com");
cli.set_ca_cert_path(CA_CERT_FILE);
cli.enable_server_certificate_verification(true);
#else
httplib::Client cli("localhost", 8080);
#endif
if (auto res = cli.Get("/hi")) {
cout << res->status << endl;
cout << res->get_header_value("Content-Type") << endl;
cout << res->body << endl;
} else {
cout << "error code: " << res.error() << std::endl;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto result = cli.get_openssl_verify_result();
if (result) {
cout << "verify error: " << X509_verify_cert_error_string(result) << endl;
}
#endif
}
return 0;
}

View File

@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6DB1FC63-B153-4279-92B7-D8A11AF285D6}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>client</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="client.cc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,46 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27703.2047
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "server.vcxproj", "{864CD288-050A-4C8B-9BEF-3048BD876C5B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client.vcxproj", "{6DB1FC63-B153-4279-92B7-D8A11AF285D6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{280E605F-0CB8-4336-8D9F-CE50A9472AE2}"
ProjectSection(SolutionItems) = preProject
..\README.md = ..\README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|Win32.ActiveCfg = Debug|Win32
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|Win32.Build.0 = Debug|Win32
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|x64.ActiveCfg = Debug|x64
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Debug|x64.Build.0 = Debug|x64
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|Win32.ActiveCfg = Release|Win32
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|Win32.Build.0 = Release|Win32
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|x64.ActiveCfg = Release|x64
{864CD288-050A-4C8B-9BEF-3048BD876C5B}.Release|x64.Build.0 = Release|x64
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|Win32.ActiveCfg = Debug|Win32
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|Win32.Build.0 = Debug|Win32
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|x64.ActiveCfg = Debug|x64
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Debug|x64.Build.0 = Debug|x64
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|Win32.ActiveCfg = Release|Win32
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|Win32.Build.0 = Release|Win32
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|x64.ActiveCfg = Release|x64
{6DB1FC63-B153-4279-92B7-D8A11AF285D6}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7097C9E4-07F8-48C6-A888-BBA9EBB5D17D}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,19 @@
//
// hello.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <httplib.h>
using namespace httplib;
int main(void) {
Server svr;
svr.Get("/hi", [](const Request & /*req*/, Response &res) {
res.set_content("Hello World!", "text/plain");
});
svr.listen("0.0.0.0", 8080);
}

View File

@@ -0,0 +1,60 @@
//
// redirect.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <httplib.h>
#define SERVER_CERT_FILE "./cert.pem"
#define SERVER_PRIVATE_KEY_FILE "./key.pem"
using namespace httplib;
int main(void) {
// HTTP server
Server http;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
SSLServer https(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
#endif
http.Get("/test", [](const Request & /*req*/, Response &res) {
res.set_content("Test\n", "text/plain");
});
http.set_error_handler([](const Request & /*req*/, Response &res) {
res.set_redirect("https://localhost:8081/");
});
// HTTPS server
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
https.Get("/", [=](const Request & /*req*/, Response &res) {
res.set_redirect("/hi");
});
https.Get("/hi", [](const Request & /*req*/, Response &res) {
res.set_content("Hello World!\n", "text/plain");
});
https.Get("/stop", [&](const Request & /*req*/, Response & /*res*/) {
https.stop();
http.stop();
});
#endif
// Run servers
auto httpThread = std::thread([&]() { http.listen("localhost", 8080); });
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto httpsThread = std::thread([&]() { https.listen("localhost", 8081); });
#endif
httpThread.join();
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
httpsThread.join();
#endif
return 0;
}

View File

@@ -0,0 +1,113 @@
//
// sample.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <chrono>
#include <cstdio>
#include <httplib.h>
#define SERVER_CERT_FILE "./cert.pem"
#define SERVER_PRIVATE_KEY_FILE "./key.pem"
using namespace httplib;
std::string dump_headers(const Headers &headers) {
std::string s;
char buf[BUFSIZ];
for (auto it = headers.begin(); it != headers.end(); ++it) {
const auto &x = *it;
snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str());
s += buf;
}
return s;
}
std::string log(const Request &req, const Response &res) {
std::string s;
char buf[BUFSIZ];
s += "================================\n";
snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(),
req.version.c_str(), req.path.c_str());
s += buf;
std::string query;
for (auto it = req.params.begin(); it != req.params.end(); ++it) {
const auto &x = *it;
snprintf(buf, sizeof(buf), "%c%s=%s",
(it == req.params.begin()) ? '?' : '&', x.first.c_str(),
x.second.c_str());
query += buf;
}
snprintf(buf, sizeof(buf), "%s\n", query.c_str());
s += buf;
s += dump_headers(req.headers);
s += "--------------------------------\n";
snprintf(buf, sizeof(buf), "%d %s\n", res.status, res.version.c_str());
s += buf;
s += dump_headers(res.headers);
s += "\n";
if (!res.body.empty()) { s += res.body; }
s += "\n";
return s;
}
int main(void) {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
#else
Server svr;
#endif
if (!svr.is_valid()) {
printf("server has an error...\n");
return -1;
}
svr.Get("/", [=](const Request & /*req*/, Response &res) {
res.set_redirect("/hi");
});
svr.Get("/hi", [](const Request & /*req*/, Response &res) {
res.set_content("Hello World!\n", "text/plain");
});
svr.Get("/slow", [](const Request & /*req*/, Response &res) {
std::this_thread::sleep_for(std::chrono::seconds(2));
res.set_content("Slow...\n", "text/plain");
});
svr.Get("/dump", [](const Request &req, Response &res) {
res.set_content(dump_headers(req.headers), "text/plain");
});
svr.Get("/stop",
[&](const Request & /*req*/, Response & /*res*/) { svr.stop(); });
svr.set_error_handler([](const Request & /*req*/, Response &res) {
const char *fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
svr.set_logger([](const Request &req, const Response &res) {
printf("%s", log(req, res).c_str());
});
svr.listen("localhost", 8080);
return 0;
}

View File

@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{864CD288-050A-4C8B-9BEF-3048BD876C5B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>sample</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)_obj\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="server.cc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,29 @@
//
// simplecli.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <httplib.h>
#include <iostream>
using namespace std;
int main(void) {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto scheme_host_port = "https://localhost:8080";
#else
auto scheme_host_port = "http://localhost:8080";
#endif
if (auto res = httplib::Client(scheme_host_port).Get("/hi")) {
cout << res->status << endl;
cout << res->get_header_value("Content-Type") << endl;
cout << res->body << endl;
} else {
cout << res.error() << endl;
}
return 0;
}

View File

@@ -0,0 +1,135 @@
//
// simplesvr.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <cstdio>
#include <httplib.h>
#include <iostream>
#define SERVER_CERT_FILE "./cert.pem"
#define SERVER_PRIVATE_KEY_FILE "./key.pem"
using namespace httplib;
using namespace std;
string dump_headers(const Headers &headers) {
string s;
char buf[BUFSIZ];
for (const auto &x : headers) {
snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str());
s += buf;
}
return s;
}
string dump_multipart_files(const MultipartFormDataMap &files) {
string s;
char buf[BUFSIZ];
s += "--------------------------------\n";
for (const auto &x : files) {
const auto &name = x.first;
const auto &file = x.second;
snprintf(buf, sizeof(buf), "name: %s\n", name.c_str());
s += buf;
snprintf(buf, sizeof(buf), "filename: %s\n", file.filename.c_str());
s += buf;
snprintf(buf, sizeof(buf), "content type: %s\n", file.content_type.c_str());
s += buf;
snprintf(buf, sizeof(buf), "text length: %zu\n", file.content.size());
s += buf;
s += "----------------\n";
}
return s;
}
string log(const Request &req, const Response &res) {
string s;
char buf[BUFSIZ];
s += "================================\n";
snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(),
req.version.c_str(), req.path.c_str());
s += buf;
string query;
for (auto it = req.params.begin(); it != req.params.end(); ++it) {
const auto &x = *it;
snprintf(buf, sizeof(buf), "%c%s=%s",
(it == req.params.begin()) ? '?' : '&', x.first.c_str(),
x.second.c_str());
query += buf;
}
snprintf(buf, sizeof(buf), "%s\n", query.c_str());
s += buf;
s += dump_headers(req.headers);
s += dump_multipart_files(req.files);
s += "--------------------------------\n";
snprintf(buf, sizeof(buf), "%d\n", res.status);
s += buf;
s += dump_headers(res.headers);
return s;
}
int main(int argc, const char **argv) {
if (argc > 1 && string("--help") == argv[1]) {
cout << "usage: simplesvr [PORT] [DIR]" << endl;
return 1;
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
#else
Server svr;
#endif
svr.Post("/multipart", [](const Request &req, Response &res) {
auto body = dump_headers(req.headers) + dump_multipart_files(req.files);
res.set_content(body, "text/plain");
});
svr.set_error_handler([](const Request & /*req*/, Response &res) {
const char *fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
svr.set_logger(
[](const Request &req, const Response &res) { cout << log(req, res); });
auto port = 8080;
if (argc > 1) { port = atoi(argv[1]); }
auto base_dir = "./";
if (argc > 2) { base_dir = argv[2]; }
if (!svr.set_mount_point("/", base_dir)) {
cout << "The specified base directory doesn't exist...";
return 1;
}
cout << "The server started at port " << port << "..." << endl;
svr.listen("localhost", port);
return 0;
}

View File

@@ -0,0 +1,61 @@
//
// upload.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <fstream>
#include <httplib.h>
#include <iostream>
using namespace httplib;
using namespace std;
const char *html = R"(
<form id="formElem">
<input type="file" name="image_file" accept="image/*">
<input type="file" name="text_file" accept="text/*">
<input type="submit">
</form>
<script>
formElem.onsubmit = async (e) => {
e.preventDefault();
let res = await fetch('/post', {
method: 'POST',
body: new FormData(formElem)
});
console.log(await res.text());
};
</script>
)";
int main(void) {
Server svr;
svr.Get("/", [](const Request & /*req*/, Response &res) {
res.set_content(html, "text/html");
});
svr.Post("/post", [](const Request &req, Response &res) {
auto image_file = req.get_file_value("image_file");
auto text_file = req.get_file_value("text_file");
cout << "image file length: " << image_file.content.length() << endl
<< "image file name: " << image_file.filename << endl
<< "text file length: " << text_file.content.length() << endl
<< "text file name: " << text_file.filename << endl;
{
ofstream ofs(image_file.filename, ios::binary);
ofs << image_file.content;
}
{
ofstream ofs(text_file.filename);
ofs << text_file.content;
}
res.set_content("done", "text/plain");
});
svr.listen("localhost", 1234);
}

View File

@@ -0,0 +1,6 @@
#/usr/bin/env bash
for i in {1..1000000}
do
echo "#### $i ####"
curl -X POST -F image_file=@$1 http://localhost:1234/post > /dev/null
done

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,84 @@
# Generates a macro to auto-configure everything
@PACKAGE_INIT@
# Setting these here so they're accessible after install.
# Might be useful for some users to check which settings were used.
set(HTTPLIB_IS_USING_OPENSSL @HTTPLIB_IS_USING_OPENSSL@)
set(HTTPLIB_IS_USING_ZLIB @HTTPLIB_IS_USING_ZLIB@)
set(HTTPLIB_IS_COMPILED @HTTPLIB_COMPILE@)
set(HTTPLIB_IS_USING_BROTLI @HTTPLIB_IS_USING_BROTLI@)
set(HTTPLIB_VERSION @PROJECT_VERSION@)
include(CMakeFindDependencyMacro)
# We add find_dependency calls here to not make the end-user have to call them.
find_dependency(Threads)
if(@HTTPLIB_IS_USING_OPENSSL@)
# OpenSSL COMPONENTS were added in Cmake v3.11
if(CMAKE_VERSION VERSION_LESS "3.11")
find_dependency(OpenSSL @_HTTPLIB_OPENSSL_MIN_VER@)
else()
# Once the COMPONENTS were added, they were made optional when not specified.
# Since we use both, we need to search for both.
find_dependency(OpenSSL @_HTTPLIB_OPENSSL_MIN_VER@ COMPONENTS Crypto SSL)
endif()
endif()
if(@HTTPLIB_IS_USING_ZLIB@)
find_dependency(ZLIB)
endif()
if(@HTTPLIB_IS_USING_BROTLI@)
# Needed so we can use our own FindBrotli.cmake in this file.
# Note that the FindBrotli.cmake file is installed in the same dir as this file.
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
set(BROTLI_USE_STATIC_LIBS @BROTLI_USE_STATIC_LIBS@)
find_dependency(Brotli COMPONENTS common encoder decoder)
endif()
# Mildly useful for end-users
# Not really recommended to be used though
set_and_check(HTTPLIB_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@")
# Lets the end-user find the header path with the header appended
# This is helpful if you're using Cmake's pre-compiled header feature
set_and_check(HTTPLIB_HEADER_PATH "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/httplib.h")
# Consider each library support as a "component"
set(httplib_OpenSSL_FOUND @HTTPLIB_IS_USING_OPENSSL@)
set(httplib_ZLIB_FOUND @HTTPLIB_IS_USING_ZLIB@)
set(httplib_Brotli_FOUND @HTTPLIB_IS_USING_BROTLI@)
check_required_components(httplib)
# Brings in the target library, but only if all required components are found
if(NOT DEFINED httplib_FOUND OR httplib_FOUND)
include("${CMAKE_CURRENT_LIST_DIR}/httplibTargets.cmake")
endif()
# Outputs a "found httplib /usr/include/httplib.h" message when using find_package(httplib)
include(FindPackageMessage)
if(TARGET httplib::httplib)
set(HTTPLIB_FOUND TRUE)
# Since the compiled version has a lib, show that in the message
if(@HTTPLIB_COMPILE@)
# The list of configurations is most likely just 1 unless they installed a debug & release
get_target_property(_httplib_configs httplib::httplib "IMPORTED_CONFIGURATIONS")
# Need to loop since the "IMPORTED_LOCATION" property isn't want we want.
# Instead, we need to find the IMPORTED_LOCATION_RELEASE or IMPORTED_LOCATION_DEBUG which has the lib path.
foreach(_httplib_conf "${_httplib_configs}")
# Grab the path to the lib and sets it to HTTPLIB_LIBRARY
get_target_property(HTTPLIB_LIBRARY httplib::httplib "IMPORTED_LOCATION_${_httplib_conf}")
# Check if we found it
if(HTTPLIB_LIBRARY)
break()
endif()
endforeach()
unset(_httplib_configs)
unset(_httplib_conf)
find_package_message(httplib "Found httplib: ${HTTPLIB_LIBRARY} (found version \"${HTTPLIB_VERSION}\")" "[${HTTPLIB_LIBRARY}][${HTTPLIB_HEADER_PATH}]")
else()
find_package_message(httplib "Found httplib: ${HTTPLIB_HEADER_PATH} (found version \"${HTTPLIB_VERSION}\")" "[${HTTPLIB_HEADER_PATH}]")
endif()
endif()

View File

@@ -0,0 +1,118 @@
# SPDX-FileCopyrightText: 2021 Andrea Pappacoda
#
# SPDX-License-Identifier: MIT
project(
'cpp-httplib',
'cpp',
license: 'MIT',
default_options: [
'cpp_std=c++11',
'buildtype=release',
'b_ndebug=if-release',
'b_lto=true',
'warning_level=3'
],
meson_version: '>=0.47.0'
)
# Check just in case downstream decides to edit the source
# and add a project version
version = meson.project_version()
if version == 'undefined'
cxx = meson.get_compiler('cpp')
version = cxx.get_define('CPPHTTPLIB_VERSION',
prefix: '#include <httplib.h>',
include_directories: include_directories('.')).strip('"')
assert(version != '', 'failed to get version from httplib.h')
endif
deps = [dependency('threads')]
args = []
openssl_dep = dependency('openssl', version: '>=3.0.0', required: get_option('cpp-httplib_openssl'))
if openssl_dep.found()
deps += openssl_dep
args += '-DCPPHTTPLIB_OPENSSL_SUPPORT'
if host_machine.system() == 'darwin'
macosx_keychain_dep = dependency('appleframeworks', modules: ['CoreFoundation', 'Security'], required: get_option('cpp-httplib_macosx_keychain'))
if macosx_keychain_dep.found()
deps += macosx_keychain_dep
args += '-DCPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN'
endif
endif
endif
zlib_dep = dependency('zlib', required: get_option('cpp-httplib_zlib'))
if zlib_dep.found()
deps += zlib_dep
args += '-DCPPHTTPLIB_ZLIB_SUPPORT'
endif
brotli_deps = [dependency('libbrotlicommon', required: get_option('cpp-httplib_brotli'))]
brotli_deps += dependency('libbrotlidec', required: get_option('cpp-httplib_brotli'))
brotli_deps += dependency('libbrotlienc', required: get_option('cpp-httplib_brotli'))
brotli_found_all = true
foreach brotli_dep : brotli_deps
if not brotli_dep.found()
brotli_found_all = false
endif
endforeach
if brotli_found_all
deps += brotli_deps
args += '-DCPPHTTPLIB_BROTLI_SUPPORT'
endif
cpp_httplib_dep = dependency('', required: false)
if get_option('cpp-httplib_compile')
python3 = find_program('python3')
httplib_ch = custom_target(
'split',
input: 'httplib.h',
output: ['httplib.cc', 'httplib.h'],
command: [python3, files('split.py'), '--out', meson.current_build_dir()],
install: true,
install_dir: [false, get_option('includedir')]
)
lib = library(
'cpp-httplib',
sources: httplib_ch,
dependencies: deps,
cpp_args: args,
version: version,
soversion: version.split('.')[0] + '.' + version.split('.')[1],
install: true
)
cpp_httplib_dep = declare_dependency(compile_args: args, dependencies: deps, link_with: lib, sources: httplib_ch[1])
import('pkgconfig').generate(
lib,
description: 'A C++ HTTP/HTTPS server and client library',
extra_cflags: args,
url: 'https://github.com/yhirose/cpp-httplib',
version: version
)
else
install_headers('httplib.h')
cpp_httplib_dep = declare_dependency(compile_args: args, dependencies: deps, include_directories: include_directories('.'))
import('pkgconfig').generate(
name: 'cpp-httplib',
description: 'A C++ HTTP/HTTPS server and client library',
install_dir: join_paths(get_option('datadir'), 'pkgconfig'),
url: 'https://github.com/yhirose/cpp-httplib',
version: version
)
endif
if meson.version().version_compare('>=0.54.0')
meson.override_dependency('cpp-httplib', cpp_httplib_dep)
endif
if get_option('cpp-httplib_test')
subdir('test')
endif

View File

@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: 2021 Andrea Pappacoda
#
# SPDX-License-Identifier: MIT
option('cpp-httplib_openssl', type: 'feature', value: 'auto', description: 'Enable OpenSSL support')
option('cpp-httplib_zlib', type: 'feature', value: 'auto', description: 'Enable zlib support')
option('cpp-httplib_brotli', type: 'feature', value: 'auto', description: 'Enable Brotli support')
option('cpp-httplib_macosx_keychain', type: 'feature', value: 'auto', description: 'Enable loading certs from the Keychain on Apple devices')
option('cpp-httplib_compile', type: 'boolean', value: false, description: 'Split the header into a compilable header & source file (requires python3)')
option('cpp-httplib_test', type: 'boolean', value: false, description: 'Build tests')

View File

@@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""This script splits httplib.h into .h and .cc parts."""
import argparse
import os
import sys
border = '// ----------------------------------------------------------------------------'
args_parser = argparse.ArgumentParser(description=__doc__)
args_parser.add_argument(
"-e", "--extension", help="extension of the implementation file (default: cc)",
default="cc"
)
args_parser.add_argument(
"-o", "--out", help="where to write the files (default: out)", default="out"
)
args = args_parser.parse_args()
cur_dir = os.path.dirname(sys.argv[0])
lib_name = 'httplib'
header_name = '/' + lib_name + '.h'
source_name = '/' + lib_name + '.' + args.extension
# get the input file
in_file = cur_dir + header_name
# get the output file
h_out = args.out + header_name
cc_out = args.out + source_name
# if the modification time of the out file is after the in file,
# don't split (as it is already finished)
do_split = True
if os.path.exists(h_out):
in_time = os.path.getmtime(in_file)
out_time = os.path.getmtime(h_out)
do_split = in_time > out_time
if do_split:
with open(in_file) as f:
lines = f.readlines()
python_version = sys.version_info[0]
if python_version < 3:
os.makedirs(args.out)
else:
os.makedirs(args.out, exist_ok=True)
in_implementation = False
cc_out = args.out + source_name
with open(h_out, 'w') as fh, open(cc_out, 'w') as fc:
fc.write('#include "httplib.h"\n')
fc.write('namespace httplib {\n')
for line in lines:
is_border_line = border in line
if is_border_line:
in_implementation = not in_implementation
elif in_implementation:
fc.write(line.replace('inline ', ''))
else:
fh.write(line)
fc.write('} // namespace httplib\n')
print("Wrote {} and {}".format(h_out, cc_out))
else:
print("{} and {} are up to date".format(h_out, cc_out))

View File

@@ -0,0 +1,2 @@
include/
lib_*/

View File

@@ -0,0 +1,139 @@
# if include exist, then add it to ADD_INCLUDE for local debug
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/cvi_tpu_lib)
list(APPEND ADD_INCLUDE "cvi_tpu_lib/include")
# if toolchain path string contain musl, then use musl libc
if(${CONFIG_TOOLCHAIN_PATH} MATCHES "musl")
message(STATUS "cvi_tpu lib use musl libc")
list(APPEND ADD_STATIC_LIB "cvi_tpu_lib/lib_musl/libcvimath-static.a"
"cvi_tpu_lib/lib_musl/libcviruntime-static.a"
"cvi_tpu_lib/lib_musl/libcvikernel-static.a"
)
else()
message(STATUS "cvi_tpu lib use glibc")
list(APPEND ADD_STATIC_LIB "cvi_tpu_lib/lib_glibc/libcvimath-static.a"
"cvi_tpu_lib/lib_glibc/libcviruntime-static.a"
"cvi_tpu_lib/lib_glibc/libcvikernel-static.a"
)
endif()
elseif(PLATFORM_MAIXCAM AND NOT CONFIG_COMPONENTS_COMPILE_FROM_SOURCE)
if(CONFIG_TOOLCHAIN_PATH MATCHES "musl" OR CONFIG_TOOLCHAIN_PATH MATCHES "glibc")
list(APPEND ADD_FILE_DOWNLOADS "{
'url': 'https://github.com/sipeed/MaixCDK/releases/download/v0.0.0/cvi_tpu_lib_v4.1.0-23-gb920beb.tar.xz',
'urls': [],
'sites': ['https://github.com/sipeed/MaixCDK/releases/tag/v0.0.0'],
'sha256sum': '8177ce35a05565a4fdc6cf1ac6bef0dc18809a31fff332321e17d01d2b85421a',
'filename': 'cvi_tpu_lib_v4.1.0-23-gb920beb.tar.xz',
'path': 'cvi_tpu',
'check_files': ['cvi_tpu_lib_v4.1.0-23-gb920beb']
}"
)
set(cvi_tpu_lib_dir "${DL_EXTRACTED_PATH}/cvi_tpu/cvi_tpu_lib_v4.1.0-23-gb920beb")
set(harfbuzz_include_dir "${cvi_tpu_lib_dir}/include")
set_property(SOURCE ${harfbuzz_include_dir} PROPERTY GENERATED 1)
endif()
if(CONFIG_TOOLCHAIN_PATH MATCHES "musl")
set(harfbuzz_lib_file "${cvi_tpu_lib_dir}/lib_musl/libcvimath-static.a"
"${cvi_tpu_lib_dir}/lib_musl/libcviruntime-static.a"
"${cvi_tpu_lib_dir}/lib_musl/libcvikernel-static.a"
)
elseif(CONFIG_TOOLCHAIN_PATH MATCHES "glibc")
set(harfbuzz_lib_file "${cvi_tpu_lib_dir}/lib_glibc/libcvimath-static.a"
"${cvi_tpu_lib_dir}/lib_glibc/libcviruntime-static.a"
"${cvi_tpu_lib_dir}/lib_glibc/libcvikernel-static.a"
)
endif()
if(harfbuzz_lib_file)
set_property(SOURCE ${harfbuzz_lib_file} PROPERTY GENERATED 1)
list(APPEND ADD_INCLUDE ${harfbuzz_include_dir})
list(APPEND ADD_STATIC_LIB ${harfbuzz_lib_file})
endif()
endif()
if(PLATFORM_MAIXCAM AND NOT ADD_INCLUDE)
message(FATAL_ERROR "cvi_tpu_lib not found please check")
endif()
register_component()
# Config enable component2 or not in Kconfig
################# Add include #################
# list(APPEND ADD_INCLUDE "include"
# )
# list(APPEND ADD_PRIVATE_INCLUDE "include_private")
###############################################
############## Add source files ###############
# list(APPEND ADD_SRCS "src/lib2.c"
# )
# FILE(GLOB_RECURSE EXTRA_SRC "src/*.c")
# FILE(GLOB EXTRA_SRC "src/*.c")
# list(APPEND ADD_SRCS ${EXTRA_SRC})
# aux_source_directory(src ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
# set(ADD_ASM_SRCS "src/asm.S")
# list(APPEND ADD_SRCS ${ADD_ASM_SRCS})
# SET_PROPERTY(SOURCE ${ADD_ASM_SRCS} PROPERTY LANGUAGE C) # set .S ASM file as C language
# SET_SOURCE_FILES_PROPERTIES(${ADD_ASM_SRCS} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp -D BBBBB")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS basic)
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS pthread m) # add system libs, pthread and math lib for example here
# set (OpenCV_DIR opencv/lib/cmake/opencv4)
# find_package(OpenCV REQUIRED)
###############################################
############ Add static libs ##################
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
###############################################
############ Add dynamic libs ##################
# list(APPEND ADD_DYNAMIC_LIB "lib/arch/v831/libmaix_nn.so"
# "lib/arch/v831/libmaix_cam.so"
# )
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
###############################################
############ Add static libs ##################
#### Update parent's variables like CMAKE_C_LINK_FLAGS
# set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group libmaix/libtest.a -ltest2 -Wl,--end-group" PARENT_SCOPE)
###############################################
######### Add files need to download #########
# list(APPEND ADD_FILE_DOWNLOADS "{
# 'url': 'https://*****/abcde.tar.xz',
# 'urls': [], # backup urls, if url failed, will try urls
# 'sites': [], # download site, user can manually download file and put it into dl_path
# 'sha256sum': '',
# 'filename': 'abcde.tar.xz',
# 'path': 'toolchains/xxxxx',
# 'check_files': []
# }"
# )
#
# then extracted file in ${DL_EXTRACTED_PATH}/toolchains/xxxxx,
# you can directly use then, for example use it in add_custom_command
##############################################
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
# register_component()

0
components/3rd_party/cvi_tpu/Kconfig vendored Normal file
View File

View File

@@ -0,0 +1,144 @@
############### Add include ###################
# list(APPEND ADD_INCLUDE "include"
# )
# list(APPEND ADD_PRIVATE_INCLUDE "")
###############################################
############ Add source files #################
# list(APPEND ADD_SRCS "src/main.c"
# "src/test.c"
# )
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test2.c")
# FILE(GLOB_RECURSE EXTRA_SRC "src/*.c")
# FILE(GLOB EXTRA_SRC "src/*.c")
# list(APPEND ADD_SRCS ${EXTRA_SRC})
# aux_source_directory(src ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
# set(ADD_ASM_SRCS "src/asm.S")
# list(APPEND ADD_SRCS ${ADD_ASM_SRCS})
# SET_PROPERTY(SOURCE ${ADD_ASM_SRCS} PROPERTY LANGUAGE C) # set .S ASM file as C language
# SET_SOURCE_FILES_PROPERTIES(${ADD_ASM_SRCS} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp -D BBBBB")
###############################################
###### Add required/dependent components ######
list(APPEND ADD_REQUIREMENTS brotli)
# list(APPEND ADD_FILE_DEPENDS include/axx.h)
# set_property(SOURCE ${python_h_path} PROPERTY GENERATED 1)
# add_custom_command(OUTPUT include/axx.h
# COMMAND echo "" > include/axx.h
# COMMENT "Generating axx.h ..."
# )
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS pthread m) # add system libs, pthread and math lib for example here
# set (freetype_DIR freetype/lib/cmake/freetype4)
# find_package(freetype REQUIRED)
###############################################
############ Add static libs ##################
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
###############################################
############ Add dynamic libs ##################
# list(APPEND ADD_DYNAMIC_LIB "lib/arch/v831/libmaix_nn.so"
# "lib/arch/v831/libmaix_cam.so"
# )
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
###############################################
############ Add static libs ##################
#### Update parent's variables like CMAKE_C_LINK_FLAGS
# set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group libmaix/libtest.a -ltest2 -Wl,--end-group" PARENT_SCOPE)
###############################################
######### Add files need to download #########
# list(APPEND ADD_FILE_DOWNLOADS "{
# 'url': 'https://*****/abcde.tar.xz',
# 'urls': [], # backup urls, if url failed, will try urls
# 'sites': [], # download site, user can manually download file and put it into dl_path
# 'sha256sum': '',
# 'filename': 'abcde.tar.xz',
# 'path': 'toolchains/xxxxx',
# 'check_files': []
# }"
# )
#
# then extracted file in ${DL_EXTRACTED_PATH}/toolchains/xxxxx,
# you can directly use then, for example use it in add_custom_command
##############################################
set(freetype_version_str "${CONFIG_FREETYPE_VERSION_MAJOR}.${CONFIG_FREETYPE_VERSION_MINOR}.${CONFIG_FREETYPE_VERSION_PATCH}")
# write build python version to CMAKE_BINARY_DIR/config/python_version.txt
# file(WRITE ${CMAKE_BINARY_DIR}/config/freetype_version.txt "${freetype_version_str}")
set(freetype_install_dir "${CMAKE_BINARY_DIR}/freetype_install")
set(freetype_include_dir "${freetype_install_dir}/include/freetype2" "${freetype_install_dir}/include")
set(freetype_h_path "${freetype_install_dir}/include/freetype2/freetype/freetype.h")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(freetype_lib_file "${freetype_install_dir}/lib/libfreetyped.a")
else()
set(freetype_lib_file "${freetype_install_dir}/lib/libfreetype.a")
endif()
set(freetype_build_dir "${CMAKE_BINARY_DIR}/freetype_build")
list(APPEND ADD_INCLUDE ${freetype_include_dir})
list(APPEND ADD_STATIC_LIB ${freetype_lib_file})
set_property(SOURCE ${freetype_include_dir} PROPERTY GENERATED 1)
set_property(SOURCE ${freetype_h_path} PROPERTY GENERATED 1)
set_property(SOURCE ${freetype_lib_file} PROPERTY GENERATED 1)
set(freetype_url "https://phoenixnap.dl.sourceforge.net/project/freetype/freetype2/${freetype_version_str}/freetype-${freetype_version_str}.tar.xz")
set(freetype_filename "freetype-${freetype_version_str}.tar.xz")
set(freetype_unzip_path "${DL_EXTRACTED_PATH}/freetype_srcs")
set(freetype_src_path "${freetype_unzip_path}/freetype-${freetype_version_str}")
if(freetype_version_str EQUAL "2.13.2")
set(freetype_file_sha256sum "12991c4e55c506dd7f9b765933e62fd2be2e06d421505d7950a132e4f1bb484d")
endif()
list(APPEND ADD_FILE_DOWNLOADS "{
'url': '${freetype_url}',
'urls': [],
'sha256sum': '${freetype_file_sha256sum}',
'filename': '${freetype_filename}',
'path': 'freetype_srcs',
'check_files': ['freetype-${freetype_version_str}']
}"
)
if(PLATFORM_M2DOCK)
set(freetype_toolchain_file ${CMAKE_CURRENT_LIST_DIR}/toolchain_m2dock.cmake)
elseif(PLATFORM_MAIXCAM)
set(freetype_toolchain_file ${CMAKE_CURRENT_LIST_DIR}/toolchain_linux_cross.cmake)
elseif(PLATFORM_LINUX)
set(freetype_toolchain_file ${CMAKE_CURRENT_LIST_DIR}/toolchain_linux.cmake)
else()
message(FATAL_ERROR "No freetype toolchain config for this board, please edit to add freetype support for this board")
endif()
set(freetype_compile_cmd COMMAND mkdir -p ${freetype_build_dir} && cd ${freetype_build_dir} && SDK_PATH=${SDK_PATH} TOOLCHAIN_PATH=${CONFIG_TOOLCHAIN_PATH} TOOLCHAIN_PREFIX=${CONFIG_TOOLCHAIN_PREFIX} cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_PREFIX_PATH="${CMAKE_BINARY_DIR}/brotli_install/lib/pkgconfig" -DCMAKE_TOOLCHAIN_FILE=${freetype_toolchain_file} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${freetype_install_dir} -DFT_DISABLE_ZLIB=ON -DFT_DISABLE_PNG=ON -DFT_DISABLE_HARFBUZZ=ON -DFT_DISABLE_BZIP2=ON -DFT_DISABLE_BROTLI=ON ${freetype_src_path} && make -j`nproc` install)
add_custom_command(OUTPUT ${freetype_h_path}
${freetype_compile_cmd}
COMMENT "Building freetype-${freetype_version_str} ..."
DEPENDS brotli
)
list(APPEND ADD_FILE_DEPENDS ${freetype_h_path})
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
register_component()

20
components/3rd_party/freetype/Kconfig vendored Normal file
View File

@@ -0,0 +1,20 @@
# freetype version major minor patch
menu "freetype version"
config FREETYPE_VERSION_MAJOR
int "freetype package major version"
default 2
help
freetype package major version, 0 means auto select according to board
config FREETYPE_VERSION_MINOR
int "freetype package minor version"
default 13
help
freetype package minor version
config FREETYPE_VERSION_PATCH
int "freetype package patch version"
default 2
help
freetype package patch version
endmenu

View File

@@ -0,0 +1,26 @@
set(CMAKE_SYSTEM_NAME Linux)
# CMAKE_SYSTEM_PROCESSOR from command `uname -m`
execute_process(COMMAND uname -m OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR OUTPUT_STRIP_TRAILING_WHITESPACE)
# set(GNU_MACHINE "arm-openwrt-linux" CACHE STRING "GNU compiler triple")
# if(NOT CMAKE_INSTALL_PREFIX)
# set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/opencv4_install)
# endif()
# set(SDK_PATH $ENV{SDK_PATH}) # toolchain cmake file can not read var from cmake cmd's -D option, so use env var instead
# if(NOT TOOLCHAIN_PATH)
# if($ENV{TOOLCHAIN_PATH} STREQUAL "")
# set(TOOLCHAIN_PATH "${SDK_PATH}/dl/extracted/toolchains/m2dock/toolchain-sunxi-musl/toolchain/bin")
# else()
# set(TOOLCHAIN_PATH $ENV{TOOLCHAIN_PATH})
# endif()
# endif()
# set(prefix "arm-openwrt-linux-")
# set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/${prefix}gcc)
# set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/${prefix}g++)
# include("${CMAKE_CURRENT_LIST_DIR}/opencv4/platforms/linux/arm.toolchain.cmake")

View File

@@ -0,0 +1,22 @@
set(CMAKE_SYSTEM_NAME Linux)
set(toolchain $ENV{TOOLCHAIN_PATH})
set(prefix $ENV{TOOLCHAIN_PREFIX})
string(LENGTH "${toolchain}" toolchain_prefix_len)
math(EXPR toolchain_prefix_len "${toolchain_prefix_len} - 1")
string(SUBSTRING "${prefix}" 0 ${toolchain_prefix_len} prefix_no_minus)
# set(GNU_MACHINE "${prefix_no_minus}" CACHE STRING "GNU compiler triple")
execute_process(COMMAND ${toolchain}/${prefix}gcc -dumpmachine OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR)
string(REGEX REPLACE "([^-]+)-.*" "\\1" CMAKE_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_C_COMPILER ${toolchain}/${prefix}gcc)
set(CMAKE_CXX_COMPILER ${toolchain}/${prefix}g++)
# if ${toolchain}/../sysroot exists, set CMAKE_SYSROOT
if(EXISTS ${toolchain}/../sysroot)
set(CMAKE_SYSROOT ${toolchain}/../sysroot)
endif()

View File

@@ -0,0 +1,22 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(GNU_MACHINE "arm-openwrt-linux" CACHE STRING "GNU compiler triple")
if(NOT CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/freetype_install)
endif()
# toolchain path must the same as sdk_path/platforms/xxxx.yaml
set(SDK_PATH $ENV{SDK_PATH}) # toolchain cmake file can not read var from cmake cmd's -D option, so use env var instead
if(NOT TOOLCHAIN_PATH)
if($ENV{TOOLCHAIN_PATH} STREQUAL "")
set(TOOLCHAIN_PATH "${SDK_PATH}/dl/extracted/toolchains/m2dock/toolchain-sunxi-musl/toolchain/bin")
else()
set(TOOLCHAIN_PATH $ENV{TOOLCHAIN_PATH})
endif()
endif()
set(prefix "arm-openwrt-linux-")
set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/${prefix}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/${prefix}g++)

View File

@@ -0,0 +1,22 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(GNU_MACHINE "arm-openwrt-linux" CACHE STRING "GNU compiler triple")
if(NOT CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/freetype_install)
endif()
# toolchain path must the same as sdk_path/platforms/xxxx.yaml
set(SDK_PATH $ENV{SDK_PATH}) # toolchain cmake file can not read var from cmake cmd's -D option, so use env var instead
if(NOT TOOLCHAIN_PATH)
if($ENV{TOOLCHAIN_PATH} STREQUAL "")
set(TOOLCHAIN_PATH "${SDK_PATH}/dl/extracted/toolchains/maixcam/toolchain-sunxi-musl/toolchain/bin")
else()
set(TOOLCHAIN_PATH $ENV{TOOLCHAIN_PATH})
endif()
endif()
set(prefix "arm-openwrt-linux-")
set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/${prefix}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/${prefix}g++)

View File

@@ -0,0 +1,165 @@
############### Add include ###################
# list(APPEND ADD_INCLUDE "include"
# )
# list(APPEND ADD_PRIVATE_INCLUDE "")
###############################################
############ Add source files #################
# list(APPEND ADD_SRCS "src/main.c"
# "src/test.c"
# )
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test2.c")
# FILE(GLOB_RECURSE EXTRA_SRC "src/*.c")
# FILE(GLOB EXTRA_SRC "src/*.c")
# list(APPEND ADD_SRCS ${EXTRA_SRC})
# aux_source_directory(src ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
# set(ADD_ASM_SRCS "src/asm.S")
# list(APPEND ADD_SRCS ${ADD_ASM_SRCS})
# SET_PROPERTY(SOURCE ${ADD_ASM_SRCS} PROPERTY LANGUAGE C) # set .S ASM file as C language
# SET_SOURCE_FILES_PROPERTIES(${ADD_ASM_SRCS} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp -D BBBBB")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS basic)
# list(APPEND ADD_FILE_DEPENDS include/axx.h)
# set_property(SOURCE ${python_h_path} PROPERTY GENERATED 1)
# add_custom_command(OUTPUT include/axx.h
# COMMAND echo "" > include/axx.h
# COMMENT "Generating axx.h ..."
# )
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS pthread m) # add system libs, pthread and math lib for example here
# set (harfbuzz_DIR harfbuzz/lib/cmake/harfbuzz4)
# find_package(harfbuzz REQUIRED)
###############################################
############ Add static libs ##################
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
###############################################
############ Add dynamic libs ##################
# list(APPEND ADD_DYNAMIC_LIB "lib/arch/v831/libmaix_nn.so"
# "lib/arch/v831/libmaix_cam.so"
# )
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
###############################################
############ Add static libs ##################
#### Update parent's variables like CMAKE_C_LINK_FLAGS
# set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group libmaix/libtest.a -ltest2 -Wl,--end-group" PARENT_SCOPE)
###############################################
######### Add files need to download #########
# list(APPEND ADD_FILE_DOWNLOADS "{
# 'url': 'https://*****/abcde.tar.xz',
# 'urls': [], # backup urls, if url failed, will try urls
# 'sites': [], # download site, user can manually download file and put it into dl_path
# 'sha256sum': '',
# 'filename': 'abcde.tar.xz',
# 'path': 'toolchains/xxxxx',
# 'check_files': []
# }"
# )
#
# then extracted file in ${DL_EXTRACTED_PATH}/toolchains/xxxxx,
# you can directly use then, for example use it in add_custom_command
##############################################
list(APPEND ADD_REQUIREMENTS freetype yaml)
set(harfbuzz_version_str "${CONFIG_HARFBUZZ_VERSION_MAJOR}.${CONFIG_HARFBUZZ_VERSION_MINOR}.${CONFIG_HARFBUZZ_VERSION_PATCH}")
# write build python version to CMAKE_BINARY_DIR/config/python_version.txt
# file(WRITE ${CMAKE_BINARY_DIR}/config/harfbuzz_version.txt "${harfbuzz_version_str}")
if(PLATFORM_MAIXCAM AND NOT CONFIG_COMPONENTS_COMPILE_FROM_SOURCE)
if(CONFIG_TOOLCHAIN_PATH MATCHES "musl")
list(APPEND ADD_FILE_DOWNLOADS "{
'url': 'https://github.com/sipeed/MaixCDK/releases/download/v0.0.0/harfbuzz_maixcam_musl_v8.2.1.tar.xz',
'urls': [],
'sites': ['https://github.com/sipeed/MaixCDK/releases/tag/v0.0.0'],
'sha256sum': '0ee057914aeabd4d44c23f776e3dde79a3ec0a34cfe5e0a9c09737d0bf34e7fb',
'filename': 'harfbuzz_maixcam_musl_v8.2.1.tar.xz',
'path': 'harfbuzz',
'check_files': ['harfbuzz_maixcam_musl_v8.2.1']
}"
)
set(harfbuzz_lib_dir "${DL_EXTRACTED_PATH}/harfbuzz/harfbuzz_maixcam_musl_v8.2.1")
set(harfbuzz_include_dir "${harfbuzz_lib_dir}/include/harfbuzz" "${harfbuzz_lib_dir}/include")
set(harfbuzz_lib_file "${harfbuzz_lib_dir}/lib/libharfbuzz.a")
set_property(SOURCE ${harfbuzz_lib_file} PROPERTY GENERATED 1)
set_property(SOURCE ${harfbuzz_include_dir} PROPERTY GENERATED 1)
list(APPEND ADD_INCLUDE ${harfbuzz_include_dir})
list(APPEND ADD_STATIC_LIB ${harfbuzz_lib_file})
endif()
endif()
if(NOT ADD_INCLUDE)
set(harfbuzz_build_dir "${CMAKE_BINARY_DIR}/harfbuzz_build")
set(harfbuzz_install_dir "${CMAKE_BINARY_DIR}/harfbuzz_install")
set(harfbuzz_include_dir "${harfbuzz_install_dir}/include/harfbuzz" "${harfbuzz_install_dir}/include")
set(harfbuzz_h_path "${harfbuzz_install_dir}/include/harfbuzz/harfbuzz.h")
set(harfbuzz_lib_file "${harfbuzz_install_dir}/lib/libharfbuzz.a")
list(APPEND ADD_INCLUDE ${harfbuzz_include_dir})
list(APPEND ADD_STATIC_LIB ${harfbuzz_lib_file})
set_property(SOURCE ${harfbuzz_include_dir} PROPERTY GENERATED 1)
set_property(SOURCE ${harfbuzz_h_path} PROPERTY GENERATED 1)
set_property(SOURCE ${harfbuzz_lib_file} PROPERTY GENERATED 1)
set(harfbuzz_url "https://master.dl.sourceforge.net/project/harfbuzz.mirror/${harfbuzz_version_str}/harfbuzz-${harfbuzz_version_str}.tar.xz?viasf=1")
set(harfbuzz_filename "harfbuzz-${harfbuzz_version_str}.tar.xz")
set(harfbuzz_unzip_path "${DL_EXTRACTED_PATH}/harfbuzz_srcs")
set(harfbuzz_src_path "${harfbuzz_unzip_path}/harfbuzz-${harfbuzz_version_str}")
if(harfbuzz_version_str EQUAL "8.2.1")
set(harfbuzz_file_sha256sum "0fec78f98c9c8faf228957a201c8846f809452c20f8445eb092a1ba6f22dbea5")
endif()
list(APPEND ADD_FILE_DOWNLOADS "{
'url': '${harfbuzz_url}',
'urls': [],
'sha256sum': '${harfbuzz_file_sha256sum}',
'filename': '${harfbuzz_filename}',
'path': 'harfbuzz_srcs',
'check_files': ['harfbuzz-${harfbuzz_version_str}']
}"
)
if(PLATFORM_M2DOCK)
set(harfbuzz_toolchain_file ${CMAKE_CURRENT_LIST_DIR}/toolchain_m2dock.cmake)
elseif(PLATFORM_MAIXCAM)
set(harfbuzz_toolchain_file ${CMAKE_CURRENT_LIST_DIR}/toolchain_linux_cross.cmake)
elseif(PLATFORM_LINUX)
set(harfbuzz_toolchain_file ${CMAKE_CURRENT_LIST_DIR}/toolchain_linux.cmake)
else()
message(FATAL_ERROR "No harfbuzz toolchain config for this board, please edit to add harfbuzz support for this board")
endif()
set(harfbuzz_compile_cmd COMMAND mkdir -p ${harfbuzz_build_dir} && cd ${harfbuzz_build_dir} && VERSION=${harfbuzz_version_str} MAIXCDK_BUILD_DIR=${CMAKE_BINARY_DIR} SDK_PATH=${SDK_PATH} TOOLCHAIN_PATH=${CONFIG_TOOLCHAIN_PATH} TOOLCHAIN_PREFIX=${CONFIG_TOOLCHAIN_PREFIX} cmake -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY -DHB_HAVE_FREETYPE=ON -DCMAKE_FIND_ROOT_PATH="${CMAKE_BINARY_DIR}/freetype_install" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_TOOLCHAIN_FILE=${harfbuzz_toolchain_file} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${harfbuzz_install_dir} ${harfbuzz_src_path} && make -j`nproc` install)
add_custom_command(OUTPUT ${harfbuzz_h_path}
${harfbuzz_compile_cmd}
COMMENT "Building harfbuzz-${harfbuzz_version_str} ..."
DEPENDS freetype
)
list(APPEND ADD_FILE_DEPENDS ${harfbuzz_h_path})
endif()
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
register_component()

20
components/3rd_party/harfbuzz/Kconfig vendored Normal file
View File

@@ -0,0 +1,20 @@
# harfbuzz version major minor patch
menu "harfbuzz version"
config HARFBUZZ_VERSION_MAJOR
int "harfbuzz package major version"
default 8
help
harfbuzz package major version, 0 means auto select according to board
config HARFBUZZ_VERSION_MINOR
int "harfbuzz package minor version"
default 2
help
harfbuzz package minor version
config HARFBUZZ_VERSION_PATCH
int "harfbuzz package patch version"
default 1
help
harfbuzz package patch version
endmenu

View File

@@ -0,0 +1,25 @@
set(CMAKE_SYSTEM_NAME Linux)
# CMAKE_SYSTEM_PROCESSOR from command `uname -m`
execute_process(COMMAND uname -m OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR OUTPUT_STRIP_TRAILING_WHITESPACE)
# set(GNU_MACHINE "arm-openwrt-linux" CACHE STRING "GNU compiler triple")
# if(NOT CMAKE_INSTALL_PREFIX)
# set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/opencv4_install)
# endif()
# set(SDK_PATH $ENV{SDK_PATH}) # toolchain cmake file can not read var from cmake cmd's -D option, so use env var instead
# if(NOT TOOLCHAIN_PATH)
# if($ENV{TOOLCHAIN_PATH} STREQUAL "")
# set(TOOLCHAIN_PATH "${SDK_PATH}/dl/extracted/toolchains/m2dock/toolchain-sunxi-musl/toolchain/bin")
# else()
# set(TOOLCHAIN_PATH $ENV{TOOLCHAIN_PATH})
# endif()
# endif()
# set(prefix "arm-openwrt-linux-")
# set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/${prefix}gcc)
# set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/${prefix}g++)
# include("${CMAKE_CURRENT_LIST_DIR}/opencv4/platforms/linux/arm.toolchain.cmake")

View File

@@ -0,0 +1,22 @@
set(CMAKE_SYSTEM_NAME Linux)
set(toolchain $ENV{TOOLCHAIN_PATH})
set(prefix $ENV{TOOLCHAIN_PREFIX})
string(LENGTH "${toolchain}" toolchain_prefix_len)
math(EXPR toolchain_prefix_len "${toolchain_prefix_len} - 1")
string(SUBSTRING "${prefix}" 0 ${toolchain_prefix_len} prefix_no_minus)
# set(GNU_MACHINE "${prefix_no_minus}" CACHE STRING "GNU compiler triple")
execute_process(COMMAND ${toolchain}/${prefix}gcc -dumpmachine OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR)
string(REGEX REPLACE "([^-]+)-.*" "\\1" CMAKE_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_C_COMPILER ${toolchain}/${prefix}gcc)
set(CMAKE_CXX_COMPILER ${toolchain}/${prefix}g++)
# if ${toolchain}/../sysroot exists, set CMAKE_SYSROOT
if(EXISTS ${toolchain}/../sysroot)
set(CMAKE_SYSROOT ${toolchain}/../sysroot)
endif()

View File

@@ -0,0 +1,24 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(GNU_MACHINE "arm-openwrt-linux" CACHE STRING "GNU compiler triple")
# if(NOT CMAKE_INSTALL_PREFIX)
# set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/freetype_install)
# endif()
# toolchain path must the same as sdk_path/platforms/xxxx.yaml
set(SDK_PATH $ENV{SDK_PATH}) # toolchain cmake file can not read var from cmake cmd's -D option, so use env var instead
if(NOT TOOLCHAIN_PATH)
if($ENV{TOOLCHAIN_PATH} STREQUAL "")
set(TOOLCHAIN_PATH "${SDK_PATH}/dl/extracted/toolchains/m2dock/toolchain-sunxi-musl/toolchain/bin")
else()
set(TOOLCHAIN_PATH $ENV{TOOLCHAIN_PATH})
endif()
endif()
set(prefix "arm-openwrt-linux-")
set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/${prefix}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/${prefix}g++)

View File

@@ -0,0 +1,24 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(GNU_MACHINE "arm-openwrt-linux" CACHE STRING "GNU compiler triple")
# if(NOT CMAKE_INSTALL_PREFIX)
# set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/freetype_install)
# endif()
# toolchain path must the same as sdk_path/platforms/xxxx.yaml
set(SDK_PATH $ENV{SDK_PATH}) # toolchain cmake file can not read var from cmake cmd's -D option, so use env var instead
if(NOT TOOLCHAIN_PATH)
if($ENV{TOOLCHAIN_PATH} STREQUAL "")
set(TOOLCHAIN_PATH "${SDK_PATH}/dl/extracted/toolchains/maixcam/toolchain-sunxi-musl/toolchain/bin")
else()
set(TOOLCHAIN_PATH $ENV{TOOLCHAIN_PATH})
endif()
endif()
set(prefix "arm-openwrt-linux-")
set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/${prefix}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/${prefix}g++)

View File

@@ -0,0 +1,55 @@
################# Add include #################
list(APPEND ADD_INCLUDE "HTTPRequest/include"
)
# list(APPEND ADD_PRIVATE_INCLUDE "include_private")
###############################################
############## Add source files ###############
# list(APPEND ADD_SRCS "src/lib1.c"
# )
# aux_source_directory("inifile2/src" ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS component1)
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS m) # add system libs, pthread or m(math) lib for example
###############################################
############ Add static libs ##################
# if(CONFIG_COMPONENT1_INCLUDE_STATIC_LIB)
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
# endif()
###############################################
############ Add dynamic libs ##################
# list(APPEND ADD_DYNAMIC_LIB "lib/arch/v831/libmaix_nn.so"
# "lib/arch/v831/libmaix_cam.so"
# )
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
###############################################
############ Add static libs ##################
#### Update parent's variables like CMAKE_C_LINK_FLAGS
# set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group libmaix/libtest.a -ltest2 -Wl,--end-group" PARENT_SCOPE)
###############################################
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
register_component()

View File

@@ -0,0 +1,36 @@
version: 2.1
jobs:
test:
docker:
- image: gcc:8.2
steps:
- checkout
- run: git submodule update --init
- run:
name: Download SonarCloud
command: |
mkdir -p $HOME/.sonar
wget https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip -P $HOME/.sonar
unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/
- run:
name: Build and run
command: |
export PATH=$HOME/.sonar/build-wrapper-linux-x86:$PATH
build-wrapper-linux-x86-64 --out-dir bw-output make -C tests/
tests/tests
- run:
name: Generate coverage
command: |
cd tests
gcov encoding.cpp main.cpp parsing.cpp
- sonarcloud/scan
orbs:
sonarcloud: sonarsource/sonarcloud@1.0.3
workflows:
main:
jobs:
- test:
context: SonarCloud

View File

@@ -0,0 +1,32 @@
example/example.xcodeproj/project.xcworkspace/xcshareddata
example/example.xcodeproj/project.xcworkspace/xcuserdata
example/example.xcodeproj/xcshareddata
example/example.xcodeproj/xcuserdata
example/.vs
example/Win32
example/x64/
example/example.opensdf
example/example.sdf
example/example.VC.db
example/example.VC.VC.opendb
example/example
example/example.exe
*.o
*.d
*.user
tests/tests.xcodeproj/project.xcworkspace/xcshareddata
tests/tests.xcodeproj/project.xcworkspace/xcuserdata
tests/tests.xcodeproj/xcshareddata
tests/tests.xcodeproj/xcuserdata
tests/.vs
tests/Win32
tests/x64/
tests/tests.opensdf
tests/tests.sdf
tests/tests.VC.db
tests/tests.VC.VC.opendb
tests/tests
tests/tests.exe
*.gcov
*.gcda
*.gcno

View File

@@ -0,0 +1,3 @@
[submodule "external/Catch2"]
path = external/Catch2
url = https://github.com/catchorg/Catch2.git

View File

@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.8)
project(HTTPRequest CXX)
# Header only library will be interface. All properties get passed to targets that 'link' to it
add_library(HTTPRequest INTERFACE)
target_compile_features(HTTPRequest INTERFACE cxx_std_17)
target_include_directories(HTTPRequest
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# Optionally build unit tests
option(BUILD_TESTING "Build Unit Tests" OFF)
if (BUILD_TESTING)
enable_testing()
add_subdirectory(tests)
endif()

View File

@@ -0,0 +1,78 @@
# HTTPRequest
HTTPRequest is a single-header C++ library for making HTTP requests. You can just include it in your project and use it. HTTPRequest was tested on macOS, Windows, Haiku, BSD, and GNU/Linux, but it should work on most of the Linux-based platforms. Supports IPv4 and IPv6. HTTRequest requires C++17 or newer.
## Usage
To use the library simply include `HTTPRequest.hpp` using `#include "HTTPRequest.hpp"`.
### Example of a GET request
```cpp
try
{
// you can pass http::InternetProtocol::V6 to Request to make an IPv6 request
http::Request request{"http://test.com/test"};
// send a get request
const auto response = request.send("GET");
std::cout << std::string{response.body.begin(), response.body.end()} << '\n'; // print the result
}
catch (const std::exception& e)
{
std::cerr << "Request failed, error: " << e.what() << '\n';
}
```
### Example of a POST request with form data
```cpp
try
{
http::Request request{"http://test.com/test"};
const string body = "foo=1&bar=baz";
const auto response = request.send("POST", body, {
{"Content-Type", "application/x-www-form-urlencoded"}
});
std::cout << std::string{response.body.begin(), response.body.end()} << '\n'; // print the result
}
catch (const std::exception& e)
{
std::cerr << "Request failed, error: " << e.what() << '\n';
}
```
### Example of a POST request with a JSON body
```cpp
try
{
http::Request request{"http://test.com/test"};
const std::string body = "{\"foo\": 1, \"bar\": \"baz\"}";
const auto response = request.send("POST", body, {
{"Content-Type", "application/json"}
});
std::cout << std::string{response.body.begin(), response.body.end()} << '\n'; // print the result
}
catch (const std::exception& e)
{
std::cerr << "Request failed, error: " << e.what() << '\n';
}
```
### Example of a GET request using Basic authorization
```cpp
try
{
http::Request request{"http://user:password@test.com/test"};
const auto response = request.send("GET");
std::cout << std::string{response.body.begin(), response.body.end()} << '\n'; // print the result
}
catch (const std::exception& e)
{
std::cerr << "Request failed, error: " << e.what() << '\n';
}
```
To set a timeout for HTTP requests, pass `std::chrono::duration` as a last parameter to `send()`. A negative duration (default) passed to `send()` disables timeout.
## License
HTTPRequest is released to the Public Domain.

View File

@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
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 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.
For more information, please refer to <http://unlicense.org/>

View File

@@ -0,0 +1,81 @@
trigger:
- master
jobs:
- job: Tests_Linux
displayName: Tests on Linux
pool:
vmImage: 'Ubuntu-latest'
steps:
- checkout: self
submodules: true
- script: |
cd tests
make -j2
displayName: 'make'
- script: |
cd tests
./tests
displayName: 'run'
- job: Tests_Windows
displayName: Tests on Windows
pool:
vmImage: 'vs2017-win2016'
steps:
- checkout: self
submodules: true
- task: MSBuild@1
inputs:
solution: tests/tests.vcxproj
configuration: Release
- script: |
cd tests/Win32/Release
tests.exe
displayName: 'run'
- job: Tests_macOS
displayName: Tests on macOS
pool:
vmImage: 'macOS-10.15'
steps:
- checkout: self
submodules: true
- script: |
cd tests
make -j2
displayName: 'make'
- script: |
cd tests
./tests
displayName: 'run'
- job: Example_Linux
displayName: Example on Linux
pool:
vmImage: 'Ubuntu-latest'
steps:
- script: |
cd example
make -j2
displayName: 'make'
- job: Example_Windows
displayName: Example on Windows
pool:
vmImage: 'vs2017-win2016'
steps:
- task: MSBuild@1
inputs:
solution: example/example.vcxproj
configuration: Release
- job: Example_macOS
displayName: Example on macOS
pool:
vmImage: 'macOS-10.15'
steps:
- script: |
cd example
make -j2
displayName: 'make'

View File

@@ -0,0 +1,41 @@
DEBUG=0
ifeq ($(OS),Windows_NT)
platform=windows
else ifeq ($(shell uname -s),Linux)
platform=linux
endif
ifeq ($(shell uname -s),Darwin)
platform=macos
else ifeq ($(shell uname -s),Haiku)
platform=haiku
endif
CXXFLAGS=-std=c++11 -Wall -Wshadow -O2 -I../include
LDFLAGS=-O2
ifeq ($(platform),windows)
LDFLAGS+=-lws2_32
else ifeq ($(platform),haiku)
LDFLAGS+=-lnetwork
endif
SOURCES=main.cpp
BASE_NAMES=$(basename $(SOURCES))
OBJECTS=$(BASE_NAMES:=.o)
DEPENDENCIES=$(OBJECTS:.o=.d)
EXECUTABLE=example
all: $(EXECUTABLE)
ifeq ($(DEBUG),1)
all: CXXFLAGS+=-DDEBUG -g
endif
$(EXECUTABLE): $(OBJECTS)
$(CXX) $(OBJECTS) $(LDFLAGS) -o $@
-include $(DEPENDENCIES)
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) -MMD -MP $< -o $@
.PHONY: clean
clean:
$(RM) $(EXECUTABLE) $(OBJECTS) $(DEPENDENCIES) $(EXECUTABLE).exe

View File

@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example.vcxproj", "{614C7EC0-3262-40DF-B884-224B959A01F9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{614C7EC0-3262-40DF-B884-224B959A01F9}.Debug|Win32.ActiveCfg = Debug|Win32
{614C7EC0-3262-40DF-B884-224B959A01F9}.Debug|Win32.Build.0 = Debug|Win32
{614C7EC0-3262-40DF-B884-224B959A01F9}.Debug|x64.ActiveCfg = Debug|x64
{614C7EC0-3262-40DF-B884-224B959A01F9}.Debug|x64.Build.0 = Debug|x64
{614C7EC0-3262-40DF-B884-224B959A01F9}.Release|Win32.ActiveCfg = Release|Win32
{614C7EC0-3262-40DF-B884-224B959A01F9}.Release|Win32.Build.0 = Release|Win32
{614C7EC0-3262-40DF-B884-224B959A01F9}.Release|x64.ActiveCfg = Release|x64
{614C7EC0-3262-40DF-B884-224B959A01F9}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\HTTPRequest.hpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{614C7EC0-3262-40DF-B884-224B959A01F9}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>rtmp_relay</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>../include;$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>../include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>../include;$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>../include;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,284 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
30DAD98B1ECA11AC00E9F3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 30DAD98A1ECA11AC00E9F3D7 /* main.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
30DAD9801ECA117100E9F3D7 /* example */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = example; sourceTree = BUILT_PRODUCTS_DIR; };
30DAD98A1ECA11AC00E9F3D7 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
30DAD98E1ECA180B00E9F3D7 /* HTTPRequest.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = HTTPRequest.hpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
30DAD9771ECA117100E9F3D7 = {
isa = PBXGroup;
children = (
30DAD98D1ECA11BC00E9F3D7 /* include */,
30DAD98C1ECA11B600E9F3D7 /* example */,
30DAD9811ECA117100E9F3D7 /* Products */,
);
sourceTree = "<group>";
};
30DAD9811ECA117100E9F3D7 /* Products */ = {
isa = PBXGroup;
children = (
30DAD9801ECA117100E9F3D7 /* example */,
);
name = Products;
sourceTree = "<group>";
};
30DAD98C1ECA11B600E9F3D7 /* example */ = {
isa = PBXGroup;
children = (
30DAD98A1ECA11AC00E9F3D7 /* main.cpp */,
);
name = example;
sourceTree = "<group>";
};
30DAD98D1ECA11BC00E9F3D7 /* include */ = {
isa = PBXGroup;
children = (
30DAD98E1ECA180B00E9F3D7 /* HTTPRequest.hpp */,
);
name = include;
path = ../include;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
30DAD97F1ECA117100E9F3D7 /* example */ = {
isa = PBXNativeTarget;
buildConfigurationList = 30DAD9871ECA117100E9F3D7 /* Build configuration list for PBXNativeTarget "example" */;
buildPhases = (
30DAD97C1ECA117100E9F3D7 /* Sources */,
);
buildRules = (
);
dependencies = (
);
name = example;
productName = example;
productReference = 30DAD9801ECA117100E9F3D7 /* example */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
30DAD9781ECA117100E9F3D7 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0830;
ORGANIZATIONNAME = "Elviss Strazdins";
TargetAttributes = {
30DAD97F1ECA117100E9F3D7 = {
CreatedOnToolsVersion = 8.3.2;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 30DAD97B1ECA117100E9F3D7 /* Build configuration list for PBXProject "example" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = 30DAD9771ECA117100E9F3D7;
productRefGroup = 30DAD9811ECA117100E9F3D7 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
30DAD97F1ECA117100E9F3D7 /* example */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
30DAD97C1ECA117100E9F3D7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
30DAD98B1ECA11AC00E9F3D7 /* main.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
30DAD9851ECA117100E9F3D7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_ASSIGN_ENUM = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES;
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = ../include;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
30DAD9861ECA117100E9F3D7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_ASSIGN_ENUM = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES;
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = ../include;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
name = Release;
};
30DAD9881ECA117100E9F3D7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
30DAD9891ECA117100E9F3D7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
30DAD97B1ECA117100E9F3D7 /* Build configuration list for PBXProject "example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
30DAD9851ECA117100E9F3D7 /* Debug */,
30DAD9861ECA117100E9F3D7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
30DAD9871ECA117100E9F3D7 /* Build configuration list for PBXNativeTarget "example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
30DAD9881ECA117100E9F3D7 /* Debug */,
30DAD9891ECA117100E9F3D7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 30DAD9781ECA117100E9F3D7 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:example.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,104 @@
//
// HTTPRequest
//
#include <iostream>
#include <fstream>
#include "HTTPRequest.hpp"
int main(int argc, const char* argv[])
{
try
{
std::string uri;
std::string method = "GET";
std::string arguments;
std::string output;
auto protocol = http::InternetProtocol::v4;
for (int i = 1; i < argc; ++i)
{
const auto arg = std::string{argv[i]};
if (arg == "--help")
{
std::cout << "example --url <url> [--protocol <protocol>] [--method <method>] [--arguments <arguments>] [--output <output>]\n";
return EXIT_SUCCESS;
}
else if (arg == "--uri")
{
if (++i < argc) uri = argv[i];
else throw std::runtime_error("Missing argument for --url");
}
else if (arg == "--protocol")
{
if (++i < argc)
{
if (std::string{argv[i]} == "ipv4")
protocol = http::InternetProtocol::v4;
else if (std::string{argv[i]} == "ipv6")
protocol = http::InternetProtocol::v6;
else
throw std::runtime_error{"Invalid protocol"};
}
else throw std::runtime_error{"Missing argument for --protocol"};
}
else if (arg == "--method")
{
if (++i < argc) method = argv[i];
else throw std::runtime_error{"Missing argument for --method"};
}
else if (arg == "--arguments")
{
if (++i < argc) arguments = argv[i];
else throw std::runtime_error{"Missing argument for --arguments"};
}
else if (arg == "--output")
{
if (++i < argc) output = argv[i];
else throw std::runtime_error{"Missing argument for --output"};
}
else
throw std::runtime_error{"Invalid flag: " + arg};
}
http::Request request{uri, protocol};
const auto response = request.send(method, arguments, {
{"Content-Type", "application/x-www-form-urlencoded"},
{"User-Agent", "runscope/0.1"},
{"Accept", "*/*"}
}, std::chrono::seconds(2));
std::cout << response.status.reason << '\n';
if (response.status.code == http::Status::Ok)
{
if (!output.empty())
{
std::ofstream outfile{output, std::ofstream::binary};
outfile.write(reinterpret_cast<const char*>(response.body.data()),
static_cast<std::streamsize>(response.body.size()));
}
else
std::cout << std::string{response.body.begin(), response.body.end()} << '\n';
}
}
catch (const http::RequestError& e)
{
std::cerr << "Request error: " << e.what() << '\n';
return EXIT_FAILURE;
}
catch (const http::ResponseError& e)
{
std::cerr << "Response error: " << e.what() << '\n';
return EXIT_FAILURE;
}
catch (const std::exception& e)
{
std::cerr << "Error: " << e.what() << '\n';
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
sonar.projectKey=elnormous_HTTPRequest
sonar.organization=elnormous-github
# This is the name and version displayed in the SonarCloud UI.
#sonar.projectName=HTTPRequest
#sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
sonar.sources=include,tests
# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8
sonar.cfamily.build-wrapper-output=bw-output
sonar.cfamily.gcov.reportsPath=tests

View File

@@ -0,0 +1,21 @@
add_executable(HTTPRequest_tests
main.cpp
encoding.cpp
parsing.cpp
)
target_link_libraries(HTTPRequest_tests
PRIVATE
HTTPRequest
)
target_include_directories(HTTPRequest_tests
PRIVATE
${PROJECT_SOURCE_DIR}/external/Catch2/single_include
)
# Enable use of 'make test'
add_test(test HTTPRequest_tests)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
DEPENDS HTTPRequest_tests)

View File

@@ -0,0 +1,28 @@
DEBUG=0
CXXFLAGS=-std=c++17 -Wall -Wextra -Wshadow -I../external/Catch2/single_include -I../include
SOURCES=encoding.cpp main.cpp parsing.cpp
BASE_NAMES=$(basename $(SOURCES))
OBJECTS=$(BASE_NAMES:=.o)
DEPENDENCIES=$(OBJECTS:.o=.d)
EXECUTABLE=tests
.PHONY: all
all: $(EXECUTABLE)
ifeq ($(DEBUG),1)
all: CXXFLAGS+=-DDEBUG -g
else
all: CXXFLAGS+=-O3
all: LDFLAGS+=-O3
endif
$(EXECUTABLE): $(OBJECTS)
$(CXX) $(OBJECTS) $(LDFLAGS) -o $@ -fprofile-arcs -ftest-coverage
-include $(DEPENDENCIES)
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) -MMD -MP $< -o $@ -fprofile-arcs -ftest-coverage
.PHONY: clean
clean:
$(RM) $(EXECUTABLE) $(OBJECTS) $(DEPENDENCIES) $(EXECUTABLE).exe *.gcda *.gcno

View File

@@ -0,0 +1,95 @@
#include <cstddef>
#include "catch2/catch.hpp"
#include "HTTPRequest.hpp"
TEST_CASE("Encode status line", "[serialization]")
{
const auto result = http::encodeRequestLine("GET", "/");
REQUIRE(result == "GET / HTTP/1.1\r\n");
}
TEST_CASE("Encode header", "[serialization]")
{
const auto result = http::encodeHeaderFields({
{"a", "b"}
});
REQUIRE(result == "a: b\r\n");
}
TEST_CASE("Encode header without value", "[serialization]")
{
const auto result = http::encodeHeaderFields({
{"a", ""}
});
REQUIRE(result == "a: \r\n");
}
TEST_CASE("Encode headers", "[serialization]")
{
const auto result = http::encodeHeaderFields({
{"a", "b"},
{"c", "d"}
});
REQUIRE(result == "a: b\r\nc: d\r\n");
}
TEST_CASE("Encode header with an empty name", "[serialization]")
{
REQUIRE_THROWS_AS(http::encodeHeaderFields({
{"", "b"}
}), http::RequestError);
}
TEST_CASE("Encode header with a new-line in name", "[serialization]")
{
REQUIRE_THROWS_AS(http::encodeHeaderFields({
{"a\n", ""}
}), http::RequestError);
}
TEST_CASE("Encode header with a new-line in value", "[serialization]")
{
REQUIRE_THROWS_AS(http::encodeHeaderFields({
{"a", "\n"}
}), http::RequestError);
}
TEST_CASE("Encode Base64", "[serialization]")
{
const std::string str = "test:test";
const auto result = http::encodeBase64(str.begin(), str.end());
REQUIRE(result == "dGVzdDp0ZXN0");
}
TEST_CASE("Encode HTML", "[serialization]")
{
http::Uri uri;
uri.scheme = "http";
uri.path = "/";
uri.host = "test.com";
const auto result = http::detail::encodeHtml(uri, "GET", {}, {});
const std::string check = "GET / HTTP/1.1\r\nHost: test.com\r\nContent-Length: 0\r\n\r\n";
REQUIRE(check.size() == result.size());
for (std::size_t i = 0; i < check.size(); ++i)
REQUIRE(static_cast<uint8_t>(check[i]) == result[i]);
}
TEST_CASE("Encode HTML with data", "[serialization]")
{
http::Uri uri;
uri.scheme = "http";
uri.path = "/";
uri.host = "test.com";
const std::vector<std::uint8_t> body = {'1'};
const auto result = http::detail::encodeHtml(uri, "GET", body, {});
const std::string check = "GET / HTTP/1.1\r\nHost: test.com\r\nContent-Length: 1\r\n\r\n1";
REQUIRE(check.size() == result.size());
for (std::size_t i = 0; i < check.size(); ++i)
REQUIRE(static_cast<uint8_t>(check[i]) == result[i]);
}

View File

@@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include "catch2/catch.hpp"

View File

@@ -0,0 +1,466 @@
#include <cstddef>
#include "catch2/catch.hpp"
#include "HTTPRequest.hpp"
TEST_CASE("White space", "[parsing]")
{
for (int c = 0; c < 256; ++c)
REQUIRE(http::isWhiteSpaceChar(static_cast<char>(c)) == (c == ' ' || c == '\t'));
}
TEST_CASE("Digit", "[parsing]")
{
for (int c = 0; c < 256; ++c)
REQUIRE(http::isDigitChar(static_cast<char>(c)) == (c >= '0' && c <= '9'));
}
TEST_CASE("Alpha", "[parsing]")
{
for (int c = 0; c < 256; ++c)
REQUIRE(http::isAlphaChar(static_cast<char>(c)) == ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')));
}
TEST_CASE("Token char", "[parsing]")
{
for (int c = 0; c < 256; ++c)
REQUIRE(http::isTokenChar(static_cast<char>(c)) ==
(c >= 0x21 && c <= 0x7E &&
c != '"' && c != '(' && c != ')' && c != ',' && c != '/' &&
c != ':' && c != ';' && c != '<' && c != '=' && c != '>' &&
c != '?' && c != '@' && c != '[' && c != '\\' && c != ']' &&
c != '{' && c != '}'));
}
TEST_CASE("Visible char", "[parsing]")
{
for (int c = 0; c < 256; ++c)
REQUIRE(http::isVisibleChar(static_cast<char>(c)) == (c >= 0x21 && c <= 0x7E));
}
TEST_CASE("OBS text char", "[parsing]")
{
for (int c = 0; c < 256; ++c)
REQUIRE(http::isObsoleteTextChar(static_cast<char>(c)) == (c >= 0x80 && c <= 0xFF));
}
TEST_CASE("Skip empty whites paces", "[parsing]")
{
const std::string str = "";
const auto i = http::skipWhiteSpaces(str.begin(), str.end());
REQUIRE(i == str.begin());
REQUIRE(i == str.end());
}
TEST_CASE("Skip one white space", "[parsing]")
{
const std::string str = " ";
const auto i = http::skipWhiteSpaces(str.begin(), str.end());
REQUIRE(i == str.end());
}
TEST_CASE("Skip one white space at the beggining", "[parsing]")
{
const std::string str = " a";
const auto i = http::skipWhiteSpaces(str.begin(), str.end());
REQUIRE(i == str.begin() + 1);
}
TEST_CASE("Don't skip white spaces", "[parsing]")
{
const std::string str = "a ";
const auto i = http::skipWhiteSpaces(str.begin(), str.end());
REQUIRE(i == str.begin());
}
TEST_CASE("Parse token", "[parsing]")
{
const std::string str = "token";
const auto result = http::parseToken(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == "token");
}
TEST_CASE("Parse HTTP version", "[parsing]")
{
const std::string str = "HTTP/1.1";
const auto result = http::parseHttpVersion(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second.major == 1U);
REQUIRE(result.second.minor == 1U);
}
TEST_CASE("Invalid HTTP in version", "[parsing]")
{
const std::string str = "TTP/1.1";
REQUIRE_THROWS_AS(http::parseHttpVersion(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("No slash in HTTP version", "[parsing]")
{
const std::string str = "HTTP1.1";
REQUIRE_THROWS_AS(http::parseHttpVersion(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("No minor version in HTTP version", "[parsing]")
{
const std::string str = "HTTP/1.";
REQUIRE_THROWS_AS(http::parseHttpVersion(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Parse status code", "[parsing]")
{
const std::string str = "333";
const auto result = http::parseStatusCode(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == 333);
}
TEST_CASE("Too short status code", "[parsing]")
{
const std::string str = "33";
REQUIRE_THROWS_AS(http::parseStatusCode(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Too long status code", "[parsing]")
{
const std::string str = "3333";
REQUIRE_THROWS_AS(http::parseStatusCode(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Invalid status code", "[parsing]")
{
const std::string str = "33a";
REQUIRE_THROWS_AS(http::parseStatusCode(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Parse reason phrase", "[parsing]")
{
const std::string str = "reason";
const auto result = http::parseReasonPhrase(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == "reason");
}
TEST_CASE("Parse reason phrase with space", "[parsing]")
{
const std::string str = "reason s";
const auto result = http::parseReasonPhrase(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == "reason s");
}
TEST_CASE("Parse status", "[parsing]")
{
const std::string str = "HTTP/1.1 123 test\r\n";
const auto result = http::parseStatusLine(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second.httpVersion.major == 1);
REQUIRE(result.second.httpVersion.minor == 1);
REQUIRE(result.second.code == 123);
REQUIRE(result.second.reason == "test");
}
TEST_CASE("Parse field value", "[parsing]")
{
const std::string str = "value";
const auto result = http::parseFieldValue(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == "value");
}
TEST_CASE("Parse field value with a space", "[parsing]")
{
const std::string str = "value s";
const auto result = http::parseFieldValue(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == "value s");
}
TEST_CASE("Parse field value with trailing white spaces", "[parsing]")
{
const std::string str = "value \t";
const auto result = http::parseFieldValue(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == "value");
}
TEST_CASE("Parse field content", "[parsing]")
{
const std::string str = "content";
const auto result = http::parseFieldContent(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == "content");
}
TEST_CASE("Parse field content with obsolete folding", "[parsing]")
{
const std::string str = "content\r\n t";
const auto result = http::parseFieldContent(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == "content t");
}
TEST_CASE("Parse field content with obsolete folding and white space", "[parsing]")
{
const std::string str = "content\r\n t";
const auto result = http::parseFieldContent(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == "content t");
}
TEST_CASE("Parse field content with obsolete folding with empty first line", "[parsing]")
{
const std::string str = "\r\n t";
const auto result = http::parseFieldContent(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second == " t");
}
TEST_CASE("Parse header field", "[parsing]")
{
const std::string str = "field:value\r\n";
const auto result = http::parseHeaderField(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second.first == "field");
REQUIRE(result.second.second == "value");
}
TEST_CASE("Parse header field upper case", "[parsing]")
{
const std::string str = "Field:Value\r\n";
const auto result = http::parseHeaderField(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second.first == "Field");
REQUIRE(result.second.second == "Value");
}
TEST_CASE("Parse header field with spaces", "[parsing]")
{
const std::string str = "field:value s\r\n";
const auto result = http::parseHeaderField(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second.first == "field");
REQUIRE(result.second.second == "value s");
}
TEST_CASE("Parse header field with spaces after colon", "[parsing]")
{
const std::string str = "field: \tvalue\r\n";
const auto result = http::parseHeaderField(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second.first == "field");
REQUIRE(result.second.second == "value");
}
TEST_CASE("Parse header field with no value", "[parsing]")
{
const std::string str = "field:\r\n";
auto result = http::parseHeaderField(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second.first == "field");
REQUIRE(result.second.second == "");
}
TEST_CASE("Parse header field with trailing white space", "[parsing]")
{
const std::string str = "field:value \r\n";
auto result = http::parseHeaderField(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second.first == "field");
REQUIRE(result.second.second == "value");
}
TEST_CASE("Parse header field with no colon", "[parsing]")
{
const std::string str = "field\r\n";
REQUIRE_THROWS_AS(http::parseHeaderField(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Parse header with missing line feed", "[parsing]")
{
const std::string str = "a:b\rc:d\r\n";
REQUIRE_THROWS_AS(http::parseHeaderField(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Parse header with missing carriage return", "[parsing]")
{
const std::string str = "a:b\nc:d\r\n";
REQUIRE_THROWS_AS(http::parseHeaderField(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Parse header field without CRLF", "[parsing]")
{
const std::string str = "field:value";
REQUIRE_THROWS_AS(http::parseHeaderField(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Parse header field with obsolete fold", "[parsing]")
{
const std::string str = "field:value1\r\n value2\r\n";
const auto result = http::parseHeaderField(str.begin(), str.end());
REQUIRE(result.first == str.end());
REQUIRE(result.second.first == "field");
REQUIRE(result.second.second == "value1 value2");
}
TEST_CASE("Digit to unsigned int", "[parsing]")
{
const char c = '1';
REQUIRE(http::digitToUint<std::size_t>(c) == 1U);
}
TEST_CASE("Invalid digit", "[parsing]")
{
const char c = 'a';
REQUIRE_THROWS_AS(http::digitToUint<std::size_t>(c), http::ResponseError);
}
TEST_CASE("Digits to unsigned int", "[parsing]")
{
const std::string str = "11";
REQUIRE(http::stringToUint<std::size_t>(str.begin(), str.end()) == 11U);
}
TEST_CASE("Invalid digit string", "[parsing]")
{
const std::string str = "1x";
REQUIRE_THROWS_AS(http::stringToUint<std::size_t>(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Hex digit and letter to unsigned int", "[parsing]")
{
const std::string str = "1A";
REQUIRE(http::hexStringToUint<std::size_t>(str.begin(), str.end()) == 26U);
}
TEST_CASE("Hex digit to unsigned int", "[parsing]")
{
const char c = '1';
REQUIRE(http::hexDigitToUint<std::size_t>(c) == 1U);
}
TEST_CASE("Hex lowercase letter to unsigned int", "[parsing]")
{
const char c = 'a';
REQUIRE(http::hexDigitToUint<std::size_t>(c) == 10U);
}
TEST_CASE("Hex uppercase letter to unsigned int", "[parsing]")
{
const char c = 'A';
REQUIRE(http::hexDigitToUint<std::size_t>(c) == 10U);
}
TEST_CASE("Invalid hex", "[parsing]")
{
const char c = 'x';
REQUIRE_THROWS_AS(http::hexDigitToUint<std::size_t>(c), http::ResponseError);
}
TEST_CASE("Hex digits with a letter last to unsigned int", "[parsing]")
{
const std::string str = "1A";
REQUIRE(http::hexStringToUint<std::size_t>(str.begin(), str.end()) == 26U);
}
TEST_CASE("Hex digits with a letter first to unsigned int", "[parsing]")
{
const std::string str = "A1";
REQUIRE(http::hexStringToUint<std::size_t>(str.begin(), str.end()) == 161U);
}
TEST_CASE("Invalid hex string", "[parsing]")
{
const std::string str = "ax";
REQUIRE_THROWS_AS(http::hexStringToUint<std::size_t>(str.begin(), str.end()), http::ResponseError);
}
TEST_CASE("Parse URL", "[parsing]")
{
const std::string str = "tt://www.test.com:80/path";
const http::Uri uri = http::parseUri(str.begin(), str.end());
REQUIRE(uri.scheme == "tt");
REQUIRE(uri.user == "");
REQUIRE(uri.password == "");
REQUIRE(uri.host == "www.test.com");
REQUIRE(uri.port == "80");
REQUIRE(uri.path == "/path");
REQUIRE(uri.query == "");
REQUIRE(uri.fragment == "");
}
TEST_CASE("Parse URL with non-alpha non-digit characters in scheme", "[parsing]")
{
const std::string str = "t.t+-://foo";
const http::Uri uri = http::parseUri(str.begin(), str.end());
REQUIRE(uri.scheme == "t.t+-");
REQUIRE(uri.host == "foo");
}
TEST_CASE("Parse URL with invalid character in scheme", "[parsing]")
{
const std::string str = "tt!://foo";
REQUIRE_THROWS_AS(http::parseUri(str.begin(), str.end()), http::RequestError);
}
TEST_CASE("Parse URL with fragment", "[parsing]")
{
const std::string str = "tt://www.test.com/path#fragment";
const http::Uri uri = http::parseUri(str.begin(), str.end());
REQUIRE(uri.scheme == "tt");
REQUIRE(uri.user == "");
REQUIRE(uri.password == "");
REQUIRE(uri.host == "www.test.com");
REQUIRE(uri.port == "");
REQUIRE(uri.path == "/path");
REQUIRE(uri.query == "");
REQUIRE(uri.fragment == "fragment");
}
TEST_CASE("Parse URL with query and fragment", "[parsing]")
{
const std::string str = "tt://www.test.com/path?query=1#fragment";
const http::Uri uri = http::parseUri(str.begin(), str.end());
REQUIRE(uri.scheme == "tt");
REQUIRE(uri.user == "");
REQUIRE(uri.password == "");
REQUIRE(uri.host == "www.test.com");
REQUIRE(uri.port == "");
REQUIRE(uri.path == "/path");
REQUIRE(uri.query == "query=1");
REQUIRE(uri.fragment == "fragment");
}
TEST_CASE("Parse URL without scheme", "[parsing]")
{
const std::string str = "www.test.com/path?query=1#fragment";
REQUIRE_THROWS_AS(http::parseUri(str.begin(), str.end()), http::RequestError);
}
TEST_CASE("Parse URL with user", "[parsing]")
{
const std::string str = "tt://test@test.com/";
const http::Uri uri = http::parseUri(str.begin(), str.end());
REQUIRE(uri.scheme == "tt");
REQUIRE(uri.user == "test");
REQUIRE(uri.password == "");
REQUIRE(uri.host == "test.com");
REQUIRE(uri.port == "");
REQUIRE(uri.path == "/");
REQUIRE(uri.query == "");
REQUIRE(uri.fragment == "");
}
TEST_CASE("Parse URL with user and password", "[parsing]")
{
const std::string str = "tt://test:test@test.com/";
const http::Uri uri = http::parseUri(str.begin(), str.end());
REQUIRE(uri.scheme == "tt");
REQUIRE(uri.user == "test");
REQUIRE(uri.password == "test");
REQUIRE(uri.host == "test.com");
REQUIRE(uri.port == "");
REQUIRE(uri.path == "/");
REQUIRE(uri.query == "");
REQUIRE(uri.fragment == "");
}

View File

@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcxproj", "{614C7EC0-3262-40DF-B884-224B959A01F9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{614C7EC0-3262-40DF-B884-224B959A01F9}.Debug|Win32.ActiveCfg = Debug|Win32
{614C7EC0-3262-40DF-B884-224B959A01F9}.Debug|Win32.Build.0 = Debug|Win32
{614C7EC0-3262-40DF-B884-224B959A01F9}.Debug|x64.ActiveCfg = Debug|x64
{614C7EC0-3262-40DF-B884-224B959A01F9}.Debug|x64.Build.0 = Debug|x64
{614C7EC0-3262-40DF-B884-224B959A01F9}.Release|Win32.ActiveCfg = Release|Win32
{614C7EC0-3262-40DF-B884-224B959A01F9}.Release|Win32.Build.0 = Release|Win32
{614C7EC0-3262-40DF-B884-224B959A01F9}.Release|x64.ActiveCfg = Release|x64
{614C7EC0-3262-40DF-B884-224B959A01F9}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="encoding.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="parsing.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\HTTPRequest.hpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{614C7EC0-3262-40DF-B884-224B959A01F9}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>rtmp_relay</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>..\external\Catch2\single_include;..\include;$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>..\external\Catch2\single_include;..\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>..\external\Catch2\single_include;..\include;$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>..\external\Catch2\single_include;..\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,320 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
303E879D251EE589008B7E24 /* parsing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 303E879C251EE589008B7E24 /* parsing.cpp */; };
307E6ED527CB02AC00D665C8 /* encoding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 307E6ED427CB02AC00D665C8 /* encoding.cpp */; };
C6C90FD721A5A24D00B5FCB7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6C90FD621A5A24D00B5FCB7 /* main.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
C6C90FD121A5A24D00B5FCB7 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
303E879C251EE589008B7E24 /* parsing.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = parsing.cpp; sourceTree = "<group>"; };
307E6ED427CB02AC00D665C8 /* encoding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = encoding.cpp; sourceTree = "<group>"; };
30977F4B27B496BA00D89E07 /* HTTPRequest.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = HTTPRequest.hpp; path = ../include/HTTPRequest.hpp; sourceTree = "<group>"; };
C6C90FD321A5A24D00B5FCB7 /* tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tests; sourceTree = BUILT_PRODUCTS_DIR; };
C6C90FD621A5A24D00B5FCB7 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C6C90FD021A5A24D00B5FCB7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
C6C90FCA21A5A24D00B5FCB7 = {
isa = PBXGroup;
children = (
307E6ED427CB02AC00D665C8 /* encoding.cpp */,
30977F4B27B496BA00D89E07 /* HTTPRequest.hpp */,
C6C90FD621A5A24D00B5FCB7 /* main.cpp */,
303E879C251EE589008B7E24 /* parsing.cpp */,
C6C90FD421A5A24D00B5FCB7 /* Products */,
);
sourceTree = "<group>";
};
C6C90FD421A5A24D00B5FCB7 /* Products */ = {
isa = PBXGroup;
children = (
C6C90FD321A5A24D00B5FCB7 /* tests */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C6C90FD221A5A24D00B5FCB7 /* tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = C6C90FDA21A5A24D00B5FCB7 /* Build configuration list for PBXNativeTarget "tests" */;
buildPhases = (
C6C90FCF21A5A24D00B5FCB7 /* Sources */,
C6C90FD021A5A24D00B5FCB7 /* Frameworks */,
C6C90FD121A5A24D00B5FCB7 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = tests;
productName = WebsocketTest;
productReference = C6C90FD321A5A24D00B5FCB7 /* tests */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
C6C90FCB21A5A24D00B5FCB7 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1010;
ORGANIZATIONNAME = "Elviss Strazdins";
TargetAttributes = {
C6C90FD221A5A24D00B5FCB7 = {
CreatedOnToolsVersion = 10.1;
};
};
};
buildConfigurationList = C6C90FCE21A5A24D00B5FCB7 /* Build configuration list for PBXProject "tests" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = C6C90FCA21A5A24D00B5FCB7;
productRefGroup = C6C90FD421A5A24D00B5FCB7 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
C6C90FD221A5A24D00B5FCB7 /* tests */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
C6C90FCF21A5A24D00B5FCB7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C6C90FD721A5A24D00B5FCB7 /* main.cpp in Sources */,
303E879D251EE589008B7E24 /* parsing.cpp in Sources */,
307E6ED527CB02AC00D665C8 /* encoding.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
C6C90FD821A5A24D00B5FCB7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES;
CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES;
CLANG_WARN_ASSIGN_ENUM = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_FLOAT_CONVERSION = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
C6C90FD921A5A24D00B5FCB7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES;
CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES;
CLANG_WARN_ASSIGN_ENUM = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_FLOAT_CONVERSION = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
};
name = Release;
};
C6C90FDB21A5A24D00B5FCB7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
../external/Catch2/single_include,
../include,
);
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
C6C90FDC21A5A24D00B5FCB7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
../external/Catch2/single_include,
../include,
);
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C6C90FCE21A5A24D00B5FCB7 /* Build configuration list for PBXProject "tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C6C90FD821A5A24D00B5FCB7 /* Debug */,
C6C90FD921A5A24D00B5FCB7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C6C90FDA21A5A24D00B5FCB7 /* Build configuration list for PBXNativeTarget "tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C6C90FDB21A5A24D00B5FCB7 /* Debug */,
C6C90FDC21A5A24D00B5FCB7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = C6C90FCB21A5A24D00B5FCB7 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:tests.xcodeproj">
</FileRef>
</Workspace>

View File

71
components/3rd_party/ini/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,71 @@
################# Add include #################
list(APPEND ADD_INCLUDE "inifile2/src"
)
# list(APPEND ADD_PRIVATE_INCLUDE "include_private")
###############################################
############## Add source files ###############
# list(APPEND ADD_SRCS "src/lib1.c"
# )
aux_source_directory("inifile2/src" ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS component1)
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS m) # add system libs, pthread or m(math) lib for example
###############################################
############ Add static libs ##################
# if(CONFIG_COMPONENT1_INCLUDE_STATIC_LIB)
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
# endif()
###############################################
############ Add dynamic libs ##################
# list(APPEND ADD_DYNAMIC_LIB "lib/arch/v831/libmaix_nn.so"
# "lib/arch/v831/libmaix_cam.so"
# )
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
###############################################
############ Add static libs ##################
#### Update parent's variables like CMAKE_C_LINK_FLAGS
# set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group libmaix/libtest.a -ltest2 -Wl,--end-group" PARENT_SCOPE)
###############################################
######### Add files need to download #########
# list(APPEND ADD_FILE_DOWNLOADS "{
# 'url': 'https://*****/abcde.tar.xz',
# 'urls': [], # backup urls, if url failed, will try urls
# 'sites': [], # download site, user can manually download file and put it into dl_path
# 'sha256sum': '',
# 'filename': 'abcde.tar.xz',
# 'path': 'toolchains/xxxxx',
# 'check_files': []
# }"
# )
#
# then extracted file in ${DL_EXTRACTED_PATH}/toolchains/xxxxx,
# you can directly use then, for example use it in add_custom_command
##############################################
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
register_component()

0
components/3rd_party/ini/Kconfig vendored Normal file
View File

View File

@@ -0,0 +1,58 @@
inifile2
========
## 一个轻量级的inifile文件解析库
### 一. 使用介绍
* 支持解析ini文件
* 支持修改、保存ini文件
* 支持设置多个注释符,默认为“#”和';'
* 支持参数名重复
* 使用gtest和valgrind做过测试
使用很简单生成一个ini文件test.ini
```
>cat > test.ini
#this is commit
;this is commit
[COMMON]
DB = mysql
PASSWD=root
```
首先指定头文件和命名空间 然后使用open函数打开ini文件 getValue可以获取指定段的指定项的值
```
#include "inifile.h"
using namespace inifile;
filepath = "test.ini";
IniFile ini;
ini.load(filepath);
//获取指定段的指定项的值
int ret = 0;
string db_name = ini.getValue("COMMON","DB",ret);
```
### 二. 本地测试构建方式
* 构建: `./build.sh`
* 清理: `./build.sh clean`
* 帮助: `./build.sh -h` 或者`./build.sh --help`
```
$./build.sh --help
usage: ./build.sh [clean] [-h|--help]
```
### 三. 如何引用inifile库
1. 源码引用:
编译时将src目录下的inifile.cpp 和inifile.h 拷贝到您的源码中直接进行编译即可,对于编译选项或者编译器有要求的建议使用这种源码拷贝的方式.
2. 二进制库引用:libinifile.so或者libinifile.a 引用
执行`./build.sh`后在build/lib目录下会生成libinifile.so和libinifile.a,您可以将这两个库添加到您的工程中对应的头文件为inifile.h.

View File

@@ -0,0 +1,838 @@
/* Copyright (c) 2014-2019 WinnerHust
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* The names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <iostream>
#include <fstream>
#include "inifile.h"
namespace inifile
{
// 构造函数会初始化注释字符集合flags_容器目前只使用#和;作为注释前缀
IniFile::IniFile()
:commentDelimiter("#")
{
}
//解析一行数据,得到键值
/* --------------------------------------------------------------------------*/
/**
* @brief parse
*
* @param content 数据源指针
* @param key 键名
* @param value 键值
* @param c 分隔符
*
* @return bool
*/
/* ----------------------------------------------------------------------------*/
bool IniFile::parse(const string &content, string *key, string *value)
{
return split(content, "=", key, value);
}
int IniFile::UpdateSection(const string &cleanLine, const string &comment,
const string &rightComment, IniSection **section)
{
IniSection *newSection;
// 查找右中括号
size_t index = cleanLine.find_first_of(']');
if (index == string::npos) {
errMsg = string("no matched ] found");
return ERR_UNMATCHED_BRACKETS;
}
int len = index - 1;
// 若段名为空,继续下一行
if (len <= 0) {
errMsg = string("section name is empty");
return ERR_SECTION_EMPTY;
}
// 取段名
string s(cleanLine, 1, len);
trim(s);
//检查段是否已存在
if (getSection(s) != NULL) {
errMsg = string("section ") + s + string("already exist");
return ERR_SECTION_ALREADY_EXISTS;
}
// 申请一个新段由于map容器会自动排序打乱原有顺序因此改用vector存储sections_vt
newSection = new IniSection();
// 填充段名
newSection->name = s;
// 填充段开头的注释
newSection->comment = comment;
newSection->rightComment = rightComment;
sections_vt.push_back(newSection);
*section = newSection;
return 0;
}
int IniFile::AddKeyValuePair(const string &cleanLine, const string &comment,
const string &rightComment, IniSection *section)
{
string key, value;
if (!parse(cleanLine, &key, &value)) {
errMsg = string("parse line failed:") + cleanLine;
return ERR_PARSE_KEY_VALUE_FAILED;
}
IniItem item;
item.key = key;
item.value = value;
item.comment = comment;
item.rightComment = rightComment;
section->items.push_back(item);
return 0;
}
int IniFile::Load(const string &filePath)
{
int err;
string line; // 带注释的行
string cleanLine; // 去掉注释后的行
string comment;
string rightComment;
IniSection *currSection = NULL; // 初始化一个字段指针
release();
iniFilePath = filePath;
std::ifstream ifs(iniFilePath);
if (!ifs.is_open()) {
errMsg = string("open") +iniFilePath+ string(" file failed");
return ERR_OPEN_FILE_FAILED;
}
//增加默认段,即 无名段""
currSection = new IniSection();
currSection->name = "";
sections_vt.push_back(currSection);
// 每次读取一行内容到line
while (std::getline(ifs, line)) {
trim(line);
// step 0空行处理如果长度为0说明是空行添加到comment当作是注释的一部分
if (line.length() <= 0) {
comment += delim;
continue;
}
// step 1
// 如果行首不是注释,查找行尾是否存在注释
// 如果该行以注释开头添加到comment跳过当前循环continue
if (IsCommentLine(line)) {
comment += line + delim;
continue;
}
// 如果行首不是注释查找行尾是否存在注释若存在切割该行将注释内容添加到rightComment
split(line, commentDelimiter, &cleanLine, &rightComment);
// step 2判断line内容是否为段或键
//段开头查找 [
if (cleanLine[0] == '[') {
err = UpdateSection(cleanLine, comment, rightComment, &currSection);
} else {
// 如果该行是键值添加到section段的items容器
err = AddKeyValuePair(cleanLine, comment, rightComment, currSection);
}
if (err != 0) {
ifs.close();
return err;
}
// comment清零
comment = "";
rightComment = "";
}
ifs.close();
return 0;
}
int IniFile::Save()
{
return SaveAs(iniFilePath);
}
int IniFile::SaveAs(const string &filePath)
{
string data = "";
/* 载入section数据 */
for (IniSection_it sect = sections_vt.begin(); sect != sections_vt.end(); ++sect) {
if ((*sect)->comment != "") {
data += (*sect)->comment;
}
if ((*sect)->name != "") {
data += string("[") + (*sect)->name + string("]");
data += delim;
}
if ((*sect)->rightComment != "") {
data += " " + commentDelimiter +(*sect)->rightComment;
}
/* 载入item数据 */
for (IniSection::IniItem_it item = (*sect)->items.begin(); item != (*sect)->items.end(); ++item) {
if (item->comment != "") {
data += item->comment;
if (data[data.length()-1] != '\n') {
data += delim;
}
}
data += item->key + "=" + item->value;
if (item->rightComment != "") {
data += " " + commentDelimiter + item->rightComment;
}
if (data[data.length()-1] != '\n') {
data += delim;
}
}
}
std::ofstream ofs(filePath);
ofs << data;
ofs.close();
return 0;
}
IniSection *IniFile::getSection(const string &section /*=""*/)
{
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
if ((*it)->name == section) {
return *it;
}
}
return NULL;
}
int IniFile::GetSections(vector<string> *sections)
{
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
sections->push_back((*it)->name);
}
return sections->size();
}
int IniFile::GetSectionNum()
{
return sections_vt.size();
}
int IniFile::GetStringValue(const string &section, const string &key, string *value)
{
return getValue(section, key, value);
}
int IniFile::GetIntValue(const string &section, const string &key, int *intValue)
{
int err;
string strValue;
err = getValue(section, key, &strValue);
*intValue = atoi(strValue.c_str());
return err;
}
int IniFile::GetDoubleValue(const string &section, const string &key, double *value)
{
int err;
string strValue;
err = getValue(section, key, &strValue);
*value = atof(strValue.c_str());
return err;
}
int IniFile::GetBoolValue(const string &section, const string &key, bool *value)
{
int err;
string strValue;
err = getValue(section, key, &strValue);
if (StringCmpIgnoreCase(strValue, "true") || StringCmpIgnoreCase(strValue, "1")) {
*value = true;
} else if (StringCmpIgnoreCase(strValue, "false") || StringCmpIgnoreCase(strValue, "0")) {
*value = false;
}
return err;
}
/* 获取section段第一个键为key的string值成功返回获取的值否则返回默认值 */
void IniFile::GetStringValueOrDefault(const string &section, const string &key,
string *value, const string &defaultValue)
{
if (GetStringValue(section, key, value) != 0) {
*value = defaultValue;
}
return;
}
/* 获取section段第一个键为key的int值成功返回获取的值否则返回默认值 */
void IniFile::GetIntValueOrDefault(const string &section, const string &key, int *value, int defaultValue)
{
if (GetIntValue(section, key, value) != 0) {
*value = defaultValue;
}
return;
}
/* 获取section段第一个键为key的double值成功返回获取的值否则返回默认值 */
void IniFile::GetDoubleValueOrDefault(const string &section, const string &key, double *value, double defaultValue)
{
if (GetDoubleValue(section, key, value) != 0) {
*value = defaultValue;
}
return;
}
/* 获取section段第一个键为key的bool值成功返回获取的值否则返回默认值 */
void IniFile::GetBoolValueOrDefault(const string &section, const string &key, bool *value, bool defaultValue)
{
if (GetBoolValue(section, key, value) != 0) {
*value = defaultValue;
}
return;
}
/* 获取注释如果key=""则获取段注释 */
int IniFile::GetComment(const string &section, const string &key, string *comment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
if (key == "") {
*comment = sect->comment;
return RET_OK;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
*comment = it->comment;
return RET_OK;
}
}
errMsg = string("not find the key ")+section;
return ERR_NOT_FOUND_KEY;
}
/* 获取行尾注释如果key=""则获取段的行尾注释 */
int IniFile::GetRightComment(const string &section, const string &key, string *rightComment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
if (key == "") {
*rightComment = sect->rightComment;
return RET_OK;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
*rightComment = it->rightComment;
return RET_OK;
}
}
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
int IniFile::getValue(const string &section, const string &key, string *value)
{
string comment;
return getValue(section, key, value, &comment);
}
int IniFile::getValue(const string &section, const string &key, string *value, string *comment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
*value = it->value;
*comment = it->comment;
return RET_OK;
}
}
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
int IniFile::GetValues(const string &section, const string &key, vector<string> *values)
{
vector<string> comments;
return GetValues(section, key, values, &comments);
}
int IniFile::GetValues(const string &section, const string &key, vector<string> *values, vector<string> *comments)
{
string value, comment;
values->clear();
comments->clear();
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
value = it->value;
comment = it->comment;
values->push_back(value);
comments->push_back(comment);
}
}
if (values->size() == 0) {
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
return RET_OK;
}
bool IniFile::HasSection(const string &section)
{
return (getSection(section) != NULL);
}
bool IniFile::HasKey(const string &section, const string &key)
{
IniSection *sect = getSection(section);
if (sect != NULL) {
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
return true;
}
}
}
return false;
}
int IniFile::setValue(const string &section, const string &key, const string &value, const string &comment /*=""*/)
{
IniSection *sect = getSection(section);
string comt = comment;
if (comt != "") {
comt = commentDelimiter + comt;
}
if (sect == NULL) {
//如果段不存在,新建一个
sect = new IniSection();
if (sect == NULL) {
errMsg = string("no enough memory!");
return ERR_NO_ENOUGH_MEMORY;
}
sect->name = section;
if (sect->name == "") {
// 确保空section在第一个
sections_vt.insert(sections_vt.begin(), sect);
} else {
sections_vt.push_back(sect);
}
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
it->value = value;
it->comment = comt;
return RET_OK;
}
}
// not found key
IniItem item;
item.key = key;
item.value = value;
item.comment = comt;
sect->items.push_back(item);
return RET_OK;
}
int IniFile::SetStringValue(const string &section, const string &key, const string &value)
{
return setValue(section, key, value);
}
int IniFile::SetIntValue(const string &section, const string &key, int value)
{
char buf[64] = {0};
snprintf(buf, sizeof(buf), "%d", value);
return setValue(section, key, buf);
}
int IniFile::SetDoubleValue(const string &section, const string &key, double value)
{
char buf[64] = {0};
snprintf(buf, sizeof(buf), "%f", value);
return setValue(section, key, buf);
}
int IniFile::SetBoolValue(const string &section, const string &key, bool value)
{
if (value) {
return setValue(section, key, "true");
} else {
return setValue(section, key, "false");
}
}
int IniFile::SetComment(const string &section, const string &key, const string &comment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("Not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
if (key == "") {
sect->comment = comment;
return RET_OK;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
it->comment = comment;
return RET_OK;
}
}
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
int IniFile::SetRightComment(const string &section, const string &key, const string &rightComment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("Not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
if (key == "") {
sect->rightComment = rightComment;
return RET_OK;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
it->rightComment = rightComment;
return RET_OK;
}
}
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
void IniFile::SetCommentDelimiter(const string &delimiter)
{
commentDelimiter = delimiter;
}
void IniFile::DeleteSection(const string &section)
{
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ) {
if ((*it)->name == section) {
delete *it;
it = sections_vt.erase(it);
break;
} else {
it++;
}
}
}
void IniFile::DeleteKey(const string &section, const string &key)
{
IniSection *sect = getSection(section);
if (sect != NULL) {
for (IniSection::IniItem_it it = sect->begin(); it != sect->end();) {
if (it->key == key) {
it = sect->items.erase(it);
break;
} else {
it++;
}
}
}
}
/*-------------------------------------------------------------------------*/
/**
@brief release: 释放全部资源,清空容器
@param none
@return none
*/
/*--------------------------------------------------------------------------*/
void IniFile::release()
{
iniFilePath = "";
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
delete (*it); // 清除section
}
sections_vt.clear();
}
/*-------------------------------------------------------------------------*/
/**
@brief 判断是否是注释
@param str 一个string变量
@return 如果是注释则为真
*/
/*--------------------------------------------------------------------------*/
bool IniFile::IsCommentLine(const string &str)
{
return StartWith(str, commentDelimiter);
}
/*-------------------------------------------------------------------------*/
/**
@brief print for debug
@param none
@return none
*/
/*--------------------------------------------------------------------------*/
void IniFile::print()
{
printf("############ print start ############\n");
printf("filePath:[%s]\n", iniFilePath.c_str());
printf("commentDelimiter:[%s]\n", commentDelimiter.c_str());
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
printf("comment :[\n%s]\n", (*it)->comment.c_str());
printf("section :\n[%s]\n", (*it)->name.c_str());
if ((*it)->rightComment != "") {
printf("rightComment:\n%s", (*it)->rightComment.c_str());
}
for (IniSection::IniItem_it i = (*it)->items.begin(); i != (*it)->items.end(); ++i) {
printf(" comment :[\n%s]\n", i->comment.c_str());
printf(" parm :%s=%s\n", i->key.c_str(), i->value.c_str());
if (i->rightComment != "") {
printf(" rcomment:[\n%s]\n", i->rightComment.c_str());
}
}
}
printf("############ print end ############\n");
return;
}
const string & IniFile::GetErrMsg()
{
return errMsg;
}
bool IniFile::StartWith(const string &str, const string &prefix)
{
if (strncmp(str.c_str(), prefix.c_str(), prefix.size()) == 0) {
return true;
}
return false;
}
void IniFile::trimleft(string &str, char c /*=' '*/)
{
int len = str.length();
int i = 0;
while (str[i] == c && str[i] != '\0') {
i++;
}
if (i != 0) {
str = string(str, i, len - i);
}
}
void IniFile::trimright(string &str, char c /*=' '*/)
{
int i = 0;
int len = str.length();
for (i = len - 1; i >= 0; --i) {
if (str[i] != c) {
break;
}
}
str = string(str, 0, i + 1);
}
/*-------------------------------------------------------------------------*/
/**
@brief trim整理一行字符串去掉首尾空格
@param str string变量
*/
/*--------------------------------------------------------------------------*/
void IniFile::trim(string &str)
{
int len = str.length();
int i = 0;
while ((i < len) && isspace(str[i]) && (str[i] != '\0')) {
i++;
}
if (i != 0) {
str = string(str, i, len - i);
}
len = str.length();
for (i = len - 1; i >= 0; --i) {
if (!isspace(str[i])) {
break;
}
}
str = string(str, 0, i + 1);
}
/*-------------------------------------------------------------------------*/
/**
@brief split用分隔符切割字符串
@param str 输入字符串
@param left_str 分隔后得到的左字符串
@param right_str 分隔后得到的右字符串不包含seperator
@param seperator 分隔符
@return pos
*/
/*--------------------------------------------------------------------------*/
bool IniFile::split(const string &str, const string &sep, string *pleft, string *pright)
{
size_t pos = str.find(sep);
string left, right;
if (pos != string::npos) {
left = string(str, 0, pos);
right = string(str, pos+1);
trim(left);
trim(right);
*pleft = left;
*pright = right;
return true;
} else {
left = str;
right = "";
trim(left);
*pleft = left;
*pright = right;
return false;
}
}
bool IniFile::StringCmpIgnoreCase(const string &str1, const string &str2)
{
string a = str1;
string b = str2;
transform(a.begin(), a.end(), a.begin(), towupper);
transform(b.begin(), b.end(), b.begin(), towupper);
return (a == b);
}
} /* namespace inifile */

View File

@@ -0,0 +1,205 @@
/* Copyright (c) 2014-2019 WinnerHust
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* The names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef INIFILE_H_
#define INIFILE_H_
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
using std::string;
using std::vector;
#define RET_OK 0
// 没有找到匹配的]
#define ERR_UNMATCHED_BRACKETS 2
// 段为空
#define ERR_SECTION_EMPTY 3
// 段名已经存在
#define ERR_SECTION_ALREADY_EXISTS 4
// 解析key value失败
#define ERR_PARSE_KEY_VALUE_FAILED 5
// 打开文件失败
#define ERR_OPEN_FILE_FAILED 6
// 内存不足
#define ERR_NO_ENOUGH_MEMORY 7
// 没有找到对应的key
#define ERR_NOT_FOUND_KEY 8
// 没有找到对应的section
#define ERR_NOT_FOUND_SECTION 9
namespace inifile
{
const char delim[] = "\n";
struct IniItem {
string key;
string value;
string comment; // 每个键的注释,都是指该行上方的内容
string rightComment;
};
struct IniSection {
typedef vector<IniItem>::iterator IniItem_it; // 定义一个迭代器,即指向键元素的指针
IniItem_it begin() {
return items.begin(); // 段结构体的begin元素指向items的头指针
}
IniItem_it end() {
return items.end(); // 段结构体的begin元素指向items的尾指针
}
string name;
string comment; // 每个段的注释,都是指该行上方的内容
string rightComment;
vector<IniItem> items; // 键值项数组一个段可以有多个键值所有用vector来储存
};
class IniFile
{
public:
IniFile();
~IniFile() {
release();
}
public:
/* 打开并解析一个名为fname的INI文件 */
int Load(const string &fname);
/* 将内容保存到当前文件 */
int Save();
/* 将内容另存到一个名为fname的文件 */
int SaveAs(const string &fname);
/* 获取section段第一个键为key的string值成功返回0否则返回错误码 */
int GetStringValue(const string &section, const string &key, string *value);
/* 获取section段第一个键为key的int值成功返回0否则返回错误码 */
int GetIntValue(const string &section, const string &key, int *value);
/* 获取section段第一个键为key的double值成功返回0否则返回错误码 */
int GetDoubleValue(const string &section, const string &key, double *value);
/* 获取section段第一个键为key的bool值成功返回0否则返回错误码 */
int GetBoolValue(const string &section, const string &key, bool *value);
/* 获取注释如果key=""则获取段注释 */
int GetComment(const string &section, const string &key, string *comment);
/* 获取行尾注释如果key=""则获取段的行尾注释 */
int GetRightComment(const string &section, const string &key, string *rightComment);
/* 获取section段第一个键为key的string值成功返回获取的值否则返回默认值 */
void GetStringValueOrDefault(const string &section, const string &key, string *value, const string &defaultValue);
/* 获取section段第一个键为key的int值成功返回获取的值否则返回默认值 */
void GetIntValueOrDefault(const string &section, const string &key, int *value, int defaultValue);
/* 获取section段第一个键为key的double值成功返回获取的值否则返回默认值 */
void GetDoubleValueOrDefault(const string &section, const string &key, double *value, double defaultValue);
/* 获取section段第一个键为key的bool值成功返回获取的值否则返回默认值 */
void GetBoolValueOrDefault(const string &section, const string &key, bool *value, bool defaultValue);
/* 获取section段所有键为key的值,并将值赋到values的vector中 */
int GetValues(const string &section, const string &key, vector<string> *values);
/* 获取section列表,并返回section个数 */
int GetSections(vector<string> *sections);
/* 获取section个数至少存在一个空section */
int GetSectionNum();
/* 是否存在某个section */
bool HasSection(const string &section);
/* 获取指定section的所有ken=value信息 */
IniSection *getSection(const string &section = "");
/* 是否存在某个key */
bool HasKey(const string &section, const string &key);
/* 设置字符串值 */
int SetStringValue(const string &section, const string &key, const string &value);
/* 设置整形值 */
int SetIntValue(const string &section, const string &key, int value);
/* 设置浮点数值 */
int SetDoubleValue(const string &section, const string &key, double value);
/* 设置布尔值 */
int SetBoolValue(const string &section, const string &key, bool value);
/* 设置注释如果key=""则设置段注释 */
int SetComment(const string &section, const string &key, const string &comment);
/* 设置行尾注释如果key=""则设置段的行尾注释 */
int SetRightComment(const string &section, const string &key, const string &rightComment);
/* 删除段 */
void DeleteSection(const string &section);
/* 删除特定段的特定参数 */
void DeleteKey(const string &section, const string &key);
/*设置注释分隔符,默认为"#" */
void SetCommentDelimiter(const string &delimiter);
const string &GetErrMsg();
private:
/* 获取section段所有键为key的值,并将值赋到values的vector中,,将注释赋到comments的vector中 */
int GetValues(const string &section, const string &key, vector<string> *value, vector<string> *comments);
/* 同时设置值和注释 */
int setValue(const string &section, const string &key, const string &value, const string &comment = "");
/* 去掉str前面的c字符 */
static void trimleft(string &str, char c = ' ');
/* 去掉str后面的c字符 */
static void trimright(string &str, char c = ' ');
/* 去掉str前面和后面的空格符,Tab符等空白符 */
static void trim(string &str);
/* 将字符串str按分割符delim分割成多个子串 */
private:
int UpdateSection(const string &cleanLine, const string &comment,
const string &rightComment, IniSection **section);
int AddKeyValuePair(const string &cleanLine, const string &comment,
const string &rightComment, IniSection *section);
void release();
bool split(const string &str, const string &sep, string *left, string *right);
bool IsCommentLine(const string &str);
bool parse(const string &content, string *key, string *value);
// for debug
void print();
private:
/* 获取section段第一个键为key的值,并将值赋到value中 */
int getValue(const string &section, const string &key, string *value);
/* 获取section段第一个键为key的值,并将值赋到value中,将注释赋到comment中 */
int getValue(const string &section, const string &key, string *value, string *comment);
bool StringCmpIgnoreCase(const string &str1, const string &str2);
bool StartWith(const string &str, const string &prefix);
private:
typedef vector<IniSection *>::iterator IniSection_it;
vector<IniSection *> sections_vt; // 用于存储段集合的vector容器
string iniFilePath;
string commentDelimiter;
string errMsg; // 保存出错时的错误信息
};
} // endof namespace inifile
#endif // INIFILE_H_

121
components/3rd_party/lvgl/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,121 @@
set(version_str "${CONFIG_LVGL_VERSION_MAJOR}.${CONFIG_LVGL_VERSION_MINOR}.${CONFIG_LVGL_VERSION_PATCH}")
set(url "https://github.com/lvgl/lvgl/archive/refs/tags/v${version_str}.tar.gz")
set(filename "lvgl-${version_str}.tar.gz")
set(unzip_dir_name "lvgl-${version_str}")
if(version_str EQUAL "8.3.5")
set(file_sha256sum "2b28a12b70a01cfbe8145abbc56f57fc0e9d7e34cacce5acda19a175fadf5935")
elseif(version_str EQUAL "8.3.10")
set(file_sha256sum "f27c4a963501871390c5aa415dfcbdfd46297a4a33f86c2d2c35b34d385ee39d")
elseif(version_str EQUAL "9.0.0")
set(file_sha256sum "73ae6ef7b44b434b41f25755ce4f6f5d23c49c1c254c4b7774b5a9cf83a46b7f")
elseif(version_str EQUAL "9.1.0")
set(file_sha256sum "6930f1605d305fcd43f31d5f470ecf4a013c4ce0980e78ee4c33b96a589bf433")
else()
message(FATAL_ERROR "lvgl version ${version_str} not support, please edit CMakeLists.txt to add support")
endif()
list(APPEND ADD_FILE_DOWNLOADS "{
'url': '${url}',
'urls': [],
'sites': [],
'sha256sum': '${file_sha256sum}',
'filename': '${filename}',
'path': 'lvgl_srcs/${unzip_dir_name}',
'rename': {'${unzip_dir_name}': 'lvgl'},
'check_files': ['lvgl']
}"
)
set(unzip_path "${DL_EXTRACTED_PATH}/lvgl_srcs/${unzip_dir_name}")
set(src_path "${unzip_path}/lvgl") # MaixCDK/dl/extracted/lvgl_srcs/lvgl-9.0.0/lvgl
################# Add include #################
list(APPEND ADD_INCLUDE "conf"
"."
"include"
"driver"
"${unzip_path}"
"${src_path}"
"${src_path}/src/"
"${src_path}/src/core"
"${src_path}/src/display"
"${src_path}/src/draw"
"${src_path}/src/drivers"
"${src_path}/src/font"
"${src_path}/src/indev"
"${src_path}/src/layouts"
"${src_path}/src/libs"
"${src_path}/src/misc"
"${src_path}/src/osal"
"${src_path}/src/others"
"${src_path}/src/stdlib"
"${src_path}/src/themes"
"${src_path}/src/tick"
"${src_path}/src/widgets"
"${src_path}/src"
)
# list(APPEND ADD_PRIVATE_INCLUDE "include_private")
###############################################
############## Add source files ###############
# list(APPEND ADD_SRCS "src/lib1.c"
# )
# aux_source_directory(src ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
FILE(GLOB_RECURSE EXTRA_SRC "${src_path}/src/*.c")
LIST(APPEND ADD_SRCS ${EXTRA_SRC})
append_srcs_dir(ADD_SRCS "driver")
append_srcs_dir(ADD_SRCS "src")
# set_property(SOURCE ${src_path} PROPERTY GENERATED 1)
list(APPEND ADD_REQUIREMENTS basic vision)
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS component1)
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
list(APPEND ADD_REQUIREMENTS rlottie)
###############################################
############ Add static libs ##################
# if(CONFIG_COMPONENT1_INCLUDE_STATIC_LIB)
# list(APPEND ADD_STATIC_LIB "lib/libtest.a")
# endif()
###############################################
############ Add dynamic libs ##################
# list(APPEND ADD_DYNAMIC_LIB "lib/arch/v831/libmaix_nn.so"
# "lib/arch/v831/libmaix_cam.so"
# )
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
list(APPEND ADD_DEFINITIONS -DLV_CONF_INCLUDE_SIMPLE -DLV_LVGL_H_INCLUDE_SIMPLE)
# if(CONFIG_LV_CONF_SKIP)
# list(APPEND ADD_DEFINITIONS -DLV_CONF_SKIP)
# endif()
###############################################
############ Add static libs ##################
#### Update parent's variables like CMAKE_C_LINK_FLAGS
# set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group libmaix/libtest.a -ltest2 -Wl,--end-group" PARENT_SCOPE)
###############################################
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
register_component()

28
components/3rd_party/lvgl/Kconfig vendored Normal file
View File

@@ -0,0 +1,28 @@
menu "gui_lvgl component configuration"
menu "LVGL version"
config LVGL_VERSION_MAJOR
int "LVGL version major"
default 9
config LVGL_VERSION_MINOR
int "LVGL version minor"
default 1
config LVGL_VERSION_PATCH
int "LVGL version patch"
default 0
endmenu
config LVGL_USE_MOUSE
bool "Use mouse(touchpad) input"
default y
help
Enable mouse input support.
config LVGL_SHOW_PERFORMANCE
bool "Show performance monitor"
default n
help
Show performance monitor on the screen.
osource "${SDK_PATH}/dl/extracted/lvgl_srcs/lvgl/Kconfig"
endmenu

963
components/3rd_party/lvgl/conf/lv_conf.h vendored Normal file
View File

@@ -0,0 +1,963 @@
/**
* @file lv_conf.h
* Configuration file for v8.0.0
*/
/*
* COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER
*/
#if 1 /*Set it to "1" to enable content*/
#ifndef LV_CONF_H
#define LV_CONF_H
/*clang-format off*/
/***************** maix *********************/
#include <stdint.h>
#include <stdbool.h>
#include "global_config.h"
extern bool lv_ui_mutex_lock(int timeout);
extern void lv_ui_mutex_unlock();
/***************** maix *********************/
/*====================
COLOR SETTINGS
*====================*/
/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
#define LV_COLOR_DEPTH 32
/*=========================
STDLIB WRAPPER SETTINGS
*=========================*/
/* Possible values
* - LV_STDLIB_BUILTIN: LVGL's built in implementation
* - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc
* - LV_STDLIB_MICROPYTHON: MicroPython implementation
* - LV_STDLIB_RTTHREAD: RT-Thread implementation
* - LV_STDLIB_CUSTOM: Implement the functions externally
*/
#define LV_USE_STDLIB_MALLOC LV_STDLIB_CLIB
#define LV_USE_STDLIB_STRING LV_STDLIB_CLIB
#define LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
/*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/
#define LV_MEM_SIZE (64 * 1024U) /*[bytes]*/
/*Size of the memory expand for `lv_malloc()` in bytes*/
#define LV_MEM_POOL_EXPAND_SIZE 0
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
#define LV_MEM_ADR 0 /*0: unused*/
/*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
#if LV_MEM_ADR == 0
#undef LV_MEM_POOL_INCLUDE
#undef LV_MEM_POOL_ALLOC
#endif
#endif /*LV_USE_MALLOC == LV_STDLIB_BUILTIN*/
/*====================
HAL SETTINGS
*====================*/
/*Default display refresh, input device read and animation step period.*/
#define LV_DEF_REFR_PERIOD 33 /*[ms]*/
/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.
*(Not so important, you can adjust it to modify default sizes and spaces)*/
#define LV_DPI_DEF 180 /*[px/inch]*/
/*=================
* OPERATING SYSTEM
*=================*/
/*Select an operating system to use. Possible options:
* - LV_OS_NONE
* - LV_OS_PTHREAD
* - LV_OS_FREERTOS
* - LV_OS_CMSIS_RTOS2
* - LV_OS_RTTHREAD
* - LV_OS_WINDOWS
* - LV_OS_CUSTOM */
#define LV_USE_OS LV_OS_PTHREAD
#if LV_USE_OS == LV_OS_CUSTOM
#define LV_OS_CUSTOM_INCLUDE <stdint.h>
#endif
/*========================
* RENDERING CONFIGURATION
*========================*/
/*Align the stride of all layers and images to this bytes*/
#define LV_DRAW_BUF_STRIDE_ALIGN 1
/*Align the start address of draw_buf addresses to this bytes*/
#define LV_DRAW_BUF_ALIGN 4
#define LV_USE_DRAW_SW 1
#if LV_USE_DRAW_SW == 1
/* Set the number of draw unit.
* > 1 requires an operating system enabled in `LV_USE_OS`
* > 1 means multiply threads will render the screen in parallel */
#define LV_DRAW_SW_DRAW_UNIT_CNT 1
/* Use Arm-2D to accelerate the sw render */
#define LV_USE_DRAW_ARM2D_SYNC 0
/* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode
* it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks.
* "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers
* and can't be drawn in chunks. */
/*The target buffer size for simple layer chunks.*/
#define LV_DRAW_SW_LAYER_SIMPLE_BUF_SIZE (64 * 1024) /*[bytes]*/
/* 0: use a simple renderer capable of drawing only simple rectangles with gradient, images, texts, and straight lines only
* 1: use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too */
#define LV_DRAW_SW_COMPLEX 1
#if LV_DRAW_SW_COMPLEX == 1
/*Allow buffering some shadow calculation.
*LV_DRAW_SW_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius`
*Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost*/
#define LV_DRAW_SW_SHADOW_CACHE_SIZE 0
/* Set number of maximally cached circle data.
* The circumference of 1/4 circle are saved for anti-aliasing
* radius * 4 bytes are used per circle (the most often used radiuses are saved)
* 0: to disable caching */
#define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4
#endif
#define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE
#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM
#define LV_DRAW_SW_ASM_CUSTOM_INCLUDE ""
#endif
#endif
/* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */
#define LV_USE_DRAW_VGLITE 0
#if LV_USE_DRAW_VGLITE
/* Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */
#define LV_USE_VGLITE_BLIT_SPLIT 0
#if LV_USE_OS
/* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */
#define LV_USE_VGLITE_DRAW_ASYNC 1
#endif
/* Enable VGLite asserts. */
#define LV_USE_VGLITE_ASSERT 0
#endif
/* Use NXP's PXP on iMX RTxxx platforms. */
#define LV_USE_DRAW_PXP 0
#if LV_USE_DRAW_PXP
/* Enable PXP asserts. */
#define LV_USE_PXP_ASSERT 0
#endif
/* Use Renesas Dave2D on RA platforms. */
#define LV_USE_DRAW_DAVE2D 0
/* Draw using cached SDL textures*/
#define LV_USE_DRAW_SDL 0
/* Use VG-Lite GPU. */
#define LV_USE_DRAW_VG_LITE 0
#if LV_USE_DRAW_VG_LITE
/* Enable VG-Lite custom external 'gpu_init()' function */
#define LV_VG_LITE_USE_GPU_INIT 0
/* Enable VG-Lite assert. */
#define LV_VG_LITE_USE_ASSERT 0
#endif
/*=======================
* FEATURE CONFIGURATION
*=======================*/
/*-------------
* Logging
*-----------*/
/*Enable the log module*/
#define LV_USE_LOG 0
#if LV_USE_LOG
/*How important log should be added:
*LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
*LV_LOG_LEVEL_INFO Log important events
*LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
*LV_LOG_LEVEL_USER Only logs added by the user
*LV_LOG_LEVEL_NONE Do not log anything*/
#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
/*1: Print the log with 'printf';
*0: User need to register a callback with `lv_log_register_print_cb()`*/
#define LV_LOG_PRINTF 0
/*1: Enable print timestamp;
*0: Disable print timestamp*/
#define LV_LOG_USE_TIMESTAMP 1
/*1: Print file and line number of the log;
*0: Do not print file and line number of the log*/
#define LV_LOG_USE_FILE_LINE 1
/*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
#define LV_LOG_TRACE_MEM 1
#define LV_LOG_TRACE_TIMER 1
#define LV_LOG_TRACE_INDEV 1
#define LV_LOG_TRACE_DISP_REFR 1
#define LV_LOG_TRACE_EVENT 1
#define LV_LOG_TRACE_OBJ_CREATE 1
#define LV_LOG_TRACE_LAYOUT 1
#define LV_LOG_TRACE_ANIM 1
#define LV_LOG_TRACE_CACHE 1
#endif /*LV_USE_LOG*/
/*-------------
* Asserts
*-----------*/
/*Enable asserts if an operation is failed or an invalid data is found.
*If LV_USE_LOG is enabled an error message will be printed on failure*/
#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/
#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/
#define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/
#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/
#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/
/*Add a custom handler when assert happens e.g. to restart the MCU*/
#define LV_ASSERT_HANDLER_INCLUDE <stdint.h>
#define LV_ASSERT_HANDLER while(1); /*Halt by default*/
/*-------------
* Debug
*-----------*/
/*1: Draw random colored rectangles over the redrawn areas*/
#define LV_USE_REFR_DEBUG 0
/*1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/
#define LV_USE_LAYER_DEBUG 0
/*1: Draw overlays with different colors for each draw_unit's tasks.
*Also add the index number of the draw unit on white background.
*For layers add the index number of the draw unit on black background.*/
#define LV_USE_PARALLEL_DRAW_DEBUG 0
/*-------------
* Others
*-----------*/
#define LV_ENABLE_GLOBAL_CUSTOM 0
#if LV_ENABLE_GLOBAL_CUSTOM
/*Header to include for the custom 'lv_global' function"*/
#define LV_GLOBAL_CUSTOM_INCLUDE <stdint.h>
#endif
/*Default cache size in bytes.
*Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory.
*If size is not set to 0, the decoder will fail to decode when the cache is full.
*If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/
#define LV_CACHE_DEF_SIZE 0
/*Default number of image header cache entries. The cache is used to store the headers of images
*The main logic is like `LV_CACHE_DEF_SIZE` but for image headers.*/
#define LV_IMAGE_HEADER_CACHE_DEF_CNT 0
/*Number of stops allowed per gradient. Increase this to allow more stops.
*This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
#define LV_GRADIENT_MAX_STOPS 2
/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently.
* 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */
#define LV_COLOR_MIX_ROUND_OFS 0
/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */
#define LV_OBJ_STYLE_CACHE 0
/* Add `id` field to `lv_obj_t` */
#define LV_USE_OBJ_ID 0
/* Use lvgl builtin method for obj ID */
#define LV_USE_OBJ_ID_BUILTIN 0
/*Use obj property set/get API*/
#define LV_USE_OBJ_PROPERTY 0
/* VG-Lite Simulator */
/*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */
#define LV_USE_VG_LITE_THORVG 0
#if LV_USE_VG_LITE_THORVG
/*Enable LVGL's blend mode support*/
#define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0
/*Enable YUV color format support*/
#define LV_VG_LITE_THORVG_YUV_SUPPORT 0
/*Enable 16 pixels alignment*/
#define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1
/*Enable multi-thread render*/
#define LV_VG_LITE_THORVG_THREAD_RENDER 0
#endif
/*=====================
* COMPILER SETTINGS
*====================*/
/*For big endian systems set to 1*/
#define LV_BIG_ENDIAN_SYSTEM 0
/*Define a custom attribute to `lv_tick_inc` function*/
#define LV_ATTRIBUTE_TICK_INC
/*Define a custom attribute to `lv_timer_handler` function*/
#define LV_ATTRIBUTE_TIMER_HANDLER
/*Define a custom attribute to `lv_display_flush_ready` function*/
#define LV_ATTRIBUTE_FLUSH_READY
/*Required alignment size for buffers*/
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1
/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default).
* E.g. __attribute__((aligned(4)))*/
#define LV_ATTRIBUTE_MEM_ALIGN
/*Attribute to mark large constant arrays for example font's bitmaps*/
#define LV_ATTRIBUTE_LARGE_CONST
/*Compiler prefix for a big array declaration in RAM*/
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY
/*Place performance critical functions into a faster memory (e.g RAM)*/
#define LV_ATTRIBUTE_FAST_MEM
/*Export integer constant to binding. This macro is used with constants in the form of LV_<CONST> that
*should also appear on LVGL binding API such as Micropython.*/
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/
/*Prefix all global extern data with this*/
#define LV_ATTRIBUTE_EXTERN_DATA
/* Use `float` as `lv_value_precise_t` */
#define LV_USE_FLOAT 0
/*==================
* FONT USAGE
*===================*/
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
*https://fonts.google.com/specimen/Montserrat*/
#define LV_FONT_MONTSERRAT_8 0
#define LV_FONT_MONTSERRAT_10 0
#define LV_FONT_MONTSERRAT_12 1
#define LV_FONT_MONTSERRAT_14 1
#define LV_FONT_MONTSERRAT_16 1
#define LV_FONT_MONTSERRAT_18 0
#define LV_FONT_MONTSERRAT_20 1
#define LV_FONT_MONTSERRAT_22 0
#define LV_FONT_MONTSERRAT_24 1
#define LV_FONT_MONTSERRAT_26 0
#define LV_FONT_MONTSERRAT_28 0
#define LV_FONT_MONTSERRAT_30 0
#define LV_FONT_MONTSERRAT_32 1
#define LV_FONT_MONTSERRAT_34 0
#define LV_FONT_MONTSERRAT_36 0
#define LV_FONT_MONTSERRAT_38 0
#define LV_FONT_MONTSERRAT_40 0
#define LV_FONT_MONTSERRAT_42 0
#define LV_FONT_MONTSERRAT_44 0
#define LV_FONT_MONTSERRAT_46 0
#define LV_FONT_MONTSERRAT_48 0
/*Demonstrate special features*/
#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/
#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/
/*Pixel perfect monospace fonts*/
#define LV_FONT_UNSCII_8 0
#define LV_FONT_UNSCII_16 0
/*Optionally declare custom fonts here.
*You can use these fonts as default font too and they will be available globally.
*E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/
#define LV_FONT_CUSTOM_DECLARE
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_montserrat_14
/*Enable handling large font and/or fonts with a lot of characters.
*The limit depends on the font size, font face and bpp.
*Compiler error will be triggered if a font needs it.*/
#define LV_FONT_FMT_TXT_LARGE 0
/*Enables/disables support for compressed fonts.*/
#define LV_USE_FONT_COMPRESSED 0
/*Enable drawing placeholders when glyph dsc is not found*/
#define LV_USE_FONT_PLACEHOLDER 1
/*=================
* TEXT SETTINGS
*=================*/
/**
* Select a character encoding for strings.
* Your IDE or editor should have the same character encoding
* - LV_TXT_ENC_UTF8
* - LV_TXT_ENC_ASCII
*/
#define LV_TXT_ENC LV_TXT_ENC_UTF8
/*Can break (wrap) texts on these chars*/
#define LV_TXT_BREAK_CHARS " ,.;:-_)]}"
/*If a word is at least this long, will break wherever "prettiest"
*To disable, set to a value <= 0*/
#define LV_TXT_LINE_BREAK_LONG_LEN 0
/*Minimum number of characters in a long word to put on a line before a break.
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
/*Minimum number of characters in a long word to put on a line after a break.
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts.
*The direction will be processed according to the Unicode Bidirectional Algorithm:
*https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
#define LV_USE_BIDI 0
#if LV_USE_BIDI
/*Set the default direction. Supported values:
*`LV_BASE_DIR_LTR` Left-to-Right
*`LV_BASE_DIR_RTL` Right-to-Left
*`LV_BASE_DIR_AUTO` detect texts base direction*/
#define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO
#endif
/*Enable Arabic/Persian processing
*In these languages characters should be replaced with an other form based on their position in the text*/
#define LV_USE_ARABIC_PERSIAN_CHARS 0
/*==================
* WIDGETS
*================*/
/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/
#define LV_WIDGETS_HAS_DEFAULT_VALUE 1
#define LV_USE_ANIMIMG 1
#define LV_USE_ARC 1
#define LV_USE_BAR 1
#define LV_USE_BUTTON 1
#define LV_USE_BUTTONMATRIX 1
#define LV_USE_CALENDAR 1
#if LV_USE_CALENDAR
#define LV_CALENDAR_WEEK_STARTS_MONDAY 0
#if LV_CALENDAR_WEEK_STARTS_MONDAY
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}
#else
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"}
#endif
#define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
#define LV_USE_CALENDAR_HEADER_ARROW 1
#define LV_USE_CALENDAR_HEADER_DROPDOWN 1
#endif /*LV_USE_CALENDAR*/
#define LV_USE_CANVAS 1
#define LV_USE_CHART 1
#define LV_USE_CHECKBOX 1
#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/
#define LV_USE_IMAGE 1 /*Requires: lv_label*/
#define LV_USE_IMAGEBUTTON 1
#define LV_USE_KEYBOARD 1
#define LV_USE_LABEL 1
#if LV_USE_LABEL
#define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/
#define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/
#define LV_LABEL_WAIT_CHAR_COUNT 3 /*The count of wait chart*/
#endif
#define LV_USE_LED 1
#define LV_USE_LINE 1
#define LV_USE_LIST 1
#define LV_USE_MENU 1
#define LV_USE_MSGBOX 1
#define LV_USE_ROLLER 1 /*Requires: lv_label*/
#define LV_USE_SCALE 1
#define LV_USE_SLIDER 1 /*Requires: lv_bar*/
#define LV_USE_SPAN 1
#if LV_USE_SPAN
/*A line text can contain maximum num of span descriptor */
#define LV_SPAN_SNIPPET_STACK_SIZE 64
#endif
#define LV_USE_SPINBOX 1
#define LV_USE_SPINNER 1
#define LV_USE_SWITCH 1
#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/
#if LV_USE_TEXTAREA != 0
#define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/
#endif
#define LV_USE_TABLE 1
#define LV_USE_TABVIEW 1
#define LV_USE_TILEVIEW 1
#define LV_USE_WIN 1
/*==================
* THEMES
*==================*/
/*A simple, impressive and very complete theme*/
#define LV_USE_THEME_DEFAULT 1
#if LV_USE_THEME_DEFAULT
/*0: Light mode; 1: Dark mode*/
#define LV_THEME_DEFAULT_DARK 1
/*1: Enable grow on press*/
#define LV_THEME_DEFAULT_GROW 1
/*Default transition time in [ms]*/
#define LV_THEME_DEFAULT_TRANSITION_TIME 80
#endif /*LV_USE_THEME_DEFAULT*/
/*A very simple theme that is a good starting point for a custom theme*/
#define LV_USE_THEME_SIMPLE 1
/*A theme designed for monochrome displays*/
#define LV_USE_THEME_MONO 1
/*==================
* LAYOUTS
*==================*/
/*A layout similar to Flexbox in CSS.*/
#define LV_USE_FLEX 1
/*A layout similar to Grid in CSS.*/
#define LV_USE_GRID 1
/*====================
* 3RD PARTS LIBRARIES
*====================*/
/*File system interfaces for common APIs */
/*API for fopen, fread, etc*/
#define LV_USE_FS_STDIO 1
#if LV_USE_FS_STDIO
#define LV_FS_STDIO_LETTER 'A' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
#define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
#endif
/*API for open, read, etc*/
#define LV_USE_FS_POSIX 0
#if LV_USE_FS_POSIX
#define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
#define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
#endif
/*API for CreateFile, ReadFile, etc*/
#define LV_USE_FS_WIN32 0
#if LV_USE_FS_WIN32
#define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
#define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
#endif
/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
#define LV_USE_FS_FATFS 0
#if LV_USE_FS_FATFS
#define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
#endif
/*API for memory-mapped file access. */
#define LV_USE_FS_MEMFS 0
#if LV_USE_FS_MEMFS
#define LV_FS_MEMFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#endif
/*LODEPNG decoder library*/
#define LV_USE_LODEPNG 1
/*PNG decoder(libpng) library*/
#define LV_USE_LIBPNG 0
/*BMP decoder library*/
#define LV_USE_BMP 0
/* JPG + split JPG decoder library.
* Split JPG is a custom format optimized for embedded systems. */
#define LV_USE_TJPGD 0
/* libjpeg-turbo decoder library.
* Supports complete JPEG specifications and high-performance JPEG decoding. */
#define LV_USE_LIBJPEG_TURBO 0
/*GIF decoder library*/
#define LV_USE_GIF 0
#if LV_USE_GIF
/*GIF decoder accelerate*/
#define LV_GIF_CACHE_DECODE_DATA 0
#endif
/*Decode bin images to RAM*/
#define LV_BIN_DECODER_RAM_LOAD 0
/*RLE decompress library*/
#define LV_USE_RLE 0
/*QR code library*/
#define LV_USE_QRCODE 0
/*Barcode code library*/
#define LV_USE_BARCODE 0
/*FreeType library*/
#define LV_USE_FREETYPE 0
#if LV_USE_FREETYPE
/*Memory used by FreeType to cache characters in kilobytes*/
#define LV_FREETYPE_CACHE_SIZE 768
/*Let FreeType to use LVGL memory and file porting*/
#define LV_FREETYPE_USE_LVGL_PORT 0
/* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */
/* (0:use system defaults) */
#define LV_FREETYPE_CACHE_FT_FACES 8
#define LV_FREETYPE_CACHE_FT_SIZES 8
#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256
#endif
/* Built-in TTF decoder */
#define LV_USE_TINY_TTF 0
#if LV_USE_TINY_TTF
/* Enable loading TTF data from files */
#define LV_TINY_TTF_FILE_SUPPORT 0
#endif
/*Rlottie library*/
#define LV_USE_RLOTTIE 1
/*Enable Vector Graphic APIs*/
#define LV_USE_VECTOR_GRAPHIC 0
/* Enable ThorVG (vector graphics library) from the src/libs folder */
#define LV_USE_THORVG_INTERNAL 0
/* Enable ThorVG by assuming that its installed and linked to the project */
#define LV_USE_THORVG_EXTERNAL 0
/*Enable LZ4 compress/decompress lib*/
#define LV_USE_LZ4 0
/*Use lvgl built-in LZ4 lib*/
#define LV_USE_LZ4_INTERNAL 0
/*Use external LZ4 library*/
#define LV_USE_LZ4_EXTERNAL 0
/*FFmpeg library for image decoding and playing videos
*Supports all major image formats so do not enable other image decoder with it*/
#define LV_USE_FFMPEG 0
#if LV_USE_FFMPEG
/*Dump input information to stderr*/
#define LV_FFMPEG_DUMP_FORMAT 0
#endif
/*==================
* OTHERS
*==================*/
/*1: Enable API to take snapshot for object*/
#define LV_USE_SNAPSHOT 0
/*1: Enable system monitor component*/
#define LV_USE_SYSMON 0
#if LV_USE_SYSMON
/*Get the idle percentage. E.g. uint32_t my_get_idle(void);*/
#define LV_SYSMON_GET_IDLE lv_timer_get_idle
/*1: Show CPU usage and FPS count
* Requires `LV_USE_SYSMON = 1`*/
#define LV_USE_PERF_MONITOR 0
#if LV_USE_PERF_MONITOR
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
/*0: Displays performance data on the screen, 1: Prints performance data using log.*/
#define LV_USE_PERF_MONITOR_LOG_MODE 0
#endif
/*1: Show the used memory and the memory fragmentation
* Requires `LV_USE_BUILTIN_MALLOC = 1`
* Requires `LV_USE_SYSMON = 1`*/
#define LV_USE_MEM_MONITOR 0
#if LV_USE_MEM_MONITOR
#define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT
#endif
#endif /*LV_USE_SYSMON*/
/*1: Enable the runtime performance profiler*/
#define LV_USE_PROFILER 0
#if LV_USE_PROFILER
/*1: Enable the built-in profiler*/
#define LV_USE_PROFILER_BUILTIN 1
#if LV_USE_PROFILER_BUILTIN
/*Default profiler trace buffer size*/
#define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /*[bytes]*/
#endif
/*Header to include for the profiler*/
#define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h"
/*Profiler start point function*/
#define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN
/*Profiler end point function*/
#define LV_PROFILER_END LV_PROFILER_BUILTIN_END
/*Profiler start point function with custom tag*/
#define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG
/*Profiler end point function with custom tag*/
#define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG
#endif
/*1: Enable Monkey test*/
#define LV_USE_MONKEY 0
/*1: Enable grid navigation*/
#define LV_USE_GRIDNAV 0
/*1: Enable lv_obj fragment*/
#define LV_USE_FRAGMENT 0
/*1: Support using images as font in label or span widgets */
#define LV_USE_IMGFONT 0
/*1: Enable an observer pattern implementation*/
#define LV_USE_OBSERVER 1
/*1: Enable Pinyin input method*/
/*Requires: lv_keyboard*/
#define LV_USE_IME_PINYIN 0
#if LV_USE_IME_PINYIN
/*1: Use default thesaurus*/
/*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/
#define LV_IME_PINYIN_USE_DEFAULT_DICT 1
/*Set the maximum number of candidate panels that can be displayed*/
/*This needs to be adjusted according to the size of the screen*/
#define LV_IME_PINYIN_CAND_TEXT_NUM 6
/*Use 9 key input(k9)*/
#define LV_IME_PINYIN_USE_K9_MODE 1
#if LV_IME_PINYIN_USE_K9_MODE == 1
#define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3
#endif /*LV_IME_PINYIN_USE_K9_MODE*/
#endif
/*1: Enable file explorer*/
/*Requires: lv_table*/
#define LV_USE_FILE_EXPLORER 0
#if LV_USE_FILE_EXPLORER
/*Maximum length of path*/
#define LV_FILE_EXPLORER_PATH_MAX_LEN (128)
/*Quick access bar, 1:use, 0:not use*/
/*Requires: lv_list*/
#define LV_FILE_EXPLORER_QUICK_ACCESS 1
#endif
/*==================
* DEVICES
*==================*/
/*Use SDL to open window on PC and handle mouse and keyboard*/
#define LV_USE_SDL 0
#if LV_USE_SDL
#define LV_SDL_INCLUDE_PATH <SDL2/SDL.h>
#define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/
#define LV_SDL_BUF_COUNT 1 /*1 or 2*/
#define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/
#define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/
#endif
/*Use X11 to open window on Linux desktop and handle mouse and keyboard*/
#define LV_USE_X11 0
#if LV_USE_X11
#define LV_X11_DIRECT_EXIT 1 /*Exit the application when all X11 windows have been closed*/
#define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for endering*/
/*select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!)*/
#define LV_X11_RENDER_MODE_PARTIAL 1 /*Partial render mode (preferred)*/
#define LV_X11_RENDER_MODE_DIRECT 0 /*direct render mode*/
#define LV_X11_RENDER_MODE_FULL 0 /*Full render mode*/
#endif
/*Driver for /dev/fb*/
#define LV_USE_LINUX_FBDEV 0
#if LV_USE_LINUX_FBDEV
#define LV_LINUX_FBDEV_BSD 0
#define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL
#define LV_LINUX_FBDEV_BUFFER_COUNT 0
#define LV_LINUX_FBDEV_BUFFER_SIZE 60
#endif
/*Use Nuttx to open window and handle touchscreen*/
#define LV_USE_NUTTX 0
#if LV_USE_NUTTX
#define LV_USE_NUTTX_LIBUV 0
/*Use Nuttx custom init API to open window and handle touchscreen*/
#define LV_USE_NUTTX_CUSTOM_INIT 0
/*Driver for /dev/lcd*/
#define LV_USE_NUTTX_LCD 0
#if LV_USE_NUTTX_LCD
#define LV_NUTTX_LCD_BUFFER_COUNT 0
#define LV_NUTTX_LCD_BUFFER_SIZE 60
#endif
/*Driver for /dev/input*/
#define LV_USE_NUTTX_TOUCHSCREEN 0
#endif
/*Driver for /dev/dri/card*/
#define LV_USE_LINUX_DRM 0
/*Interface for TFT_eSPI*/
#define LV_USE_TFT_ESPI 0
/*Driver for evdev input devices*/
#define LV_USE_EVDEV 0
/*Drivers for LCD devices connected via SPI/parallel port*/
#define LV_USE_ST7735 0
#define LV_USE_ST7789 0
#define LV_USE_ST7796 0
#define LV_USE_ILI9341 0
#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
/* LVGL Windows backend */
#define LV_USE_WINDOWS 0
/*==================
* EXAMPLES
*==================*/
/*Enable the examples to be built with the library*/
#define LV_BUILD_EXAMPLES 1
/*===================
* DEMO USAGE
====================*/
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
#define LV_USE_DEMO_WIDGETS 0
#if LV_USE_DEMO_WIDGETS
#define LV_DEMO_WIDGETS_SLIDESHOW 0
#endif
/*Demonstrate the usage of encoder and keyboard*/
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
/*Benchmark your system*/
#define LV_USE_DEMO_BENCHMARK 0
/*Render test for each primitives. Requires at least 480x272 display*/
#define LV_USE_DEMO_RENDER 0
/*Stress test for LVGL*/
#define LV_USE_DEMO_STRESS 0
/*Music player demo*/
#define LV_USE_DEMO_MUSIC 0
#if LV_USE_DEMO_MUSIC
#define LV_DEMO_MUSIC_SQUARE 0
#define LV_DEMO_MUSIC_LANDSCAPE 0
#define LV_DEMO_MUSIC_ROUND 0
#define LV_DEMO_MUSIC_LARGE 0
#define LV_DEMO_MUSIC_AUTO_PLAY 0
#endif
/*Flex layout demo*/
#define LV_USE_DEMO_FLEX_LAYOUT 0
/*Smart-phone like multi-language demo*/
#define LV_USE_DEMO_MULTILANG 0
/*Widget transformation demo*/
#define LV_USE_DEMO_TRANSFORM 0
/*Demonstrate scroll settings*/
#define LV_USE_DEMO_SCROLL 0
/*Vector graphic demo*/
#define LV_USE_DEMO_VECTOR_GRAPHIC 0
/*--END OF LV_CONF_H--*/
#endif /*LV_CONF_H*/
#endif /*End of "Content enable"*/

View File

@@ -0,0 +1,60 @@
/**
* @file sdl_kb.c
*
*/
/*********************
* INCLUDES
*********************/
#include "keyboard.h"
#if USE_KEYBOARD
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
// static uint32_t last_key;
// static lv_indev_state_t state;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the keyboard
*/
void keyboard_init(void)
{
/*Nothing to init*/
}
/**
* Get the last pressed or released character from the PC's keyboard
* @param indev_drv pointer to the related input device driver
* @param data store the read data here
* @return false: because the points are not buffered, so no more data to be read
*/
void keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
(void) indev_drv; /*Unused*/
// data->state = state;
// data->key = keycode_to_ascii(last_key);
}
#endif

View File

@@ -0,0 +1,71 @@
/**
* @file keyboard.h
*
*/
#ifndef KEYBOARD_H
#define KEYBOARD_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
// #ifndef LV_DRV_NO_CONF
// #ifdef LV_CONF_INCLUDE_SIMPLE
// #include "lv_drv_conf.h"
// #else
// #include "../../lv_drv_conf.h"
// #endif
// #endif
#if USE_KEYBOARD
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#ifndef MONITOR_SDL_INCLUDE_PATH
#define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
#include MONITOR_SDL_INCLUDE_PATH
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the keyboard
*/
void keyboard_init(void);
/**
* Get the last pressed or released character from the PC's keyboard
* @param indev_drv pointer to the related input device driver
* @param data store the read data here
*/
void keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/**********************
* MACROS
**********************/
#endif /*USE_KEYBOARD*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*KEYBOARD_H*/

View File

@@ -0,0 +1,76 @@
/**
* @file monitor.c
*
*/
/*********************
* INCLUDES
*********************/
#include "monitor.h"
// #if USE_MONITOR
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "mouse.h"
#include "keyboard.h"
#include "mousewheel.h"
#include "maix_lvgl.hpp"
#include "maix_basic.hpp"
#include <stdexcept>
using namespace maix;
static int hres = 552;
static int vres = 368;
/**
* Initialize the monitor
*/
void monitor_init(int w, int h)
{
hres = w;
vres = h;
}
/**
* Flush a buffer to the marked area
* @param drv pointer to driver where this function belongs
* @param area an area where to copy `color_p`
* @param color_p an array of pixel to copy to the `area` part of the screen
*/
void monitor_flush(lv_display_t *disp_drv, const lv_area_t * area, uint8_t *px_map)
{
assert(LV_COLOR_DEPTH == 32);
uint32_t * color_p = (uint32_t *)px_map;
// printf("x1:%d,y1:%d,x2:%d,y2:%d\n", area->x1, area->y1, area->x2, area->y2);
/*Return if the area is out the screen*/
if(area->x2 < 0 || area->y2 < 0 || area->x1 >= hres || area->y1 >= vres) {
lv_disp_flush_ready(disp_drv);
return;
}
int32_t y;
uint32_t w = lv_area_get_width(area);
assert(maix_image->data());
for(y = area->y1; y <= area->y2 && y < vres; y++) {
memcpy(((uint32_t*)maix_image->data()) + y * hres + area->x1, color_p, (area->x2 - area->x1 + 1) * 4);
color_p += w;
}
/* TYPICALLY YOU DO NOT NEED THIS
* If it was the last part to refresh update the texture of the window.*/
if(lv_disp_flush_is_last(disp_drv)) {
maix_display->show(*maix_image);
}
/*IMPORTANT! It must be called to tell the system the flush is ready*/
lv_disp_flush_ready(disp_drv);
}
// #endif /*USE_MONITOR*/

View File

@@ -0,0 +1,47 @@
/**
* @file monitor.h
*
*/
#ifndef MONITOR_H
#define MONITOR_H
#ifdef __cplusplus
extern "C" {
#endif
#include "global_config.h"
/*********************
* INCLUDES
*********************/
// #include "lv_drv_conf.h"
// #if USE_MONITOR
#include "lvgl.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void monitor_init(int w, int h);
void monitor_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * color_p);
/**********************
* MACROS
**********************/
// #endif /* USE_MONITOR */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* MONITOR_H */

View File

@@ -0,0 +1,84 @@
/**
* @file mouse.c
*
*/
/*********************
* INCLUDES
*********************/
#include "mouse.h"
#include "maix_lvgl.hpp"
#include "maix_basic.hpp"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
#if CONFIG_LVGL_USE_MOUSE
/**
* Initialize the mouse
*/
void mouse_init(lv_indev_t * indev_drv)
{
// maix::thread::Thread t = maix::thread::Thread([](void *args){
// lv_indev_t *indev_drv = (lv_indev_t *)args;
// while (!maix::app::need_exit())
// {
// maix::maix_touchscreen->available(-1);
// printf("mouse thread read\n");
// // lv_indev_read(indev_drv);
// }
// }, indev_drv);
// t.detach();
}
/**
* Get the current position and state of the mouse
* @param indev_drv pointer to the related input device driver
* @param data store the mouse data here
*/
void mouse_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
(void) indev_drv; /*Unused*/
static int x, y;
static bool pressed, continue_reading;
if(maix::maix_touchscreen->read0(x, y, pressed) == maix::err::ERR_NOT_READY)
{
data->point.x = (lv_coord_t)x;
data->point.y = (lv_coord_t)y;
data->state = pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
return;
}
continue_reading = maix::maix_touchscreen->available();
data->point.x = (lv_coord_t)x;
data->point.y = (lv_coord_t)y;
data->state = pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
data->continue_reading = continue_reading;
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/
// #endif

View File

@@ -0,0 +1,78 @@
/**
* @file mouse.h
*
*/
#ifndef MOUSE_H
#define MOUSE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "global_config.h"
/*********************
* INCLUDES
*********************/
// #ifndef LV_DRV_NO_CONF
// #ifdef LV_CONF_INCLUDE_SIMPLE
// #include "lv_drv_conf.h"
// #else
// #include "../../lv_drv_conf.h"
// #endif
// #endif
#if CONFIG_LVGL_USE_MOUSE
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#if PLATFORM_LINUX
#ifndef MONITOR_SDL_INCLUDE_PATH
#define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
#endif
#include MONITOR_SDL_INCLUDE_PATH
#endif // PLATFORM_LINUX
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the mouse
*/
void mouse_init(lv_indev_t * indev_drv);
/**
* Get the current position and state of the mouse
* @param indev_drv pointer to the related input device driver
* @param data store the mouse data here
*/
void mouse_read(lv_indev_t * indev, lv_indev_data_t * data);
/**********************
* MACROS
**********************/
#endif /* CONFIG_LVGL_USE_MOUSE */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* MOUSE_H */

View File

@@ -0,0 +1,66 @@
/**
* @file mousewheel.c
*
*/
#if USE_MOUSEWHEEL
/*********************
* INCLUDES
*********************/
#include "mousewheel.h"
#include "lv_indev.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static int16_t enc_diff = 0;
static lv_indev_state_t state = LV_INDEV_STATE_RELEASED;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the mousewheel
*/
void mousewheel_init(void)
{
/*Nothing to init*/
}
/**
* Get encoder (i.e. mouse wheel) ticks difference and pressed state
* @param indev_drv pointer to the related input device driver
* @param data store the read data here
*/
void mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
(void) indev_drv; /*Unused*/
data->state = state;
data->enc_diff = enc_diff;
enc_diff = 0;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@@ -0,0 +1,76 @@
/**
* @file mousewheel.h
*
*/
#ifndef MOUSEWHEEL_H
#define MOUSEWHEEL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "global_config.h"
/*********************
* INCLUDES
*********************/
// #ifndef LV_DRV_NO_CONF
// #ifdef LV_CONF_INCLUDE_SIMPLE
// #include "lv_drv_conf.h"
// #else
// #include "../../lv_drv_conf.h"
// #endif
// #endif
#if USE_MOUSEWHEEL
#if PLATFORM_LINUX
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#ifndef MONITOR_SDL_INCLUDE_PATH
#define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
#endif
#include MONITOR_SDL_INCLUDE_PATH
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the encoder
*/
void mousewheel_init(void);
/**
* Get encoder (i.e. mouse wheel) ticks difference and pressed state
* @param indev_drv pointer to the related input device driver
* @param data store the read data here
*/
void mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/**********************
* MACROS
**********************/
#endif /*PLATFORM_LINUX*/
#endif /*USE_MOUSEWHEEL*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*MOUSEWHEEL_H*/

View File

@@ -0,0 +1,19 @@
#pragma once
#include "maix_display.hpp"
#include "maix_touchscreen.hpp"
namespace maix
{
extern display::Display *maix_display;
extern image::Image *maix_image;
extern touchscreen::TouchScreen *maix_touchscreen;
/**
* @brief init lvgl
* @param display display device, display must init first
*/
void lvgl_init(display::Display *display, touchscreen::TouchScreen *touchscreen);
void lvgl_destroy();
}

View File

@@ -0,0 +1,141 @@
#include "maix_lvgl.hpp"
#include "monitor.h"
#include "mouse.h"
#include "keyboard.h"
#include "lvgl.h"
#include "maix_basic.hpp"
namespace maix
{
display::Display *maix_display = nullptr;
image::Image *maix_image = nullptr;
touchscreen::TouchScreen *maix_touchscreen = nullptr;
static thread::Thread *tick_th = nullptr;
static volatile bool tick_th_exit = false;
static volatile bool tick_th_exit_done = false;
static lv_color_t *buf1_1 = nullptr;
static lv_color_t *buf1_2 = nullptr;
static inline uint32_t get_time_ms()
{
return time::time_ms();
}
void lvgl_init(display::Display *display, touchscreen::TouchScreen *touchscreen)
{
assert(LV_COLOR_DEPTH == 32);
if (!display)
{
throw std::runtime_error("lvgl_init display is null");
}
if (!touchscreen)
{
throw std::runtime_error("lvgl_init touchscreen is null");
}
int buf_size_byte = display->width() * 100 * 4;
if (buf1_1)
{
throw std::runtime_error("lvgl_init already init");
}
buf1_1 = (lv_color_t *)malloc(buf_size_byte);
if (!buf1_1)
{
throw std::runtime_error("lvgl_init malloc failed");
}
buf1_2 = (lv_color_t *)malloc(buf_size_byte);
if (!buf1_2)
{
free(buf1_1);
buf1_1 = nullptr;
throw std::runtime_error("lvgl_init malloc failed");
}
maix_image = new maix::image::Image(display->width(), display->height(), image::FMT_BGRA8888);
maix_display = display;
maix_touchscreen = touchscreen;
#ifdef PLATFORM_LINUX
assert(maix::image::fmt_size[maix_display->format()] == LV_COLOR_DEPTH / 8);
#endif
// LVGL global init
lv_init();
monitor_init(display->width(), display->height());
/* Tick init.
* You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about
* how much time were elapsed Create an SDL thread to do this*/
// tick_th = new thread::Thread(tick_thread, nullptr);
// tick_th->detach();
lv_tick_set_cb(get_time_ms);
/*Create a display buffer*/
/*Create a display*/
lv_display_t *disp_drv = lv_display_create(display->width(), display->height());
lv_display_set_buffers(disp_drv, buf1_1, buf1_2, buf_size_byte, LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_flush_cb(disp_drv, monitor_flush);
// disp_drv->antialiasing = 1;
lv_theme_t *th = lv_theme_default_init(disp_drv, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), LV_THEME_DEFAULT_DARK, LV_FONT_DEFAULT);
lv_disp_set_theme(disp_drv, th);
lv_group_t *g = lv_group_create();
lv_group_set_default(g);
/* Add the mouse as input device
* Use the 'mouse' driver which reads the PC's mouse*/
#if CONFIG_LVGL_USE_MOUSE
lv_indev_t * indev = lv_indev_create();
mouse_init(indev);
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, mouse_read);
// lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT);
#endif
#if USE_KEYBOARD
keyboard_init();
static lv_indev_drv_t indev_drv_2;
lv_indev_drv_init(&indev_drv_2); /*Basic initialization*/
indev_drv_2.type = LV_INDEV_TYPE_KEYPAD;
indev_drv_2.read_cb = keyboard_read;
lv_indev_t *kb_indev = lv_indev_drv_register(&indev_drv_2);
lv_indev_set_group(kb_indev, g);
#endif
}
void lvgl_destroy()
{
if (maix_image)
delete maix_image;
if (tick_th)
{
tick_th_exit_done = true;
tick_th_exit = true;
while (!tick_th_exit_done)
{
thread::sleep_ms(1);
}
delete tick_th;
tick_th = nullptr;
}
maix_image = nullptr;
maix_display = nullptr;
maix_touchscreen = nullptr;
lv_deinit();
if (buf1_1)
{
free(buf1_1);
buf1_1 = nullptr;
}
if (buf1_2)
{
free(buf1_2);
buf1_2 = nullptr;
}
}
}

View File

@@ -0,0 +1,116 @@
set(media_server_version_str "${CONFIG_MEDIA_SERVER_VERSION_MAJOR}.${CONFIG_MEDIA_SERVER_VERSION_MINOR}.${CONFIG_MEDIA_SERVER_VERSION_PATCH}")
set(media_server_filename "media_server-${media_server_version_str}.zip")
set(media_server_unzip_path "${DL_EXTRACTED_PATH}/media_server")
set(src_path "${media_server_unzip_path}/media_server-${media_server_version_str}")
if(${media_server_version_str} VERSION_EQUAL "1.0.0")
set(media_server_url "https://files.catbox.moe/c7rklp.zip")
set(media_server_file_sha256sum "dfe405cedbf3969fbf1f252634e7b1c71e8bb3e2d0857db2fe7e70189474ecd1")
elseif(${media_server_version_str} VERSION_EQUAL "1.0.1")
set(media_server_url "https://files.catbox.moe/acqhv1.zip")
set(media_server_file_sha256sum "ce06dc3d03b6036165956e60afd5eec5bfd37e7746e4b427f2099732478ecc22")
endif()
############### Add include ###################
set(media_server_private_include_dir
"${src_path}/librtsp/source/server"
"${src_path}/sdk/include"
"${src_path}/sdk/libhttp/include"
"${src_path}/librtp/include"
"${src_path}/libmpeg/include"
"${src_path}/libflv/include"
"${src_path}/libmkv/include"
"${src_path}/avcodec/avcodec/include"
"${src_path}/avcodec/avbsf/include"
"${src_path}/libmov/include"
"${src_path}/include"
"${src_path}/media")
# list(APPEND ADD_PRIVATE_INCLUDE ${media_server_private_include_dir})
set(media_server_include_dir "${src_path}"
".")
list(APPEND ADD_INCLUDE ${media_server_include_dir}
${media_server_private_include_dir})
set_property(SOURCE ${media_server_include_dir} PROPERTY GENERATED 1)
set_property(SOURCE ${media_server_private_include_dir} PROPERTY GENERATED 1)
###############################################
############ Add source files #################
list(APPEND ADD_SRCS
)
append_srcs_dir(ADD_SRCS "${src_path}"
"${src_path}/media") # append source file in src dir to var ADD_SRCS
set_property(SOURCE ${ADD_SRCS} PROPERTY GENERATED 1)
# list(REMOVE_ITEM COMPONENT_SRCS "src/test2.c")
# FILE(GLOB_RECURSE EXTRA_SRC "src/*.c")
# FILE(GLOB EXTRA_SRC "src/*.c")
# list(APPEND ADD_SRCS ${EXTRA_SRC})
# aux_source_directory(src ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
# set(ADD_ASM_SRCS "src/asm.S")
# list(APPEND ADD_SRCS ${ADD_ASM_SRCS})
# SET_PROPERTY(SOURCE ${ADD_ASM_SRCS} PROPERTY LANGUAGE C) # set .S ASM file as C language
# SET_SOURCE_FILES_PROPERTIES(${ADD_ASM_SRCS} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp -D BBBBB")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS)
# list(APPEND ADD_FILE_DEPENDS include/axx.h)
# set_property(SOURCE ${python_h_path} PROPERTY GENERATED 1)
# add_custom_command(OUTPUT include/axx.h
# COMMAND echo "" > include/axx.h
# COMMENT "Generating axx.h ..."
# )
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS pthread m) # add system libs, pthread and math lib for example here
# set (media_server_DIR media_server/lib/cmake/media_server4)
# find_package(media_server REQUIRED)
###############################################
############ Add static libs ##################
list(APPEND ADD_STATIC_LIB "${src_path}/libs/librtsp.a"
"${src_path}/libs/libhttp.a"
"${src_path}/libs/libflv.a"
"${src_path}/libs/libmov.a"
"${src_path}/libs/librtp.a"
"${src_path}/libs/libmpeg.a"
"${src_path}/libs/libsdk.a"
"${src_path}/libs/libavcodec.a"
"${src_path}/libs/libavbsf.a")
set_property(SOURCE ${ADD_STATIC_LIB} PROPERTY GENERATED 1)
###############################################
############ Add dynamic libs ##################
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
list(APPEND ADD_DEFINITIONS -D__ERROR__=00*10000000+__LINE__*1000)
###############################################
list(APPEND ADD_FILE_DOWNLOADS "{
'url': '${media_server_url}',
'urls': [],
'sites': [],
'sha256sum': '${media_server_file_sha256sum}',
'filename': '${media_server_filename}',
'path': 'media_server',
'check_files': ['media_server-${media_server_version_str}']
}"
)
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
register_component()

View File

@@ -0,0 +1,20 @@
# media_server version major minor patch
menu "media_server version"
config MEDIA_SERVER_VERSION_MAJOR
int "media_server package major version"
default 1
help
media_server package major version, 0 means auto select according to board
config MEDIA_SERVER_VERSION_MINOR
int "media_server package minor version"
default 0
help
media_server package minor version
config MEDIA_SERVER_VERSION_PATCH
int "media_server package patch version"
default 1
help
media_server package patch version
endmenu

View File

@@ -0,0 +1,14 @@
# readme
对openmv库进行了代码裁剪保证代码量尽量的小以方便在出现问题时可以快速定位到是否是移植带来的问题。
其中主要修改的部分:
1. alloc文件用于内存管理由于openmv的内存管理与板级强相关所以这里的实现与源码有差异
2. common文件用于存放一些通用函数。这里删除掉了大部分用不到的文件只保留了一些方便imlib编译通过的文件。删除大部分文件的优势是可以更快的理解imlib依赖的代码缺点是如果源码库中common文件有更新需要手动同步到这里
3. imlib文件用于存放imlib的核心代码
4. ports文件保存了配置文件、与板级相关的代码、与第三方库相关的代码
# TODO:
1. 未实现文件操作功能。在ports/linux中添加了oofatfs只是为了编译通过实际上并没有实现文件操作功能

166
components/3rd_party/omv/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,166 @@
set(omv_version_str "${CONFIG_OMV_VERSION_MAJOR}.${CONFIG_OMV_VERSION_MINOR}.${CONFIG_OMV_VERSION_PATCH}")
set(omv_filename "omv-${omv_version_str}.zip")
set(omv_unzip_path "${DL_EXTRACTED_PATH}/omv")
set(src_path "${omv_unzip_path}/omv-${omv_version_str}")
if(${omv_version_str} VERSION_EQUAL "1.0.0")
set(omv_url "https://files.catbox.moe/2c84zd.zip")
set(omv_file_sha256sum "4ef0f61febe32886e5d85bb47f661e5d3455f5fe79b3edaacbe833a22566e985")
elseif(${omv_version_str} VERSION_EQUAL "1.0.1")
set(omv_url "https://files.catbox.moe/gcyi07.zip")
set(omv_file_sha256sum "37f5b8ae6072cdef38678effc07cc6dee223bbbbedd79616a506c303d6cd30f1")
elseif(${omv_version_str} VERSION_EQUAL "1.0.2")
set(omv_url "https://files.catbox.moe/20evr3.zip")
set(omv_file_sha256sum "1aee6d293e955a448aa5bdbd3d8f613c2126a4a49d129aeb1a0fbad22f66d773")
elseif(${omv_version_str} VERSION_EQUAL "1.0.3")
set(omv_url "https://files.catbox.moe/idfwis.zip")
set(omv_file_sha256sum "f6654992a52006fd2e01302fa778a6cee1e99e1f9f78a9eea9f759e4f6199d82")
elseif(${omv_version_str} VERSION_EQUAL "1.0.4")
set(omv_url "https://files.catbox.moe/3za319.zip")
set(omv_file_sha256sum "c36c3b8a0ac141be6d7843f129602ffb600a1f596391cd810c1044e20fbbf472")
elseif(${omv_version_str} VERSION_EQUAL "1.0.5")
set(omv_url "https://files.catbox.moe/d36bwl.zip")
set(omv_file_sha256sum "04075965c44f9957efb425880b6a221bda8b049230bff857340306d938d54ec7")
elseif(${omv_version_str} VERSION_EQUAL "1.0.6")
set(omv_url "https://files.catbox.moe/5iyqf2.zip")
set(omv_file_sha256sum "c025d8438ac814229b0c099d18cee77bdd2296ae24173f69a8e46b5ab71700e6")
elseif(${omv_version_str} VERSION_EQUAL "1.0.7")
set(omv_url "https://files.catbox.moe/ik2hdj.zip")
set(omv_file_sha256sum "450d3b97287055679d73c35e6f9d67a192c68b7ac3f8a0f7c6bf7fa3df48b743")
elseif(${omv_version_str} VERSION_EQUAL "1.0.8")
set(omv_url "https://files.catbox.moe/26rfr9.zip")
set(omv_file_sha256sum "a651cd2988ec7b25a80c41466aed55210162bc679c2b8711211525b970bdf417")
elseif(${omv_version_str} VERSION_EQUAL "1.0.9")
set(omv_url "https://files.catbox.moe/ypel5x.zip")
set(omv_file_sha256sum "770680d55f501a095e846bb8727d9fe0ad6a446be8fbc1671b61da0788977475")
elseif(${omv_version_str} VERSION_EQUAL "1.0.10")
set(omv_url "https://files.catbox.moe/olys7p.zip")
set(omv_file_sha256sum "e3b6d04a5379be52b226434ef0dfce404faf91955dfab0386a189684b99940bd")
endif()
############### Add include ###################
set(omv_include_dir "."
"${src_path}/alloc"
"${src_path}"
"${src_path}/imlib"
"${src_path}/common"
"${src_path}/ports/linux"
"${src_path}/ports/linux/cmsis"
"${src_path}/ports/linux/oofatfs"
"${src_path}/ports/linux/py")
list(APPEND ADD_INCLUDE ${omv_include_dir})
set_property(SOURCE ${omv_include_dir} PROPERTY GENERATED 1)
# list(APPEND ADD_PRIVATE_INCLUDE "")
###############################################
############ Add source files #################
list(APPEND ADD_SRCS # DO NOT ADD "${src_path}/alloc/framebuffer.c" of omv, it is not supported.
"${src_path}/alloc/fb_alloc.c"
"${src_path}/alloc/umm_malloc.c"
"${src_path}/alloc/unaligned_memcpy.c"
"${src_path}/alloc/xalloc.c"
"${src_path}/ports/linux/py/mpprint.c"
"${src_path}/ports/linux/py/obj.c"
"${src_path}/ports/linux/py/runtime.c"
"${src_path}/imlib/imlib.c"
"${src_path}/imlib/hough.c"
"${src_path}/imlib/lsd.c"
"${src_path}/imlib/fmath.c"
"${src_path}/imlib/xyz_tab.c"
"${src_path}/imlib/mathop.c"
"${src_path}/imlib/filter.c"
"${src_path}/imlib/clahe.c"
"${src_path}/imlib/isp.c"
"${src_path}/imlib/draw.c"
"${src_path}/imlib/font.c"
"${src_path}/imlib/yuv.c"
"${src_path}/imlib/bayer.c"
"${src_path}/imlib/blob.c"
"${src_path}/imlib/collections.c"
"${src_path}/imlib/lab_tab.c"
"${src_path}/imlib/sincos_tab.c"
"${src_path}/imlib/binary.c"
"${src_path}/imlib/phasecorrelation.c"
"${src_path}/imlib/fft.c"
"${src_path}/imlib/apriltag.c"
"${src_path}/imlib/rectangle.c"
"${src_path}/imlib/line.c"
"${src_path}/imlib/stats.c"
"${src_path}/imlib/qrcode.c"
"${src_path}/imlib/dmtx.c"
"${src_path}/imlib/zbar.c"
"${src_path}/imlib/template.c"
"${src_path}/imlib/integral.c"
"${src_path}/imlib/eye.c"
"${src_path}/imlib/lbp.c"
"${src_path}/imlib/edge.c"
"${src_path}/imlib/hog.c"
"${src_path}/imlib/pool.c"
"${src_path}/imlib/lab_tab.c"
"${src_path}/imlib/yuv_tab.c"
"${src_path}/common/array.c"
)
set_property(SOURCE ${ADD_SRCS} PROPERTY GENERATED 1)
set_property(SOURCE "${src_path}/alloc" PROPERTY GENERATED 1)
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test2.c")
# FILE(GLOB_RECURSE EXTRA_SRC "src/*.c")
# FILE(GLOB EXTRA_SRC "src/*.c")
# list(APPEND ADD_SRCS ${EXTRA_SRC})
# aux_source_directory(src ADD_SRCS) # collect all source file in src dir, will set var ADD_SRCS
# append_srcs_dir(ADD_SRCS "src") # append source file in src dir to var ADD_SRCS
# list(REMOVE_ITEM COMPONENT_SRCS "src/test.c")
# set(ADD_ASM_SRCS "src/asm.S")
# list(APPEND ADD_SRCS ${ADD_ASM_SRCS})
# SET_PROPERTY(SOURCE ${ADD_ASM_SRCS} PROPERTY LANGUAGE C) # set .S ASM file as C language
# SET_SOURCE_FILES_PROPERTIES(${ADD_ASM_SRCS} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp -D BBBBB")
###############################################
###### Add required/dependent components ######
# list(APPEND ADD_REQUIREMENTS)
# list(APPEND ADD_FILE_DEPENDS include/axx.h)
# set_property(SOURCE ${python_h_path} PROPERTY GENERATED 1)
# add_custom_command(OUTPUT include/axx.h
# COMMAND echo "" > include/axx.h
# COMMENT "Generating axx.h ..."
# )
###############################################
###### Add link search path for requirements/libs ######
# list(APPEND ADD_LINK_SEARCH_PATH "${CONFIG_TOOLCHAIN_PATH}/lib")
# list(APPEND ADD_REQUIREMENTS pthread m) # add system libs, pthread and math lib for example here
# set (omv_DIR omv/lib/cmake/omv4)
# find_package(omv REQUIRED)
###############################################
############ Add static libs ##################
###############################################
############ Add dynamic libs ##################
###############################################
#### Add compile option for this component ####
#### Just for this component, won't affect other
#### modules, including component that depend
#### on this component
# list(APPEND ADD_DEFINITIONS_PRIVATE -DAAAAA=1)
#### Add compile option for this component
#### and components denpend on this component
# list(APPEND ADD_DEFINITIONS -DAAAAA222=1
# -DAAAAA333=1)
###############################################
list(APPEND ADD_FILE_DOWNLOADS "{
'url': '${omv_url}',
'urls': [],
'sites': [],
'sha256sum': '${omv_file_sha256sum}',
'filename': '${omv_filename}',
'path': 'omv',
'check_files': ['omv-${omv_version_str}']
}"
)
# register component, DYNAMIC or SHARED flags will make component compiled to dynamic(shared) lib
register_component()

Some files were not shown because too many files have changed in this diff Show More