[website] refactor website and docs (#263)
|
@ -20,6 +20,9 @@ concurrency:
|
||||||
group: "pages"
|
group: "pages"
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
websiteDir: "${{github.workspace}}/website"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# Single deploy job since we're just deploying
|
# Single deploy job since we're just deploying
|
||||||
deploy:
|
deploy:
|
||||||
|
@ -28,26 +31,26 @@ jobs:
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Install
|
|
||||||
run: sudo apt-get install doxygen graphviz
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Setup Pages
|
- name: Setup Pages
|
||||||
uses: actions/configure-pages@v3
|
uses: actions/configure-pages@v3
|
||||||
- name: Clone doxygen-awesome-css
|
- name: Install package
|
||||||
run: git clone https://github.com/jothepro/doxygen-awesome-css.git
|
run: sudo apt-get install doxygen graphviz
|
||||||
working-directory: ${{github.workspace}}
|
|
||||||
- name: Yarn Install
|
- name: Yarn Install
|
||||||
run: yarn install
|
run: yarn install
|
||||||
working-directory: ${{github.workspace}}
|
working-directory: ${{env.websiteDir}}
|
||||||
|
- name: Clone doxygen-awesome-css
|
||||||
|
run: git clone https://github.com/jothepro/doxygen-awesome-css.git
|
||||||
|
working-directory: ${{env.websiteDir}}
|
||||||
- name: Build Website
|
- name: Build Website
|
||||||
run: bash gen_doc.sh ${{github.workspace}}
|
run: bash generate.sh
|
||||||
working-directory: ${{github.workspace}}
|
working-directory: ${{env.websiteDir}}
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v1
|
uses: actions/upload-pages-artifact@v1
|
||||||
with:
|
with:
|
||||||
# Upload entire repository
|
# Upload entire repository
|
||||||
path: 'docs'
|
path: 'website/dist'
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
id: deployment
|
id: deployment
|
||||||
uses: actions/deploy-pages@v1
|
uses: actions/deploy-pages@v1
|
||||||
|
|
|
@ -323,14 +323,6 @@ see [Build Website](https://alibaba.github.io/yalantinglibs/README.html)
|
||||||
4. Choose one or more reviewers from contributors: (e.g., qicosmos, poor-circle, PikachuHyA).
|
4. Choose one or more reviewers from contributors: (e.g., qicosmos, poor-circle, PikachuHyA).
|
||||||
5. Get approved and merged.
|
5. Get approved and merged.
|
||||||
|
|
||||||
# Discussion group
|
|
||||||
|
|
||||||
DingTalk group
|
|
||||||
|
|
||||||
<center>
|
|
||||||
<img src="./src/coro_rpc/doc/images/yalantinglibs_ding_talk_group.png" alt="dingtalk" width="200" height="200" align="bottom" />
|
|
||||||
</center>
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
yaLanTingLibs is distributed under the Apache License (Version 2.0)
|
yaLanTingLibs is distributed under the Apache License (Version 2.0)
|
||||||
|
|
47
gen_doc.sh
|
@ -1,47 +0,0 @@
|
||||||
set -e
|
|
||||||
ROOT_DIR=$(pwd)
|
|
||||||
rm -rf docs
|
|
||||||
mkdir docs
|
|
||||||
|
|
||||||
cd website
|
|
||||||
rm -rf guide
|
|
||||||
mkdir guide
|
|
||||||
cd guide
|
|
||||||
cp ../how-to-use-as-git-submodule.md how-to-use-as-git-submodule.md
|
|
||||||
cp ../how-to-use-by-cmake-find_package.md how-to-use-by-cmake-find_package.md
|
|
||||||
cp ../../README.md what-is-yalantinglibs.md
|
|
||||||
cp ../../src/struct_pack/doc/Introduction_EN.md struct-pack-intro.md
|
|
||||||
cp ../../src/struct_pack/doc/struct_pack_layout_EN.md struct-pack-layout.md
|
|
||||||
cp ../../src/struct_pack/doc/struct_pack_type_system_EN.md struct-pack-type-system.md
|
|
||||||
cp ../../src/struct_pb/doc/*.md .
|
|
||||||
cp ../../src/coro_rpc/doc/coro_rpc_introduction_en.md coro-rpc-intro.md
|
|
||||||
|
|
||||||
mkdir -p src/coro_rpc/doc/images
|
|
||||||
cp ../../src/coro_rpc/doc/images/yalantinglibs_ding_talk_group.png src/coro_rpc/doc/images
|
|
||||||
|
|
||||||
rm -rf images
|
|
||||||
mkdir images
|
|
||||||
cd images
|
|
||||||
cp -r ../../../src/struct_pack/doc/images/* .
|
|
||||||
cp -r ../../../src/struct_pb/doc/images/* .
|
|
||||||
cp -r ../../../src/coro_rpc/doc/images/* .
|
|
||||||
cd ../..
|
|
||||||
|
|
||||||
rm -rf zh
|
|
||||||
mkdir zh
|
|
||||||
cd zh
|
|
||||||
mkdir guide
|
|
||||||
cd guide
|
|
||||||
cp ../../../README.md what-is-yalantinglibs.md
|
|
||||||
cp ../../../src/struct_pack/doc/Introduction_CN.md struct-pack-intro.md
|
|
||||||
cp ../../../src/struct_pack/doc/struct_pack_type_system_CN.md struct-pack-type-system.md
|
|
||||||
cp ../../../src/struct_pack/doc/struct_pack_layout_CN.md struct-pack-layout.md
|
|
||||||
cp ../../../src/coro_rpc/doc/coro_rpc_introduction_cn.md coro-rpc-intro.md
|
|
||||||
cp -r ../../guide/images .
|
|
||||||
cp -r ../../guide/src .
|
|
||||||
|
|
||||||
cd "$ROOT_DIR" || exit 1
|
|
||||||
yarn docs:build
|
|
||||||
doxygen Doxyfile
|
|
||||||
doxygen Doxyfile_cn
|
|
||||||
echo 'Generate Done!'
|
|
|
@ -1,4 +1,4 @@
|
||||||
guide
|
node_modules
|
||||||
images
|
dist
|
||||||
zh
|
cache
|
||||||
dist
|
doxygen-awesome-css
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
export default {
|
|
||||||
lang: 'en-US',
|
|
||||||
title: 'yalantinglibs',
|
|
||||||
description: 'A collection of C++20 libraries, include async_simple, coro_rpc and struct_pack.',
|
|
||||||
base: '/yalantinglibs/',
|
|
||||||
lastUpdated: true,
|
|
||||||
ignoreDeadLinks: false,
|
|
||||||
outDir: "../docs",
|
|
||||||
locales: {
|
|
||||||
"/": {
|
|
||||||
lang: 'en-US',
|
|
||||||
title: 'yalantinglibs',
|
|
||||||
description: 'A collection of C++20 libraries, include async_simple, coro_rpc and struct_pack.',
|
|
||||||
},
|
|
||||||
"/zh/": {
|
|
||||||
lang: 'zh-CN',
|
|
||||||
title: '雅兰亭库',
|
|
||||||
description: 'C++20程序库,包含async_simple, coro_rpc and struct_pack.',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
head: [],
|
|
||||||
|
|
||||||
themeConfig: {
|
|
||||||
nav: nav(),
|
|
||||||
|
|
||||||
sidebar: {
|
|
||||||
"/guide/": sidebarGuide(),
|
|
||||||
'/zh/guide/': sidebarGuideZh(),
|
|
||||||
},
|
|
||||||
|
|
||||||
socialLinks: [
|
|
||||||
{icon: 'github', link: 'https://github.com/alibaba/yalantinglibs'}
|
|
||||||
],
|
|
||||||
|
|
||||||
footer: {
|
|
||||||
message: 'This website is released under the MIT License.',
|
|
||||||
copyright: 'Copyright © 2022 yalantinglibs contributors'
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function nav() {
|
|
||||||
return [
|
|
||||||
{text: 'Guide', link: '/guide/what-is-yalantinglibs', activeMatch: '/guide/'},
|
|
||||||
{
|
|
||||||
text: "Language",
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
text: "English", link: "/guide/what-is-yalantinglibs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "简体中文", link: '/zh/guide/what-is-yalantinglibs'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Github Issues',
|
|
||||||
link: 'https://github.com/alibaba/yalantinglibs/issues'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
function sidebarGuide() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
text: 'how to use?',
|
|
||||||
collapsible: true,
|
|
||||||
items: [
|
|
||||||
{text: 'Use as Git Submodule', link: '/guide/how-to-use-as-git-submodule'},
|
|
||||||
{text: 'Use by CMake find_package', link: '/guide/how-to-use-by-cmake-find_package'}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'struct_pack',
|
|
||||||
collapsible: true,
|
|
||||||
items: [
|
|
||||||
{text: 'What is struct_pack?', link: '/guide/struct-pack-intro'},
|
|
||||||
{text: 'struct_pack layout', link: '/guide/struct-pack-layout'},
|
|
||||||
{text: 'struct_pack type system', link: '/guide/struct-pack-type-system'},
|
|
||||||
{
|
|
||||||
text: 'API Reference',
|
|
||||||
link: "https://alibaba.github.io/yalantinglibs/en/html/group__struct__pack.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'struct_pb',
|
|
||||||
collapsible: true,
|
|
||||||
items: [
|
|
||||||
{text: 'What is struct_pb?', link: '/guide/struct-pb-intro'},
|
|
||||||
{text: 'Quick Start', link: '/guide/struct-pb-quick-start'},
|
|
||||||
{text: 'Supported Features', link: '/guide/struct-pb-supported-features'},
|
|
||||||
{text: 'Guide (proto3)', link: '/guide/struct-pb-guide-proto3'},
|
|
||||||
{text: 'Generating your struct', link: '/guide/struct-pb-generating-your-struct'},
|
|
||||||
{text: 'struct_pb API', link: '/guide/struct-pb-api'},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'coro_rpc',
|
|
||||||
collapsible: true,
|
|
||||||
items: [
|
|
||||||
{text: 'What is coro_rpc?', link: '/guide/coro-rpc-intro'},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
function sidebarGuideZh() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
text: 'struct_pack',
|
|
||||||
collapsible: true,
|
|
||||||
items: [
|
|
||||||
{text: 'struct_pack简介', link: '/zh/guide/struct-pack-intro'},
|
|
||||||
{text: 'struct_pack类型系统', link: '/zh/guide/struct-pack-type-system'},
|
|
||||||
{text: 'struct_pack布局', link: '/zh/guide/struct-pack-layout'},
|
|
||||||
{
|
|
||||||
text: 'API Reference',
|
|
||||||
link: "https://alibaba.github.io/yalantinglibs/cn/html/group__struct__pack.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'coro_rpc',
|
|
||||||
collapsible: true,
|
|
||||||
items: [
|
|
||||||
{text: 'coro_rpc简介', link: '/zh/guide/coro-rpc-intro'},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
export const guidLinks = [
|
||||||
|
{text: 'Introduce YalantingLibs', link: '/guide/what_is_yalantinglibs'},
|
||||||
|
{text: 'Use as Git Submodule', link: '/guide/how_to_use_as_git_submodule'},
|
||||||
|
{text: 'Use by CMake find_package', link: '/guide/how_to_use_by_cmake_find_package'},
|
||||||
|
];
|
||||||
|
|
||||||
|
//构建系统相关语法
|
||||||
|
export const struct_pb_Links = [
|
||||||
|
{text: 'What is struct_pb?', link: '/struct_pb/struct_pb_intro'},
|
||||||
|
{text: 'Quick Start', link: '/struct_pb/struct_pb_quick_start'},
|
||||||
|
{text: 'Supported Features', link: '/struct_pb/struct_pb_supported_features'},
|
||||||
|
{text: 'Guide (proto3)', link: '/struct_pb/struct_pb_guide_proto3'},
|
||||||
|
{text: 'Generating your struct', link: '/struct_pb/struct_pb_generating_your_struct'},
|
||||||
|
{text: 'struct_pb API', link: '/struct_pb/struct_pb_api'},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const struct_pack_Links = [
|
||||||
|
{text: 'What is struct_pack?', link: '/struct_pack/struct_pack_intro'},
|
||||||
|
{text: 'struct_pack layout', link: '/struct_pack/struct_pack_layout'},
|
||||||
|
{text: 'struct_pack type system', link: '/struct_pack/struct_pack_type_system'},
|
||||||
|
{text: 'API Reference', link: "https://alibaba.github.io/yalantinglibs/doxygen_en/html/group__struct__pack.html"}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const coro_rpc_Links = [
|
||||||
|
{text: 'What is coro_rpc?', link: '/coro_rpc/coro_rpc_introduction'},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const aboutLinks = [
|
||||||
|
{text: 'purecpp', link: '/about/community'},
|
||||||
|
{text: 'contribute', link: '/about/contribute'},
|
||||||
|
{text: 'community', link: '/about/teams'},
|
||||||
|
{text: 'team', link: '/about/yalantingUser'},
|
||||||
|
];
|
|
@ -0,0 +1,30 @@
|
||||||
|
import {LocaleSpecificConfig, DefaultTheme} from 'vitepress';
|
||||||
|
import * as data from './en_data'
|
||||||
|
|
||||||
|
export const en_themeConfig = <DefaultTheme.Config>
|
||||||
|
{
|
||||||
|
nav: [
|
||||||
|
{text: 'Guide', link: data.guidLinks[0].link},
|
||||||
|
{text: 'Issues', link: 'https://github.com/alibaba/yalantinglibs/issues'}
|
||||||
|
],
|
||||||
|
sidebar: [
|
||||||
|
{text: 'guide', items: data.guidLinks,},
|
||||||
|
{text: 'struct_pack', items: data.struct_pack_Links,},
|
||||||
|
{text: 'struct_pb', items: data.struct_pb_Links,},
|
||||||
|
{text: 'coro_rpc', items: data.coro_rpc_Links},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export const en_LocaleConfig = <LocaleSpecificConfig>{
|
||||||
|
label: 'english',
|
||||||
|
|
||||||
|
lang: 'en-US',
|
||||||
|
title: 'yalantinglibs',
|
||||||
|
description: 'A collection of C++20 libraries, include async_simple, coro_rpc and struct_pack.',
|
||||||
|
|
||||||
|
// titleTemplate?: string | boolean
|
||||||
|
// head?: HeadConfig[]
|
||||||
|
themeConfig:en_themeConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
import {defineConfig} from "vitepress";
|
||||||
|
|
||||||
|
import {en_LocaleConfig} from "./en_locale";
|
||||||
|
import {zh_LocaleConfig} from "./zh_locale";
|
||||||
|
|
||||||
|
export default defineConfig(
|
||||||
|
{
|
||||||
|
//Resource
|
||||||
|
srcDir: "docs",
|
||||||
|
outDir: "dist",
|
||||||
|
//Website
|
||||||
|
base: '/yalantinglibs/',
|
||||||
|
//Article
|
||||||
|
lastUpdated: true,
|
||||||
|
ignoreDeadLinks: false,
|
||||||
|
|
||||||
|
head: [],
|
||||||
|
//Common theme config
|
||||||
|
themeConfig: {
|
||||||
|
logo: '/icon/logo.svg',
|
||||||
|
socialLinks: [
|
||||||
|
{icon: 'github', link: 'https://github.com/alibaba/yalantinglibs'}
|
||||||
|
],
|
||||||
|
footer: {
|
||||||
|
message: 'This website is released under the MIT License.',
|
||||||
|
copyright: 'Copyright © 2022 yalantinglibs contributors'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
//Locales config and theme-specify
|
||||||
|
locales: {
|
||||||
|
'root': <any>en_LocaleConfig,
|
||||||
|
'zh': <any>zh_LocaleConfig,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
|
@ -0,0 +1,33 @@
|
||||||
|
export const guidLinks = [
|
||||||
|
{text: 'Introduce YalantingLibs', link: '/zh/guide/what_is_yalantinglibs'},
|
||||||
|
{text: 'Use as Git Submodule', link: '/zh/guide/how_to_use_as_git_submodule'},
|
||||||
|
{text: 'Use by CMake find_package', link: '/zh/guide/how_to_use_by_cmake_find_package'},
|
||||||
|
];
|
||||||
|
|
||||||
|
//构建系统相关语法
|
||||||
|
export const struct_pb_Links = [
|
||||||
|
{text: 'What is struct_pb?', link: '/zh/struct_pb/struct_pb_intro'},
|
||||||
|
{text: 'Quick Start', link: '/zh/struct_pb/struct_pb_quick_start'},
|
||||||
|
{text: 'Supported Features', link: '/zh/struct_pb/struct_pb_supported_features'},
|
||||||
|
{text: 'Guide (proto3)', link: '/zh/struct_pb/struct_pb_guide_proto3'},
|
||||||
|
{text: 'Generating your struct', link: '/zh/struct_pb/struct_pb_generating_your_struct'},
|
||||||
|
{text: 'struct_pb API', link: '/zh/struct_pb/struct_pb_api'},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const struct_pack_Links = [
|
||||||
|
{text: 'What is struct_pack?', link: '/zh/struct_pack/struct_pack_intro'},
|
||||||
|
{text: 'struct_pack layout', link: '/zh/struct_pack/struct_pack_layout'},
|
||||||
|
{text: 'struct_pack type system', link: '/zh/struct_pack/struct_pack_type_system'},
|
||||||
|
{text: 'API Reference', link: "https://alibaba.github.io/yalantinglibs/doxygen_cn/html/group__struct__pack.html"}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const coro_rpc_Links = [
|
||||||
|
{text: 'What is coro_rpc?', link: '/zh/coro_rpc/coro_rpc_introduction'},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const aboutLinks = [
|
||||||
|
{text: 'purecpp', link: '/zh/about/community'}, //TODO 未来支持英语
|
||||||
|
{text: 'contribute', link: '/zh/about/contribute'},
|
||||||
|
{text: 'community', link: '/zh/about/teams'},
|
||||||
|
{text: 'team', link: '/zh/about/yalantingUser'},
|
||||||
|
];
|
|
@ -0,0 +1,28 @@
|
||||||
|
import {LocaleSpecificConfig, DefaultTheme} from 'vitepress'
|
||||||
|
import * as data from './zh_data'
|
||||||
|
|
||||||
|
export const zh_themeConfig = <DefaultTheme.Config>
|
||||||
|
{
|
||||||
|
nav: [
|
||||||
|
{text: '指南', link: data.guidLinks[0].link},
|
||||||
|
{text: 'Issues', link: 'https://github.com/alibaba/yalantinglibs/issues'}
|
||||||
|
],
|
||||||
|
sidebar: [
|
||||||
|
{text: '指南', items: data.guidLinks,},
|
||||||
|
{text: 'struct_pack', items: data.struct_pack_Links,},
|
||||||
|
{text: 'struct_pb', items: data.struct_pb_Links,},
|
||||||
|
{text: 'coro_rpc', items: data.coro_rpc_Links},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export const zh_LocaleConfig = <LocaleSpecificConfig>{
|
||||||
|
label: '简体中文',
|
||||||
|
|
||||||
|
lang: 'zh-CN',
|
||||||
|
title: '雅兰亭库',
|
||||||
|
description: '中文简介待补充',
|
||||||
|
|
||||||
|
// titleTemplate?: string | boolean
|
||||||
|
// head?: HeadConfig[]
|
||||||
|
themeConfig:zh_themeConfig
|
||||||
|
};
|
|
@ -1,9 +1,11 @@
|
||||||
PROJECT_NAME=yaLanTingLibs
|
PROJECT_NAME=yaLanTingLibs
|
||||||
GENERATE_HTML=yes
|
GENERATE_HTML=yes
|
||||||
GENERATE_LATEX=no
|
GENERATE_LATEX=no
|
||||||
INPUT=include/struct_pack include/coro_rpc include/coro_rpc/coro_rpc \
|
INPUT=../include/struct_pack \
|
||||||
include/struct_pack/struct_pack/struct_pack_impl.hpp \
|
../include/coro_rpc \
|
||||||
src/coro_rpc/doc/coro_rpc_introduction_EN.md
|
../include/coro_rpc/coro_rpc \
|
||||||
|
../include/struct_pack/struct_pack/struct_pack_impl.hpp \
|
||||||
|
docs/coro_rpc/coro_rpc_introduction.md
|
||||||
|
|
||||||
GENERATE_TREEVIEW = YES # required!
|
GENERATE_TREEVIEW = YES # required!
|
||||||
DISABLE_INDEX = NO
|
DISABLE_INDEX = NO
|
||||||
|
@ -19,8 +21,8 @@ HTML_EXTRA_FILES = doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js
|
||||||
doxygen-awesome-css/doxygen-awesome-paragraph-link.js \
|
doxygen-awesome-css/doxygen-awesome-paragraph-link.js \
|
||||||
doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js \
|
doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js \
|
||||||
doxygen-awesome-css/doxygen-awesome-interactive-toc.js
|
doxygen-awesome-css/doxygen-awesome-interactive-toc.js
|
||||||
HTML_HEADER = header.html
|
HTML_HEADER = doxy/header.html
|
||||||
IMAGE_PATH = src/coro_rpc/doc/images src/struct_pack/doc/images
|
IMAGE_PATH = docs/coro_rpc/images docs/struct_pack/images
|
||||||
EXAMPLE_PATH = src/coro_rpc/examples
|
EXAMPLE_PATH = ../src/coro_rpc/examples
|
||||||
EXAMPLE_RECURSIVE = YES
|
EXAMPLE_RECURSIVE = YES
|
||||||
OUTPUT_DIRECTORY = docs/en
|
OUTPUT_DIRECTORY = dist/doxygen_en
|
|
@ -1,10 +1,10 @@
|
||||||
PROJECT_NAME=yaLanTingLibs
|
PROJECT_NAME=yaLanTingLibs
|
||||||
GENERATE_HTML=yes
|
GENERATE_HTML=yes
|
||||||
GENERATE_LATEX=no
|
GENERATE_LATEX=no
|
||||||
INPUT=src/coro_rpc/doc/coro_rpc_doc.hpp \
|
INPUT=docs/zh/coro_rpc/coro_rpc_doc.hpp \
|
||||||
src/coro_rpc/doc/coro_rpc_introduction_cn.md \
|
docs/zh/coro_rpc/coro_rpc_intro.md \
|
||||||
src/struct_pack/doc/struct_pack_doc.hpp \
|
docs/zh/struct_pack/struct_pack_doc.hpp \
|
||||||
src/struct_pack/doc/Introduction_CN.md
|
docs/zh/struct_pack/struct_pack_intro.md
|
||||||
|
|
||||||
GENERATE_TREEVIEW = YES # required!
|
GENERATE_TREEVIEW = YES # required!
|
||||||
DISABLE_INDEX = NO
|
DISABLE_INDEX = NO
|
||||||
|
@ -20,9 +20,9 @@ HTML_EXTRA_FILES = doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js
|
||||||
doxygen-awesome-css/doxygen-awesome-paragraph-link.js \
|
doxygen-awesome-css/doxygen-awesome-paragraph-link.js \
|
||||||
doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js \
|
doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js \
|
||||||
doxygen-awesome-css/doxygen-awesome-interactive-toc.js
|
doxygen-awesome-css/doxygen-awesome-interactive-toc.js
|
||||||
HTML_HEADER = header.html
|
HTML_HEADER = doxy/header.html
|
||||||
IMAGE_PATH = src/coro_rpc/doc/images src/struct_pack/doc/images
|
IMAGE_PATH = docs/coro_rpc/images docs/struct_pack/images
|
||||||
EXAMPLE_PATH = src/coro_rpc/examples
|
EXAMPLE_PATH = ../src/coro_rpc/examples
|
||||||
EXAMPLE_RECURSIVE = YES
|
EXAMPLE_RECURSIVE = YES
|
||||||
OUTPUT_LANGUAGE = Chinese
|
OUTPUT_LANGUAGE = Chinese
|
||||||
OUTPUT_DIRECTORY = docs/cn
|
OUTPUT_DIRECTORY = dist/doxygen_cn
|
|
@ -66,6 +66,6 @@ finished...
|
||||||
Done!
|
Done!
|
||||||
```
|
```
|
||||||
|
|
||||||
the config of vitepress is `website/.vitepress/config.ts`
|
the config of vitepress is `website/.vitepress/config/index.ts`
|
||||||
|
|
||||||
the config of doxygen is `Doxyfile` and `Doxyfile_cn`
|
the config of doxygen is `Doxyfile` and `Doxyfile_cn`
|
||||||
|
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
|
@ -0,0 +1,330 @@
|
||||||
|
<p align="center">
|
||||||
|
<h1 align="center">yaLanTingLibs</h1>
|
||||||
|
<h6 align="center">A Collection of C++20 libraries, include struct_pack, struct_json, struct_pb, easylog, coro_rpc, coro_http and async_simple </h6>
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<img alt="license" src="https://img.shields.io/github/license/alibaba/async_simple?style=flat-square">
|
||||||
|
<img alt="language" src="https://img.shields.io/github/languages/top/alibaba/yalantinglibs?style=flat-square">
|
||||||
|
<img alt="last commit" src="https://img.shields.io/github/last-commit/alibaba/async_simple?style=flat-square">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
yaLanTingLibs is a collection of C++20 libraries, now it contains struct_pack, struct_json, struct_pb, easylog, coro_rpc, coro_http and [async_simple](https://github.com/alibaba/async_simple), more and more cool libraries will be added into yaLanTingLibs(such as http.) in the future.
|
||||||
|
|
||||||
|
The target of yaLanTingLibs: provide very easy and high performance C++20 libraries for C++ developers, it can help to quickly build high performance applications.
|
||||||
|
|
||||||
|
| OS (Compiler Version) | Status |
|
||||||
|
|------------------------------------------------|----------------------------------------------------------------------------------------------------------|
|
||||||
|
| Ubuntu 22.04 (clang 14.0.0) |  |
|
||||||
|
| Ubuntu 22.04 (gcc 11.2.0) |  |
|
||||||
|
| macOS Monterey 12 (AppleClang 14.0.0.14000029) |  |
|
||||||
|
| Windows Server 2022 (MSVC 19.33.31630.0) |  |
|
||||||
|
|
||||||
|
## coro_rpc
|
||||||
|
|
||||||
|
Very easy-to-use, coroutine-based, high performance rpc framework with C++20, more than 2000w qps in echo scene. coro_rpc is a header only library.
|
||||||
|
|
||||||
|
You can finish a rpc server and rpc client in 5 minutes!
|
||||||
|
|
||||||
|
[English Introduction](https://alibaba.github.io/yalantinglibs/guide/coro-rpc-intro.html) | [中文简介](https://alibaba.github.io/yalantinglibs/zh/guide/coro-rpc-intro.html)
|
||||||
|
|
||||||
|
English API(TODO) | [中文API](https://alibaba.github.io/yalantinglibs/cn/html/group__coro__rpc.html)
|
||||||
|
|
||||||
|
[Talk](https://alibaba.github.io/yalantinglibs/coro_rpc_introduction_purecpp_talk.pdf) of coro_rpc on purecpp conference.
|
||||||
|
|
||||||
|
[Video](https://live.csdn.net/room/csdnlive1/bKFbKP7T) on purecpp conference, start from 04:55:08 of the video record.
|
||||||
|
|
||||||
|
### quick example
|
||||||
|
|
||||||
|
1.define a rpc function as a local normal function.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// rpc_service.hpp
|
||||||
|
inline std::string_view echo(std::string_view str) { return str; }
|
||||||
|
```
|
||||||
|
|
||||||
|
2.register rpc function and start a server
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "rpc_service.hpp"
|
||||||
|
#include <coro_rpc/coro_rpc_server.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
coro_rpc_server server(/*thread_num =*/10, /*port =*/9000);
|
||||||
|
server.register_handler<echo>(); // register function echo
|
||||||
|
server.start(); // start the server & block
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3.rpc client call rpc service
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "rpc_service.hpp"
|
||||||
|
#include <coro_rpc/coro_rpc_client.hpp>
|
||||||
|
|
||||||
|
Lazy<void> test_client() {
|
||||||
|
coro_rpc_client client;
|
||||||
|
co_await client.connect("localhost", /*port =*/"9000"); // connect to the server
|
||||||
|
|
||||||
|
auto r = co_await client.call<echo>("hello coro_rpc"); // call remote function echo
|
||||||
|
std::cout << r.result.value() << "\n"; //will print "hello coro_rpc"
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
syncAwait(test_client());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
More examples [here](https://github.com/alibaba/yalantinglibs/tree/main/src/coro_rpc/examples).
|
||||||
|
|
||||||
|
## struct_pack
|
||||||
|
|
||||||
|
Based on compile-time reflection, very easy to use, high performance serialization library, struct_pack is a header only library, it is used by coro_rpc now.
|
||||||
|
|
||||||
|
Only one line code to finish serialization and deserialization, 10-50x faster than protobuf.
|
||||||
|
|
||||||
|
[English Introduction](https://alibaba.github.io/yalantinglibs/guide/struct-pack-intro.html) | [中文简介](https://alibaba.github.io/yalantinglibs/zh/guide/struct-pack-intro.html)
|
||||||
|
|
||||||
|
English API(TODO) | [中文API](https://alibaba.github.io/yalantinglibs/cn/html/group__struct__pack.html)
|
||||||
|
|
||||||
|
[(Slides) A Faster Serialization Library Based on Compile-time Reflection and C++ 20](https://alibaba.github.io/yalantinglibs/A%20Faster%20Serialization%20Library%20Based%20on%20Compile-time%20Reflection%20and%20C++%2020.pdf) of struct_pack on CppCon2022
|
||||||
|
|
||||||
|
[Slides](https://alibaba.github.io/yalantinglibs/struct_pack_introduce_CN.pdf) of struct_pack on purecpp conference.
|
||||||
|
|
||||||
|
[(Video) A Faster Serialization Library Based on Compile-time Reflection and C++ 20](https://www.youtube.com/watch?v=myhB8ZlwOlE) on cppcon2022
|
||||||
|
|
||||||
|
[Video](https://live.csdn.net/room/csdnlive1/bKFbKP7T) on purecpp conference, start from 01:32:20 of the video record.
|
||||||
|
|
||||||
|
### quick example
|
||||||
|
```cpp
|
||||||
|
struct person {
|
||||||
|
int64_t id;
|
||||||
|
std::string name;
|
||||||
|
int age;
|
||||||
|
double salary;
|
||||||
|
};
|
||||||
|
|
||||||
|
person person1{.id = 1, .name = "hello struct pack", .age = 20, .salary = 1024.42};
|
||||||
|
|
||||||
|
// one line code serialize
|
||||||
|
std::vector<char> buffer = struct_pack::serialize(person1);
|
||||||
|
|
||||||
|
// one line code deserialization
|
||||||
|
auto person2 = deserialize<person>(buffer);
|
||||||
|
```
|
||||||
|
See more examples [here](https://github.com/alibaba/yalantinglibs/tree/main/src/struct_pack/examples).
|
||||||
|
|
||||||
|
## struct_json
|
||||||
|
reflection-based json lib, very easy to do struct to json and json to struct.
|
||||||
|
|
||||||
|
### quick example
|
||||||
|
```cpp
|
||||||
|
#include "struct_json/json_reader.h"
|
||||||
|
#include "struct_json/json_writer.h"
|
||||||
|
|
||||||
|
struct person {
|
||||||
|
std::string name;
|
||||||
|
int age;
|
||||||
|
};
|
||||||
|
REFLECTION(person, name, age);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
person p{.name = "tom", .age = 20};
|
||||||
|
std::string str;
|
||||||
|
struct_json::to_json(p, str); // {"name":"tom","age":20}
|
||||||
|
|
||||||
|
person p1;
|
||||||
|
struct_json::from_json(p1, str);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## coro_http_client
|
||||||
|
|
||||||
|
coro_http_client is a C++20 coroutine http(https) client, include: get/post, websocket, multipart file upload, chunked and ranges download etc.
|
||||||
|
|
||||||
|
### get/post
|
||||||
|
```cpp
|
||||||
|
#include "coro_http/coro_http_client.h"
|
||||||
|
using namespace ylt;
|
||||||
|
|
||||||
|
async_simple::coro::Lazy<void> get_post(coro_http_client &client) {
|
||||||
|
std::string uri = "http://www.example.com";
|
||||||
|
auto result = co_await client.async_get(uri);
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
|
||||||
|
result = co_await client.async_post(uri, "hello", req_content_type::string);
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
coro_http_client client{};
|
||||||
|
async_simple::coro::syncAwait(get_post(client));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### websocket
|
||||||
|
```cpp
|
||||||
|
async_simple::coro::Lazy<void> websocket(coro_http_client &client) {
|
||||||
|
client.on_ws_close([](std::string_view reason) {
|
||||||
|
std::cout << "web socket close " << reason << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on_ws_msg([](resp_data data) {
|
||||||
|
std::cout << data.resp_body << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
// connect to your websocket server.
|
||||||
|
bool r = co_await client.async_connect("ws://example.com/ws");
|
||||||
|
if (!r) {
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
co_await client.async_send_ws("hello websocket");
|
||||||
|
co_await client.async_send_ws("test again", /*need_mask = */ false);
|
||||||
|
co_await client.async_send_ws_close("ws close reason");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### upload/download
|
||||||
|
```cpp
|
||||||
|
async_simple::coro::Lazy<void> upload_files(coro_http_client &client) {
|
||||||
|
std::string uri = "http://example.com";
|
||||||
|
|
||||||
|
client.add_str_part("hello", "world");
|
||||||
|
client.add_str_part("key", "value");
|
||||||
|
client.add_file_part("test", "test.jpg");
|
||||||
|
auto result = co_await client.async_upload(uri);
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
|
||||||
|
result = co_await client.async_upload(uri, "test", "test.jpg");
|
||||||
|
}
|
||||||
|
|
||||||
|
async_simple::coro::Lazy<void> download_files(coro_http_client &client) {
|
||||||
|
// chunked download
|
||||||
|
auto result = co_await client.async_download("http://example.com/test.jpg",
|
||||||
|
"myfile.jpg");
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
|
||||||
|
// ranges download
|
||||||
|
result = co_await client.async_download("http://example.com/test.txt",
|
||||||
|
"myfile.txt", "1-10,11-16");
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## async_simple
|
||||||
|
|
||||||
|
A C++ 20 coroutine library offering simple, light-weight and easy-to-use components to write asynchronous codes.
|
||||||
|
See [async_simple](https://github.com/alibaba/async_simple)
|
||||||
|
|
||||||
|
## compiler requirements
|
||||||
|
|
||||||
|
make sure you have such compilers:
|
||||||
|
- clang11 and libstdc++-8 above;
|
||||||
|
- or gcc10 and g++10 above;
|
||||||
|
- or msvc2019 above
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
- clone repo
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/alibaba/yalantinglibs.git
|
||||||
|
```
|
||||||
|
|
||||||
|
- build & install
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd yalantinglibs
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
# You can use those option to skip build unit-test & benchmark & example:
|
||||||
|
# cmake .. -DBUILD_EXAMPLES=OFF -DBUILD_BENCHMARK=OFF -DBUILD_UNIT_TESTS=OFF
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
- run tests
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ctest .
|
||||||
|
```
|
||||||
|
|
||||||
|
- start your coding
|
||||||
|
|
||||||
|
### coro_rpc
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd yalantinglibs/src/coro_rpc/examples/helloworld
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
make
|
||||||
|
# For more detail, see Cmakelist.txt in helloworld.
|
||||||
|
```
|
||||||
|
|
||||||
|
### struct_pack
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## Benchmark
|
||||||
|
|
||||||
|
options:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./benchmark_client [threads] [client_pre_thread] [pipeline_size] [host] [port] [test_data_path] [test_time] [warm_up_time]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build Options
|
||||||
|
|
||||||
|
| option | description | default |
|
||||||
|
| ----------------- | ------------------------------------------------ | ------- |
|
||||||
|
| CMAKE_BUILD_TYPE | build type | Release |
|
||||||
|
| BUILD_WITH_LIBCXX | Build with libc++ | OFF |
|
||||||
|
| BUILD_EXAMPLES | Build examples | ON |
|
||||||
|
| BUILD_BENCHMARK | Build benchmark | ON |
|
||||||
|
| BUILD_UNIT_TESTS | Build unit test | ON |
|
||||||
|
| USE_CONAN | Use conan package manager to handle dependencies | OFF |
|
||||||
|
| ENABLE_SSL | Enable ssl support | OFF |
|
||||||
|
| ENABLE_IO_URING | Enable io_uring support | OFF |
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
We use doctest for unit test.
|
||||||
|
All third-party dependencies are put in include/thirdparty.
|
||||||
|
|
||||||
|
### coro_rpc
|
||||||
|
|
||||||
|
- [struct_pack](https://github.com/alibaba/yalantinglibs)
|
||||||
|
- [easylog](https://github.com/alibaba/yalantinglibs)
|
||||||
|
- [asio](https://github.com/chriskohlhoff/asio)
|
||||||
|
- openssl (optional)
|
||||||
|
### struct_pack
|
||||||
|
|
||||||
|
No dependency.
|
||||||
|
|
||||||
|
### struct_json
|
||||||
|
|
||||||
|
- [iguana](https://github.com/qicosmos/iguana)
|
||||||
|
|
||||||
|
### struct_pb
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
### easylog
|
||||||
|
|
||||||
|
No dependency.
|
||||||
|
|
||||||
|
# How to generate document
|
||||||
|
|
||||||
|
see [Build Website](https://alibaba.github.io/yalantinglibs/README.html)
|
||||||
|
|
||||||
|
# How to Contribute
|
||||||
|
1. Create an issue in the issue template.
|
||||||
|
2. Run tests and `git-clang-format HEAD^` locally for the change.
|
||||||
|
3. Create a PR, fill in the PR template.
|
||||||
|
4. Choose one or more reviewers from contributors: (e.g., qicosmos, poor-circle, PikachuHyA).
|
||||||
|
5. Get approved and merged.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
yaLanTingLibs is distributed under the Apache License (Version 2.0)
|
||||||
|
This product contains various third-party components under other open-source licenses.
|
||||||
|
See the NOTICE file for more information.
|
|
@ -10,7 +10,7 @@ hero:
|
||||||
actions:
|
actions:
|
||||||
- theme: brand
|
- theme: brand
|
||||||
text: Get Started
|
text: Get Started
|
||||||
link: /guide/what-is-yalantinglibs
|
link: /guide/what_is_yalantinglibs
|
||||||
- theme: alt
|
- theme: alt
|
||||||
text: View on GitHub
|
text: View on GitHub
|
||||||
link: https://github.com/alibaba/yalantinglibs.git
|
link: https://github.com/alibaba/yalantinglibs.git
|
||||||
|
@ -22,4 +22,4 @@ features:
|
||||||
details: Very easy-to-use, coroutine-based, high performance rpc framework with C++20, more than 2000w qps in echo scene.
|
details: Very easy-to-use, coroutine-based, high performance rpc framework with C++20, more than 2000w qps in echo scene.
|
||||||
- title: struct_json
|
- title: struct_json
|
||||||
details: Reflection-based json lib, very easy to do struct to json and json to struct.
|
details: Reflection-based json lib, very easy to do struct to json and json to struct.
|
||||||
---
|
---
|
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
@ -1,13 +1,13 @@
|
||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="bgBt0THlO4EiIMCifpc1" name="第 1 页">
|
<diagram id="bgBt0THlO4EiIMCifpc1" name="第 1 页">
|
||||||
<mxGraphModel dx="530" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
<mxGraphModel dx="530" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="2" value="DATA_LEN" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="2" value="DATA_LEN" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
<mxGeometry x="200" y="440" width="120" height="60" as="geometry"/>
|
<mxGeometry x="200" y="440" width="120" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
</mxfile>
|
</mxfile>
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
@ -1,34 +1,34 @@
|
||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="Pdm-2sLAR-h-lwVb3lNh" name="第 1 页">
|
<diagram id="Pdm-2sLAR-h-lwVb3lNh" name="第 1 页">
|
||||||
<mxGraphModel dx="383" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
<mxGraphModel dx="383" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" vertex="1" parent="1">
|
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" vertex="1" parent="1">
|
||||||
<mxGeometry x="40" y="440" width="280" height="60" as="geometry"/>
|
<mxGeometry x="40" y="440" width="280" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="3" value="" style="endArrow=none;html=1;entryX=0.75;entryY=0;entryDx=0;entryDy=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="2" target="2">
|
<mxCell id="3" value="" style="endArrow=none;html=1;entryX=0.75;entryY=0;entryDx=0;entryDy=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="2" target="2">
|
||||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
<mxPoint x="180" y="490" as="sourcePoint"/>
|
<mxPoint x="180" y="490" as="sourcePoint"/>
|
||||||
<mxPoint x="180" y="370" as="targetPoint"/>
|
<mxPoint x="180" y="370" as="targetPoint"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="5" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="4" target="2">
|
<mxCell id="5" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="4" target="2">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="4" value="31 bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="4" value="31 bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||||
<mxGeometry x="120" y="410" width="60" height="30" as="geometry"/>
|
<mxGeometry x="120" y="410" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="6" value="类型哈希" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="6" value="类型哈希" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||||
<mxGeometry x="110" y="455" width="80" height="30" as="geometry"/>
|
<mxGeometry x="110" y="455" width="80" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="7" value="1 bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="7" value="1 bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||||
<mxGeometry x="250" y="410" width="70" height="30" as="geometry"/>
|
<mxGeometry x="250" y="410" width="70" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="8" value="选项:是否存在元信息" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="8" value="选项:是否存在元信息" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||||
<mxGeometry x="252.5" y="455" width="65" height="30" as="geometry"/>
|
<mxGeometry x="252.5" y="455" width="65" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
</mxfile>
|
</mxfile>
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
@ -1,22 +1,22 @@
|
||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="oe2Vl5H5gF7YLMPssPNC" name="第 1 页">
|
<diagram id="oe2Vl5H5gF7YLMPssPNC" name="第 1 页">
|
||||||
<mxGraphModel dx="936" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="none" math="0" shadow="0">
|
<mxGraphModel dx="936" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="none" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="30" value="类型哈希" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="30" value="类型哈希" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="11" y="160" width="319" height="60" as="geometry"/>
|
<mxGeometry x="11" y="160" width="319" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="31" value="4 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="31" value="4 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="141" y="130" width="60" height="30" as="geometry"/>
|
<mxGeometry x="141" y="130" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="37" value="负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="37" value="负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="330" y="160" width="401" height="60" as="geometry"/>
|
<mxGeometry x="330" y="160" width="401" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="38" value="可变长度" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="38" value="可变长度" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="485.5" y="130" width="90" height="30" as="geometry"/>
|
<mxGeometry x="485.5" y="130" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
</mxfile>
|
</mxfile>
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
@ -1,46 +1,46 @@
|
||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="oe2Vl5H5gF7YLMPssPNC" name="第 1 页">
|
<diagram id="oe2Vl5H5gF7YLMPssPNC" name="第 1 页">
|
||||||
<mxGraphModel dx="1335" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="none" math="0" shadow="0">
|
<mxGraphModel dx="1335" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="none" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="2" value="类型哈希" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="2" value="类型哈希" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="11" y="400" width="320" height="60" as="geometry"/>
|
<mxGeometry x="11" y="400" width="320" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="3" value="4 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="3" value="4 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="141" y="370" width="60" height="30" as="geometry"/>
|
<mxGeometry x="141" y="370" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="5" value="1 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="5" value="1 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="341" y="370" width="60" height="30" as="geometry"/>
|
<mxGeometry x="341" y="370" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="6" value="元信息头<br>(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="6" value="元信息头<br>(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="331" y="400" width="80" height="60" as="geometry"/>
|
<mxGeometry x="331" y="400" width="80" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="7" value="完整类型信息<br>(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="7" value="完整类型信息<br>(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="491" y="400" width="80" height="60" as="geometry"/>
|
<mxGeometry x="491" y="400" width="80" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="9" value="数据总长度<br>(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="9" value="数据总长度<br>(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="411" y="400" width="80" height="60" as="geometry"/>
|
<mxGeometry x="411" y="400" width="80" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="10" value="DATA_SIZE" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="10" value="DATA_SIZE" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="421" y="370" width="60" height="30" as="geometry"/>
|
<mxGeometry x="421" y="370" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="11" value="已知字段负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="11" value="已知字段负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="571" y="400" width="160" height="60" as="geometry"/>
|
<mxGeometry x="571" y="400" width="160" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="12" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="12" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="606" y="370" width="90" height="30" as="geometry"/>
|
<mxGeometry x="606" y="370" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="13" value="未知字段负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="13" value="未知字段负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="731" y="400" width="80" height="60" as="geometry"/>
|
<mxGeometry x="731" y="400" width="80" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="16" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="16" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="486" y="370" width="90" height="30" as="geometry"/>
|
<mxGeometry x="486" y="370" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="17" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="17" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="726" y="370" width="90" height="30" as="geometry"/>
|
<mxGeometry x="726" y="370" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
</mxfile>
|
</mxfile>
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
@ -1,46 +1,46 @@
|
||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="_e0WKF2P-E546wreTLZB" name="第 1 页">
|
<diagram id="_e0WKF2P-E546wreTLZB" name="第 1 页">
|
||||||
<mxGraphModel dx="1453" dy="873" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
<mxGraphModel dx="1453" dy="873" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="2" value="保留给后续扩展,目前应全为0" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="2" value="保留给后续扩展,目前应全为0" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="80" y="450" width="240" height="60" as="geometry"/>
|
<mxGeometry x="80" y="450" width="240" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="3" value="是否存储完整类型信息" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="3" value="是否存储完整类型信息" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="480" y="450" width="80" height="60" as="geometry"/>
|
<mxGeometry x="480" y="450" width="80" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="4" value="DATA_SIZE<br>(0B,2B,4B,8B)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="4" value="DATA_SIZE<br>(0B,2B,4B,8B)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="560" y="450" width="160" height="60" as="geometry"/>
|
<mxGeometry x="560" y="450" width="160" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="5" value="LEN_SIZE<br>(1B,2B,4B,8B)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
<mxCell id="5" value="LEN_SIZE<br>(1B,2B,4B,8B)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
|
||||||
<mxGeometry x="320" y="450" width="160" height="60" as="geometry"/>
|
<mxGeometry x="320" y="450" width="160" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="6" value="2bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="6" value="2bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="370" y="420" width="60" height="30" as="geometry"/>
|
<mxGeometry x="370" y="420" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="7" value="1bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="7" value="1bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="490" y="420" width="60" height="30" as="geometry"/>
|
<mxGeometry x="490" y="420" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="8" value="2bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="8" value="2bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="610" y="420" width="60" height="30" as="geometry"/>
|
<mxGeometry x="610" y="420" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="9" value="3bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="9" value="3bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="170" y="420" width="60" height="30" as="geometry"/>
|
<mxGeometry x="170" y="420" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="10" value="" style="endArrow=classic;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;" parent="1" source="11" target="12" edge="1">
|
<mxCell id="10" value="" style="endArrow=classic;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;" parent="1" source="11" target="12" edge="1">
|
||||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
<mxPoint x="650" y="540" as="sourcePoint"/>
|
<mxPoint x="650" y="540" as="sourcePoint"/>
|
||||||
<mxPoint x="130" y="540" as="targetPoint"/>
|
<mxPoint x="130" y="540" as="targetPoint"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="11" value="低位" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="11" value="低位" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="660" y="510" width="60" height="30" as="geometry"/>
|
<mxGeometry x="660" y="510" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="12" value="高位" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
<mxCell id="12" value="高位" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="80" y="510" width="60" height="30" as="geometry"/>
|
<mxGeometry x="80" y="510" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
</mxfile>
|
</mxfile>
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 197 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
@ -251,4 +251,4 @@ class coro_rpc_client {
|
||||||
*/
|
*/
|
||||||
auto &get_executor();
|
auto &get_executor();
|
||||||
};
|
};
|
||||||
} // namespace coro_rpc
|
} // namespace coro_rpc
|
|
@ -0,0 +1,62 @@
|
||||||
|
# Use as Git Submodule
|
||||||
|
|
||||||
|
Thanks to [@piperoc](https://github.com/piperoc), and the demo code is [here](https://github.com/PikachuHyA/yalantinglibs_as_submodule_demo).
|
||||||
|
|
||||||
|
|
||||||
|
**Step 1**: create your project directory mkdir `~/code/awesome-solution` and cd `~/code/awesome-solution`.
|
||||||
|
|
||||||
|
**Step 2**: make it a git repo by calling `git init` (this will initialize and empty git repo)
|
||||||
|
|
||||||
|
**Step 3**: add the library as a ***true submodule*** with `git submodule add https://github.com/alibaba/yalantinglibs.git` .
|
||||||
|
At this point you should have a file system structure like:
|
||||||
|
|
||||||
|
```
|
||||||
|
awesome-solution
|
||||||
|
├── .git
|
||||||
|
├── .gitmodules
|
||||||
|
└── yalantinglibs
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
**Step 4**: there are often more than one project using the library in the solution. In our demo, there would be a client app and a server app that both use the library. Those apps would be separate projects, so the file system will start looking like:
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
awesome-solution
|
||||||
|
├── CMakeLists.txt
|
||||||
|
├── client
|
||||||
|
│ ├── CMakeLists.txt
|
||||||
|
│ ├── client.cpp
|
||||||
|
│ ├── service.h
|
||||||
|
├─── server
|
||||||
|
│ ├── CMakeLists.txt
|
||||||
|
│ ├── server.cpp
|
||||||
|
│ ├── service.h
|
||||||
|
└─── yalantinglibs
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 5**: here's the root CMakeLists.txt (it's very important to set the compiler flags if you are running g++)
|
||||||
|
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
|
||||||
|
project(awesome-solution LANGUAGES CXX)
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
# it's very important to set the compiler flags
|
||||||
|
# if you use gcc/g++
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines")
|
||||||
|
if (CMAKE_CXX_COMPILER_VERSION MATCHES "12.*")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
add_subdirectory(client)
|
||||||
|
add_subdirectory(server)
|
||||||
|
add_subdirectory(yalantinglibs)
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,63 @@
|
||||||
|
# Use by CMake find_package
|
||||||
|
|
||||||
|
To use CMake find_package, CMake and yaLanTingLibs must be installed first.
|
||||||
|
|
||||||
|
And you have to use CMake to manage your project.
|
||||||
|
|
||||||
|
## Install yaLanTingLibs
|
||||||
|
|
||||||
|
Currently, only build from sources supported.
|
||||||
|
Install from package manager (e.g. conan and vcpkg) is WIP.
|
||||||
|
|
||||||
|
use the following instructions
|
||||||
|
|
||||||
|
- clone yaLanTingLibs
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/alibaba/yalantinglibs.git
|
||||||
|
cd yalantinglibs
|
||||||
|
```
|
||||||
|
|
||||||
|
- build yaLanTingLibs
|
||||||
|
```shell
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
make -j
|
||||||
|
```
|
||||||
|
- install yaLanTingLibs
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# sudo if needed
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use yaLanTingLibs
|
||||||
|
write `CMakeLists.txt` and use find_package
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
|
||||||
|
project(awesome-solution LANGUAGES CXX)
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
# it's very important to set the compiler flags
|
||||||
|
# if you use gcc/g++
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines")
|
||||||
|
if (CMAKE_CXX_COMPILER_VERSION MATCHES "12.*")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
find_package(yalantinglibs REQUIRED)
|
||||||
|
# add your server
|
||||||
|
target_link_libraries(your_server PRIVATE yalantinglibs::coro_rpc)
|
||||||
|
```
|
||||||
|
|
||||||
|
the full demo is here: https://github.com/PikachuHyA/yalantinglibs_find_package_demo
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- [CMake find_package Document](https://cmake.org/cmake/help/latest/command/find_package.html?highlight=find_package)
|
||||||
|
- [use yaLanTingLibs with CMake find_package demo code](https://github.com/PikachuHyA/yalantinglibs_find_package_demo)
|
||||||
|
- [use yaLanTingLibs as Git Submodule demo code](https://github.com/PikachuHyA/yalantinglibs_as_submodule_demo)
|
|
@ -0,0 +1,330 @@
|
||||||
|
<p align="center">
|
||||||
|
<h1 align="center">yaLanTingLibs</h1>
|
||||||
|
<h6 align="center">A Collection of C++20 libraries, include struct_pack, struct_json, struct_pb, easylog, coro_rpc, coro_http and async_simple </h6>
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<img alt="license" src="https://img.shields.io/github/license/alibaba/async_simple?style=flat-square">
|
||||||
|
<img alt="language" src="https://img.shields.io/github/languages/top/alibaba/yalantinglibs?style=flat-square">
|
||||||
|
<img alt="last commit" src="https://img.shields.io/github/last-commit/alibaba/async_simple?style=flat-square">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
yaLanTingLibs is a collection of C++20 libraries, now it contains struct_pack, struct_json, struct_pb, easylog, coro_rpc, coro_http and [async_simple](https://github.com/alibaba/async_simple), more and more cool libraries will be added into yaLanTingLibs(such as http.) in the future.
|
||||||
|
|
||||||
|
The target of yaLanTingLibs: provide very easy and high performance C++20 libraries for C++ developers, it can help to quickly build high performance applications.
|
||||||
|
|
||||||
|
| OS (Compiler Version) | Status |
|
||||||
|
|------------------------------------------------|----------------------------------------------------------------------------------------------------------|
|
||||||
|
| Ubuntu 22.04 (clang 14.0.0) |  |
|
||||||
|
| Ubuntu 22.04 (gcc 11.2.0) |  |
|
||||||
|
| macOS Monterey 12 (AppleClang 14.0.0.14000029) |  |
|
||||||
|
| Windows Server 2022 (MSVC 19.33.31630.0) |  |
|
||||||
|
|
||||||
|
## coro_rpc
|
||||||
|
|
||||||
|
Very easy-to-use, coroutine-based, high performance rpc framework with C++20, more than 2000w qps in echo scene. coro_rpc is a header only library.
|
||||||
|
|
||||||
|
You can finish a rpc server and rpc client in 5 minutes!
|
||||||
|
|
||||||
|
[English Introduction](https://alibaba.github.io/yalantinglibs/guide/coro-rpc-intro.html) | [中文简介](https://alibaba.github.io/yalantinglibs/zh/guide/coro-rpc-intro.html)
|
||||||
|
|
||||||
|
English API(TODO) | [中文API](https://alibaba.github.io/yalantinglibs/cn/html/group__coro__rpc.html)
|
||||||
|
|
||||||
|
[Talk](https://alibaba.github.io/yalantinglibs/coro_rpc_introduction_purecpp_talk.pdf) of coro_rpc on purecpp conference.
|
||||||
|
|
||||||
|
[Video](https://live.csdn.net/room/csdnlive1/bKFbKP7T) on purecpp conference, start from 04:55:08 of the video record.
|
||||||
|
|
||||||
|
### quick example
|
||||||
|
|
||||||
|
1.define a rpc function as a local normal function.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// rpc_service.hpp
|
||||||
|
inline std::string_view echo(std::string_view str) { return str; }
|
||||||
|
```
|
||||||
|
|
||||||
|
2.register rpc function and start a server
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "rpc_service.hpp"
|
||||||
|
#include <coro_rpc/coro_rpc_server.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
coro_rpc_server server(/*thread_num =*/10, /*port =*/9000);
|
||||||
|
server.register_handler<echo>(); // register function echo
|
||||||
|
server.start(); // start the server & block
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3.rpc client call rpc service
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "rpc_service.hpp"
|
||||||
|
#include <coro_rpc/coro_rpc_client.hpp>
|
||||||
|
|
||||||
|
Lazy<void> test_client() {
|
||||||
|
coro_rpc_client client;
|
||||||
|
co_await client.connect("localhost", /*port =*/"9000"); // connect to the server
|
||||||
|
|
||||||
|
auto r = co_await client.call<echo>("hello coro_rpc"); // call remote function echo
|
||||||
|
std::cout << r.result.value() << "\n"; //will print "hello coro_rpc"
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
syncAwait(test_client());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
More examples [here](https://github.com/alibaba/yalantinglibs/tree/main/src/coro_rpc/examples).
|
||||||
|
|
||||||
|
## struct_pack
|
||||||
|
|
||||||
|
Based on compile-time reflection, very easy to use, high performance serialization library, struct_pack is a header only library, it is used by coro_rpc now.
|
||||||
|
|
||||||
|
Only one line code to finish serialization and deserialization, 10-50x faster than protobuf.
|
||||||
|
|
||||||
|
[English Introduction](https://alibaba.github.io/yalantinglibs/guide/struct-pack-intro.html) | [中文简介](https://alibaba.github.io/yalantinglibs/zh/guide/struct-pack-intro.html)
|
||||||
|
|
||||||
|
English API(TODO) | [中文API](https://alibaba.github.io/yalantinglibs/cn/html/group__struct__pack.html)
|
||||||
|
|
||||||
|
[(Slides) A Faster Serialization Library Based on Compile-time Reflection and C++ 20](https://alibaba.github.io/yalantinglibs/A%20Faster%20Serialization%20Library%20Based%20on%20Compile-time%20Reflection%20and%20C++%2020.pdf) of struct_pack on CppCon2022
|
||||||
|
|
||||||
|
[Slides](https://alibaba.github.io/yalantinglibs/struct_pack_introduce_CN.pdf) of struct_pack on purecpp conference.
|
||||||
|
|
||||||
|
[(Video) A Faster Serialization Library Based on Compile-time Reflection and C++ 20](https://www.youtube.com/watch?v=myhB8ZlwOlE) on cppcon2022
|
||||||
|
|
||||||
|
[Video](https://live.csdn.net/room/csdnlive1/bKFbKP7T) on purecpp conference, start from 01:32:20 of the video record.
|
||||||
|
|
||||||
|
### quick example
|
||||||
|
```cpp
|
||||||
|
struct person {
|
||||||
|
int64_t id;
|
||||||
|
std::string name;
|
||||||
|
int age;
|
||||||
|
double salary;
|
||||||
|
};
|
||||||
|
|
||||||
|
person person1{.id = 1, .name = "hello struct pack", .age = 20, .salary = 1024.42};
|
||||||
|
|
||||||
|
// one line code serialize
|
||||||
|
std::vector<char> buffer = struct_pack::serialize(person1);
|
||||||
|
|
||||||
|
// one line code deserialization
|
||||||
|
auto person2 = deserialize<person>(buffer);
|
||||||
|
```
|
||||||
|
See more examples [here](https://github.com/alibaba/yalantinglibs/tree/main/src/struct_pack/examples).
|
||||||
|
|
||||||
|
## struct_json
|
||||||
|
reflection-based json lib, very easy to do struct to json and json to struct.
|
||||||
|
|
||||||
|
### quick example
|
||||||
|
```cpp
|
||||||
|
#include "struct_json/json_reader.h"
|
||||||
|
#include "struct_json/json_writer.h"
|
||||||
|
|
||||||
|
struct person {
|
||||||
|
std::string name;
|
||||||
|
int age;
|
||||||
|
};
|
||||||
|
REFLECTION(person, name, age);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
person p{.name = "tom", .age = 20};
|
||||||
|
std::string str;
|
||||||
|
struct_json::to_json(p, str); // {"name":"tom","age":20}
|
||||||
|
|
||||||
|
person p1;
|
||||||
|
struct_json::from_json(p1, str);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## coro_http_client
|
||||||
|
|
||||||
|
coro_http_client is a C++20 coroutine http(https) client, include: get/post, websocket, multipart file upload, chunked and ranges download etc.
|
||||||
|
|
||||||
|
### get/post
|
||||||
|
```cpp
|
||||||
|
#include "coro_http/coro_http_client.h"
|
||||||
|
using namespace ylt;
|
||||||
|
|
||||||
|
async_simple::coro::Lazy<void> get_post(coro_http_client &client) {
|
||||||
|
std::string uri = "http://www.example.com";
|
||||||
|
auto result = co_await client.async_get(uri);
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
|
||||||
|
result = co_await client.async_post(uri, "hello", req_content_type::string);
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
coro_http_client client{};
|
||||||
|
async_simple::coro::syncAwait(get_post(client));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### websocket
|
||||||
|
```cpp
|
||||||
|
async_simple::coro::Lazy<void> websocket(coro_http_client &client) {
|
||||||
|
client.on_ws_close([](std::string_view reason) {
|
||||||
|
std::cout << "web socket close " << reason << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on_ws_msg([](resp_data data) {
|
||||||
|
std::cout << data.resp_body << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
// connect to your websocket server.
|
||||||
|
bool r = co_await client.async_connect("ws://example.com/ws");
|
||||||
|
if (!r) {
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
co_await client.async_send_ws("hello websocket");
|
||||||
|
co_await client.async_send_ws("test again", /*need_mask = */ false);
|
||||||
|
co_await client.async_send_ws_close("ws close reason");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### upload/download
|
||||||
|
```cpp
|
||||||
|
async_simple::coro::Lazy<void> upload_files(coro_http_client &client) {
|
||||||
|
std::string uri = "http://example.com";
|
||||||
|
|
||||||
|
client.add_str_part("hello", "world");
|
||||||
|
client.add_str_part("key", "value");
|
||||||
|
client.add_file_part("test", "test.jpg");
|
||||||
|
auto result = co_await client.async_upload(uri);
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
|
||||||
|
result = co_await client.async_upload(uri, "test", "test.jpg");
|
||||||
|
}
|
||||||
|
|
||||||
|
async_simple::coro::Lazy<void> download_files(coro_http_client &client) {
|
||||||
|
// chunked download
|
||||||
|
auto result = co_await client.async_download("http://example.com/test.jpg",
|
||||||
|
"myfile.jpg");
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
|
||||||
|
// ranges download
|
||||||
|
result = co_await client.async_download("http://example.com/test.txt",
|
||||||
|
"myfile.txt", "1-10,11-16");
|
||||||
|
std::cout << result.status << "\n";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## async_simple
|
||||||
|
|
||||||
|
A C++ 20 coroutine library offering simple, light-weight and easy-to-use components to write asynchronous codes.
|
||||||
|
See [async_simple](https://github.com/alibaba/async_simple)
|
||||||
|
|
||||||
|
## compiler requirements
|
||||||
|
|
||||||
|
make sure you have such compilers:
|
||||||
|
- clang11 and libstdc++-8 above;
|
||||||
|
- or gcc10 and g++10 above;
|
||||||
|
- or msvc2019 above
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
- clone repo
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/alibaba/yalantinglibs.git
|
||||||
|
```
|
||||||
|
|
||||||
|
- build & install
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd yalantinglibs
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
# You can use those option to skip build unit-test & benchmark & example:
|
||||||
|
# cmake .. -DBUILD_EXAMPLES=OFF -DBUILD_BENCHMARK=OFF -DBUILD_UNIT_TESTS=OFF
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
- run tests
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ctest .
|
||||||
|
```
|
||||||
|
|
||||||
|
- start your coding
|
||||||
|
|
||||||
|
### coro_rpc
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd yalantinglibs/src/coro_rpc/examples/helloworld
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
make
|
||||||
|
# For more detail, see Cmakelist.txt in helloworld.
|
||||||
|
```
|
||||||
|
|
||||||
|
### struct_pack
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## Benchmark
|
||||||
|
|
||||||
|
options:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./benchmark_client [threads] [client_pre_thread] [pipeline_size] [host] [port] [test_data_path] [test_time] [warm_up_time]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build Options
|
||||||
|
|
||||||
|
| option | description | default |
|
||||||
|
| ----------------- | ------------------------------------------------ | ------- |
|
||||||
|
| CMAKE_BUILD_TYPE | build type | Release |
|
||||||
|
| BUILD_WITH_LIBCXX | Build with libc++ | OFF |
|
||||||
|
| BUILD_EXAMPLES | Build examples | ON |
|
||||||
|
| BUILD_BENCHMARK | Build benchmark | ON |
|
||||||
|
| BUILD_UNIT_TESTS | Build unit test | ON |
|
||||||
|
| USE_CONAN | Use conan package manager to handle dependencies | OFF |
|
||||||
|
| ENABLE_SSL | Enable ssl support | OFF |
|
||||||
|
| ENABLE_IO_URING | Enable io_uring support | OFF |
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
We use doctest for unit test.
|
||||||
|
All third-party dependencies are put in include/thirdparty.
|
||||||
|
|
||||||
|
### coro_rpc
|
||||||
|
|
||||||
|
- [struct_pack](https://github.com/alibaba/yalantinglibs)
|
||||||
|
- [easylog](https://github.com/alibaba/yalantinglibs)
|
||||||
|
- [asio](https://github.com/chriskohlhoff/asio)
|
||||||
|
- openssl (optional)
|
||||||
|
### struct_pack
|
||||||
|
|
||||||
|
No dependency.
|
||||||
|
|
||||||
|
### struct_json
|
||||||
|
|
||||||
|
- [iguana](https://github.com/qicosmos/iguana)
|
||||||
|
|
||||||
|
### struct_pb
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
### easylog
|
||||||
|
|
||||||
|
No dependency.
|
||||||
|
|
||||||
|
# How to generate document
|
||||||
|
|
||||||
|
see [Build Website](https://alibaba.github.io/yalantinglibs/README.html)
|
||||||
|
|
||||||
|
# How to Contribute
|
||||||
|
1. Create an issue in the issue template.
|
||||||
|
2. Run tests and `git-clang-format HEAD^` locally for the change.
|
||||||
|
3. Create a PR, fill in the PR template.
|
||||||
|
4. Choose one or more reviewers from contributors: (e.g., qicosmos, poor-circle, PikachuHyA).
|
||||||
|
5. Get approved and merged.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
yaLanTingLibs is distributed under the Apache License (Version 2.0)
|
||||||
|
This product contains various third-party components under other open-source licenses.
|
||||||
|
See the NOTICE file for more information.
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
layout: home
|
||||||
|
|
||||||
|
title: 雅兰亭库
|
||||||
|
titleTemplate: A collection of C++20 libraries, include async_simple, coro_rpc and struct_pack.
|
||||||
|
|
||||||
|
hero:
|
||||||
|
name: 雅兰亭库
|
||||||
|
text: A collection of C++20 libraries.
|
||||||
|
actions:
|
||||||
|
- theme: brand
|
||||||
|
text: 快速开始
|
||||||
|
link: /zh/guide/what_is_yalantinglibs
|
||||||
|
- theme: alt
|
||||||
|
text: 开源仓库
|
||||||
|
link: https://github.com/alibaba/yalantinglibs.git
|
||||||
|
|
||||||
|
features:
|
||||||
|
- title: struct_pack
|
||||||
|
details: 只需要一行代码完成序列化和反序列化, 比 protobuf 快 10-50 倍.
|
||||||
|
- title: coro_rpc
|
||||||
|
details: Very easy-to-use, coroutine-based, high performance rpc framework with C++20, more than 2000w qps in echo scene.
|
||||||
|
- title: struct_json
|
||||||
|
details: 基于反射的 json 库, 结构体和 json 的相互转换.
|
||||||
|
---
|
|
@ -0,0 +1,65 @@
|
||||||
|
# struct_pb API
|
||||||
|
|
||||||
|
Current, struct_pb provide low-level APIs only, which are in namespace `struct_pb::internal`.
|
||||||
|
|
||||||
|
For example, the `SearchRequest` message from [Language Guide (proto3)](https://developers.google.com/protocol-buffers/docs/proto3#simple)
|
||||||
|
|
||||||
|
```
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
message SearchRequest {
|
||||||
|
string query = 1;
|
||||||
|
int32 page_number = 2;
|
||||||
|
int32 result_per_page = 3;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
we generate the source code
|
||||||
|
```cpp
|
||||||
|
struct SearchRequest {
|
||||||
|
std::string query; // string, field number = 1
|
||||||
|
int32_t page_number; // int32, field number = 2
|
||||||
|
int32_t result_per_page; // int32, field number = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace struct_pb {
|
||||||
|
namespace internal {
|
||||||
|
// ::SearchRequest
|
||||||
|
std::size_t get_needed_size(const ::SearchRequest&, const ::struct_pb::UnknownFields& unknown_fields = {});
|
||||||
|
void serialize_to(char*, std::size_t, const ::SearchRequest&, const ::struct_pb::UnknownFields& unknown_fields = {});
|
||||||
|
bool deserialize_to(::SearchRequest&, const char*, std::size_t, ::struct_pb::UnknownFields& unknown_fields);
|
||||||
|
bool deserialize_to(::SearchRequest&, const char*, std::size_t);
|
||||||
|
|
||||||
|
} // internal
|
||||||
|
} // struct_pb
|
||||||
|
```
|
||||||
|
|
||||||
|
## Serialization
|
||||||
|
|
||||||
|
- get_needed_size
|
||||||
|
|
||||||
|
To get the buffer size, use the `get_needed_size` function.
|
||||||
|
|
||||||
|
To support [Unknown Fields](https://developers.google.com/protocol-buffers/docs/proto3#unknowns),
|
||||||
|
an extra argument `unknown_fields` with default value is added.
|
||||||
|
|
||||||
|
- serialize_to
|
||||||
|
|
||||||
|
To serialize a message to a buffer, use the `serialize_to` function.
|
||||||
|
|
||||||
|
Before use this function, make sure the buffer is sufficiently large.
|
||||||
|
e.g. use `get_needed_size` and then allocate buffer.
|
||||||
|
|
||||||
|
To support [Unknown Fields](https://developers.google.com/protocol-buffers/docs/proto3#unknowns),
|
||||||
|
an extra argument `unknown_fields` with default value is added.
|
||||||
|
|
||||||
|
## Deserialization
|
||||||
|
|
||||||
|
- deserialize_to
|
||||||
|
|
||||||
|
To deserialize a message from buffer, use the `deserialize_to` function.
|
||||||
|
|
||||||
|
Returns true on success.
|
||||||
|
|
||||||
|
To support [Unknown Fields](https://developers.google.com/protocol-buffers/docs/proto3#unknowns),
|
||||||
|
the overload function with an extra argument `unknown_fields` is added.
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Generating source code
|
||||||
|
|
||||||
|
First, you need install protobuf.
|
||||||
|
|
||||||
|
on Mac
|
||||||
|
```shell
|
||||||
|
brew install protobuf
|
||||||
|
```
|
||||||
|
|
||||||
|
on Ubuntu
|
||||||
|
```shell
|
||||||
|
apt-get install protobuf
|
||||||
|
```
|
||||||
|
|
||||||
|
on CentOS
|
||||||
|
```shell
|
||||||
|
yum install protobuf
|
||||||
|
```
|
||||||
|
|
||||||
|
Second, you need install or compile struct_pb protoc plugin `protoc-gen-struct_pb`.
|
||||||
|
|
||||||
|
Finally, you can use the following command to generate the code.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
protoc --plugin=protoc-gen-struct_pb --struct_pb_out . xxx.proto
|
||||||
|
```
|
||||||
|
|
||||||
|
or use the helper function on your `CMakeLists.txt`
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
find_package(Protobuf)
|
||||||
|
protobuf_generate_struct_pb(PROTO_SRCS PROTO_HDRS xxxx.proto)
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
# struct_pb Guide (proto3)
|
||||||
|
|
||||||
|
## Defining A Message Type
|
||||||
|
|
||||||
|
Here is a simple message type from [official document - Defining A Message Type](https://developers.google.com/protocol-buffers/docs/proto3#simple).
|
||||||
|
|
||||||
|
```
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
message SearchRequest {
|
||||||
|
string query = 1;
|
||||||
|
int32 page_number = 2;
|
||||||
|
int32 result_per_page = 3;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Our protoc plugin convert the message type to C++ struct and corresponding low-level serialization API.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct SearchRequest {
|
||||||
|
std::string query; // string, field number = 1
|
||||||
|
int32_t page_number; // int32, field number = 2
|
||||||
|
int32_t result_per_page; // int32, field number = 3
|
||||||
|
};
|
||||||
|
namespace struct_pb {
|
||||||
|
namespace internal {
|
||||||
|
// ::SearchRequest
|
||||||
|
std::size_t get_needed_size(const ::SearchRequest&, const ::struct_pb::UnknownFields& unknown_fields = {});
|
||||||
|
void serialize_to(char*, std::size_t, const ::SearchRequest&, const ::struct_pb::UnknownFields& unknown_fields = {});
|
||||||
|
bool deserialize_to(::SearchRequest&, const char*, std::size_t, ::struct_pb::UnknownFields& unknown_fields);
|
||||||
|
bool deserialize_to(::SearchRequest&, const char*, std::size_t);
|
||||||
|
|
||||||
|
} // internal
|
||||||
|
} // struct_pb
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use the struct `SearchRequest` as a normal C++ struct.
|
||||||
|
|
||||||
|
## Enumerations
|
||||||
|
|
||||||
|
```
|
||||||
|
syntax = "proto3";
|
||||||
|
enum Corpus {
|
||||||
|
CORPUS_UNSPECIFIED = 0;
|
||||||
|
CORPUS_UNIVERSAL = 1;
|
||||||
|
CORPUS_WEB = 2;
|
||||||
|
CORPUS_IMAGES = 3;
|
||||||
|
CORPUS_LOCAL = 4;
|
||||||
|
CORPUS_NEWS = 5;
|
||||||
|
CORPUS_PRODUCTS = 6;
|
||||||
|
CORPUS_VIDEO = 7;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
enum class Corpus: int {
|
||||||
|
CORPUS_UNSPECIFIED = 0,
|
||||||
|
CORPUS_UNIVERSAL = 1,
|
||||||
|
CORPUS_WEB = 2,
|
||||||
|
CORPUS_IMAGES = 3,
|
||||||
|
CORPUS_LOCAL = 4,
|
||||||
|
CORPUS_NEWS = 5,
|
||||||
|
CORPUS_PRODUCTS = 6,
|
||||||
|
CORPUS_VIDEO = 7,
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Nested messages
|
||||||
|
|
||||||
|
Here is the sample from [proto3 Nested Types](https://developers.google.com/protocol-buffers/docs/proto3#nested)
|
||||||
|
|
||||||
|
```
|
||||||
|
syntax = "proto3";
|
||||||
|
message Outer { // Level 0
|
||||||
|
message MiddleAA { // Level 1
|
||||||
|
message Inner { // Level 2
|
||||||
|
int64 ival = 1;
|
||||||
|
bool booly = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message MiddleBB { // Level 1
|
||||||
|
message Inner { // Level 2
|
||||||
|
int32 ival = 1;
|
||||||
|
bool booly = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct Outer {
|
||||||
|
struct MiddleAA {
|
||||||
|
struct Inner {
|
||||||
|
int64_t ival; // int64, field number = 1
|
||||||
|
bool booly; // bool, field number = 2
|
||||||
|
};
|
||||||
|
};
|
||||||
|
struct MiddleBB {
|
||||||
|
struct Inner {
|
||||||
|
int32_t ival; // int32, field number = 1
|
||||||
|
bool booly; // bool, field number = 2
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Oneof
|
||||||
|
|
||||||
|
Here is the sample from [proto3 Oneof](https://developers.google.com/protocol-buffers/docs/proto3#oneof)
|
||||||
|
|
||||||
|
```
|
||||||
|
syntax = "proto3";
|
||||||
|
message SampleMessage {
|
||||||
|
oneof test_oneof {
|
||||||
|
string name = 4;
|
||||||
|
SubMessage sub_message = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message SubMessage {
|
||||||
|
int32 val = 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
The oneof type is mapped to `std::varint` with lots of helper functions.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct SampleMessage {
|
||||||
|
enum class TestOneofCase {
|
||||||
|
none = 0,
|
||||||
|
name = 4,
|
||||||
|
sub_message = 9,
|
||||||
|
};
|
||||||
|
TestOneofCase test_oneof_case() const {
|
||||||
|
switch (test_oneof.index()) {
|
||||||
|
case 1:
|
||||||
|
return TestOneofCase::name;
|
||||||
|
case 2:
|
||||||
|
return TestOneofCase::sub_message;
|
||||||
|
default:
|
||||||
|
return TestOneofCase::none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::variant<std::monostate
|
||||||
|
, std::string // string, field number = 4
|
||||||
|
, std::unique_ptr<::SubMessage> // message, field number = 9
|
||||||
|
> test_oneof;
|
||||||
|
|
||||||
|
bool has_name() const {
|
||||||
|
return test_oneof.index() == 1;
|
||||||
|
}
|
||||||
|
void set_name(std::string name) {
|
||||||
|
test_oneof.emplace<1>(std::move(name));
|
||||||
|
}
|
||||||
|
const std::string& name() const {
|
||||||
|
assert(test_oneof.index() == 1);
|
||||||
|
return std::get<1>(test_oneof);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_sub_message() const {
|
||||||
|
return test_oneof.index() == 2;
|
||||||
|
}
|
||||||
|
void set_allocated_sub_message(::SubMessage* p) {
|
||||||
|
assert(p);
|
||||||
|
test_oneof.emplace<2>(p);
|
||||||
|
}
|
||||||
|
const std::unique_ptr<::SubMessage>& sub_message() const {
|
||||||
|
assert(test_oneof.index() == 2);
|
||||||
|
return std::get<2>(test_oneof);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct SubMessage {
|
||||||
|
int32_t val; // int32, field number = 1
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Maps
|
||||||
|
|
||||||
|
```
|
||||||
|
syntax = "proto3";
|
||||||
|
message SampleMap {
|
||||||
|
map<string, Project> projects = 3;
|
||||||
|
}
|
||||||
|
message Project {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct SampleMap {
|
||||||
|
std::map<std::string, ::Project> projects; // message, field number = 3
|
||||||
|
};
|
||||||
|
struct Project {
|
||||||
|
std::string name; // string, field number = 1
|
||||||
|
};
|
||||||
|
```
|