Compare commits
20 Commits
UI
...
269412b371
| Author | SHA1 | Date | |
|---|---|---|---|
| 269412b371 | |||
| 78fa2665b0 | |||
| cf51900c96 | |||
| 6aa522f3e2 | |||
| c5d109e9be | |||
|
|
ab7ee978e7 | ||
|
|
e22a779dda | ||
|
|
dcdbf051d0 | ||
|
|
bcb56200c1 | ||
|
|
0811c0eabb | ||
|
|
415d9ab518 | ||
|
|
76be13001f | ||
|
|
814f42120c | ||
|
|
4fe4749826 | ||
|
|
2ff880c267 | ||
|
|
abcfc78596 | ||
|
|
bcbf890ebd | ||
|
|
9fe2fe5874 | ||
|
|
1be1ecbbf2 | ||
|
|
37e7d278bd |
7
.claude/settings.local.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"mcp__ide__getDiagnostics"
|
||||
]
|
||||
}
|
||||
}
|
||||
63
.gitattributes
vendored
@@ -1,63 +0,0 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
23
.gitignore
vendored
@@ -1,3 +1,20 @@
|
||||
build/*
|
||||
build64/*
|
||||
demo/*
|
||||
################################################################################
|
||||
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
|
||||
################################################################################
|
||||
|
||||
ThirdParty/
|
||||
_temp/
|
||||
_bin/
|
||||
.vs/
|
||||
/build
|
||||
/build_x64
|
||||
/example
|
||||
/demo
|
||||
/lib
|
||||
/.vs
|
||||
/.vscode
|
||||
*.db
|
||||
*.gitignore
|
||||
*.gitattributes
|
||||
*.exe
|
||||
*.pdb
|
||||
59
CLAUDE.md
@@ -9,20 +9,31 @@ EzUI 是一个基于原生 Win32 消息机制和 Direct2D 的 C++ 桌面 UI 框
|
||||
## 构建命令
|
||||
|
||||
```bash
|
||||
build.bat # 构建 32 位版本
|
||||
build64.bat # 构建 64 位版本
|
||||
# 生成 Visual Studio 项目(推荐)
|
||||
cmake -S . -B build_x86 -A Win32 # 32位 VS 项目
|
||||
cmake -S . -B build_x64 -A x64 # 64位 VS 项目
|
||||
|
||||
# 或使用现有的批处理脚本
|
||||
build_x86.bat # 生成 32 位项目并打开
|
||||
build_x64.bat # 生成 64 位项目并打开
|
||||
```
|
||||
|
||||
或使用 CMake 直接构建:
|
||||
CMake 构建:
|
||||
```bash
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
静态库/动态库切换:
|
||||
```bash
|
||||
cmake -B build -DBUILD_SHARED_LIBS=ON # 动态库
|
||||
cmake -B build -DBUILD_SHARED_LIBS=OFF # 静态库(默认)
|
||||
```
|
||||
|
||||
## 核心架构
|
||||
|
||||
### 窗口类型 (继承层次)
|
||||
- `Window` - 经典边框窗口
|
||||
- `Window` - 经典带边框窗口
|
||||
- `BorderlessWindow` - 无边框带阴影窗口
|
||||
- `LayeredWindow` - 分层透明窗口,支持异形
|
||||
- `PopupWindow` - 失焦自动关闭的弹出窗口
|
||||
@@ -32,7 +43,13 @@ cmake --build build
|
||||
- 基础控件:`Label`, `Button`, `TextBox`, `PictureBox`
|
||||
- 选择控件:`CheckBox`, `RadioButton`, `ComboBox`
|
||||
- 布局容器:`HLayout`, `VLayout`, `HListView`, `VListView`, `TileListView`, `TabLayout`
|
||||
- 功能控件:`ScrollBar`, `Menu`, `NotifyIcon`, `ProgressBar`
|
||||
- 功能控件:`ScrollBar`, `Menu`, `NotifyIcon`, `ProgressBar`, `TreeView`, `Spacer`, `TableView`, `IFrame`
|
||||
|
||||
### 布局系统
|
||||
- **尺寸优先级**:比例尺寸 (`SetRateWidth/Height`) > 绝对尺寸 (`SetFixedSize`) > 控件内容大小
|
||||
- **自动布局**:`SetAutoWidth/Height` 让控件根据内容自动调整大小
|
||||
- **停靠布局**:`SetDockStyle` 支持 Fill/Vertical/Horizontal 停靠
|
||||
- **布局状态**:`TryPendLayout`/`ResumeLayout` 批量添加控件后统一布局
|
||||
|
||||
### 样式与渲染
|
||||
- `UIManager` - UI 样式与资源管理,支持 XML 布局加载
|
||||
@@ -41,7 +58,35 @@ cmake --build build
|
||||
- `RenderTypes` - 颜色、对齐方式等绘图类型
|
||||
|
||||
### 事件系统
|
||||
支持事件冒泡机制,可实现事件捕获与穿透。Debug 模式下按 F11 可查看布局信息和控件边界。
|
||||
- 支持事件冒泡机制,可实现事件捕获与穿透
|
||||
- `NotifyFlags` 控制控件哪些事件需要通知窗口
|
||||
- `Event` 枚举定义所有事件类型,支持位运算组合
|
||||
- Debug 模式下按 F11 可查看布局信息和控件边界
|
||||
|
||||
### 线程模型
|
||||
- UI 线程:`Application::Run` 启动消息循环
|
||||
- 跨线程调用:`BeginInvoke`(异步)/ `Invoke`(同步)
|
||||
- 全局隐藏窗口 `__EzUI_MessageWnd` 用于线程通讯
|
||||
|
||||
### 动画系统
|
||||
- `Animation` 类支持类似 Qt 的过渡动画
|
||||
- 可用于控件属性(位置、大小、透明度等)的平滑过渡
|
||||
|
||||
### 资源管理
|
||||
- 控件树内存由父控件自动管理:`Attach`/`Detach`
|
||||
- 图片资源通过 `PtrManager` 自动释放
|
||||
- XML 布局加载后由 `UIManager` 管理生命周期
|
||||
- `ResPackage.exe` 工具用于打包资源文件
|
||||
|
||||
## Demo 示例
|
||||
|
||||
Demo 位于 `demo/` 目录:
|
||||
- `helloWorld` - 基础 HelloWorld 示例
|
||||
- `QQ` - 仿 QQ 登录界面
|
||||
- `kugou` - 仿酷狗音乐播放器(需要 VLC 解码库)
|
||||
|
||||
Demo 新版位于 `demoEx/` 目录:
|
||||
- `Adminstor` - 用户管理 界面示例
|
||||
|
||||
## 开发约定
|
||||
|
||||
@@ -49,3 +94,5 @@ cmake --build build
|
||||
- 源文件位于 `sources/` 目录
|
||||
- 一切皆控件,纯代码组合 UI
|
||||
- 使用 CSS 驱动视觉,结构与样式分离
|
||||
- 中文注释,中文沟通
|
||||
- 每次编码完毕无需编译,让用户自行编译验证
|
||||
|
||||
@@ -44,4 +44,7 @@ function(add_resource_package TARGET_NAME INPUT_DIR OUTPUT_FILE)
|
||||
endfunction()
|
||||
|
||||
#添加子项目
|
||||
#add_subdirectory(./demo) # 暂时注释掉,只编译库
|
||||
option(BUILD_DEMO "Build demo projects" ON)
|
||||
if(BUILD_DEMO)
|
||||
add_subdirectory(./demo)
|
||||
endif()
|
||||
|
||||
4
build_x64.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
chcp 65001
|
||||
@echo off
|
||||
cmake -S . -B build_x64 -A x64 -DBUILD_EZUI=OFF
|
||||
pause
|
||||
4
build_x86.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
chcp 65001
|
||||
@echo off
|
||||
cmake -S . -B build_x86 -A Win32 -DBUILD_EZUI=OFF
|
||||
pause
|
||||
95
demo/CMakeLists.txt
Normal file
@@ -0,0 +1,95 @@
|
||||
cmake_minimum_required(VERSION 3.0...9.0)
|
||||
|
||||
#gui库的包含目录位置
|
||||
set(include ../include)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(ARCH_NAME "x64")
|
||||
else()
|
||||
set(ARCH_NAME "x86")
|
||||
endif()
|
||||
|
||||
|
||||
#一个简单的helloworld
|
||||
project(helloWorld)
|
||||
file(GLOB src helloWorld/*.*)
|
||||
add_executable(helloWorld WIN32 ${src})
|
||||
target_include_directories(helloWorld PRIVATE ${include})
|
||||
target_link_libraries(helloWorld PRIVATE EzUI)
|
||||
set_property(TARGET helloWorld PROPERTY FOLDER "demo")
|
||||
|
||||
#资源打包器
|
||||
project(ResPackage)
|
||||
file(GLOB src ./ResPackage/*.*)
|
||||
add_executable(ResPackage WIN32 ${src} )
|
||||
target_include_directories(ResPackage PRIVATE ${include})
|
||||
target_link_libraries(ResPackage PRIVATE EzUI)
|
||||
set_property(TARGET ResPackage PROPERTY FOLDER "demo")
|
||||
|
||||
|
||||
#仿QQ登录界面
|
||||
project(QQ)
|
||||
#主程序
|
||||
file(GLOB src CONFIGURE_DEPENDS
|
||||
"./QQ/*.h"
|
||||
"./QQ/*.hpp"
|
||||
"./QQ/*.c"
|
||||
"./QQ/*.cpp"
|
||||
"./QQ/*.rc"
|
||||
)
|
||||
add_executable(QQ WIN32 ${src})
|
||||
target_include_directories(QQ PRIVATE ${include})
|
||||
target_link_libraries(QQ PRIVATE EzUI)
|
||||
# 添加资源文件到"Res"筛选项下
|
||||
file(GLOB_RECURSE res_files CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/QQ/res/*.*")
|
||||
target_sources(QQ PRIVATE ${res_files})
|
||||
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/QQ/res" PREFIX "res" FILES ${res_files})
|
||||
add_resource_package(QQ ./QQ/res ./QQ/QQ.res)
|
||||
set_property(TARGET QQ PROPERTY FOLDER "demo")
|
||||
|
||||
|
||||
#模仿酷狗音乐demo
|
||||
project(kugou)
|
||||
#主程序
|
||||
file(GLOB src CONFIGURE_DEPENDS
|
||||
"./kugou/*.h"
|
||||
"./kugou/*.hpp"
|
||||
"./kugou/*.c"
|
||||
"./kugou/*.cpp"
|
||||
"./kugou/*.rc"
|
||||
)
|
||||
add_executable(kugou WIN32 ${src})
|
||||
|
||||
# 添加资源文件到"Res"筛选项下
|
||||
file(GLOB_RECURSE res_files CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/kugou/res/*.*")
|
||||
target_sources(kugou PRIVATE ${res_files})
|
||||
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/kugou/res" PREFIX "res" FILES ${res_files})
|
||||
|
||||
target_include_directories(kugou PRIVATE ${include})
|
||||
#添加常用库依赖
|
||||
target_include_directories(kugou PRIVATE ./kugou/include/Common/include)
|
||||
target_include_directories(kugou PRIVATE ./kugou/include/vlc/include)
|
||||
#添加vlc解码器依赖
|
||||
target_link_directories(kugou PRIVATE ./kugou/lib/${ARCH_NAME}/Common)
|
||||
target_link_directories(kugou PRIVATE ./kugou/lib/${ARCH_NAME}/vlc)
|
||||
|
||||
set_property(TARGET kugou PROPERTY FOLDER "demo")
|
||||
#添加引用
|
||||
target_link_libraries(kugou PRIVATE EzUI)
|
||||
#解决 "模块对于 SAFESEH 映像是不安全的" 的报错
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
|
||||
#指定为c++编译
|
||||
set_target_properties(kugou PROPERTIES LINKER_LANGUAGE CXX)
|
||||
target_compile_definitions(kugou PRIVATE WIN32_LEAN_AND_MEAN)
|
||||
|
||||
#打包kugou/res文件夹下的所有资源 输出至kugou/kugou.res
|
||||
add_resource_package(kugou ./kugou/res ./kugou/kugou.res)
|
||||
|
||||
#执行解压vlc的解码库
|
||||
add_custom_command(
|
||||
TARGET kugou
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/kugou/extract${ARCH_NAME}.bat" "$<TARGET_FILE_DIR:kugou>"
|
||||
COMMENT "Running extract.bat to conditionally extract dll.zip"
|
||||
)
|
||||
BIN
demo/QQ/QQ.APS
Normal file
1
demo/QQ/QQ.rc
Normal file
@@ -0,0 +1 @@
|
||||
my_res EZUI_RES QQ.res
|
||||
BIN
demo/QQ/QQ.res
Normal file
195
demo/QQ/QQ.vcxproj
Normal file
@@ -0,0 +1,195 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}</ProjectGuid>
|
||||
<RootNamespace>QQ</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</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'">
|
||||
<OutDir>..\_bin\</OutDir>
|
||||
<IntDir>..\_temp\$(Platform)$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>..\..\lib;$(LibraryPath)</LibraryPath>
|
||||
<TargetName>$(ProjectName)_$(Configuration)_$(Platform)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>..\_bin\</OutDir>
|
||||
<IntDir>..\_temp\$(Platform)$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>..\..\lib;$(LibraryPath)</LibraryPath>
|
||||
<TargetName>$(ProjectName)_$(Configuration)_$(Platform)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>..\_bin\</OutDir>
|
||||
<IntDir>..\_temp\$(Platform)$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>..\..\lib;$(LibraryPath)</LibraryPath>
|
||||
<TargetName>$(ProjectName)_$(Configuration)_$(Platform)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>..\_bin\</OutDir>
|
||||
<IntDir>..\_temp\$(Platform)$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<IncludePath>..\..\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>..\..\lib;$(LibraryPath)</LibraryPath>
|
||||
<TargetName>$(ProjectName)_$(Configuration)_$(Platform)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>EZUI_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>EZUI_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>EZUI_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>EZUI_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="loginForm.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="mainForm.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="loginForm.h" />
|
||||
<ClInclude Include="mainForm.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="QQ.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="res\head.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
46
demo/QQ/QQ.vcxproj.filters
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="loginForm.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mainForm.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="loginForm.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mainForm.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="QQ.rc">
|
||||
<Filter>资源文件</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="res\head.png">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
4
demo/QQ/QQ.vcxproj.user
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
51
demo/QQ/loginForm.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "loginForm.h"
|
||||
#include "mainForm.h"
|
||||
|
||||
LoginForm::LoginForm() :LayeredWindow(320, 448)
|
||||
{
|
||||
umg.LoadXml("res/loginForm.htm");//加载xml里面的控件与样式
|
||||
umg.SetupUI(this);
|
||||
}
|
||||
void LoginForm::OnNotify(Control* sender, EventArgs& args)
|
||||
{
|
||||
if (args.EventType == Event::OnMouseDown) {
|
||||
if (sender->Name == "btnLogin") {
|
||||
TextBox* editUser = (TextBox*)FindControl("user");
|
||||
TextBox* editpwd = (TextBox*)FindControl("pwd");
|
||||
CheckBox* ckbox = (CheckBox*)FindControl("ckbox");
|
||||
if (!ckbox->GetCheck()) {
|
||||
::MessageBox(Hwnd(), L"请阅读协议并勾选!", L"提示", MB_OK);
|
||||
return;
|
||||
}
|
||||
UIString user = editUser->GetText();
|
||||
UIString pwd = editpwd->GetText();
|
||||
if (user == "718987717" && pwd == "123456") {
|
||||
// 登录成功,跳转到主界面
|
||||
Hide(); // 隐藏登录窗口
|
||||
static MainForm mainForm;
|
||||
mainForm.Show(); // 显示主界面
|
||||
}
|
||||
else {
|
||||
::MessageBox(Hwnd(), L"用户名或密码错误!", L"提示", MB_OK);
|
||||
}
|
||||
}
|
||||
if (sender->Name == "btnExit") {
|
||||
Application::Exit();
|
||||
}
|
||||
if (!sender->GetAttribute("url").empty()) {
|
||||
::ShellExecuteA(0, "open", sender->GetAttribute("url").c_str(), "", "", SW_SHOW);
|
||||
}
|
||||
}
|
||||
__super::OnNotify(sender, args);
|
||||
}
|
||||
|
||||
void LoginForm::OnClose(bool& bClose)
|
||||
{
|
||||
//bClose = false;
|
||||
Application::Exit();
|
||||
}
|
||||
|
||||
LoginForm::~LoginForm()
|
||||
{
|
||||
|
||||
}
|
||||
36
demo/QQ/loginForm.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "ezui/Application.h" //app类
|
||||
#include "EzUI/Window.h" //基础窗口类
|
||||
#include "EzUI/Button.h" //按钮
|
||||
#include "EzUI/TextBox.h" //文本框
|
||||
#include "EzUI/CheckBox.h" //复选框
|
||||
#include "EzUI/PictureBox.h" //图片控件
|
||||
#include "EzUI/TabLayout.h" //选项卡控件
|
||||
#include "EzUI/VLayout.h" //垂直布局
|
||||
#include "EzUI/HLayout.h"//水平布局
|
||||
#include "EzUI/VListView.h"//垂直带滚动条列表
|
||||
#include "EzUI/HListView.h"//水平带滚动条列表
|
||||
#include "EzUI/TileListView.h"//瓦片列表
|
||||
#include "EzUI/LayeredWindow.h"//分层窗口类-可以异型透明窗口
|
||||
#include "ezui/UIManager.h"//ui管理类(使用xml生成控件)
|
||||
|
||||
using namespace ezui;
|
||||
|
||||
using Form = LayeredWindow; //支持异形透明窗口(带阴影)
|
||||
//using Form = BorderlessWindow; //常规无边框窗口(带阴影)
|
||||
//using Form = Window; //标准窗口(带系统标题栏)
|
||||
|
||||
//登录窗口
|
||||
class LoginForm :public Form
|
||||
{
|
||||
private:
|
||||
//ui管理类
|
||||
UIManager umg;
|
||||
protected:
|
||||
virtual void OnNotify(Control* sender, EventArgs& args)override;//重载事件通知
|
||||
virtual void OnClose(bool& close)override;//当窗口关闭的时候
|
||||
public:
|
||||
LoginForm();
|
||||
virtual ~LoginForm();
|
||||
};
|
||||
|
||||
22
demo/QQ/main.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "loginForm.h"
|
||||
|
||||
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
|
||||
_In_opt_ HINSTANCE hPrevInstance,
|
||||
_In_ LPWSTR lpCmdLine,
|
||||
_In_ int nCmdShow)
|
||||
{
|
||||
//app类
|
||||
Application app(hInstance);
|
||||
app.EnableHighDpi();//启用高DPI
|
||||
app.SetResource("my_res");//设定资源名称
|
||||
|
||||
//创建登录创建
|
||||
LoginForm loginFrm;
|
||||
loginFrm.Show();
|
||||
|
||||
//loginFrm.CloseShadowBox();
|
||||
|
||||
//开始消息循环
|
||||
int code = app.Exec();
|
||||
return code;
|
||||
}
|
||||
38
demo/QQ/mainForm.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "mainForm.h"
|
||||
|
||||
void MainForm::OnNotify(Control* sender, EventArgs& args)
|
||||
{
|
||||
if (args.EventType == Event::OnMouseDown) {
|
||||
if (sender->Name == "btnMin") {
|
||||
SendMessage(Hwnd(), WM_SYSCOMMAND, SC_MINIMIZE, 0);
|
||||
}
|
||||
else if (sender->Name == "btnMax") {
|
||||
if (IsZoomed(Hwnd())) {
|
||||
SendMessage(Hwnd(), WM_SYSCOMMAND, SC_RESTORE, 0);
|
||||
}
|
||||
else {
|
||||
SendMessage(Hwnd(), WM_SYSCOMMAND, SC_MAXIMIZE, 0);
|
||||
}
|
||||
}
|
||||
else if (sender->Name == "btnClose") {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
__super::OnNotify(sender, args);
|
||||
}
|
||||
|
||||
void MainForm::OnClose(bool& close)
|
||||
{
|
||||
Application::Exit();
|
||||
}
|
||||
|
||||
MainForm::MainForm() : LayeredWindow(800, 600)
|
||||
{
|
||||
SetText(L"QQ主界面");
|
||||
umg.LoadXml("res/mainForm.htm");
|
||||
umg.SetupUI(this);
|
||||
}
|
||||
|
||||
MainForm::~MainForm()
|
||||
{
|
||||
}
|
||||
35
demo/QQ/mainForm.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#include "ezui/Application.h" //app类
|
||||
#include "EzUI/Window.h" //基础窗口类
|
||||
#include "EzUI/Button.h" //按钮
|
||||
#include "EzUI/TextBox.h" //文本框
|
||||
#include "EzUI/CheckBox.h" //复选框
|
||||
#include "EzUI/PictureBox.h" //图片控件
|
||||
#include "EzUI/TabLayout.h" //选项卡控件
|
||||
#include "EzUI/VLayout.h" //垂直布局
|
||||
#include "EzUI/HLayout.h"//水平布局
|
||||
#include "EzUI/VListView.h"//垂直带滚动条列表
|
||||
#include "EzUI/HListView.h"//水平带滚动条列表
|
||||
#include "EzUI/TileListView.h"//瓦片列表
|
||||
#include "EzUI/LayeredWindow.h"//分层窗口类-可以异型透明窗口
|
||||
#include "ezui/UIManager.h"//ui管理类(使用xml生成控件)
|
||||
#include "EzUI/LayeredWindow.h"
|
||||
#include "EzUI/Label.h"
|
||||
#include "EzUI/VLayout.h"
|
||||
#include "EzUI/HLayout.h"
|
||||
#include "EzUI/UIManager.h"
|
||||
|
||||
using namespace ezui;
|
||||
|
||||
// 主界面
|
||||
class MainForm : public LayeredWindow
|
||||
{
|
||||
private:
|
||||
UIManager umg;
|
||||
protected:
|
||||
virtual void OnNotify(Control* sender, EventArgs& args) override;
|
||||
virtual void OnClose(bool& close) override;
|
||||
public:
|
||||
MainForm();
|
||||
virtual ~MainForm();
|
||||
};
|
||||
BIN
demo/QQ/res/check.png
Normal file
|
After Width: | Height: | Size: 784 B |
BIN
demo/QQ/res/check_1.png
Normal file
|
After Width: | Height: | Size: 938 B |
BIN
demo/QQ/res/close.png
Normal file
|
After Width: | Height: | Size: 496 B |
BIN
demo/QQ/res/down.png
Normal file
|
After Width: | Height: | Size: 510 B |
BIN
demo/QQ/res/gif2.gif
Normal file
|
After Width: | Height: | Size: 3.6 MiB |
BIN
demo/QQ/res/head.png
Normal file
|
After Width: | Height: | Size: 244 KiB |
86
demo/QQ/res/loginForm.htm
Normal file
@@ -0,0 +1,86 @@
|
||||
<vbox id="mainLayout" action="move">
|
||||
|
||||
<hbox height="20" margin-top="5" action="move">
|
||||
<spacer></spacer>
|
||||
<label size="20,20" style="background-image: url(res/setting.png)"></label>
|
||||
<spacer width="10"></spacer>
|
||||
<label id="btnExit" size="20,20" action="close" style="background-image: url(res/close.png)"></label>
|
||||
<spacer width="10"></spacer>
|
||||
</hbox>
|
||||
|
||||
<!--<spacer height="40"></spacer>-->
|
||||
<label margin-top="30" id="headImg" size="80,80" action="move"></label>
|
||||
|
||||
<!-- 账号输入框 -->
|
||||
<hbox margin-top="25" size="258,42" style="border-radius:5px;background-color:white;">
|
||||
<spacer width="24"></spacer>
|
||||
<input id="user" halign="center" placeholder="输入QQ号" />
|
||||
<label size="24,24" margin-right="5" style="background-image:url(res/down.png)"></label>
|
||||
</hbox>
|
||||
|
||||
<!-- 密码输入框 -->
|
||||
<hbox margin-top="10" size="258,42" style="border-radius:5px;background-color:white;">
|
||||
<spacer width="24"></spacer>
|
||||
<input passwordchar="*" id="pwd" halign="center" placeholder="输入密码" />
|
||||
<label size="15,15" margin-right="10" style="background-image:url(res/close.png)"></label>
|
||||
</hbox>
|
||||
|
||||
<!-- 协议勾选 -->
|
||||
<hbox size="258,42" margin-top="10" style="font-size:12px">
|
||||
<checkbox size="18,18" id="ckbox"></checkbox>
|
||||
<label width="auto" text="我已阅读并同意"></label>
|
||||
<button url="www.baidu.com" width="auto" style="color: #2D77E5;cursor:pointer" text="服务协议"></button>
|
||||
<label width="auto" text="和"></label>
|
||||
<button url="www.bing.com" width="auto" style="color: #2D77E5" text="QQ隐私保护指引"></button>
|
||||
</hbox>
|
||||
|
||||
<button margin-top="15" size="258,38" id="btnLogin" text="登录"> </button>
|
||||
|
||||
|
||||
<!-- 扫码登陆/更多选项 -->
|
||||
<hbox size="258,20" margin-top="40" style="font-size:14px">
|
||||
|
||||
<spacer></spacer>
|
||||
|
||||
<button width="auto" text="扫码登录" style="color: #2D77E5 "></button>
|
||||
|
||||
<label width="auto" text="|" margin="0,5,0,5" style="color: #E4DFEB"></label>
|
||||
|
||||
<button width="auto" text="更多选项" style="color: #2D77E5 "></button>
|
||||
|
||||
<spacer></spacer>
|
||||
|
||||
</hbox>
|
||||
|
||||
</vbox>
|
||||
|
||||
<style>
|
||||
#mainLayout {
|
||||
background-color: #E8F0FF;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#headImg {
|
||||
background-image: url(res/head.png);
|
||||
border-radius: 80px;
|
||||
border: 2px solid white;
|
||||
}
|
||||
|
||||
#ckbox {
|
||||
background-image: url(res/check.png);
|
||||
}
|
||||
|
||||
#ckbox:checked {
|
||||
background-image: url(res/check_1.png);
|
||||
}
|
||||
|
||||
#btnLogin {
|
||||
background-color: #0099FF;
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
}
|
||||
/*登录按钮鼠标悬浮时候的外观*/
|
||||
#btnLogin:hover {
|
||||
background-color: #008DEB;
|
||||
}
|
||||
</style>
|
||||
18
demo/QQ/res/mainForm.htm
Normal file
@@ -0,0 +1,18 @@
|
||||
<vlayout id="mainLayout" action="move">
|
||||
<!-- 标题栏 -->
|
||||
<hbox height="20" margin-top="5" action="move">
|
||||
<spacer></spacer>
|
||||
<!-- 退出按钮 -->
|
||||
<button id="btnExitMain" size="20,20" style="background-image: url(res/close.png)"></button>
|
||||
<spacer width="10"></spacer>
|
||||
</hbox>
|
||||
|
||||
</vlayout>
|
||||
|
||||
<style>
|
||||
#mainLayout {
|
||||
background-color: #E8F0FF;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
</style>
|
||||
BIN
demo/QQ/res/setting.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
183
demo/ResPackage/FileSystem.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
#include "FileSystem.h"
|
||||
namespace ezui {
|
||||
namespace File {
|
||||
bool Exists(const UIString& filename) {
|
||||
DWORD dwAttr = ::GetFileAttributesW(filename.unicode().c_str());
|
||||
return (dwAttr != INVALID_FILE_ATTRIBUTES && !(dwAttr & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
bool Copy(const UIString& src, const UIString& desc) {
|
||||
return ::CopyFileW(src.unicode().c_str(), desc.unicode().c_str(), FALSE);
|
||||
}
|
||||
bool Delete(const UIString& file) {
|
||||
return ::DeleteFileW(file.unicode().c_str());
|
||||
}
|
||||
bool Move(const UIString& oldName, const UIString& newName) {
|
||||
return ::MoveFileExW(oldName.unicode().c_str(), newName.unicode().c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
|
||||
}
|
||||
bool Create(const UIString& fileName) {
|
||||
std::ofstream ofs(fileName.unicode(), std::ios::out | std::ios::binary);
|
||||
return ofs.is_open();
|
||||
}
|
||||
bool Write(const char* fileData, size_t fileSize, const UIString& outFileName) {
|
||||
std::ofstream ofs(outFileName.unicode(), std::ios::binary | std::ios::app);
|
||||
if (ofs.is_open()) {
|
||||
ofs.write(fileData, fileSize);
|
||||
return ofs.good();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
size_t Read(const UIString& fileName, std::string* data) {
|
||||
std::ifstream ifs(fileName.unicode(), std::ios::binary);
|
||||
ifs.seekg(0, std::ios::end);
|
||||
size_t size = ifs.tellg();
|
||||
data->resize(size);
|
||||
ifs.seekg(0);
|
||||
ifs.read((char*)data->data(), size);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
namespace Path {
|
||||
void Format(std::string* _str) {
|
||||
auto& str = *_str;
|
||||
size_t size = str.size();
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
char* buf = new char[size];
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
if (str[i] == '\\') {
|
||||
buf[j] = '/';
|
||||
}
|
||||
else {
|
||||
buf[j] = str[i];
|
||||
}
|
||||
j++;
|
||||
}
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
// 将多个斜杠替换成单个斜杠
|
||||
if (buf[i] == '/') {
|
||||
size_t k = i + 1;
|
||||
while (buf[k] == '/' && k < size) {
|
||||
k++;
|
||||
}
|
||||
if (k > i + 1) {
|
||||
for (size_t m = i + 1; m < size - (k - i - 1); m++) {
|
||||
buf[m] = buf[m + (k - i - 1)];
|
||||
}
|
||||
size -= (k - i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
str.clear();
|
||||
str.append(buf, size);
|
||||
delete[] buf; // 释放内存
|
||||
}
|
||||
UIString GetFileNameWithoutExtension(const UIString& _filename) {
|
||||
UIString newStr = _filename;
|
||||
Path::Format(&newStr);
|
||||
int bPos = newStr.rfind("/");
|
||||
int ePos = newStr.rfind(".");
|
||||
newStr = newStr.substr(bPos + 1, ePos - bPos - 1);
|
||||
return newStr;
|
||||
}
|
||||
UIString GetDirectoryName(const UIString& _filename) {
|
||||
UIString newStr = _filename;
|
||||
Path::Format(&newStr);
|
||||
int pos = newStr.rfind("/");
|
||||
return newStr.substr(0, pos);
|
||||
}
|
||||
UIString GetExtension(const UIString& _filename) {
|
||||
size_t pos = _filename.rfind(".");
|
||||
return pos == size_t(-1) ? "" : _filename.substr(pos);
|
||||
}
|
||||
UIString GetFileName(const UIString& filename) {
|
||||
return Path::GetFileNameWithoutExtension(filename) + Path::GetExtension(filename);
|
||||
}
|
||||
}
|
||||
namespace Directory {
|
||||
void __Find(const std::wstring& path, std::vector<FileInfo>* result, const std::wstring& pattern, bool looDir) {
|
||||
WIN32_FIND_DATAW findData;
|
||||
HANDLE findHandle = FindFirstFileW((path + L"/" + pattern).c_str(), &findData);
|
||||
if (findHandle == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
if (findData.cFileName[0] == L'.') {
|
||||
continue;
|
||||
}
|
||||
FileInfo file;
|
||||
std::wstring name = path + L"/" + findData.cFileName;
|
||||
file.Name = name;
|
||||
file.Attr = findData.dwFileAttributes;
|
||||
result->push_back(file);
|
||||
if (file.IsDirectory() && looDir) {
|
||||
__Find(name, result, pattern, looDir);
|
||||
}
|
||||
} while (FindNextFileW(findHandle, &findData));
|
||||
FindClose(findHandle);
|
||||
}
|
||||
bool Exists(const UIString& directoryNme) {
|
||||
DWORD dwAttr = GetFileAttributesW(directoryNme.unicode().c_str());
|
||||
if (dwAttr == DWORD(-1)) {
|
||||
return false;
|
||||
}
|
||||
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool Create(const UIString& path) {
|
||||
::CreateDirectoryW(path.unicode().c_str(), NULL);
|
||||
if (Exists(path)) {
|
||||
return true;
|
||||
}
|
||||
//创建多级目录
|
||||
if (path.find(":") != size_t(-1)) {
|
||||
UIString dir = path + "/";
|
||||
Path::Format(&dir);
|
||||
auto arr = dir.split("/");
|
||||
UIString root;
|
||||
if (!arr.empty()) {
|
||||
root += arr[0] + "/";
|
||||
for (size_t i = 1; i < arr.size(); i++)
|
||||
{
|
||||
if (arr[i].empty()) {
|
||||
continue;
|
||||
}
|
||||
root += arr[i] + "/";
|
||||
if (!Exists(root)) {
|
||||
::CreateDirectoryW(root.unicode().c_str(), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Exists(path);
|
||||
}
|
||||
void Copy(const UIString& srcPath, const UIString& desPath)
|
||||
{
|
||||
UIString basePath = srcPath;
|
||||
Path::Format(&basePath);
|
||||
std::vector<FileInfo> result;
|
||||
Directory::Find(srcPath, &result);
|
||||
for (auto& it : result) {
|
||||
auto fileName = it.Name;
|
||||
fileName = fileName.replace(basePath, "");
|
||||
if (it.IsDirectory()) {
|
||||
Directory::Create(desPath + "/" + fileName);
|
||||
}
|
||||
else {
|
||||
File::Copy(it.Name, desPath + "/" + fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Find(const UIString& directory, std::vector<FileInfo>* result, const UIString& pattern, bool loopDir)
|
||||
{
|
||||
__Find(directory.unicode(), result, pattern.unicode(), loopDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
demo/ResPackage/FileSystem.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include "EzUI/EzUI.h"
|
||||
#include "EzUI/UIString.h"
|
||||
namespace ezui {
|
||||
struct FileInfo final {
|
||||
UIString Name;
|
||||
DWORD Attr;
|
||||
bool IsDirectory() {
|
||||
return (Attr & FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
};
|
||||
namespace File {
|
||||
//判断文件是否存在
|
||||
UI_EXPORT bool Exists(const UIString& filenNme);
|
||||
//拷贝文件
|
||||
UI_EXPORT bool Copy(const UIString& src, const UIString& desc);
|
||||
//删除文件
|
||||
UI_EXPORT bool Delete(const UIString& file);
|
||||
//文件移动或者改名
|
||||
UI_EXPORT bool Move(const UIString& oldName, const UIString& newName);
|
||||
//创建一个文件(如果文件已存在则清空其内容)
|
||||
UI_EXPORT bool Create(const UIString& fileName);
|
||||
//将指定数据以二进制方式写入文件(如果文件存在内容则追加)
|
||||
UI_EXPORT bool Write(const char* fileData, size_t fileSize, const UIString& outFileName);
|
||||
//读取文件到内存中
|
||||
UI_EXPORT size_t Read(const UIString& fileName, std::string* data);
|
||||
}
|
||||
namespace Path {
|
||||
//格式化路径
|
||||
UI_EXPORT void Format(std::string* str);
|
||||
//获取文件名(不包括目录名 不包括扩展名)
|
||||
UI_EXPORT UIString GetFileNameWithoutExtension(const UIString& _filename);
|
||||
//获取文件所在目录
|
||||
UI_EXPORT UIString GetDirectoryName(const UIString& _filename);
|
||||
//获取文件扩展名
|
||||
UI_EXPORT UIString GetExtension(const UIString& _filename);
|
||||
//获取文件名(文件名+扩展名)
|
||||
UI_EXPORT UIString GetFileName(const UIString& filename);
|
||||
}
|
||||
namespace Directory {
|
||||
//检测目录是否存在
|
||||
UI_EXPORT bool Exists(const UIString& directoryNme);
|
||||
//创建目录 不存在的多级目录将会自动创建
|
||||
UI_EXPORT bool Create(const UIString& path);
|
||||
//将目录和目录下的文件复制到指定的位置
|
||||
UI_EXPORT void Copy(const UIString& srcPath, const UIString& desPath);
|
||||
//使用通配符搜索文件和目录
|
||||
UI_EXPORT void Find(const UIString& directory, std::vector<FileInfo>* result, const UIString& pattern = "*.*", bool loopDir = true);
|
||||
}
|
||||
};
|
||||
42
demo/ResPackage/main.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "mainFrom.h"
|
||||
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
|
||||
_In_opt_ HINSTANCE hPrevInstance,
|
||||
_In_ LPWSTR lpCmdLine,
|
||||
_In_ int nCmdShow)
|
||||
{
|
||||
|
||||
//格式化命令行参数
|
||||
int argc = 0;
|
||||
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
std::vector<UIString> args;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
args.emplace_back(argv[i]);
|
||||
}
|
||||
LocalFree(argv);
|
||||
|
||||
// 查找 "-package" 参数
|
||||
auto it = std::find(args.begin(), args.end(), L"-package");
|
||||
if (it != args.end()) {
|
||||
size_t index = std::distance(args.begin(), it);
|
||||
UIString packageDir = args[index + 1];
|
||||
UIString outFile = args[index + 2];
|
||||
|
||||
UIString log = UIString("packaging... %s -> %s \n").format(packageDir.c_str(), outFile.c_str()).ansi();
|
||||
printf(log.c_str());
|
||||
bool bRet = Resource::Package(packageDir, outFile);
|
||||
if (bRet) {
|
||||
printf("package succeeded !");
|
||||
}
|
||||
else {
|
||||
printf("package failed !");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Application app;
|
||||
app.EnableHighDpi();
|
||||
MainFrm frm(lpCmdLine);
|
||||
frm.Show();
|
||||
|
||||
return app.Exec();
|
||||
};
|
||||
88
demo/ResPackage/main.html
Normal file
@@ -0,0 +1,88 @@
|
||||
<vbox id="main">
|
||||
<hbox height="40">
|
||||
<radiobutton class="btnTab" tablayout="tab" checked="true" text="打包" width="100"></radiobutton>
|
||||
<radiobutton class="btnTab" tablayout="tab" text="解包" width="100"></radiobutton>
|
||||
</hbox>
|
||||
<tablayout id="tab">
|
||||
<hbox id="page1">
|
||||
<spacer width="10"></spacer>
|
||||
<vbox>
|
||||
<spacer height="10"></spacer>
|
||||
<label height="30" halign="left" text="请选择你要打包的目录 :"></label>
|
||||
<hbox height="30"> <textbox class="edit" id="editPackDir"></textbox> <spacer width="10"></spacer><button class="btn" id="btnBrowserDir" width="100" text="浏览"></button> </hbox>
|
||||
<label halign="left" style="color:#ff0000" id="labelTipsErr" height="20"></label>
|
||||
<spacer></spacer>
|
||||
<label height="30" halign="left" text="请选择输出目录 :"></label>
|
||||
<hbox height="30"> <textbox class="edit" id="editPackName"></textbox> <spacer width="10"></spacer><button class="btn" id="btnSatrtPackage" width="100" text="开始打包"></button> </hbox>
|
||||
<spacer></spacer>
|
||||
<!-- <hbox height="30"> <spacer></spacer> <button class="btn" id="btnSatrtPackage" width="100" text="开始"></button> <spacer></spacer></hbox>-->
|
||||
<spacer height="10"></spacer>
|
||||
</vbox>
|
||||
<spacer width="10"></spacer>
|
||||
</hbox>
|
||||
|
||||
<hbox id="page2">
|
||||
<spacer width="10"></spacer>
|
||||
<vbox>
|
||||
<spacer height="10"></spacer>
|
||||
<label height="30" halign="left" text="请选择你要预览的文件 :"></label>
|
||||
<hbox height="30"> <textbox class="edit" readonly="true" id="editResFile"></textbox> <spacer width="10"></spacer><button class="btn" id="btnBrowserFile" width="100" text="浏览"></button><spacer width="10"></spacer><button class="btn" height="30" id="btnUnPackage" width="100" text="解压至..."></button> </hbox>
|
||||
<spacer height="10"></spacer>
|
||||
<vlist id="listFiles" scrollbar="fileScrollbar" style="background-color:rgba(175, 106, 106, 0.5)"></vlist>
|
||||
</vbox>
|
||||
<spacer width="10"></spacer>
|
||||
</hbox>
|
||||
|
||||
</tablayout>
|
||||
|
||||
<hbox margin="0,10" height="30">
|
||||
<label id="labelTips" text="技术支持 718987717@qq.com/19980103ly@gmail.com"></label>
|
||||
</hbox>
|
||||
|
||||
</vbox>
|
||||
|
||||
<style>
|
||||
.btn {
|
||||
border-radius: 5;
|
||||
border: 1;
|
||||
border-color: #D0D0D0;
|
||||
background-color: #FDFDFD;
|
||||
font-size: 13;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: #0078D4;
|
||||
background-color: #E0EEF9;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
font-size: 14;
|
||||
}
|
||||
|
||||
.edit {
|
||||
border: 1;
|
||||
border-radius: 2;
|
||||
border-color: #808080;
|
||||
}
|
||||
|
||||
#tab {
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
|
||||
.btnTab:checked {
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
|
||||
.btnTab:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#fileScrollbar {
|
||||
border-radius: 5;
|
||||
background-color: rgba(50,50,50,0.5);
|
||||
fore-color: rgba(200,200,200,0.5);
|
||||
}
|
||||
#fileScrollbar:active {
|
||||
fore-color: rgba(200,200,200,0.8);
|
||||
}
|
||||
</style>
|
||||
311
demo/ResPackage/mainFrom.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
#include "mainFrom.h"
|
||||
#include "FileSystem.h"
|
||||
|
||||
const wchar_t* xml = LR"xml(
|
||||
<vbox id="main">
|
||||
<hbox height="40">
|
||||
<radiobutton class="btnTab" tablayout="tab" checked="true" text="打包" width="100"></radiobutton>
|
||||
<radiobutton class="btnTab" tablayout="tab" text="解包" width="100"></radiobutton>
|
||||
</hbox>
|
||||
<tablayout id="tab">
|
||||
<hbox id="page1">
|
||||
<spacer width="10"></spacer>
|
||||
<vbox>
|
||||
<spacer height="10"></spacer>
|
||||
<label height="30" halign="left" text="请选择你要打包的目录 :"></label>
|
||||
<hbox height="30">
|
||||
<textbox class="edit" id="editPackDir"></textbox>
|
||||
<spacer width="10"></spacer>
|
||||
<button class="btn" id="btnBrowserDir" width="100" text="浏览"></button>
|
||||
</hbox>
|
||||
<label halign="left" style="color:#ff0000" id="labelTipsErr" height="20"></label>
|
||||
<spacer></spacer>
|
||||
<label height="30" halign="left" text="请选择输出目录 :"></label>
|
||||
<hbox height="30">
|
||||
<textbox class="edit" id="editPackName"></textbox>
|
||||
<spacer width="10"></spacer>
|
||||
<button class="btn" id="btnSatrtPackage" width="100" text="开始打包"></button>
|
||||
</hbox>
|
||||
<spacer></spacer>
|
||||
<spacer height="10"></spacer>
|
||||
</vbox>
|
||||
<spacer width="10"></spacer>
|
||||
</hbox>
|
||||
<hbox id="page2">
|
||||
<spacer width="10"></spacer>
|
||||
<vbox>
|
||||
<spacer height="10"></spacer>
|
||||
<label height="30" halign="left" text="请选择你要预览的文件 :"></label>
|
||||
<hbox height="30">
|
||||
<textbox class="edit" readonly="true" id="editResFile"></textbox>
|
||||
<spacer width="10"></spacer>
|
||||
<button class="btn" id="btnBrowserFile" width="100" text="浏览"></button>
|
||||
<spacer width="10"></spacer>
|
||||
<button class="btn" height="30" id="btnUnPackage" width="100" text="解压至..."></button>
|
||||
</hbox>
|
||||
<spacer height="10"></spacer>
|
||||
<vlist id="listFiles" scrollbar="fileScrollbar" style="background-color:rgba(175, 106, 106, 0.5)"></vlist>
|
||||
</vbox>
|
||||
<spacer width="10"></spacer>
|
||||
</hbox>
|
||||
</tablayout>
|
||||
<hbox margin="0,10" height="30">
|
||||
<label id="labelTips" text="技术支持 718987717@qq.com/19980103ly@gmail.com"></label>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<style>
|
||||
.btn {
|
||||
border-radius: 5px;
|
||||
border: 1px #D0D0D0 solid;
|
||||
background-color: #FDFDFD;
|
||||
font-size: 13px;
|
||||
}
|
||||
.btn:hover {
|
||||
border-color: #0078D4;
|
||||
background-color: #E0EEF9;
|
||||
}
|
||||
.btn:active {
|
||||
font-size: 14px;
|
||||
}
|
||||
.edit {
|
||||
border: 1px #808080 solid;
|
||||
border-radius: 2px;
|
||||
}
|
||||
#tab {
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
.btnTab:checked {
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
.btnTab:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
#fileScrollbar {
|
||||
border-radius: 5px;
|
||||
background-color: rgba(50,50,50,0.5);
|
||||
fore-color: rgba(200,200,200,0.5);
|
||||
}
|
||||
#fileScrollbar:active {
|
||||
fore-color: rgba(200,200,200,0.8);
|
||||
}
|
||||
</style>
|
||||
)xml";
|
||||
|
||||
void MainFrm::Init() {
|
||||
this->SetText(L"EzUI资源打包器");
|
||||
//ui.LoadXmlFile("main.html");
|
||||
UIString xmlData = xml;
|
||||
ui.LoadXml(xmlData.c_str(), xmlData.size());
|
||||
ui.SetupUI(this);
|
||||
//第一页的控件
|
||||
this->tab = (TabLayout*)this->FindControl("tab");
|
||||
this->editPackDir = (TextBox*)this->FindControl("editPackDir");
|
||||
this->editPackName = (TextBox*)this->FindControl("editPackName");
|
||||
this->btnSatrtPackage = (Button*)this->FindControl("btnSatrtPackage");
|
||||
this->labelTipsErr = (Label*)this->FindControl("labelTipsErr");
|
||||
this->labelTips = (Label*)this->FindControl("labelTips");
|
||||
this->editPackDir->TextChanged = [=](const UIString text)->void {
|
||||
this->OnPackDirChange();
|
||||
};
|
||||
|
||||
//第二页的控件
|
||||
this->editResFile = (TextBox*)this->FindControl("editResFile");
|
||||
this->btnBrowserFile = (Button*)this->FindControl("btnBrowserFile");
|
||||
this->listFiles = (VListView*)this->FindControl("listFiles");
|
||||
this->btnUnPackage = (Button*)this->FindControl("btnUnPackage");
|
||||
}
|
||||
|
||||
MainFrm::MainFrm(const UIString& cmdLine) :Window(600, 400) {
|
||||
Init();
|
||||
editPackDir->SetText(cmdLine);
|
||||
OnPackDirChange();
|
||||
}
|
||||
|
||||
void MainFrm::OnPackDirChange()
|
||||
{
|
||||
UIString dir = editPackDir->GetText();
|
||||
if (dir.empty() || !PathExist(dir)) {
|
||||
editPackName->SetText("");
|
||||
editPackName->Invalidate();
|
||||
labelTipsErr->SetText(L"打包目录无效!");
|
||||
labelTipsErr->Invalidate();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
labelTipsErr->SetText("");
|
||||
labelTipsErr->Invalidate();
|
||||
}
|
||||
|
||||
ui_text::Replace(&dir, "\"", "");
|
||||
ui_text::Replace(&dir, "\\", "/");
|
||||
ui_text::Replace(&dir, "//", "/");
|
||||
if (dir[dir.size() - 1] == '/') {
|
||||
dir.erase(dir.size() - 1, 1);
|
||||
}
|
||||
UIString resDir = dir;
|
||||
UIString rootDir;
|
||||
size_t pos = dir.rfind('/');
|
||||
UIString dirName;
|
||||
if (pos != size_t(-1)) {
|
||||
rootDir = dir.substr(0, pos);
|
||||
dirName = dir.substr(pos + 1);
|
||||
}
|
||||
UIString resFile = rootDir + "/" + dirName + ".bin";
|
||||
editPackName->SetText(resFile);
|
||||
editPackName->Invalidate();
|
||||
}
|
||||
void MainFrm::OnClose(bool& close) {
|
||||
Application::Exit(0);
|
||||
}
|
||||
bool MainFrm::FileExists(const UIString& fileName) {
|
||||
DWORD dwAttr = GetFileAttributesW(fileName.unicode().c_str());
|
||||
if (dwAttr == DWORD(-1)) {
|
||||
return false;
|
||||
}
|
||||
if (dwAttr & FILE_ATTRIBUTE_ARCHIVE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void MainFrm::OnNotify(Control* sd, EventArgs& args) {
|
||||
if (args.EventType == Event::OnMouseDown) {
|
||||
if (sd->Name == "btnBrowserDir") {
|
||||
UIString dir = ShowFolderDialog(Hwnd(), "", "");
|
||||
if (!dir.empty()) {
|
||||
this->editPackDir->SetText(dir);
|
||||
this->editPackDir->Invalidate();
|
||||
this->OnPackDirChange();
|
||||
}
|
||||
}
|
||||
if (sd->Name == "btnSatrtPackage") {
|
||||
do
|
||||
{
|
||||
UIString resDir = editPackDir->GetText();
|
||||
UIString resFile = editPackName->GetText();
|
||||
|
||||
if (task && !task->IsStopped()) {
|
||||
::MessageBoxW(Hwnd(), L"请等待上次任务完成!", L"失败", 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (FileExists(resFile) && ::DeleteFileW(resFile.unicode().c_str()) == FALSE) {
|
||||
::MessageBoxW(Hwnd(), L"文件已存在且无法覆盖!", L"失败", 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (task) {
|
||||
delete task;
|
||||
task = NULL;
|
||||
}
|
||||
|
||||
if (resFile.empty()) {
|
||||
::MessageBoxW(Hwnd(), L"打包文件路径不正确!", L"失败", 0);
|
||||
break;
|
||||
}
|
||||
|
||||
labelTips->SetText(L"正在计算...");
|
||||
labelTips->Invalidate();
|
||||
|
||||
task = new Task([resDir, resFile, this]() {
|
||||
Resource::Package(resDir, resFile, [=](const UIString& file, int index, int count) {
|
||||
Invoke([&]() {
|
||||
int rate = (index + 1) * 1.0f / count * 100 + 0.5;
|
||||
labelTips->SetText(UIString("(" + std::to_string(rate) + "%)") + UIString(L"正在打包\"") + file + "\"");
|
||||
labelTips->Invalidate();
|
||||
});
|
||||
Sleep(2);
|
||||
});
|
||||
|
||||
Invoke([&]() {
|
||||
labelTips->SetText(L"打包成功!");
|
||||
labelTips->Invalidate();
|
||||
::MessageBoxW(Hwnd(), L"打包成功!", L"成功", 0);
|
||||
});
|
||||
});
|
||||
|
||||
} while (false);
|
||||
}
|
||||
if (sd->Name == "btnBrowserFile") {
|
||||
UIString resFile = ShowFileDialog(Hwnd());
|
||||
OnResFileChange(resFile);
|
||||
}
|
||||
if (sd->Name == "btnUnPackage") {
|
||||
UIString resDir = ShowFolderDialog(Hwnd());
|
||||
if (!resDir.empty() && PathExist(resDir)) {
|
||||
for (auto& it : this->res->Items) {
|
||||
UIString fileName = resDir + "/" + it.Name;
|
||||
UIString dir = Path::GetDirectoryName(fileName);
|
||||
Directory::Create(dir);
|
||||
File::Delete(fileName);
|
||||
UIString data;
|
||||
this->res->GetFile(it, &data);
|
||||
File::Write(data.c_str(), data.size(), fileName);
|
||||
}
|
||||
::MessageBoxW(Hwnd(), L"解压完成!", L"", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
ezui::DefaultNotify(sd, args);
|
||||
}
|
||||
void MainFrm::OnResFileChange(UIString& resFile)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (FileExists(resFile)) {
|
||||
Resource* newRes = new Resource(resFile);
|
||||
if (!newRes->IsGood()) {
|
||||
::MessageBoxW(Hwnd(), L"不是标准的资源文件", L"错误", 0);
|
||||
delete newRes;
|
||||
break;
|
||||
}
|
||||
if (res) {
|
||||
delete res;
|
||||
res = NULL;
|
||||
}
|
||||
res = newRes;
|
||||
|
||||
listFiles->Clear(true);
|
||||
for (auto& item : res->Items) {
|
||||
FileItem* fileItem = new FileItem(item.Name, item.Size);
|
||||
listFiles->Add(fileItem);
|
||||
}
|
||||
listFiles->Invalidate();
|
||||
this->editResFile->SetText(resFile);
|
||||
this->editResFile->Invalidate();
|
||||
}
|
||||
} while (false);
|
||||
}
|
||||
LRESULT MainFrm::WndProc(UINT msg, WPARAM wp, LPARAM lp) {
|
||||
//准备做一个解压的功能
|
||||
if (msg == WM_DROPFILES) {
|
||||
HDROP hDrop = (HDROP)wp;
|
||||
UINT numFiles = ::DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); // 获取拖入的文件数量
|
||||
TCHAR szFilePath[MAX_PATH]{ 0 };
|
||||
::DragQueryFileW(hDrop, 0, szFilePath, sizeof(szFilePath)); // 获取第一个文件路径
|
||||
UIString file = szFilePath;
|
||||
|
||||
if (tab->GetPageIndex() == 0) {
|
||||
//打包
|
||||
if (PathExist(file)) {
|
||||
this->editPackDir->SetText(file);
|
||||
this->editPackDir->Invalidate();
|
||||
this->OnPackDirChange();
|
||||
}
|
||||
}
|
||||
else if (tab->GetPageIndex() == 1) {
|
||||
//解包
|
||||
if (FileExists(file)) {
|
||||
this->OnResFileChange(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return __super::WndProc(msg, wp, lp);
|
||||
}
|
||||
MainFrm::~MainFrm() {
|
||||
if (task) {
|
||||
delete task;
|
||||
}
|
||||
if (res) {
|
||||
delete res;
|
||||
}
|
||||
}
|
||||
189
demo/ResPackage/mainFrom.h
Normal file
@@ -0,0 +1,189 @@
|
||||
#include "EzUI/Application.h"
|
||||
#include "EzUI/VLayout.h"
|
||||
#include "EzUI/TextBox.h"
|
||||
#include "EzUI/Button.h"
|
||||
#include "EzUI/Window.h"
|
||||
#include "EzUI/Resource.h"
|
||||
#include "EzUI/Task.h"
|
||||
#include "EzUI/HLayout.h"
|
||||
#include "EzUI/UIManager.h"
|
||||
using namespace ezui;
|
||||
|
||||
class MainFrm :public Window {
|
||||
Task* task = NULL;
|
||||
UIManager ui;
|
||||
//选项卡
|
||||
TabLayout* tab;
|
||||
|
||||
//第一页的控件
|
||||
//要打包的目录
|
||||
TextBox* editPackDir;
|
||||
//打包之后要输出的文件名
|
||||
TextBox* editPackName;
|
||||
//开始打包的按钮
|
||||
Button* btnSatrtPackage;
|
||||
//提示文本
|
||||
Label* labelTips;
|
||||
Label* labelTipsErr;
|
||||
|
||||
//第二页的控件
|
||||
TextBox* editResFile;
|
||||
Button* btnBrowserFile;
|
||||
VListView* listFiles;
|
||||
Button* btnUnPackage;
|
||||
|
||||
//资源指针
|
||||
Resource* res = NULL;
|
||||
public:
|
||||
void Init();
|
||||
MainFrm(const UIString& cmdLine);
|
||||
void OnPackDirChange();
|
||||
void OnClose(bool& close) override;
|
||||
bool FileExists(const UIString& fileName);
|
||||
void OnNotify(Control* sender, EventArgs& args)override;
|
||||
void OnResFileChange(UIString& resFile);
|
||||
virtual LRESULT WndProc(UINT msg, WPARAM wp, LPARAM lp);
|
||||
virtual ~MainFrm();
|
||||
};
|
||||
|
||||
inline bool FileExists(const UIString& filename) {
|
||||
DWORD dwAttr = GetFileAttributesW(filename.unicode().c_str());
|
||||
if (dwAttr == DWORD(-1)) {
|
||||
return false;
|
||||
}
|
||||
if (dwAttr & FILE_ATTRIBUTE_ARCHIVE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
inline bool PathExist(const UIString& dir) {
|
||||
DWORD dwAttr = GetFileAttributesW(dir.unicode().c_str());
|
||||
if (dwAttr == DWORD(-1)) {
|
||||
return false;
|
||||
}
|
||||
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline bool CreatePath(const UIString& path) {
|
||||
::CreateDirectoryW(path.unicode().c_str(), NULL);
|
||||
if (PathExist(path)) {
|
||||
return true;
|
||||
}
|
||||
//创建多级目录
|
||||
if (path.find(":") != size_t(-1)) {
|
||||
UIString dir = path + "/";
|
||||
dir = dir.replace("\\", "/");
|
||||
dir = dir.replace("//", "/");
|
||||
auto arr = dir.split("/");
|
||||
UIString root;
|
||||
if (arr.size() > 0) {
|
||||
root += arr[0] + "/";
|
||||
for (size_t i = 1; i < arr.size(); i++)
|
||||
{
|
||||
if (arr[i].empty()) {
|
||||
continue;
|
||||
}
|
||||
root += arr[i] + "/";
|
||||
if (!PathExist(root)) {
|
||||
::CreateDirectoryW(root.unicode().c_str(), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PathExist(path);
|
||||
}
|
||||
|
||||
inline UIString ShowFileDialog(HWND ownerWnd, const UIString& defaultPath = "", const UIString& title = "") {
|
||||
OPENFILENAMEW ofn; // 打开文件对话框结构体
|
||||
WCHAR szFile[512]{ 0 }; // 选择的文件名
|
||||
// 初始化OPENFILENAME结构体
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.lpstrFile[0] = '\0';
|
||||
ofn.hwndOwner = ownerWnd;
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrFilter = L"All Files\0*.*\0";
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
||||
// 显示文件对话框
|
||||
if (GetOpenFileNameW(&ofn) == TRUE) {
|
||||
return szFile;
|
||||
}
|
||||
return szFile;
|
||||
}
|
||||
#include <ShlObj.h>
|
||||
inline UIString ShowFolderDialog(HWND ownerWnd, const UIString& defaultPath = "", const UIString& title = "") {
|
||||
WCHAR selectedPath[MAX_PATH]{ 0 };
|
||||
BROWSEINFOW browseInfo{ 0 };
|
||||
browseInfo.hwndOwner = ownerWnd;
|
||||
browseInfo.pszDisplayName = selectedPath;
|
||||
auto wTitle = title.unicode();
|
||||
browseInfo.lpszTitle = wTitle.c_str();
|
||||
//设置根目录
|
||||
LPITEMIDLIST pidlRoot;
|
||||
::SHParseDisplayName(defaultPath.unicode().c_str(), NULL, &pidlRoot, 0, NULL);
|
||||
browseInfo.pidlRoot = pidlRoot;
|
||||
browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
|
||||
LPITEMIDLIST itemIdList = SHBrowseForFolderW(&browseInfo);
|
||||
if (itemIdList != nullptr) {
|
||||
SHGetPathFromIDListW(itemIdList, selectedPath);//设置路径
|
||||
CoTaskMemFree(itemIdList);//清理
|
||||
return selectedPath;
|
||||
}
|
||||
return selectedPath;
|
||||
}
|
||||
inline std::string GetFileSize(__int64 _KEY_FILE_SIZE) {
|
||||
std::string ext;
|
||||
std::string disp_size;
|
||||
long double KEY_FILE_SIZE = _KEY_FILE_SIZE;
|
||||
if (KEY_FILE_SIZE > 1024) {
|
||||
KEY_FILE_SIZE = KEY_FILE_SIZE / 1024.0f; // kb
|
||||
ext = "KB";
|
||||
if (KEY_FILE_SIZE > 1024) {
|
||||
KEY_FILE_SIZE = KEY_FILE_SIZE / 1024.0f; // mb
|
||||
ext = "MB";
|
||||
if (KEY_FILE_SIZE > 1024) {
|
||||
KEY_FILE_SIZE = KEY_FILE_SIZE / 1024.0f; // gb
|
||||
ext = "GB";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ext = "BT";
|
||||
}
|
||||
disp_size = ui_text::ToString(KEY_FILE_SIZE, 2) + " " + ext;
|
||||
return disp_size;
|
||||
}
|
||||
|
||||
class FileItem :public HBox {
|
||||
Label name;
|
||||
Label size;
|
||||
public:
|
||||
FileItem(const UIString& fileName, size_t fileSize) {
|
||||
this->SetFixedHeight(25);
|
||||
this->SetDockStyle(DockStyle::Horizontal);
|
||||
|
||||
name.TextAlign = TextAlign::MiddleLeft;
|
||||
name.SetText(" " + fileName);
|
||||
name.SetElidedText("...");
|
||||
this->Add(&name);
|
||||
|
||||
size.SetFixedWidth(100);
|
||||
size.SetText(GetFileSize(fileSize));
|
||||
this->Add(&size);
|
||||
|
||||
name.SetHitTestVisible(false);
|
||||
|
||||
this->HoverStyle.BackColor = Color(100, 100, 100, 50);
|
||||
this->Style.FontSize = 13;
|
||||
this->ActiveStyle.FontSize = 14;
|
||||
}
|
||||
};
|
||||
188
demo/helloWorld/main.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
//WIN32 desktop application UI framework (2d graphical library:direct2d,后期可能会采用其他跨平台的2d图形库对整个UI框架进行跨平台)
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include "EzUI/EzUI.h"
|
||||
#include "EzUI/BorderlessWindow.h"
|
||||
#include "EzUI/Button.h"
|
||||
#include "EzUI/TileListView.h"
|
||||
#include "EzUI/VListView.h"
|
||||
#include "EzUI/HListView.h"
|
||||
#include "EzUI/HLayout.h"
|
||||
#include "EzUI/VLayout.h"
|
||||
#include "EzUI/Application.h"
|
||||
#include "EzUI/TextBox.h"
|
||||
#include "EzUI/ComBoBox.h"
|
||||
#include "EzUI/CheckBox.h"
|
||||
#include "EzUI/radiobutton.h"
|
||||
#include "EzUI/TreeView.h"
|
||||
|
||||
using namespace ezui;
|
||||
class MainFrm :public Window {
|
||||
public:
|
||||
HLayout* main;
|
||||
MainFrm(int cx, int cy) :Window(cx, cy) {
|
||||
|
||||
//以下代码专用与测试释放托管问题
|
||||
|
||||
main = new HLayout;
|
||||
|
||||
for (size_t i = 1; i <= 3; i++)
|
||||
{
|
||||
auto ck = new RadioButton(this);
|
||||
ck->CheckedStyle.Border.Bottom = 10;
|
||||
ck->CheckedStyle.Border.Style = StrokeStyle::Solid;
|
||||
ck->CheckedStyle.Border.Color = Color::Red;
|
||||
ck->CheckedStyle.BackImage = Image::Make("headImg.jpg");
|
||||
ck->SetText("aaa" + std::to_string(i));
|
||||
|
||||
main->Add(ck);
|
||||
}
|
||||
|
||||
SetLayout(main);
|
||||
}
|
||||
|
||||
virtual ~MainFrm() {
|
||||
delete main;
|
||||
}
|
||||
void OnClose(bool& b) {
|
||||
if (this->GetText() == "modal") {
|
||||
//Application::Exit(0);
|
||||
}
|
||||
else {
|
||||
Application::Exit(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
Application app;//消息循环对象
|
||||
app.EnableHighDpi();
|
||||
//{
|
||||
// MainFrm frm(800, 600);//无边框窗口
|
||||
// frm.Show();
|
||||
// return app.Exec();
|
||||
//}
|
||||
|
||||
MainFrm frm(800, 600);//无边框窗口
|
||||
VLayout mainLayout;//窗口中的main布局
|
||||
|
||||
mainLayout.Style.BackColor = Color::White;//主布局背景颜色
|
||||
//HLayout title(&mainLayout);//标题
|
||||
//title.SetFixedHeight(45);//设置固定高度
|
||||
//title.Style.BackgroundColor = Color::Pink;//控件背景颜色
|
||||
//title.Action = ControlAction::MoveWindow;//可移动窗口的行为
|
||||
|
||||
//Label text(&title);//标题文字
|
||||
//text.Action = ControlAction::MoveWindow;//可移动窗口的行为
|
||||
//text.SetText(L"hello world ");//给label设置文字
|
||||
|
||||
Label closeBtn;//关闭按钮
|
||||
|
||||
closeBtn.Action = ControlAction::Close;//关闭窗口的行为
|
||||
|
||||
closeBtn.Style.FontFamily = L"Marlett";//设置成icon字体
|
||||
|
||||
closeBtn.Style.FontSize = 13;//字体大小
|
||||
|
||||
closeBtn.HoverStyle.ForeColor = Color::White;//伪样式 鼠标悬浮字体颜色变成白色
|
||||
|
||||
closeBtn.SetFixedWidth(45);//设置绝对高度
|
||||
|
||||
closeBtn.SetText(L"r");//窗口的关闭按钮icon
|
||||
|
||||
//Label labelBottom;
|
||||
//labelBottom.SetText(L"这是一个简单的窗口示例!");
|
||||
HListView list;
|
||||
list.SetParent(&mainLayout);
|
||||
//list.SetAutoHeight(true);
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
{
|
||||
Label* lb = new Label;// (&list);
|
||||
//lb->Dock = DockStyle::Horizontal;
|
||||
lb->SetText(std::to_string(i));
|
||||
lb->Name = std::to_string(i);
|
||||
lb->SetFixedSize({ 100,30 });
|
||||
lb->Style.BackColor = Color::LightGray;
|
||||
lb->HoverStyle.BackColor = Color::Red;
|
||||
lb->Margin = 1;
|
||||
lb->EventHandler = [&list](Control* sd, const EventArgs& arg)->void {
|
||||
if (arg.EventType == Event::OnMouseDown) {
|
||||
/*list.Remove(sd);
|
||||
list.Invalidate();*/
|
||||
MainFrm frm(500, 300);//无边框窗口
|
||||
frm.SetText("modal");
|
||||
VLayout mainLayout;//窗口中的main布局
|
||||
mainLayout.Style.BackColor = Color::White;//主布局背景颜色
|
||||
frm.SetLayout(&mainLayout);
|
||||
frm.ShowModal();
|
||||
}
|
||||
};
|
||||
list.Add(lb);
|
||||
}
|
||||
|
||||
ComboBox cbox;
|
||||
cbox.Style.Border = 1;
|
||||
cbox.Style.Border.Color = Color::Gray;
|
||||
cbox.Style.Border.Style = StrokeStyle::Solid;
|
||||
|
||||
cbox.SetFixedSize({ 100,30 });
|
||||
cbox.SetParent(&mainLayout);
|
||||
cbox.AddItem(L"-请选择-");
|
||||
cbox.AddItem(L"青菜");
|
||||
cbox.AddItem(L"牛肉");
|
||||
cbox.AddItem(L"猪肉");
|
||||
cbox.SetCheck(0);
|
||||
|
||||
|
||||
TreeView treeView;
|
||||
mainLayout.Add(&treeView);
|
||||
for (size_t i = 0; i < 20; i++)
|
||||
{
|
||||
treeView.AddNode("nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_nodeName_"+std::to_string(i));
|
||||
}
|
||||
|
||||
|
||||
TextBox text;
|
||||
text.SetParent(&mainLayout);
|
||||
//text.SetFixedSize({ 100,50 });
|
||||
text.Style.Border.Color = Color::Gray;
|
||||
text.Style.Border = 1;
|
||||
text.SetMultiLine(true);
|
||||
text.Margin.Left = 20;
|
||||
text.Margin.Right = 20;
|
||||
//text.Style.Border.Radius = 20;
|
||||
|
||||
text.SetText(L"啊撒旦艰苦换个房间看电视进\n口的方电视进\n口的方电视进\n口的方电视进\n口的方电视进\n口的方电视进\n口的方电视进\n口的方电视进\n口的方电视进\n口的方式但是几乎都是复活节过段时间韩国");
|
||||
//text.HoverStyle.FontSize = 50;
|
||||
//text.ActiveStyle.FontSize = 50;
|
||||
text.GetScrollBar()->SetFixedWidth(20);
|
||||
|
||||
Button btn;
|
||||
btn.SetParent(&mainLayout);
|
||||
btn.SetText(L"单行/多行切换");
|
||||
btn.SetFixedSize({ 150,40 });
|
||||
btn.EventHandler = [&text](Control* sd, const EventArgs& arg)->void {
|
||||
if (arg.EventType == Event::OnMouseDown) {
|
||||
text.SetMultiLine(!text.IsMultiLine());
|
||||
text.Invalidate();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*for (size_t i = 0; i < 99999; i++)
|
||||
{
|
||||
Button* lb = new Button(&list);
|
||||
lb->SetText("button" + std::to_string(i));
|
||||
lb->SetFixedSize({ 50,30 });
|
||||
}*/
|
||||
|
||||
//mainLayout.AddControl(&labelBottom);//添加控件
|
||||
|
||||
frm.SetLayout(&mainLayout);//给窗口设置布局
|
||||
|
||||
frm.Show();//显示窗口
|
||||
return app.Exec();//进行消息循环
|
||||
|
||||
}
|
||||
BIN
demo/kugou/7-zip.dll
Normal file
BIN
demo/kugou/7z.dll
Normal file
BIN
demo/kugou/7z.exe
Normal file
59
demo/kugou/DesktopLrcFrm.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "desktopLrcFrm.h"
|
||||
|
||||
HWND GetDeskTopWnd() {
|
||||
HWND windowHandle = ::FindWindowW(L"Progman", L"Program Manager");
|
||||
::SendMessageW(windowHandle, 0x052c, 0, 0);
|
||||
::EnumWindows([](HWND tophandle, LPARAM lParam)->BOOL {
|
||||
HWND defview = ::FindWindowExW(tophandle, 0, L"SHELLDLL_DefView", NULL);
|
||||
if (defview != NULL)
|
||||
{
|
||||
HWND workerw = ::FindWindowExW(0, tophandle, L"WorkerW", 0);
|
||||
if (workerw == NULL) {
|
||||
workerw = ::FindWindowExW(tophandle, 0, L"WorkerW", 0);
|
||||
*((HWND*)lParam) = workerw;
|
||||
::ShowWindow(workerw, SW_SHOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
::ShowWindow(workerw, SW_HIDE);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}, (LPARAM)&windowHandle);
|
||||
return windowHandle;
|
||||
}
|
||||
|
||||
DesktopLrcFrm::DesktopLrcFrm(VlcPlayer* player) :_player(player), LayeredWindow(0, 0) {
|
||||
//关闭默认的窗口阴影
|
||||
this->CloseShadowBox();
|
||||
//获取桌面的窗口句柄
|
||||
HWND workWnd = GetDeskTopWnd();
|
||||
::SetParent(Hwnd(), workWnd);
|
||||
RECT workRect;
|
||||
::GetClientRect(workWnd, &workRect);
|
||||
::SetWindowPos(Hwnd(), NULL, workRect.left, workRect.top, workRect.left + workRect.right, workRect.top + workRect.bottom, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
//设置窗口布局
|
||||
_lrc.Style.FontSize = 20;
|
||||
_lrc.Style.ForeColor = Color::White;
|
||||
this->SetLayout(&_lrc);
|
||||
}
|
||||
void DesktopLrcFrm::LoadLrc(const UIString& lrcData) {
|
||||
_lrc.LoadLrc(lrcData);
|
||||
}
|
||||
|
||||
void DesktopLrcFrm::ChangePostion(int postion) {
|
||||
_lrc.ChangePostion(postion);
|
||||
}
|
||||
|
||||
void DesktopLrcFrm::OnPaint(PaintEventArgs& arg) {
|
||||
//绘制视频的帧图像到窗口上
|
||||
if (_player->BuffBitmap) {
|
||||
Image img(_player->BuffBitmap->GetHBITMAP());
|
||||
img.SizeMode = ImageSizeMode::Cover;
|
||||
arg.Graphics.DrawImage(&img, this->GetClientRect());
|
||||
arg.Graphics.SetColor(Color(0, 0, 0, 100));
|
||||
arg.Graphics.FillRectangle(this->GetClientRect());
|
||||
}
|
||||
__super::OnPaint(arg);
|
||||
}
|
||||
15
demo/kugou/DesktopLrcFrm.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "global.h"
|
||||
#include "lrcPanel.h"
|
||||
#include "VlcPlayer.h"
|
||||
|
||||
class DesktopLrcFrm :public LayeredWindow {
|
||||
private:
|
||||
VlcPlayer* _player;
|
||||
LrcPanel _lrc;
|
||||
protected:
|
||||
void OnPaint(PaintEventArgs& args)override;
|
||||
public:
|
||||
DesktopLrcFrm(VlcPlayer* player);
|
||||
void LoadLrc(const UIString& lrcData);
|
||||
void ChangePostion(int postion);
|
||||
};
|
||||
674
demo/kugou/MainFrm.cpp
Normal file
@@ -0,0 +1,674 @@
|
||||
#include "mainFrm.h"
|
||||
MainFrm::MainFrm() :Form(1020, 690)
|
||||
{
|
||||
InitForm();
|
||||
//托盘初始化
|
||||
ntfi.SetTips(L"酷苟音乐");
|
||||
ntfi.SetIcon(nullptr);//托盘图标
|
||||
|
||||
Menu* menu = new Menu(&ntfi);
|
||||
UINT_PTR id_open = menu->Append(L"打开主程序");
|
||||
UINT_PTR id_exit = menu->Append(L"退出");
|
||||
ntfi.SetMenu(menu);
|
||||
|
||||
menu->MouseClick = [=](UINT_PTR menuId) {
|
||||
if (menuId == id_open) {
|
||||
::ShowWindow(Hwnd(), SW_RESTORE);
|
||||
}
|
||||
if (menuId == id_exit) {
|
||||
Application::Exit();
|
||||
}
|
||||
};
|
||||
|
||||
//加载ico图标
|
||||
std::string fileData;
|
||||
HICON icon = ezui::LoadIcon("res/icon.ico");
|
||||
ntfi.SetIcon(icon);
|
||||
|
||||
ntfi.EventHandler = [=](const MouseEventArgs& args)->void {
|
||||
if (args.EventType == Event::OnMouseDoubleClick && args.Button == MouseButton::Left) {
|
||||
::ShowWindow(Hwnd(), SW_RESTORE);
|
||||
}
|
||||
};
|
||||
|
||||
this->SetMiniSize({ 800,600 });
|
||||
}
|
||||
void MainFrm::InitForm() {
|
||||
this->SetResizable(true);
|
||||
this->SetText(L"酷苟音乐");
|
||||
|
||||
this->LoadXml("res/xml/main.htm");
|
||||
|
||||
//找到三个Frame
|
||||
titleFrame = (IFrame*)this->FindControl("titleFrame");
|
||||
centerFrame = (IFrame*)this->FindControl("centerFrame");
|
||||
bottomFrame = (IFrame*)this->FindControl("bottomFrame");
|
||||
|
||||
//将这些Frame页的通知转到这个OnNotify中处理
|
||||
titleFrame->NotifyHandler = centerFrame->NotifyHandler = bottomFrame->NotifyHandler = [this](Control* sender, EventArgs& args)->void {
|
||||
this->OnNotify(sender, args);
|
||||
};
|
||||
|
||||
//设置窗口边框样式
|
||||
this->GetLayout()->Style.Border.Radius = 15;
|
||||
this->GetLayout()->Style.Border.Color = Color(128, 128, 128, 100);
|
||||
this->GetLayout()->Style.Border.Style = StrokeStyle::Solid;
|
||||
this->GetLayout()->Style.Border = 1;
|
||||
|
||||
//关闭阴影
|
||||
//this->CloseShadowBox();
|
||||
|
||||
//加载本地播放过的音乐
|
||||
listFile = new ConfigIni(Path::StartPath() + "\\list.ini");
|
||||
//找到每一个控件先
|
||||
mainLayout = this->FindControl("mainLayout");
|
||||
tools = centerFrame->FindControl("tools");
|
||||
centerLayout = centerFrame->FindControl("centerLayout");
|
||||
centerLeft = centerFrame->FindControl("centerLeft");
|
||||
mediaCtl = (TabLayout*)bottomFrame->FindControl("mediaCtl");
|
||||
labelTime = (Label*)bottomFrame->FindControl("labelTime");
|
||||
labelSinger = (Label*)bottomFrame->FindControl("labelSinger");
|
||||
playerBar2 = bottomFrame->FindControl("playerBar2");
|
||||
playerBar = bottomFrame->FindControl("playerBar");
|
||||
tabCtrl = (TabLayout*)centerFrame->FindControl("rightView");
|
||||
vlistLocal = (VListView*)centerFrame->FindControl("playList");
|
||||
vlistSearch = (VListView*)centerFrame->FindControl("searchList");
|
||||
editSearch = (TextBox*)titleFrame->FindControl("searchEdit");
|
||||
labelDeskLrc = (CheckBox*)bottomFrame->FindControl("deskLrc");
|
||||
|
||||
player.Name = "player";
|
||||
centerFrame->FindControl("vlcDock")->Add(&player);
|
||||
centerFrame->FindControl("lrcView2")->Add(&lrcPanel);//添加歌词控件
|
||||
|
||||
//创建桌面歌词视频窗口
|
||||
deskTopWnd = new DesktopLrcFrm(&player);
|
||||
|
||||
//给默认背景图片设置缩放属性
|
||||
if (mainLayout->Style.BackImage) {
|
||||
mainLayout->Style.BackImage->SizeMode = ImageSizeMode::Cover;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 1; i++)
|
||||
{
|
||||
//加载左侧播放过的音乐
|
||||
for (auto& item : listFile->GetSections()) {
|
||||
|
||||
listFile->SetSection(item);
|
||||
UIString name = listFile->ReadString("name");
|
||||
int dur = listFile->ReadInt("dur");
|
||||
UIString singer = listFile->ReadString("singer");
|
||||
LocalItem* it = new LocalItem(name, global::toTimeStr(dur));
|
||||
it->SetAttribute("FileHash", item);
|
||||
it->SetAttribute("SingerName", singer);
|
||||
it->SetTips(name);
|
||||
|
||||
Song s;
|
||||
s.SongName = listFile->ReadString("name");
|
||||
s.hash = item;
|
||||
s.Duration = listFile->ReadInt("dur");
|
||||
s.SingerName = listFile->ReadString("singer");
|
||||
|
||||
songLsit.push_back(s);
|
||||
vlistLocal->Add(it);
|
||||
}
|
||||
}
|
||||
|
||||
//滚动条滚动事件 滚动条滚动到底部加载剩余音乐
|
||||
vlistSearch->GetScrollBar()->Scroll = [=](ScrollBar* sb, float pos, Event type)->void {
|
||||
if (type == Event::OnMouseWheel) {
|
||||
NextPage(pos);
|
||||
}
|
||||
};
|
||||
//可穿透父控件
|
||||
playerBar2->SetHitTestVisible(false);
|
||||
//创建启动一个实时获取歌曲进度以及状态
|
||||
timer = new Timer;
|
||||
timer->Interval = 10;
|
||||
timer->Tick = [=](Timer*) {
|
||||
TimerTick();
|
||||
};
|
||||
//添加一些事件到窗口中的OnNotify函数
|
||||
player.NotifyFlags = player.NotifyFlags | Event::OnPaint;
|
||||
mainLayout->NotifyFlags = mainLayout->NotifyFlags | Event::OnPaint;
|
||||
//播放视频的时候每一帧的回调
|
||||
player.PlayingCallback = [&](Bitmap* bitmap)->void {
|
||||
BeginInvoke([&]() {
|
||||
this->Invalidate();
|
||||
if (deskTopWnd->IsVisible()) {
|
||||
this->deskTopWnd->GetLayout()->Style.BackImage = NULL;
|
||||
this->deskTopWnd->Invalidate();
|
||||
}
|
||||
});
|
||||
};
|
||||
//打开默认显示界面
|
||||
OpenSongView();
|
||||
}
|
||||
|
||||
void MainFrm::OnPaint(PaintEventArgs& args) {
|
||||
|
||||
__super::OnPaint(args);
|
||||
|
||||
//args.Graphics.SetColor(Color::Red);
|
||||
//Geometry path;
|
||||
|
||||
//PointF p1(100, 150); // 尖朝下(底部顶点)
|
||||
//PointF p2(50, 50); // 左上角
|
||||
//PointF p3(150, 50); // 右上角
|
||||
|
||||
//path.BeginFigure(p1); // BeginFigure
|
||||
//path.AddLine(p2); //
|
||||
//path.AddLine(p3); //
|
||||
//path.CloseFigure();
|
||||
|
||||
//args.Graphics.FillGeometry(&path);
|
||||
}
|
||||
|
||||
MainFrm::~MainFrm()
|
||||
{
|
||||
if (timer) {
|
||||
delete timer;
|
||||
}
|
||||
if (downloadTask) {
|
||||
delete downloadTask;
|
||||
}
|
||||
if (listFile) {
|
||||
delete listFile;
|
||||
}
|
||||
if (headImg) {
|
||||
delete headImg;
|
||||
}
|
||||
if (bkImg) {
|
||||
delete bkImg;
|
||||
}
|
||||
if (vlistSearch) {
|
||||
vlistSearch->Clear(true);
|
||||
}
|
||||
if (vlistLocal) {
|
||||
vlistLocal->Clear(true);
|
||||
}
|
||||
if (deskTopWnd) {
|
||||
delete deskTopWnd;
|
||||
}
|
||||
}
|
||||
|
||||
void MainFrm::OnClose(bool& cal) {
|
||||
cal = false;
|
||||
//给窗口添加淡出效果
|
||||
Animation* ant = new Animation(this);//绑定父对象为frm,则ant无需手动释放
|
||||
ant->SetStartValue(1.0);
|
||||
ant->SetEndValue(0);
|
||||
ant->ValueChanged = [&](float value) {
|
||||
Invoke([this, value] {
|
||||
this->Opacity = value;//修改透明度
|
||||
this->Invalidate();//刷新
|
||||
if (value <= 0.1) {
|
||||
//退出消息循环 程序结束
|
||||
Application::Exit(0);
|
||||
}
|
||||
});
|
||||
};
|
||||
this->Opacity = 1;
|
||||
ant->Start(200);//开始动画
|
||||
}
|
||||
|
||||
size_t MainFrm::FindLocalSong(const UIString& hash)
|
||||
{
|
||||
for (size_t i = 0; i < songLsit.size(); i++)
|
||||
{
|
||||
if (songLsit[i].hash == hash) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return size_t(-1);
|
||||
}
|
||||
void MainFrm::DownLoadImage(UIString singers, UIString headImageUrl)
|
||||
{
|
||||
//随机选一个歌手
|
||||
auto strs = singers.split("、");
|
||||
Random rdom;
|
||||
int pos = rdom.Next(0, strs.size() - 1);
|
||||
UIString SingerName = strs[pos];
|
||||
|
||||
std::string headFileData;
|
||||
//下载歌手头像 酷狗的接口
|
||||
{
|
||||
headImg = NULL;
|
||||
WebClient wc2;
|
||||
auto code = wc2.HttpGet(headImageUrl.replace("{size}", "400"), &headFileData, 5);
|
||||
if (code == 200) {
|
||||
headImg = new Image(headFileData.c_str(), headFileData.size());
|
||||
headImg->SizeMode = ImageSizeMode::Cover;
|
||||
}
|
||||
}
|
||||
|
||||
//下载歌手写真
|
||||
{
|
||||
bkImg = NULL;
|
||||
auto rect = GetClientRect();
|
||||
UIString bkurl = global::GetSingerBackground(SingerName);
|
||||
if (!bkurl.empty()) {
|
||||
std::string fileData;
|
||||
WebClient wc2;
|
||||
auto code = wc2.HttpGet(bkurl, &fileData, 5);
|
||||
if (code == 200) {
|
||||
Image* img = new Image(1020, 690);
|
||||
{
|
||||
Image* tmp = new Image(fileData.c_str(), fileData.size());
|
||||
tmp->SizeMode = ImageSizeMode::Cover;
|
||||
DXRender render(img);
|
||||
render.DrawImage(tmp, RectF(0, 0, img->Width(), img->Height()));
|
||||
delete tmp;
|
||||
}
|
||||
bkImg = img;
|
||||
bkImg->SizeMode = ImageSizeMode::Cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//回到主线程去设置歌手头像 歌手背景图
|
||||
BeginInvoke([=]() {
|
||||
if (headImg) {
|
||||
labelSinger->Style.ForeImage = headImg;
|
||||
labelSinger->Style.BackImage->Visible = false;
|
||||
}
|
||||
else {
|
||||
labelSinger->Style.BackImage->Visible = true;
|
||||
}
|
||||
if (bkImg) {
|
||||
mainLayout->Style.ForeImage = bkImg;
|
||||
mainLayout->Style.BackImage->Visible = false;
|
||||
deskTopWnd->GetLayout()->Style.BackImage = bkImg;
|
||||
}
|
||||
else {
|
||||
mainLayout->Style.BackImage->Visible = true;
|
||||
}
|
||||
labelSinger->Invalidate();
|
||||
mainLayout->Invalidate();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
bool MainFrm::PlaySong(const UIString& hash, Song& info)
|
||||
{
|
||||
timer->Stop();
|
||||
|
||||
UIString errStr;
|
||||
bool ret = global::GetSongInfo(hash, errStr, info);
|
||||
if (!ret) {
|
||||
::MessageBoxW(Hwnd(), errStr.unicode().c_str(), L"无法播放", MB_OK);
|
||||
return false;
|
||||
}
|
||||
|
||||
playType = 1;//当前正在播放音乐
|
||||
|
||||
centerFrame->FindControl("lrcView")->SendEvent(Event::OnMouseDown);
|
||||
|
||||
if (this->FindLocalSong(hash) == size_t(-1)) {
|
||||
info.hash = hash;
|
||||
songLsit.push_back(info);
|
||||
|
||||
//创建左侧音乐Item
|
||||
LocalItem* item = new LocalItem(info.fileName, global::toTimeStr(info.Duration));
|
||||
item->SetAttribute("FileHash", hash);
|
||||
item->SetAttribute("SingerName", info.SingerName);
|
||||
|
||||
//添加到左侧音乐列表
|
||||
vlistLocal->Add(item);
|
||||
vlistLocal->RefreshLayout();
|
||||
vlistLocal->GetScrollBar()->ScrollTo(item);
|
||||
vlistLocal->Invalidate();
|
||||
|
||||
//写入本地文件
|
||||
listFile->SetSection(hash);
|
||||
listFile->WriteString("name", info.fileName);
|
||||
listFile->WriteString("singer", info.SingerName);
|
||||
listFile->WriteString("dur", std::to_string(info.Duration));
|
||||
}
|
||||
|
||||
//请求歌手头像和写真
|
||||
RequestNewImage(info);
|
||||
|
||||
//设置一些状态
|
||||
this->nowSong = hash;
|
||||
this->SetText(info.fileName);
|
||||
((Label*)bottomFrame->FindControl("songName"))->SetText(info.fileName);
|
||||
//系统托盘处弹出正在播放音乐的提示
|
||||
ntfi.ShowBalloonTip(L"播放音乐", info.fileName, 2000);
|
||||
//打开URL 准备开始播放音乐
|
||||
player.OpenUrl(info.url);
|
||||
player.SetDuration(info.Duration);
|
||||
player.Play();
|
||||
UIString lrcData = global::GetSongLrc(hash);
|
||||
lrcPanel.LoadLrc(lrcData);
|
||||
deskTopWnd->LoadLrc(lrcData);
|
||||
timer->Start();
|
||||
return true;
|
||||
|
||||
}
|
||||
void MainFrm::OnKeyDown(WPARAM wparam, LPARAM lParam)
|
||||
{
|
||||
//回车搜索歌曲
|
||||
if (wparam == VK_RETURN) {
|
||||
global::page = 1;
|
||||
global::nextPage = true;
|
||||
centerFrame->FindControl("songView")->SendEvent(Event::OnMouseDown);
|
||||
UIString keyword = editSearch->GetText();
|
||||
std::vector<Song> songs = global::SearchSongs(keyword);
|
||||
vlistSearch->Clear(true);
|
||||
for (auto& it : songs) {
|
||||
SearchItem* sit = new SearchItem(it);
|
||||
vlistSearch->Add(sit);
|
||||
}
|
||||
vlistSearch->Invalidate();
|
||||
}
|
||||
__super::OnKeyDown(wparam, lParam);
|
||||
}
|
||||
void MainFrm::OnNotify(Control* sender, EventArgs& args) {
|
||||
do {
|
||||
if (args.EventType == Event::OnPaint) {
|
||||
if (sender == &player) {
|
||||
if (tabCtrl->GetPageIndex() == 2) {
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (playType == 2 && sender == mainLayout && player.BuffBitmap) {
|
||||
if (tabCtrl->GetPageIndex() == 1) {
|
||||
PaintEventArgs& arg = (PaintEventArgs&)args;
|
||||
Image img(player.BuffBitmap->GetHBITMAP());
|
||||
img.SizeMode = ImageSizeMode::Cover;
|
||||
arg.Graphics.DrawImage(&img, mainLayout->GetRect());
|
||||
return;
|
||||
}
|
||||
else if (deskTopWnd->IsVisible()) {
|
||||
deskTopWnd->Invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (args.EventType == Event::OnMouseDoubleClick) {
|
||||
if (!sender->GetAttribute("FileHash").empty()) {
|
||||
UIString hash = sender->GetAttribute("FileHash");
|
||||
Song info;
|
||||
this->PlaySong(hash, info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (args.EventType == Event::OnMouseDown) {
|
||||
if (sender->Name == "login") {
|
||||
OpenLoginFrm(sender);
|
||||
break;
|
||||
}
|
||||
if (sender->Name == "next") {
|
||||
NextSong();
|
||||
break;
|
||||
}
|
||||
if (sender->Name == "up") {
|
||||
UpSong();
|
||||
break;
|
||||
}
|
||||
if (sender->Name == "deskLrc") {
|
||||
OpenDesktopLrc();
|
||||
break;
|
||||
}
|
||||
if (sender->Name == "play") {
|
||||
player.Play();
|
||||
mediaCtl->SetPageIndex(1);
|
||||
mediaCtl->Invalidate();
|
||||
break;
|
||||
}
|
||||
if (sender->Name == "pause") {
|
||||
player.Pause();
|
||||
mediaCtl->SetPageIndex(0);
|
||||
mediaCtl->Invalidate();
|
||||
break;
|
||||
}
|
||||
if (sender->Name == "dellocal") {
|
||||
LocalItem* songItem = (LocalItem*)sender->Parent;
|
||||
vlistLocal->Remove(songItem);
|
||||
|
||||
UIString hash = songItem->GetAttribute("FileHash");
|
||||
if (!hash.empty()) {
|
||||
listFile->DeleteSection(hash);
|
||||
}
|
||||
delete songItem;
|
||||
vlistLocal->Invalidate();
|
||||
return;
|
||||
}
|
||||
if (sender->GetAttribute("tablayout") == "rightView") {
|
||||
size_t pos = sender->Parent->IndexOf(sender);
|
||||
if (pos == 0) {
|
||||
OpenSongView();
|
||||
}
|
||||
else if (pos == 1) {
|
||||
OpenLrcView();
|
||||
}
|
||||
else {
|
||||
Invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!sender->GetAttribute("mvhash").empty()) {
|
||||
timer->Stop();
|
||||
UIString mvhash = sender->GetAttribute("mvhash");
|
||||
UIString songHash = sender->Parent->GetAttribute("FileHash");
|
||||
PlayMv(mvhash, songHash);
|
||||
break;
|
||||
}
|
||||
if (sender == playerBar) {
|
||||
const MouseEventArgs& arg = (MouseEventArgs&)args;
|
||||
double f_pos = arg.Location.X * 1.0 / playerBar->Width();
|
||||
player.SetPosition(f_pos);
|
||||
player.Play();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (false);
|
||||
ezui::DefaultNotify(sender, args);
|
||||
}
|
||||
|
||||
void MainFrm::OpenDesktopLrc()
|
||||
{
|
||||
if (deskTopWnd->IsVisible()) {
|
||||
deskTopWnd->SetVisible(false);
|
||||
}
|
||||
else {
|
||||
deskTopWnd->SetVisible(true);
|
||||
deskTopWnd->Invalidate();
|
||||
}
|
||||
}
|
||||
void MainFrm::OpenLoginFrm(ezui::Control* sender)
|
||||
{
|
||||
//测试代码
|
||||
LoginFrm loginFrm(Hwnd());
|
||||
|
||||
//给窗口添加淡入效果
|
||||
Animation* ant = new Animation(&loginFrm);
|
||||
ant->SetStartValue(0.1);
|
||||
ant->SetEndValue(1.0);
|
||||
ant->ValueChanged = [&](double value) {
|
||||
HWND hWnd = loginFrm.Hwnd();
|
||||
BeginInvoke([&, value, hWnd] {
|
||||
if (!::IsWindow(hWnd))return;
|
||||
loginFrm.Opacity = value;//修改透明度
|
||||
loginFrm.Invalidate();//刷新
|
||||
});
|
||||
};
|
||||
loginFrm.Opacity = 0.1;
|
||||
ant->Start(300);//开始动画
|
||||
|
||||
int code = loginFrm.ShowModal(true);//阻塞函数内部进行消息循环
|
||||
|
||||
if (code == 1) {
|
||||
UIString text = UIString(L"欢迎您,%s").format(loginFrm.m_userName.c_str());
|
||||
((Label*)sender)->SetText(text);
|
||||
sender->Invalidate();
|
||||
}
|
||||
|
||||
}
|
||||
void MainFrm::UpSong()
|
||||
{
|
||||
int pos = this->FindLocalSong(this->nowSong);
|
||||
pos--;
|
||||
UIString hash;
|
||||
if (pos < 0) {
|
||||
hash = songLsit[songLsit.size() - 1].hash;
|
||||
}
|
||||
else {
|
||||
hash = songLsit[pos].hash;
|
||||
}
|
||||
auto it = vlistLocal->FindSingleChild("FileHash", hash);
|
||||
if (it) {
|
||||
vlistLocal->GetScrollBar()->ScrollTo(it);
|
||||
it->SendEvent(MouseEventArgs(Event::OnMouseDoubleClick));
|
||||
}
|
||||
}
|
||||
void MainFrm::NextSong()
|
||||
{
|
||||
int pos = this->FindLocalSong(this->nowSong);
|
||||
pos++;
|
||||
UIString hash;
|
||||
if (pos >= songLsit.size()) {
|
||||
hash = songLsit[0].hash;
|
||||
}
|
||||
else {
|
||||
hash = songLsit[pos].hash;
|
||||
}
|
||||
auto it = vlistLocal->FindSingleChild("FileHash", hash);
|
||||
if (it) {
|
||||
vlistLocal->GetScrollBar()->ScrollTo(it);
|
||||
it->SendEvent(MouseEventArgs(Event::OnMouseDoubleClick));
|
||||
}
|
||||
}
|
||||
void MainFrm::PlayMv(const UIString& mvhash, const UIString& songHash)
|
||||
{
|
||||
playType = 2;//当前正在播放视频
|
||||
|
||||
Song info;
|
||||
global::GetMvInfo(mvhash, info);
|
||||
|
||||
RequestNewImage(info);
|
||||
|
||||
centerFrame->FindControl("mvView")->SendEvent(Event::OnMouseDown);
|
||||
|
||||
this->SetText(info.SongName);
|
||||
((Label*)bottomFrame->FindControl("songName"))->SetText(info.SongName);
|
||||
((Label*)bottomFrame->FindControl("songName"))->Invalidate();
|
||||
|
||||
UIString filehash = songHash;
|
||||
UIString lrcData = global::GetSongLrc(filehash);
|
||||
|
||||
player.OpenUrl(info.url);
|
||||
player.Play();
|
||||
player.SetDuration(info.Duration / 1000);
|
||||
|
||||
lrcPanel.LoadLrc(lrcData);
|
||||
deskTopWnd->LoadLrc(lrcData);
|
||||
timer->Start();
|
||||
}
|
||||
void MainFrm::RequestNewImage(Song& info)
|
||||
{
|
||||
//重置头像和写真
|
||||
if (headImg) {
|
||||
delete headImg;
|
||||
labelSinger->Style.ForeImage = NULL;
|
||||
headImg = NULL;
|
||||
labelSinger->Invalidate();
|
||||
}
|
||||
if (bkImg) {
|
||||
delete bkImg;
|
||||
mainLayout->Style.ForeImage = NULL;
|
||||
deskTopWnd->GetLayout()->Style.BackImage = NULL;
|
||||
bkImg = NULL;
|
||||
mainLayout->Invalidate();
|
||||
}
|
||||
if (downloadTask) {
|
||||
delete downloadTask;
|
||||
}
|
||||
downloadTask = new Task([this](UIString singname, UIString imgUrl) {
|
||||
this->DownLoadImage(singname, imgUrl);
|
||||
}, info.SingerName, info.imgUrl);
|
||||
}
|
||||
void MainFrm::TimerTick() {
|
||||
|
||||
Invoke([=]() {
|
||||
if (player.GetState() == libvlc_state_t::libvlc_Playing) {
|
||||
long long position = player.Position();
|
||||
auto duration = player.Duration();
|
||||
double rate = position / (duration * 1000.0);
|
||||
int w = playerBar->Width() * rate;
|
||||
|
||||
lrcPanel.ChangePostion(position);
|
||||
if (deskTopWnd->IsVisible()) {
|
||||
deskTopWnd->ChangePostion(position);
|
||||
}
|
||||
|
||||
UIString f1 = global::toTimeStr(position / 1000);
|
||||
UIString f2 = global::toTimeStr(duration);
|
||||
UIString fen = f1 + "/" + f2;
|
||||
|
||||
if (mediaCtl->GetPageIndex() != 1) {
|
||||
mediaCtl->SetPageIndex(1);
|
||||
mediaCtl->Invalidate();
|
||||
}
|
||||
|
||||
labelTime->SetText(fen);
|
||||
labelTime->Invalidate();
|
||||
|
||||
playerBar2->SetFixedWidth(w);
|
||||
playerBar2->SetVisible(w > 0);
|
||||
playerBar2->Invalidate();
|
||||
}
|
||||
else {
|
||||
if (mediaCtl->GetPageIndex() != 0) {
|
||||
mediaCtl->SetPageIndex(0);
|
||||
mediaCtl->Invalidate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainFrm::NextPage(float scrollPos) {
|
||||
if (scrollPos >= 1.0f && global::nextPage) {
|
||||
global::page++;
|
||||
UIString keyword = editSearch->GetText();
|
||||
std::vector<Song> songs = global::SearchSongs(keyword);
|
||||
for (auto& it : songs) {
|
||||
SearchItem* sit = new SearchItem(it);
|
||||
vlistSearch->Add(sit);
|
||||
}
|
||||
if (!global::nextPage) {
|
||||
Label* end = new Label;
|
||||
end->SetFixedHeight(35);
|
||||
end->Style.BackColor = Color(254, 249, 229);
|
||||
end->SetText(L"已经没有更多数据");
|
||||
vlistSearch->Add(end);
|
||||
}
|
||||
vlistSearch->Invalidate();
|
||||
}
|
||||
}
|
||||
void MainFrm::OpenSongView() {
|
||||
centerLeft->Style.BackColor = Color::Transparent;
|
||||
tools->Style.Border.Bottom = 1;
|
||||
tools->Style.Border.Color = Color(238, 238, 238);
|
||||
vlistLocal->GetScrollBar()->Style.BackColor = Color(200, 200, 200, 50);
|
||||
vlistLocal->GetScrollBar()->Style.ForeColor = Color(217, 217, 217);
|
||||
vlistLocal->GetScrollBar()->ActiveStyle.ForeColor = Color(191, 191, 191);
|
||||
centerLayout->Style.BackColor = Color::White;
|
||||
centerLayout->Style.ForeColor = Color::Black;
|
||||
Invalidate();
|
||||
}
|
||||
void MainFrm::OpenLrcView() {
|
||||
centerLeft->Style.BackColor = Color(200, 200, 200, 100);
|
||||
tools->Style.Border.Bottom = 1;
|
||||
tools->Style.Border.Color = Color(238, 238, 238);
|
||||
vlistLocal->GetScrollBar()->Style.BackColor = Color(200, 200, 200, 50);
|
||||
vlistLocal->GetScrollBar()->Style.ForeColor = Color(255, 255, 255, 100);
|
||||
vlistLocal->GetScrollBar()->ActiveStyle.ForeColor = Color(255, 255, 255, 150);
|
||||
centerLayout->Style.BackColor = Color::Transparent;
|
||||
centerLayout->Style.ForeColor = Color::White;
|
||||
Invalidate();
|
||||
}
|
||||
81
demo/kugou/MainFrm.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
#include "global.h"
|
||||
#include "widgets.h"
|
||||
#include "vlcPlayer.h"
|
||||
#include "lrcPanel.h"
|
||||
#include "desktopLrcFrm.h"
|
||||
|
||||
//using Form = Window; //经典win32窗口样式
|
||||
//using Form = BorderlessWindow; //无边框窗口 带windows吸附效果
|
||||
using Form = LayeredWindow; //分层窗口 支持异形 圆角
|
||||
|
||||
class MainFrm :
|
||||
public Form
|
||||
{
|
||||
private:
|
||||
//标题Frame
|
||||
IFrame* titleFrame;
|
||||
//窗口中间部分Frame
|
||||
IFrame* centerFrame;
|
||||
//窗口底部Frame
|
||||
IFrame* bottomFrame;
|
||||
|
||||
std::vector<Song> songLsit;
|
||||
//no new 不需要释放
|
||||
NotifyIcon ntfi;
|
||||
VlcPlayer player;
|
||||
VListView* vlistLocal = NULL, * vlistSearch = NULL;
|
||||
TextBox* editSearch;
|
||||
LrcPanel lrcPanel;
|
||||
Label* labelTime, * labelSinger;
|
||||
TabLayout* tabCtrl, * mediaCtl;
|
||||
Control* mainLayout, * centerLayout, * centerLeft, * tools, * playerBar, * playerBar2;
|
||||
CheckBox* labelDeskLrc;
|
||||
//need new 需要释放
|
||||
Timer* timer = NULL;
|
||||
ConfigIni* listFile = NULL;
|
||||
Image* bkImg = NULL, * headImg = NULL;
|
||||
Task* downloadTask = NULL;
|
||||
DesktopLrcFrm* deskTopWnd;
|
||||
UIString nowSong;
|
||||
//1:歌曲 2:视频
|
||||
int playType = 0;
|
||||
protected:
|
||||
virtual void OnClose(bool& bClose) override;
|
||||
virtual void OnKeyDown(WPARAM wparam, LPARAM lParam)override;
|
||||
virtual void OnNotify(Control* sender, EventArgs& args)override;
|
||||
virtual void OnPaint(PaintEventArgs& args)override;
|
||||
private:
|
||||
//打开/关闭桌面歌词
|
||||
void OpenDesktopLrc();
|
||||
//打开登录窗口
|
||||
void OpenLoginFrm(ezui::Control* sender);
|
||||
//上一首
|
||||
void UpSong();
|
||||
//下一首
|
||||
void NextSong();
|
||||
//播放mv
|
||||
void PlayMv(const UIString& mvhash, const UIString& songHash);
|
||||
//请求新的头像和写真
|
||||
void RequestNewImage(Song& info);
|
||||
//打开歌曲界面
|
||||
void OpenSongView();
|
||||
//计时器处理的函数
|
||||
void TimerTick();
|
||||
//打开歌词滚动界面
|
||||
void OpenLrcView();
|
||||
//初始化窗口
|
||||
void InitForm();
|
||||
//下载歌手头像和写真
|
||||
void DownLoadImage(UIString SingerName, UIString headImageUrl);
|
||||
//播放歌曲
|
||||
bool PlaySong(const UIString& hash, Song& info);
|
||||
//寻找左侧列表中的歌曲
|
||||
size_t FindLocalSong(const UIString& hash);
|
||||
//下一页
|
||||
void NextPage(float scrollPos);
|
||||
public:
|
||||
MainFrm();
|
||||
virtual ~MainFrm();
|
||||
};
|
||||
|
||||
159
demo/kugou/VlcPlayer.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
#include "vlcPlayer.h"
|
||||
void* lock_cb(void* opaque, void** planes)
|
||||
{
|
||||
VlcPlayer* vp = (VlcPlayer*)opaque;
|
||||
vp->mtx.Lock();
|
||||
*planes = vp->BuffBitmap->GetPixel(); /*tell VLC to put decoded data to this buffer*/
|
||||
return NULL;
|
||||
}
|
||||
/*##get the argb picture AND save to file*/
|
||||
void unlock_cb(void* opaque, void* picture, void* const* planes)
|
||||
{
|
||||
VlcPlayer* vp = (VlcPlayer*)opaque;
|
||||
vp->mtx.UnLock();
|
||||
}
|
||||
void display_cb(void* opaque, void* picture)
|
||||
{
|
||||
VlcPlayer* vp = (VlcPlayer*)opaque;
|
||||
// 通知主线程刷新
|
||||
BeginInvoke([=] {
|
||||
if (vp->PlayingCallback) {
|
||||
vp->PlayingCallback(vp->BuffBitmap);
|
||||
}
|
||||
vp->Invalidate();
|
||||
});
|
||||
}
|
||||
void cleanup_cb(void* opaque)
|
||||
{
|
||||
VlcPlayer* vp = (VlcPlayer*)opaque;
|
||||
}
|
||||
|
||||
unsigned setup_cb(void** opaque, char* chroma, unsigned* width, unsigned* height, unsigned* pitches, unsigned* lines)
|
||||
{
|
||||
int w = *width;
|
||||
int h = *height;
|
||||
VlcPlayer* vp = (VlcPlayer*)*opaque;
|
||||
if (vp->BuffBitmap != NULL) {
|
||||
delete vp->BuffBitmap;
|
||||
}
|
||||
vp->BuffBitmap = new Bitmap(w, h);
|
||||
memcpy(chroma, "RV32", 4);
|
||||
*pitches = w * 4;
|
||||
*lines = h;
|
||||
return 1;
|
||||
}
|
||||
VlcPlayer::VlcPlayer()
|
||||
{
|
||||
m_vlc = libvlc_new(NULL, NULL);
|
||||
m_vlcplayer = libvlc_media_player_new(m_vlc);
|
||||
libvlc_video_set_callbacks(m_vlcplayer, lock_cb, unlock_cb, display_cb, this);
|
||||
libvlc_video_set_format_callbacks(m_vlcplayer, setup_cb, cleanup_cb);
|
||||
}
|
||||
VlcPlayer::~VlcPlayer()
|
||||
{
|
||||
Stop();
|
||||
if (m_task) {
|
||||
delete m_task;
|
||||
}
|
||||
if (m_vlcplayer) {
|
||||
libvlc_media_player_release(m_vlcplayer);
|
||||
}
|
||||
libvlc_release(m_vlc);
|
||||
if (BuffBitmap) {
|
||||
delete BuffBitmap;
|
||||
}
|
||||
}
|
||||
void VlcPlayer::OnBackgroundPaint(PaintEventArgs& args) {
|
||||
__super::OnBackgroundPaint(args);
|
||||
if (BuffBitmap) {
|
||||
Image img(BuffBitmap);
|
||||
img.SizeMode = ImageSizeMode::Fit;
|
||||
//img.Offset = Rect(500,50,200,200);
|
||||
args.Graphics.DrawImage(&img, GetRect());
|
||||
}
|
||||
}
|
||||
void VlcPlayer::SetConfig()
|
||||
{
|
||||
}
|
||||
void VlcPlayer::OpenPath(const UIString& file_)
|
||||
{
|
||||
if (m_task && m_task->IsStopped()) {
|
||||
delete m_task;
|
||||
m_task = NULL;
|
||||
}
|
||||
else if (m_task && !m_task->IsStopped()) {
|
||||
//上一次播放请求尚未完成
|
||||
return;
|
||||
}
|
||||
m_task = new Task([&, file_]() {
|
||||
#ifdef _DEBUG
|
||||
OutputDebugStringA("-----------------------------------------------------------stop in..\n");
|
||||
#endif // _DEBUG
|
||||
Stop();
|
||||
//回到主线程进行处理
|
||||
Invoke([&]() {
|
||||
UIString file = file_.replace("/", "\\");
|
||||
libvlc_media_t* pmedia = libvlc_media_new_path(m_vlc, file.c_str());
|
||||
libvlc_media_parse(pmedia);//
|
||||
libvlc_media_player_set_media(m_vlcplayer, pmedia);
|
||||
m_duration = libvlc_media_get_duration(pmedia);//
|
||||
libvlc_media_player_play(m_vlcplayer);
|
||||
libvlc_media_release(pmedia);
|
||||
});
|
||||
#ifdef _DEBUG
|
||||
OutputDebugStringA("-----------------------------------------------------------stop out..\n");
|
||||
#endif // _DEBUG
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
void VlcPlayer::OpenUrl(const UIString& url)
|
||||
{
|
||||
Stop();
|
||||
libvlc_media_t* pmedia = libvlc_media_new_location(m_vlc, url.c_str());
|
||||
libvlc_media_parse(pmedia);//
|
||||
libvlc_media_player_set_media(m_vlcplayer, pmedia);
|
||||
m_duration = libvlc_media_get_duration(pmedia);//
|
||||
libvlc_media_player_play(m_vlcplayer);
|
||||
libvlc_media_release(pmedia);
|
||||
}
|
||||
void VlcPlayer::Play()
|
||||
{
|
||||
libvlc_media_player_play(m_vlcplayer);
|
||||
}
|
||||
|
||||
void VlcPlayer::SetVolume(int volume) {
|
||||
libvlc_audio_set_volume(m_vlcplayer, volume);
|
||||
}
|
||||
|
||||
void VlcPlayer::Pause()
|
||||
{
|
||||
if (libvlc_media_player_can_pause(m_vlcplayer))
|
||||
{
|
||||
libvlc_media_player_pause(m_vlcplayer);
|
||||
}
|
||||
}
|
||||
void VlcPlayer::Stop()
|
||||
{
|
||||
libvlc_media_player_stop(m_vlcplayer);
|
||||
}
|
||||
long long VlcPlayer::Duration() {
|
||||
return m_duration;
|
||||
}
|
||||
void VlcPlayer::SetDuration(int dur)
|
||||
{
|
||||
m_duration = dur;
|
||||
}
|
||||
long long VlcPlayer::Position() {
|
||||
libvlc_time_t play_time = libvlc_media_player_get_time(m_vlcplayer);
|
||||
return play_time;
|
||||
}
|
||||
|
||||
void VlcPlayer::SetPosition(float f_pos)
|
||||
{
|
||||
libvlc_media_player_set_position(m_vlcplayer, f_pos);
|
||||
}
|
||||
|
||||
libvlc_state_t VlcPlayer::GetState() {
|
||||
return libvlc_media_player_get_state(m_vlcplayer);
|
||||
}
|
||||
47
demo/kugou/VlcPlayer.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "EzUI/Control.h"
|
||||
#include "EzUI/BorderlessWindow.h"
|
||||
#include "EzUI/Label.h"
|
||||
#include "EzUI/Task.h"
|
||||
#include <mutex>
|
||||
#ifdef _WIN32
|
||||
#include <basetsd.h>
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif
|
||||
#include "vlc/vlc.h"
|
||||
#pragma comment(lib,"libvlc.lib")
|
||||
#pragma comment(lib,"libvlccore.lib")
|
||||
|
||||
//封装用于播放视频的控件
|
||||
using namespace ezui;
|
||||
class VlcPlayer :public Control
|
||||
{
|
||||
private:
|
||||
libvlc_instance_t* m_vlc = NULL;
|
||||
libvlc_media_player_t* m_vlcplayer = NULL;
|
||||
libvlc_time_t m_duration = 0;
|
||||
Task * m_task = NULL;
|
||||
public:
|
||||
Mutex mtx;
|
||||
unsigned int IMG_WIDTH = 0;
|
||||
unsigned int IMG_HEIGHT = 0;
|
||||
Bitmap* BuffBitmap = NULL;
|
||||
std::function<void(Bitmap* bitmap)> PlayingCallback;
|
||||
protected:
|
||||
void SetConfig();
|
||||
virtual void OnBackgroundPaint(PaintEventArgs& args) override;
|
||||
public:
|
||||
VlcPlayer();
|
||||
virtual ~VlcPlayer();
|
||||
void OpenPath(const UIString& file);
|
||||
void OpenUrl(const UIString& url);
|
||||
void Play();
|
||||
void SetVolume(int volume);
|
||||
void Pause();
|
||||
void Stop();
|
||||
long long Duration();
|
||||
void SetDuration(int dur);
|
||||
long long Position();
|
||||
void SetPosition(float f_pos);
|
||||
libvlc_state_t GetState();
|
||||
};
|
||||
272
demo/kugou/base64.cpp
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
base64.cpp and base64.h
|
||||
base64 encoding and decoding with C++.
|
||||
More information at
|
||||
https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
|
||||
Version: 2.rc.08 (release candidate)
|
||||
Copyright (C) 2004-2017, 2020, 2021 Ren?? Nyffenegger
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
Ren?? Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
//
|
||||
// Depending on the url parameter in base64_chars, one of
|
||||
// two sets of base64 characters needs to be chosen.
|
||||
// They differ in their last two characters.
|
||||
//
|
||||
static const char* base64_chars[2] = {
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789"
|
||||
"+/",
|
||||
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789"
|
||||
"-_" };
|
||||
|
||||
static unsigned int pos_of_char(const unsigned char chr) {
|
||||
//
|
||||
// Return the position of chr within base64_encode()
|
||||
//
|
||||
|
||||
if (chr >= 'A' && chr <= 'Z') return chr - 'A';
|
||||
else if (chr >= 'a' && chr <= 'z') return chr - 'a' + ('Z' - 'A') + 1;
|
||||
else if (chr >= '0' && chr <= '9') return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
|
||||
else if (chr == '+' || chr == '-') return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters (
|
||||
else if (chr == '/' || chr == '_') return 63; // Ditto for '/' and '_'
|
||||
else
|
||||
//
|
||||
// 2020-10-23: Throw std::exception rather than const char*
|
||||
//(Pablo Martin-Gomez, https://github.com/Bouska)
|
||||
//
|
||||
throw std::runtime_error("Input is not valid base64-encoded data.");
|
||||
}
|
||||
|
||||
static std::string insert_linebreaks(std::string str, size_t distance) {
|
||||
//
|
||||
// Provided by https://github.com/JomaCorpFX, adapted by me.
|
||||
//
|
||||
if (!str.length()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t pos = distance;
|
||||
|
||||
while (pos < str.size()) {
|
||||
str.insert(pos, "\n");
|
||||
pos += distance + 1;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
template <typename String, unsigned int line_length>
|
||||
static std::string encode_with_line_breaks(String s) {
|
||||
return insert_linebreaks(base64_encode(s, false), line_length);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string encode_pem(String s) {
|
||||
return encode_with_line_breaks<String, 64>(s);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string encode_mime(String s) {
|
||||
return encode_with_line_breaks<String, 76>(s);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string encode(String s, bool url) {
|
||||
return base64_encode(reinterpret_cast<const unsigned char*>(s.data()), s.length(), url);
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, size_t in_len, bool url) {
|
||||
|
||||
size_t len_encoded = (in_len + 2) / 3 * 4;
|
||||
|
||||
unsigned char trailing_char = url ? '.' : '=';
|
||||
|
||||
//
|
||||
// Choose set of base64 characters. They differ
|
||||
// for the last two positions, depending on the url
|
||||
// parameter.
|
||||
// A bool (as is the parameter url) is guaranteed
|
||||
// to evaluate to either 0 or 1 in C++ therefore,
|
||||
// the correct character set is chosen by subscripting
|
||||
// base64_chars with url.
|
||||
//
|
||||
const char* base64_chars_ = base64_chars[url];
|
||||
|
||||
std::string ret;
|
||||
ret.reserve(len_encoded);
|
||||
|
||||
unsigned int pos = 0;
|
||||
|
||||
while (pos < in_len) {
|
||||
ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]);
|
||||
|
||||
if (pos + 1 < in_len) {
|
||||
ret.push_back(base64_chars_[((bytes_to_encode[pos + 0] & 0x03) << 4) + ((bytes_to_encode[pos + 1] & 0xf0) >> 4)]);
|
||||
|
||||
if (pos + 2 < in_len) {
|
||||
ret.push_back(base64_chars_[((bytes_to_encode[pos + 1] & 0x0f) << 2) + ((bytes_to_encode[pos + 2] & 0xc0) >> 6)]);
|
||||
ret.push_back(base64_chars_[bytes_to_encode[pos + 2] & 0x3f]);
|
||||
}
|
||||
else {
|
||||
ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & 0x0f) << 2]);
|
||||
ret.push_back(trailing_char);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0x03) << 4]);
|
||||
ret.push_back(trailing_char);
|
||||
ret.push_back(trailing_char);
|
||||
}
|
||||
|
||||
pos += 3;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string decode(String encoded_string, bool remove_linebreaks) {
|
||||
//
|
||||
// decode(??) is templated so that it can be used with String = const std::string&
|
||||
// or std::string_view (requires at least C++17)
|
||||
//
|
||||
|
||||
if (encoded_string.empty()) return std::string();
|
||||
|
||||
if (remove_linebreaks) {
|
||||
|
||||
std::string copy(encoded_string);
|
||||
|
||||
copy.erase(std::remove(copy.begin(), copy.end(), '\n'), copy.end());
|
||||
|
||||
return base64_decode(copy, false);
|
||||
}
|
||||
|
||||
size_t length_of_string = encoded_string.length();
|
||||
size_t pos = 0;
|
||||
|
||||
//
|
||||
// The approximate length (bytes) of the decoded string might be one or
|
||||
// two bytes smaller, depending on the amount of trailing equal signs
|
||||
// in the encoded string. This approximation is needed to reserve
|
||||
// enough space in the string to be returned.
|
||||
//
|
||||
size_t approx_length_of_decoded_string = length_of_string / 4 * 3;
|
||||
std::string ret;
|
||||
ret.reserve(approx_length_of_decoded_string);
|
||||
|
||||
while (pos < length_of_string) {
|
||||
//
|
||||
// Iterate over encoded input string in chunks. The size of all
|
||||
// chunks except the last one is 4 bytes.
|
||||
//
|
||||
// The last chunk might be padded with equal signs or dots
|
||||
// in order to make it 4 bytes in size as well, but this
|
||||
// is not required as per RFC 2045.
|
||||
//
|
||||
// All chunks except the last one produce three output bytes.
|
||||
//
|
||||
// The last chunk produces at least one and up to three bytes.
|
||||
//
|
||||
|
||||
size_t pos_of_char_1 = pos_of_char(encoded_string[pos + 1]);
|
||||
|
||||
//
|
||||
// Emit the first output byte that is produced in each chunk:
|
||||
//
|
||||
ret.push_back(static_cast<std::string::value_type>(((pos_of_char(encoded_string[pos + 0])) << 2) + ((pos_of_char_1 & 0x30) >> 4)));
|
||||
|
||||
if ((pos + 2 < length_of_string) && // Check for data that is not padded with equal signs (which is allowed by RFC 2045)
|
||||
encoded_string[pos + 2] != '=' &&
|
||||
encoded_string[pos + 2] != '.' // accept URL-safe base 64 strings, too, so check for '.' also.
|
||||
)
|
||||
{
|
||||
//
|
||||
// Emit a chunk's second byte (which might not be produced in the last chunk).
|
||||
//
|
||||
unsigned int pos_of_char_2 = pos_of_char(encoded_string[pos + 2]);
|
||||
ret.push_back(static_cast<std::string::value_type>(((pos_of_char_1 & 0x0f) << 4) + ((pos_of_char_2 & 0x3c) >> 2)));
|
||||
|
||||
if ((pos + 3 < length_of_string) &&
|
||||
encoded_string[pos + 3] != '=' &&
|
||||
encoded_string[pos + 3] != '.'
|
||||
)
|
||||
{
|
||||
//
|
||||
// Emit a chunk's third byte (which might not be produced in the last chunk).
|
||||
//
|
||||
ret.push_back(static_cast<std::string::value_type>(((pos_of_char_2 & 0x03) << 6) + pos_of_char(encoded_string[pos + 3])));
|
||||
}
|
||||
}
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const& s, bool remove_linebreaks) {
|
||||
return decode(s, remove_linebreaks);
|
||||
}
|
||||
|
||||
std::string base64_encode(std::string const& s, bool url) {
|
||||
return encode(s, url);
|
||||
}
|
||||
|
||||
std::string base64_encode_pem(std::string const& s) {
|
||||
return encode_pem(s);
|
||||
}
|
||||
|
||||
std::string base64_encode_mime(std::string const& s) {
|
||||
return encode_mime(s);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
//
|
||||
// Interface with std::string_view rather than const std::string&
|
||||
// Requires C++17
|
||||
// Provided by Yannic Bonenberger (https://github.com/Yannic)
|
||||
//
|
||||
|
||||
std::string base64_encode(std::string_view s, bool url) {
|
||||
return encode(s, url);
|
||||
}
|
||||
|
||||
std::string base64_encode_pem(std::string_view s) {
|
||||
return encode_pem(s);
|
||||
}
|
||||
|
||||
std::string base64_encode_mime(std::string_view s) {
|
||||
return encode_mime(s);
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string_view s, bool remove_linebreaks) {
|
||||
return decode(s, remove_linebreaks);
|
||||
}
|
||||
|
||||
#endif // __cplusplus >= 201703L
|
||||
35
demo/kugou/base64.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
//
|
||||
// base64 encoding and decoding with C++.
|
||||
// Version: 2.rc.08 (release candidate)
|
||||
//
|
||||
#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
|
||||
#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
|
||||
|
||||
#include <string>
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#include <string_view>
|
||||
#endif // __cplusplus >= 201703L
|
||||
|
||||
std::string base64_encode(std::string const& s, bool url = false);
|
||||
std::string base64_encode_pem(std::string const& s);
|
||||
std::string base64_encode_mime(std::string const& s);
|
||||
|
||||
std::string base64_decode(std::string const& s, bool remove_linebreaks = false);
|
||||
std::string base64_encode(unsigned char const*, size_t len, bool url = false);
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
//
|
||||
// Interface with std::string_view rather than const std::string&
|
||||
// Requires C++17
|
||||
// Provided by Yannic Bonenberger (https://github.com/Yannic)
|
||||
//
|
||||
std::string base64_encode(std::string_view s, bool url = false);
|
||||
std::string base64_encode_pem(std::string_view s);
|
||||
std::string base64_encode_mime(std::string_view s);
|
||||
|
||||
std::string base64_decode(std::string_view s, bool remove_linebreaks = false);
|
||||
#endif // __cplusplus >= 201703L
|
||||
|
||||
#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */
|
||||
25
demo/kugou/extractx64.bat
Normal file
@@ -0,0 +1,25 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
set OUTDIR=%1
|
||||
set MARKER_FILE=%OUTDIR%\dll_marker.txt
|
||||
set SCRIPT_DIR=%~dp0
|
||||
|
||||
if exist "%MARKER_FILE%" (
|
||||
echo DLL already extracted. Skipping.
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
echo Extracting dll.zip to %OUTDIR%...
|
||||
|
||||
"%SCRIPT_DIR%7z.exe" x "%SCRIPT_DIR%dllx64.zip" -o"%OUTDIR%" -aoa -y
|
||||
|
||||
if errorlevel 1 (
|
||||
echo Extraction failed!
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo extracted > "%MARKER_FILE%"
|
||||
echo Extraction complete.
|
||||
|
||||
endlocal
|
||||
25
demo/kugou/extractx86.bat
Normal file
@@ -0,0 +1,25 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
set OUTDIR=%1
|
||||
set MARKER_FILE=%OUTDIR%\dll_marker.txt
|
||||
set SCRIPT_DIR=%~dp0
|
||||
|
||||
if exist "%MARKER_FILE%" (
|
||||
echo DLL already extracted. Skipping.
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
echo Extracting dll.zip to %OUTDIR%...
|
||||
|
||||
"%SCRIPT_DIR%7z.exe" x "%SCRIPT_DIR%dllx86.zip" -o"%OUTDIR%" -aoa -y
|
||||
|
||||
if errorlevel 1 (
|
||||
echo Extraction failed!
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo extracted > "%MARKER_FILE%"
|
||||
echo Extraction complete.
|
||||
|
||||
endlocal
|
||||
156
demo/kugou/global.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "global.h"
|
||||
|
||||
namespace global {
|
||||
|
||||
int pageSize = 50;
|
||||
int page = 1;
|
||||
bool nextPage = true;
|
||||
|
||||
UIString toTimeStr(long dur) {
|
||||
UIString fen = std::to_string(dur / 60);
|
||||
if (fen.size() <= 1) fen = "0" + fen;
|
||||
UIString yu = std::to_string(dur % 60);
|
||||
if (yu.size() <= 1) yu = "0" + yu;
|
||||
return fen + ":" + yu;
|
||||
}
|
||||
int HttpGet(const UIString& url, UIString& resp) {
|
||||
UIString newUrl = url;
|
||||
size_t pos1 = newUrl.find("://");
|
||||
UIString host;
|
||||
if (pos1 != UIString::npos) {
|
||||
host = newUrl.substr(pos1 + 3);
|
||||
pos1 = host.find("/");
|
||||
if (pos1 != UIString::npos) {
|
||||
host = host.substr(0, pos1);
|
||||
}
|
||||
}
|
||||
WebClient wc;
|
||||
wc.AddHeader("Accept", " */*");
|
||||
wc.AddHeader("Accept-Language", " en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.2");
|
||||
wc.AddHeader("User-Agent", " Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko");
|
||||
wc.AddHeader("Host", host);
|
||||
wc.AddHeader("Connection", " Keep-Alive");
|
||||
wc.AddHeader("Cache-Control", " no-cache");
|
||||
UIString userid = "1581500898";//
|
||||
newUrl += "&userid=" + userid;
|
||||
return wc.HttpGet(newUrl, &resp);
|
||||
}
|
||||
std::vector<Song> SearchSongs(const UIString& keyword) {
|
||||
char buf[999]{ 0 };
|
||||
UIString resp;
|
||||
sprintf(buf, "https://songsearch.kugou.com/song_search_v2?platform=WebFilter&pagesize=%d&page=%d&keyword=%s", pageSize, page, Util::UrlEncode(keyword).c_str());
|
||||
HttpGet(buf, resp);
|
||||
JsonValue json(resp);
|
||||
int total = json["data"]["total"].asInt();
|
||||
int pageCount = total * 1.0 / pageSize + 0.9;
|
||||
if (page >= pageCount) {
|
||||
nextPage = false;
|
||||
}
|
||||
std::vector<Song> songs;
|
||||
for (auto&& it : json["data"]["lists"]) {
|
||||
Song s;
|
||||
s.hash = it["FileHash"].asString();
|
||||
s.Duration = it["Duration"].asInt();
|
||||
s.MvHash = it["MvHash"].asString();
|
||||
s.SongName = it["FileName"].asString();
|
||||
s.SingerName = it["SingerName"].asString();
|
||||
s.AlbumID = it["AlbumID"].asString();
|
||||
s.AlbumName = it["AlbumName"].asString();
|
||||
s.QualityLevel = it["QualityLevel"].asInt();
|
||||
songs.push_back(s);
|
||||
}
|
||||
return songs;
|
||||
}
|
||||
UIString GetSongLrc(const UIString& hash, const UIString& AlbumID) {
|
||||
UIString url = "http://krcs.kugou.com/search?ver=1&man=yes&client=mobi&keyword=&duration=&hash=" + hash + "&album_audio_id=" + AlbumID;
|
||||
UIString resp;
|
||||
HttpGet(url, resp);
|
||||
JsonValue json(resp);
|
||||
if (json["status"].asInt() != 200 || json["candidates"].size() == 0) {
|
||||
return UIString(L"[00:00.00]无歌词");
|
||||
}
|
||||
UIString id = (*json["candidates"].begin())["id"].asString();
|
||||
UIString accesskey = (*json["candidates"].begin())["accesskey"].asString();
|
||||
resp.clear();
|
||||
url = "http://lyrics.kugou.com/download?ver=1&client=pc&id=" + id + "&accesskey=" + accesskey + "&fmt=lrc&charset=utf8";
|
||||
HttpGet(url, resp);
|
||||
JsonValue json2(resp);
|
||||
UIString base64Text = json2["content"].asString();
|
||||
base64Text = base64_decode(base64Text);
|
||||
return base64Text;
|
||||
}
|
||||
bool GetSongInfo(const UIString& hash, UIString& errorInfo, Song& info)
|
||||
{
|
||||
UIString url = "http://m.kugou.com/app/i/getSongInfo.php?hash={hash}&cmd=playInfo";
|
||||
url = url.replace("{hash}", hash);
|
||||
UIString resp;
|
||||
global::HttpGet(url, resp);
|
||||
auto w = resp.unicode();
|
||||
JsonValue json(resp);
|
||||
if (json["errcode"].asInt() != 0) {
|
||||
errorInfo = UIString(json["error"].asString());
|
||||
return false;
|
||||
}
|
||||
int dur = json["timeLength"].asInt();
|
||||
UIString playUrl = json["url"].asCString();
|
||||
UIString SingerName = json["author_name"].asCString();
|
||||
|
||||
info.fileName = json["fileName"].asString();
|
||||
info.Duration = dur;
|
||||
info.url = playUrl;
|
||||
info.SingerName = SingerName;
|
||||
info.imgUrl = json["imgUrl"].asCString();
|
||||
|
||||
if (playUrl.empty()) {
|
||||
errorInfo = L"歌曲收费";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool GetMvInfo(const UIString& mvhash, Song& info) {
|
||||
UIString resp;
|
||||
WebClient wc;
|
||||
wc.HttpGet("http://m.kugou.com/app/i/mv.php?cmd=100&hash=" + mvhash + "&ismp3=1&ext=mp4", &resp);
|
||||
auto w = resp.unicode();
|
||||
JsonValue json(resp);
|
||||
std::vector<UIString> urls;
|
||||
urls.reserve(6);
|
||||
for (auto& it : json["mvdata"]) {
|
||||
UIString url = it["downurl"].asString();
|
||||
if (!url.empty()) {
|
||||
urls.push_back(url);
|
||||
}
|
||||
}
|
||||
|
||||
info.imgUrl = json["mvicon"].asString();
|
||||
info.SingerName = json["singer"].asString();
|
||||
info.Duration = json["timelength"].asInt();
|
||||
info.SongName = json["songname"].asString();
|
||||
info.url = urls[urls.size() - 1];
|
||||
return true;
|
||||
}
|
||||
UIString GetSingerBackground(const UIString& SingerName) {
|
||||
UIString imageUrl = "https://artistpicserver.kuwo.cn/pic.web?type=big_artist_pic&pictype=url&content=list&&id=0&name=" + Util::UrlEncode(SingerName) + "&from=pc&json=1&version=1&width=" + std::to_string(1920) + "&height=" + std::to_string(1080);
|
||||
UIString resp;
|
||||
WebClient wc;
|
||||
wc.HttpGet(imageUrl, &resp, 5);
|
||||
JsonValue json(resp);
|
||||
UIString bkurl;
|
||||
//使用最清晰的图片
|
||||
if (bkurl.empty()) {
|
||||
for (auto&& it : json["array"]) {
|
||||
if (!it["bkurl"].isNull()) {
|
||||
bkurl = it["bkurl"].asString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto&& it : json["array"]) {
|
||||
if (!it["wpurl"].isNull()) {
|
||||
bkurl = it["wpurl"].asString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bkurl;
|
||||
}
|
||||
}
|
||||
84
demo/kugou/global.h
Normal file
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
#include "EzUI/EzUI.h"
|
||||
#include "EzUI/TextBox.h"
|
||||
#include "EzUI/BorderlessWindow.h"
|
||||
#include "EzUI/Application.h"
|
||||
#include "EzUI/UIManager.h"
|
||||
#include "EzUI/HLayout.h"
|
||||
#include "EzUI/Label.h"
|
||||
#include "EzUI/VListView.h"
|
||||
#include "EzUI/VLayout.h"
|
||||
#include "EzUI/Button.h"
|
||||
#include "EzUI/TabLayout.h"
|
||||
#include "EzUI/NotifyIcon.h"
|
||||
#include "EzUI/LayeredWindow.h"
|
||||
#include "EzUI/Task.h"
|
||||
#include "EzUI/UISelector.h"
|
||||
#include "EzUI/Animation.h"
|
||||
#include "EzUI/IFrame.h"
|
||||
|
||||
#include "WebClient.h"
|
||||
#include "JsonValue.h"
|
||||
#include "Util.h"
|
||||
#include "base64.h"
|
||||
#include "ConfigIni.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib,"Debug/Common.lib")
|
||||
#else
|
||||
#pragma comment(lib,"Release/Common.lib")
|
||||
#endif
|
||||
|
||||
#include <random>
|
||||
class Random {
|
||||
std::mt19937 randomer;
|
||||
public:
|
||||
Random() :randomer(std::random_device()()) {
|
||||
}
|
||||
int Next(int lower, int upper) {
|
||||
std::uniform_int_distribution<int> distribution(lower, upper);
|
||||
return distribution(randomer);
|
||||
}
|
||||
float Next(float lower, float upper) {
|
||||
std::uniform_real_distribution<float> distribution(lower, upper);
|
||||
return distribution(randomer);
|
||||
}
|
||||
};
|
||||
|
||||
using namespace ezui;
|
||||
|
||||
struct Song {
|
||||
UIString hash;//歌曲哈希值
|
||||
UIString SongName;//歌曲名称
|
||||
UIString SingerName;//歌手名称
|
||||
UIString MvHash;//mv哈希值
|
||||
int Duration;//音乐时长 单位:秒
|
||||
UIString AlbumID;//
|
||||
UIString AlbumName;//
|
||||
int QualityLevel;//歌曲热度
|
||||
UIString url;
|
||||
UIString imgUrl;
|
||||
UIString fileName;
|
||||
};
|
||||
|
||||
|
||||
namespace global {
|
||||
extern int pageSize;
|
||||
extern int page;
|
||||
extern bool nextPage;
|
||||
|
||||
//歌曲长度转字符串显示
|
||||
extern UIString toTimeStr(long dur);
|
||||
//http对酷狗api的请求
|
||||
extern int HttpGet(const UIString& url, UIString& resp);
|
||||
//根据关键字进行歌曲搜索
|
||||
extern std::vector<Song> SearchSongs(const UIString& keyword);
|
||||
//使用歌曲的AlbumId寻找查找对应的歌词
|
||||
extern UIString GetSongLrc(const UIString& hash, const UIString& AlbumID = "");
|
||||
//获取歌曲信息
|
||||
extern bool GetSongInfo(const UIString& hash, UIString& errorInfo, Song& info);
|
||||
//获取mv信息
|
||||
extern bool GetMvInfo(const UIString& mvhash, Song& info);
|
||||
//获取歌手写真(酷我的接口)
|
||||
extern UIString GetSingerBackground(const UIString& SingerName);
|
||||
};
|
||||
89
demo/kugou/include/Common/include/Chat.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
//#include "os.h"
|
||||
//#include "WebClient.h"
|
||||
//
|
||||
//inline void Loop() {
|
||||
// /*Socket s;
|
||||
// s.Bind("0.0.0.0", 80);
|
||||
// bool b = s.Listen();
|
||||
// for (; b;) {
|
||||
// Socket client = s.Accep();
|
||||
// printf("连接进入 %s %d\n", client.Address.c_str(), client.Port);
|
||||
//
|
||||
// std::string resp;
|
||||
// size_t pos = -1;
|
||||
// size_t length = 0;
|
||||
// std::string body;
|
||||
// bool end = false;
|
||||
// for (;;) {
|
||||
// char buf[128]{ 0 };
|
||||
// int len = client.Receive(buf, sizeof(buf));
|
||||
// if (len == -1 || len == 0) {
|
||||
// client.Close();
|
||||
// printf("客户端断开 %s %d\n", client.Address.c_str(), client.Port);
|
||||
// break;
|
||||
// }
|
||||
// if (!end) {
|
||||
// resp.append(buf, len);
|
||||
// }
|
||||
// else {
|
||||
// body.append(buf, len);
|
||||
// }
|
||||
// if (!end && (pos = resp.find("\r\n\r\n")) != -1) {
|
||||
// body.append(resp.c_str() + pos + 4, resp.size() - pos - 4);
|
||||
// end = true;
|
||||
// auto pos2 = resp.find("Content-Length:");
|
||||
// if (pos2 != -1) {
|
||||
// std::string len;
|
||||
// for (size_t i = pos2 + 7; i < resp.size(); i++)
|
||||
// {
|
||||
// if (resp.at(i) >= '0' && resp.at(i) <= '9') {
|
||||
// len += resp.at(i);
|
||||
// }
|
||||
// else {
|
||||
// length = std::atoi(len.c_str());
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (end && body.size() >= length) {
|
||||
// client.Close();
|
||||
// printf("服务端断开 %s %d\n", client.Address.c_str(), client.Port);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// printf("%s\n", body.c_str());
|
||||
// }*/
|
||||
//}
|
||||
//
|
||||
//int main(int argc, char* argv[])
|
||||
//{
|
||||
//
|
||||
// StopWatch sw;
|
||||
// for (size_t i = 0; i < 15; i++)
|
||||
// {
|
||||
// WebClient wc;
|
||||
// std::string resp;
|
||||
// std::string key = "var items=";
|
||||
// size_t pos1 = size_t(-1), pos2 = size_t(-1);
|
||||
// wc.CallBack = ([=, &pos1, &pos2](char* contents, size_t size, size_t nmemb, void* respone)->size_t {
|
||||
// size_t count = size * nmemb;
|
||||
// std::string* str = (std::string*)respone;
|
||||
// (*str).append(contents, count);
|
||||
// if (pos1 == size_t(-1)) {
|
||||
// pos1 = str->find(key);
|
||||
// }
|
||||
// if (pos1 != size_t(-1)) {
|
||||
// pos2 = str->find("}];", key.size() + pos1);
|
||||
// if (pos2 != size_t(-1)) {
|
||||
// *str = str->substr(pos1 + key.size(), pos2 - (pos1 + key.size())) + "}]";
|
||||
// return 23;//终止
|
||||
// }
|
||||
// }
|
||||
// return count;
|
||||
// });
|
||||
// wc.HttpGet("http://163.197.44.13/Web/reserve/materialx?languages=1", resp, 999);
|
||||
// }
|
||||
// auto time = sw.ElapsedMilliseconds();
|
||||
// return 0;
|
||||
//}
|
||||
30
demo/kugou/include/Common/include/Common.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <io.h>
|
||||
#include <Windows.h>
|
||||
#include <winuser.h>
|
||||
#include <assert.h>
|
||||
|
||||
#pragma warning(disable:4018)
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4551)
|
||||
#pragma warning(disable:4293)
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4099)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4101)
|
||||
#pragma warning(disable:4267)
|
||||
|
||||
|
||||
#include "Text.h"
|
||||
#include "FileSystem.h"
|
||||
#include "Time.hpp"//防止和系统的time.h重命名
|
||||
#include "WinTool.h"
|
||||
38
demo/kugou/include/Common/include/ConfigIni.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include "Text.h"
|
||||
|
||||
class ConfigIni {
|
||||
protected:
|
||||
size_t buffSize;
|
||||
Text::String filename;
|
||||
Text::String section;
|
||||
DWORD GetValue(const Text::String& key, const Text::String& filename, Text::String& outResult);
|
||||
bool SetValue(const Text::String& key, const Text::String& Value, const Text::String& absoluteFilename);
|
||||
private:
|
||||
ConfigIni() = delete;
|
||||
ConfigIni(const ConfigIni&) = delete;
|
||||
public:
|
||||
//FileName //一定要绝对路径
|
||||
ConfigIni(const Text::String& filename, const Text::String& defaultSection = "setting", size_t buffSize = 1024);
|
||||
//设置一个名称
|
||||
void SetSection(const Text::String& sectionName);
|
||||
//读取ini中的字符
|
||||
Text::String ReadString(const Text::String& key, const Text::String& defaultValue = "");
|
||||
//读取ini中的数字
|
||||
float ReadFloat(const Text::String& key, float defaultValue = 0);
|
||||
//读取ini中的int数字
|
||||
int ReadInt(const Text::String& key, int defaultValue = 0);
|
||||
//读取bool类型值
|
||||
bool ReadBool(const Text::String& key, bool defaultValue = false);
|
||||
//写入ini
|
||||
bool WriteString(const Text::String& key, const Text::String& value);
|
||||
bool WriteFloat(const Text::String& key, float value);
|
||||
bool WriteInt(const Text::String& key, int value);
|
||||
bool WriteBool(const Text::String& key, bool defaultValue);
|
||||
|
||||
//获取所有的Section
|
||||
std::vector<Text::String> GetSections();
|
||||
//删除所有的Section
|
||||
void DeleteSection(const Text::String& section);
|
||||
};
|
||||
147
demo/kugou/include/Common/include/FileSystem.h
Normal file
@@ -0,0 +1,147 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <Windows.h>
|
||||
#include "Text.h"
|
||||
|
||||
namespace FileSystem {
|
||||
class FileInfo;
|
||||
enum FileType :int
|
||||
{
|
||||
File = 2,
|
||||
Directory = 4
|
||||
};
|
||||
//重载枚举的 | 运算符
|
||||
inline FileType operator|(FileType left, FileType right)
|
||||
{
|
||||
return static_cast<FileType>(static_cast<int>(left) | static_cast<int>(right));
|
||||
}
|
||||
};
|
||||
|
||||
namespace File {
|
||||
typedef std::string FileStream;
|
||||
//创建文件
|
||||
extern bool Create(const Text::String& filename);
|
||||
//删除文件
|
||||
extern bool Delete(const Text::String& filename);
|
||||
//判断文件是否存在
|
||||
extern bool Exists(const Text::String& filename);
|
||||
//文件移动或者改名
|
||||
extern bool Move(const Text::String& oldname, const Text::String& newname);
|
||||
//读取文件并out返回
|
||||
extern bool ReadFile(const Text::String& filename, FileStream* fileStream);
|
||||
//写入文件
|
||||
extern bool WriteFile(const FileStream* fileStream, const Text::String& filename);
|
||||
//写入文件
|
||||
extern bool WriteFile(const char* fileStream, size_t count, const Text::String& filename);
|
||||
//拷贝文件
|
||||
extern bool Copy(const Text::String& filename, const Text::String& des_filename, bool overwrite = true);
|
||||
//获取文件字节大小
|
||||
extern ULONGLONG GetFileSize(const Text::String& fileName);
|
||||
};
|
||||
|
||||
namespace Directory {
|
||||
//创建目录
|
||||
extern bool Create(const Text::String& path);
|
||||
//拷贝目录所有文件到目标目录
|
||||
extern bool Copy(const Text::String& srcPath, const Text::String& desPath, bool overwrite = true);
|
||||
//移动目录到新位置
|
||||
extern bool Move(const Text::String& oldname, const Text::String& newname);
|
||||
//删除路径 如果存在子文件夹或者文件 将会递归删除
|
||||
extern bool Delete(const Text::String& directoryName);
|
||||
//通配符查找文件夹/文件
|
||||
extern size_t Find(const Text::String& path, std::vector<FileSystem::FileInfo>& result, const Text::String& pattern = "*.*", bool loopSubDir = false, FileSystem::FileType fileType = FileSystem::FileType::Directory | FileSystem::FileType::File);
|
||||
//检查路径是否存在
|
||||
extern bool Exists(const Text::String& path);
|
||||
};
|
||||
|
||||
namespace Path {
|
||||
//格式化路径为统一反斜杠
|
||||
extern Text::String Format(const Text::String& path);
|
||||
//判断路径是不是相同
|
||||
extern bool Equal(const Text::String& path1, const Text::String& path2);
|
||||
//获取文件名称(文件名称)
|
||||
extern Text::String GetFileNameWithoutExtension(const Text::String& _filename);
|
||||
//获取文件目录名称(所在目录)
|
||||
extern Text::String GetDirectoryName(const Text::String& _filename);
|
||||
//获取文件名称+后缀
|
||||
extern Text::String GetFileName(const Text::String& _filename);
|
||||
//获取用户桌面路径
|
||||
extern Text::String UserDesktop(bool publicUser = true);
|
||||
//获取开始菜单路径
|
||||
extern Text::String StartPrograms(bool publicUser = true);
|
||||
//获取文件后缀名(后缀名)
|
||||
extern Text::String GetExtension(const Text::String& _filename);
|
||||
//获取进程所在绝对路径目录
|
||||
extern Text::String StartPath();
|
||||
//获取进程所在绝对路径包含文件名称
|
||||
extern const Text::String& StartFileName();
|
||||
#undef GetTempPath
|
||||
/// <summary>
|
||||
/// 获取应当前windows用户的临时目录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
extern Text::String GetTempPath();
|
||||
/// <summary>
|
||||
/// 获取应用程序的临时目录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
extern Text::String GetAppTempPath(const Text::String& appName = "");
|
||||
/// <summary>
|
||||
/// 获取应用程序数据存储目录 C:/Users/%s/AppData/Local/%s
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
extern Text::String GetAppDataPath(const Text::String& appName = "");
|
||||
};
|
||||
namespace FileSystem {
|
||||
class FileInfo
|
||||
{
|
||||
private:
|
||||
std::ifstream* ifs = NULL;
|
||||
ULONGLONG StreamPos = 0;
|
||||
public:
|
||||
DWORD dwFileAttributes;
|
||||
const Text::String FileName;
|
||||
bool IsFile() const {
|
||||
return !(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
bool IsReadOnly() const {
|
||||
return dwFileAttributes & FILE_ATTRIBUTE_READONLY;
|
||||
}
|
||||
const ULONGLONG FileSize = 0;
|
||||
FileInfo() {}
|
||||
FileInfo(const Text::String& fileName) {
|
||||
if (File::Exists(fileName)) {
|
||||
(Text::String)FileName = fileName;
|
||||
//获取大小
|
||||
ifs = new std::ifstream(fileName.unicode(), std::ios::binary);
|
||||
ifs->seekg(0, std::ios::end);
|
||||
(ULONGLONG&)FileSize = ifs->tellg();
|
||||
}
|
||||
}
|
||||
size_t Read(char* _buf_, size_t _rdCount = 255) {
|
||||
size_t rdbufCount = _rdCount;
|
||||
if (StreamPos + _rdCount >= FileSize) {
|
||||
rdbufCount = FileSize - StreamPos;
|
||||
}
|
||||
if (rdbufCount == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (ifs == NULL) {
|
||||
ifs = new std::ifstream(FileName.unicode(), std::ios::binary);
|
||||
}
|
||||
ifs->seekg(StreamPos);
|
||||
ifs->read(_buf_, rdbufCount);
|
||||
StreamPos += rdbufCount;
|
||||
return rdbufCount;
|
||||
}
|
||||
void Close() {
|
||||
ifs->close();
|
||||
}
|
||||
~FileInfo() {
|
||||
if (ifs) {
|
||||
delete ifs;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
39
demo/kugou/include/Common/include/JsonValue.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
|
||||
#define USEJSONCPP 1 //是否使用JsonCpp库
|
||||
|
||||
#if USEJSONCPP
|
||||
#include <json/json.h>
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
#ifdef _DEBUG
|
||||
#pragma comment (lib,"X64/json_libd.lib")
|
||||
#else
|
||||
#pragma comment (lib,"X64/json_lib.lib")
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef _DEBUG
|
||||
#pragma comment (lib,"json_libd.lib")
|
||||
#else
|
||||
#pragma comment (lib,"json_lib.lib")
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
struct JsonValue :public Json::Value {
|
||||
private:
|
||||
bool b = false;
|
||||
Json::Reader rd;
|
||||
public:
|
||||
bool IsJson();
|
||||
//JObject(const Json::Value& right);
|
||||
JsonValue& operator = (const Json::Value& other);
|
||||
JsonValue(const std::string& jsonStr);
|
||||
};
|
||||
#endif
|
||||
37
demo/kugou/include/Common/include/Log.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "Time.hpp"
|
||||
namespace Log {
|
||||
//是否启用日志
|
||||
extern bool Enable;
|
||||
extern bool WriteFile;
|
||||
extern void WriteLog(const Text::String& log);
|
||||
|
||||
template<typename ...T>
|
||||
/// <summary>
|
||||
/// 打印utf8的字符
|
||||
/// </summary>
|
||||
/// <typeparam name="...T"></typeparam>
|
||||
/// <param name="formatStr"></param>
|
||||
/// <param name="...args"></param>
|
||||
inline Text::String Info(const Text::String& formatStr, const T &...args) {
|
||||
if (!Enable)return "";
|
||||
// 计算格式化后的字符串所需的内存大小
|
||||
int bufSize = ::snprintf(nullptr, 0, formatStr.c_str(), args...) + 2; // +1是为了换行符和结束符 \n '\0'
|
||||
char* buf = new char[bufSize];
|
||||
auto count = ::sprintf_s(buf, bufSize, formatStr.c_str(), std::forward<const T&>(args)...);
|
||||
buf[count] = '\n';
|
||||
buf[count + 1] = 0;
|
||||
Text::String info(buf);
|
||||
info = Time::Now().ToString("HH:mm:ss ") + info;
|
||||
delete[] buf;
|
||||
//转为本地可识别的编码
|
||||
auto ansi = info.ansi();
|
||||
std::cout << ansi;
|
||||
OutputDebugStringA(ansi.c_str());
|
||||
WriteLog(info);
|
||||
return info;
|
||||
}
|
||||
};
|
||||
46
demo/kugou/include/Common/include/Map.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
|
||||
template<class T1, class T2>
|
||||
class Map :protected std::unordered_map<T1, T2> {
|
||||
using __base = std::unordered_map<T1, T2>;
|
||||
T2 defaultValue = T2();//当获取不到value的时候返回的默认值
|
||||
public:
|
||||
typename __base::iterator begin() {
|
||||
return __base::begin();
|
||||
}
|
||||
typename __base::iterator end() {
|
||||
return __base::end();
|
||||
}
|
||||
bool insert(const T1& key, const T2& value) {
|
||||
auto itor = __base::insert(std::pair<T1, T2>(key, value));
|
||||
return itor.second;
|
||||
}
|
||||
bool empty() {
|
||||
return __base::empty();
|
||||
}
|
||||
size_t size() {
|
||||
return __base::size();
|
||||
}
|
||||
const T2& operator[](const T1& key) const {
|
||||
auto itor = __base::find(key);
|
||||
if (itor != __base::end()) {
|
||||
return itor->second;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
typename __base::iterator find(const T1& key) {
|
||||
return __base::find(key);
|
||||
}
|
||||
void erase(const typename __base::iterator& itor) {
|
||||
__base::erase(itor);
|
||||
}
|
||||
bool erase(const T1& key) {
|
||||
auto itor = __base::find(key);
|
||||
if (itor != __base::end()) {
|
||||
__base::erase(itor);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
284
demo/kugou/include/Common/include/MySqlClient.hpp
Normal file
@@ -0,0 +1,284 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <winsock.h>
|
||||
#include <mysql/mysql.h>
|
||||
#pragma comment(lib,"libmysql.lib")
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "JsonValue.h"
|
||||
/*
|
||||
mysql的连接类
|
||||
*/
|
||||
class MySqlClient
|
||||
{
|
||||
public:
|
||||
//处理防注入的
|
||||
class PreparedStatement {
|
||||
struct Pair {
|
||||
char type;
|
||||
int value_int;//type 0
|
||||
std::string value_str;//type 1
|
||||
};
|
||||
std::string sql;
|
||||
std::vector<Pair> values;
|
||||
friend MySqlClient;
|
||||
public:
|
||||
PreparedStatement(const std::string& sql) :sql(sql) {
|
||||
}
|
||||
PreparedStatement& Replace(int value) {
|
||||
values.push_back({ 0,value });
|
||||
return *this;
|
||||
}
|
||||
PreparedStatement& Replace(const std::string& value) {
|
||||
values.push_back({ 1,0,value });
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
std::string host;
|
||||
std::string user;
|
||||
std::string pwd;
|
||||
std::string database;
|
||||
std::string charset;
|
||||
unsigned int port = 3306;
|
||||
private:
|
||||
static size_t get_data(MYSQL_RES* result, std::string& jsonArr) {
|
||||
std::vector<std::string> fields;
|
||||
//获取列名
|
||||
size_t filedCount = mysql_num_fields(result);
|
||||
for (size_t i = 0; i < filedCount; i++)
|
||||
{
|
||||
std::string name = mysql_fetch_field(result)->name;
|
||||
fields.push_back(name);
|
||||
//std::cout << name << std::endl;
|
||||
}
|
||||
jsonArr = "[";
|
||||
//获取每行的数据
|
||||
MYSQL_ROW sql_row;
|
||||
size_t rowCount = 0;
|
||||
while (sql_row = mysql_fetch_row(result))//获取具体的数据
|
||||
{
|
||||
rowCount++;
|
||||
jsonArr.append("{");
|
||||
bool frist_ = true;
|
||||
for (size_t i = 0; i < filedCount; i++)
|
||||
{
|
||||
if (sql_row[i]) {
|
||||
jsonArr.append("\"" + fields[i] + "\":\"" + sql_row[i] + "\"");
|
||||
}
|
||||
else {
|
||||
jsonArr.append("\"" + fields[i] + "\":\"\"");
|
||||
}
|
||||
jsonArr.append(",");
|
||||
}
|
||||
jsonArr.erase(jsonArr.length() - 1, 1);
|
||||
jsonArr.append("},");
|
||||
}
|
||||
jsonArr.erase(jsonArr.length() - 1, 1);
|
||||
jsonArr.append("]");
|
||||
if (rowCount == 0) {
|
||||
jsonArr = "[]";
|
||||
}
|
||||
return rowCount;
|
||||
}
|
||||
public:
|
||||
bool OpenConn(MYSQL& mysql);
|
||||
void CloseConn(MYSQL& mysql);
|
||||
MySqlClient(const std::string& host, unsigned int port, const std::string& user, const std::string& pwd, const std::string& database, const std::string& charset = "utf8mb4");
|
||||
/*执行查询*/
|
||||
bool ExecuteQuery(const std::string& sql, std::string& result);
|
||||
/*执行增删改*/
|
||||
size_t ExecuteNoQuery(const std::string& sql);
|
||||
|
||||
size_t Insert(const std::string& tableName, const Json::Value& jv);
|
||||
size_t Update(const std::string& tableName, const Json::Value& jv, const std::string& whereText);
|
||||
bool ExecuteQuery(const std::string& sql, Json::Value& result);
|
||||
bool ExecuteSTMT(const PreparedStatement& _stmt, std::string& result);
|
||||
virtual ~MySqlClient();
|
||||
};
|
||||
|
||||
inline bool MySqlClient::OpenConn(MYSQL& mysql)
|
||||
{
|
||||
const char* unix_socket = NULL;
|
||||
unsigned long client_flag = 0;
|
||||
mysql_init(&mysql); //初始化
|
||||
if ((mysql_real_connect(&mysql, host.c_str(), user.c_str(), pwd.c_str(), database.c_str(), port, unix_socket, client_flag)) == NULL) //连接MySQL
|
||||
{
|
||||
//数据库打开失败
|
||||
printf("%s\n", mysql_error(&mysql));
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
//数据库打开
|
||||
return true;
|
||||
}
|
||||
}
|
||||
inline void MySqlClient::CloseConn(MYSQL& mysql)
|
||||
{
|
||||
mysql_close(&mysql);
|
||||
}
|
||||
inline MySqlClient::MySqlClient(const std::string& host, unsigned int port, const std::string& user, const std::string& pwd, const std::string& database, const std::string& charset)
|
||||
{
|
||||
this->host = host;
|
||||
this->user = user;
|
||||
this->pwd = pwd;
|
||||
this->database = database;
|
||||
this->charset = charset;
|
||||
this->port = port;
|
||||
}
|
||||
inline bool MySqlClient::ExecuteSTMT(const PreparedStatement& _stmt, std::string& resultJson) {
|
||||
MYSQL mysql;
|
||||
if (!OpenConn(mysql)) {
|
||||
return false;
|
||||
}
|
||||
std::string charset_ = "set names ";
|
||||
charset_.append(charset);
|
||||
mysql_query(&mysql, charset_.c_str());
|
||||
|
||||
MYSQL_BIND* binds = NULL;
|
||||
MYSQL_STMT* stmt = NULL;
|
||||
MYSQL_RES* result = NULL;
|
||||
bool ok = false;
|
||||
do
|
||||
{
|
||||
binds = new MYSQL_BIND[_stmt.values.size()];
|
||||
::memset(binds, 0, sizeof(MYSQL_BIND) * _stmt.values.size());
|
||||
int pos = 0;
|
||||
for (auto& it : _stmt.values) {
|
||||
if (it.type == 0) {
|
||||
binds[pos].buffer_type = MYSQL_TYPE_LONG;
|
||||
binds[pos].buffer = (char*)&it.value_int;
|
||||
binds[pos].is_null = 0;
|
||||
}
|
||||
else if (it.type == 1) {
|
||||
binds[pos].buffer_type = MYSQL_TYPE_STRING;
|
||||
binds[pos].buffer = (char*)it.value_str.c_str();
|
||||
binds[pos].buffer_length = it.value_str.size();
|
||||
binds[pos].is_null = 0;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
stmt = mysql_stmt_init(&mysql);
|
||||
if (mysql_stmt_prepare(stmt, _stmt.sql.c_str(), _stmt.sql.size()) != 0) {
|
||||
std::cerr << "Failed to mysql_stmt_prepare: " << mysql_stmt_error(stmt) << std::endl;
|
||||
break;
|
||||
}
|
||||
if (mysql_stmt_bind_param(stmt, binds) != 0) {
|
||||
std::cerr << "Failed to mysql_stmt_bind_param: " << mysql_stmt_error(stmt) << std::endl;
|
||||
break;
|
||||
}
|
||||
//执行
|
||||
if (mysql_stmt_execute(stmt) != 0) {
|
||||
std::cerr << "Failed to mysql_stmt_execute: " << mysql_stmt_error(stmt) << std::endl;
|
||||
break;
|
||||
}
|
||||
result = mysql_stmt_result_metadata(stmt);
|
||||
ok = true;
|
||||
} while (false);
|
||||
//获取结果
|
||||
if (result == NULL) {
|
||||
resultJson = "[]";
|
||||
}
|
||||
else {
|
||||
get_data(result, resultJson);
|
||||
}
|
||||
//释放
|
||||
CloseConn(mysql);
|
||||
delete[] binds;
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_free_result(result);
|
||||
return ok;
|
||||
}
|
||||
inline bool MySqlClient::ExecuteQuery(const std::string& sql, std::string& resultx)
|
||||
{
|
||||
MYSQL mysql;
|
||||
if (!OpenConn(mysql)) {
|
||||
return false;
|
||||
}
|
||||
std::string charset_ = "set names ";
|
||||
charset_.append(charset);
|
||||
mysql_query(&mysql, charset_.c_str());
|
||||
mysql_query(&mysql, sql.c_str());
|
||||
MYSQL_RES* result = NULL;
|
||||
result = mysql_store_result(&mysql);
|
||||
//查询失败
|
||||
if (!result) {
|
||||
mysql_free_result(result);
|
||||
CloseConn(mysql);
|
||||
resultx = "[]";
|
||||
return false;
|
||||
}
|
||||
get_data(result, resultx);
|
||||
//释放
|
||||
mysql_free_result(result);
|
||||
CloseConn(mysql);
|
||||
return true;
|
||||
}
|
||||
inline size_t MySqlClient::ExecuteNoQuery(const std::string& sql)
|
||||
{
|
||||
MYSQL mysql;
|
||||
if (!OpenConn(mysql)) {
|
||||
return false;
|
||||
}
|
||||
std::string charset_ = "set names ";
|
||||
charset_.append(charset);
|
||||
mysql_query(&mysql, charset_.c_str());
|
||||
mysql_query(&mysql, sql.c_str());
|
||||
size_t affected_row = mysql_affected_rows(&mysql);
|
||||
CloseConn(mysql);
|
||||
return affected_row;
|
||||
}
|
||||
inline size_t MySqlClient::Update(const std::string& tableName, const Json::Value& jv, const std::string& whereText) {
|
||||
std::string sql = "update " + tableName + " set ";
|
||||
for (const auto& key : jv.getMemberNames()) {
|
||||
if (jv[key].isNumeric()) {
|
||||
sql += (key + "=" + jv[key].toString() + "");
|
||||
}
|
||||
else if (jv[key].isString()) {
|
||||
sql += (key + "='" + jv[key].asString() + "'");
|
||||
}
|
||||
else {
|
||||
sql += (key + "='" + jv[key].toString() + "'");
|
||||
}
|
||||
sql += ",";
|
||||
}
|
||||
sql.erase(sql.size() - 1, 1);
|
||||
sql += " " + whereText;
|
||||
return this->ExecuteNoQuery(sql);
|
||||
}
|
||||
inline size_t MySqlClient::Insert(const std::string& tableName, const Json::Value& jv) {
|
||||
std::string keys = "(";
|
||||
std::string values = "(";
|
||||
for (const auto& key : jv.getMemberNames()) {
|
||||
keys += "" + key + ",";
|
||||
if (jv[key].isNumeric()) {
|
||||
values += jv[key].toString() + ",";
|
||||
}
|
||||
else if (jv[key].isString()) {
|
||||
values += "'" + jv[key].asString() + "',";
|
||||
}
|
||||
else {
|
||||
values += "'" + jv[key].asString() + "',";
|
||||
}
|
||||
}
|
||||
keys.erase(keys.size() - 1, 1);
|
||||
values.erase(values.size() - 1, 1);
|
||||
keys += ")";
|
||||
values += ")";
|
||||
std::string sql = "insert into " + tableName + " " + keys + "values" + values;
|
||||
return this->ExecuteNoQuery(sql);
|
||||
}
|
||||
inline bool MySqlClient::ExecuteQuery(const std::string& sql, Json::Value& result)
|
||||
{
|
||||
std::string str;
|
||||
auto ret = this->ExecuteQuery(sql, str);
|
||||
result = JsonValue(str);
|
||||
return ret;
|
||||
}
|
||||
inline MySqlClient::~MySqlClient()
|
||||
{
|
||||
}
|
||||
132
demo/kugou/include/Common/include/OrcaleClient.hpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <occi/occi.h>
|
||||
using namespace oracle::occi;
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib,"oraocci12d.lib")
|
||||
#else
|
||||
#pragma comment(lib,"oraocci12.lib")
|
||||
#endif // _DEBUG
|
||||
#include <string>
|
||||
class OrcaleClient
|
||||
{
|
||||
private:
|
||||
std::string host;
|
||||
unsigned int port = 1521;
|
||||
std::string user;
|
||||
std::string pwd;
|
||||
std::string server_name;
|
||||
std::string charset;
|
||||
Environment* outEnv = NULL;
|
||||
std::string dbStr;
|
||||
public:
|
||||
virtual ~OrcaleClient() {
|
||||
if (outEnv) {
|
||||
Environment::terminateEnvironment(outEnv);
|
||||
}
|
||||
}
|
||||
OrcaleClient(const std::string& host, unsigned int port, const std::string& user, const std::string& pwd, const std::string& server_name, const std::string& charset = "UTF8");
|
||||
void CloseConn(Connection* conn);
|
||||
Connection* OpenConn();
|
||||
bool ExecuteQuery(const std::string& sql, std::string& sqlResult);
|
||||
size_t ExecuteNoQuery(const std::string& sql);
|
||||
};
|
||||
|
||||
inline Connection* OrcaleClient::OpenConn() {
|
||||
try
|
||||
{
|
||||
auto conn = outEnv->createConnection(user, pwd, dbStr);
|
||||
return conn;
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
printf("%s\n", ex.what());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
inline void OrcaleClient::CloseConn(Connection* conn) {
|
||||
outEnv->terminateConnection(conn);
|
||||
}
|
||||
inline OrcaleClient::OrcaleClient(const std::string& host, unsigned int port, const std::string& user, const std::string& pwd, const std::string& server_name, const std::string& charset) {
|
||||
this->host = host;
|
||||
this->port = port;
|
||||
this->user = user;
|
||||
this->pwd = pwd;
|
||||
this->server_name = server_name;
|
||||
this->charset = charset;
|
||||
this->dbStr = host + ":" + std::to_string(port) + "/" + server_name;
|
||||
this->outEnv = Environment::createEnvironment("ZHS16GBK", this->charset);//编码问题
|
||||
}
|
||||
inline size_t OrcaleClient::ExecuteNoQuery(const std::string& sql) {
|
||||
size_t affRow = 0;
|
||||
auto conn = OpenConn();
|
||||
if (conn) {
|
||||
Statement* stmt = NULL;
|
||||
try {
|
||||
stmt = conn->createStatement();
|
||||
affRow = stmt->executeUpdate(sql);
|
||||
}
|
||||
catch (SQLException& ex)
|
||||
{
|
||||
printf("%s\n", ex.what());
|
||||
}
|
||||
if (stmt) {
|
||||
conn->terminateStatement(stmt);
|
||||
}
|
||||
CloseConn(conn);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
inline bool OrcaleClient::ExecuteQuery(const std::string& sql, std::string& sqlResult) {
|
||||
bool ok = false;
|
||||
auto conn = OpenConn();
|
||||
if (conn) {
|
||||
std::vector<std::string> fields;
|
||||
Statement* stmt = NULL;
|
||||
ResultSet* rset = NULL;
|
||||
try {
|
||||
stmt = conn->createStatement();
|
||||
rset = stmt->executeQuery(sql);
|
||||
for (auto item : rset->getColumnListMetaData()) {
|
||||
std::string s = item.getString(MetaData::ATTR_NAME);
|
||||
fields.push_back(s);
|
||||
}
|
||||
sqlResult = "[";
|
||||
//获取每行的数据
|
||||
bool frist = true;
|
||||
size_t rowCount = 0;
|
||||
while (rset->next())//获取具体的数据
|
||||
{
|
||||
rowCount++;
|
||||
sqlResult.append("{");
|
||||
bool frist_ = true;
|
||||
for (size_t i = 0; i < fields.size(); i++)
|
||||
{
|
||||
sqlResult.append("\"" + fields[i] + "\":\"" + rset->getString(i + 1) + "\"");
|
||||
sqlResult.append(",");
|
||||
}
|
||||
sqlResult.erase(sqlResult.length() - 1, 1);
|
||||
sqlResult.append("},");
|
||||
if (frist) {
|
||||
frist = false;
|
||||
}
|
||||
}
|
||||
sqlResult.erase(sqlResult.length() - 1, 1);
|
||||
sqlResult.append("]");
|
||||
if (rowCount == 0) {
|
||||
sqlResult = "[]";
|
||||
}
|
||||
ok = true;
|
||||
}
|
||||
catch (SQLException& ex)
|
||||
{
|
||||
printf("%s\n", ex.what());
|
||||
}
|
||||
if (stmt && rset) {
|
||||
stmt->closeResultSet(rset);
|
||||
conn->terminateStatement(stmt);
|
||||
}
|
||||
CloseConn(conn);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
169
demo/kugou/include/Common/include/QrenCode.hpp
Normal file
@@ -0,0 +1,169 @@
|
||||
#pragma once
|
||||
#include "Common.h"
|
||||
#include "qrcode/qrencode.h"
|
||||
|
||||
#ifdef _WIN64
|
||||
#ifdef _DEBUG
|
||||
#pragma comment (lib,"X64/libqrencode_d.lib")
|
||||
#else
|
||||
#pragma comment (lib,"X64/libqrencode.lib")
|
||||
#endif
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib,"libqrencode_d.lib")
|
||||
#else
|
||||
#pragma comment(lib,"libqrencode.lib")
|
||||
#endif // !_DEBUG
|
||||
#endif
|
||||
|
||||
namespace QrenCode {
|
||||
//生成二维码 返回位图 用完位图记得释放
|
||||
inline HBITMAP Generate(const std::string& str, QRecLevel level = QRecLevel::QR_ECLEVEL_M) {
|
||||
unsigned int unWidth, x, y, l, n, unWidthAdjusted;
|
||||
byte* pRGBData = NULL, * pSourceData, * pDestData;
|
||||
QRcode* pQRC = NULL;
|
||||
HBITMAP bmp = NULL;
|
||||
do
|
||||
{
|
||||
if (pQRC = QRcode_encodeString(str.c_str(), 0, level, QR_MODE_8, 1))
|
||||
{
|
||||
unWidth = pQRC->width;
|
||||
unWidthAdjusted = unWidth * 8 * 3;
|
||||
if (unWidthAdjusted % 4) {
|
||||
unWidthAdjusted = (unWidthAdjusted / 4 + 1) * 4;
|
||||
}
|
||||
|
||||
BITMAPINFO bmpInfo;
|
||||
memset(&bmpInfo, 0, sizeof(bmpInfo));
|
||||
BITMAPINFOHEADER& kInfoHeader = bmpInfo.bmiHeader;
|
||||
kInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
kInfoHeader.biWidth = unWidth * 8;
|
||||
kInfoHeader.biHeight = -((int)unWidth * 8);
|
||||
kInfoHeader.biPlanes = 1;
|
||||
kInfoHeader.biBitCount = 24;
|
||||
kInfoHeader.biCompression = BI_RGB;
|
||||
kInfoHeader.biSizeImage = 0;
|
||||
kInfoHeader.biXPelsPerMeter = 0;
|
||||
kInfoHeader.biYPelsPerMeter = 0;
|
||||
kInfoHeader.biClrUsed = 0;
|
||||
kInfoHeader.biClrImportant = 0;
|
||||
// Convert QrCode bits to bmp pixels
|
||||
pSourceData = pQRC->data;
|
||||
|
||||
bmp = ::CreateDIBSection(NULL, &bmpInfo, DIB_RGB_COLORS, (void**)&pRGBData, NULL, 0);
|
||||
|
||||
for (y = 0; y < unWidth; y++)
|
||||
{
|
||||
pDestData = pRGBData + unWidthAdjusted * y * 8;
|
||||
for (x = 0; x < unWidth; x++)
|
||||
{
|
||||
if (*pSourceData & 1)
|
||||
{
|
||||
for (l = 0; l < 8; l++)
|
||||
{
|
||||
for (n = 0; n < 8; n++)
|
||||
{
|
||||
//以下三行是设置三基色,三基色都设置为0x00,则生成的二维码图片就是黑色的了,要什么颜色自己调整
|
||||
*(pDestData + n * 3 + unWidthAdjusted * l) = 0x00;
|
||||
*(pDestData + 1 + n * 3 + unWidthAdjusted * l) = 0x00;
|
||||
*(pDestData + 2 + n * 3 + unWidthAdjusted * l) = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
pDestData += 3 * 8;
|
||||
pSourceData++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (false);
|
||||
if (pQRC) {
|
||||
QRcode_free(pQRC);
|
||||
}
|
||||
return bmp;
|
||||
////绑定dc
|
||||
//HDC dc=::CreateCompatibleDC(NULL);
|
||||
//::SelectObject(dc, bmp);
|
||||
////用完释放
|
||||
//::DeleteDC(dc);
|
||||
//::DeleteObject(bmp);
|
||||
}
|
||||
//生成二维码到内存
|
||||
inline bool Generate(const std::string& str, std::string& outFileData, QRecLevel level = QRecLevel::QR_ECLEVEL_M) {
|
||||
const char* szSourceSring = str.c_str();
|
||||
unsigned int unWidth, x, y, l, n, unWidthAdjusted, unDataBytes;
|
||||
byte* pSourceData, * pDestData;
|
||||
QRcode* pQRC = NULL;
|
||||
do
|
||||
{
|
||||
if (pQRC = QRcode_encodeString(szSourceSring, 0, level, QR_MODE_8, 1))
|
||||
{
|
||||
unWidth = pQRC->width;
|
||||
unWidthAdjusted = unWidth * 8 * 3;
|
||||
if (unWidthAdjusted % 4) {
|
||||
unWidthAdjusted = (unWidthAdjusted / 4 + 1) * 4;
|
||||
}
|
||||
unDataBytes = unWidthAdjusted * unWidth * 8;
|
||||
|
||||
// Prepare bmp headers
|
||||
BITMAPFILEHEADER kFileHeader;
|
||||
kFileHeader.bfType = 0x4d42;
|
||||
kFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + unDataBytes;
|
||||
kFileHeader.bfReserved1 = 0;
|
||||
kFileHeader.bfReserved2 = 0;
|
||||
kFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
||||
BITMAPINFOHEADER kInfoHeader;
|
||||
kInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
kInfoHeader.biWidth = unWidth * 8;
|
||||
kInfoHeader.biHeight = -((int)unWidth * 8);
|
||||
kInfoHeader.biPlanes = 1;
|
||||
kInfoHeader.biBitCount = 24;
|
||||
kInfoHeader.biCompression = BI_RGB;
|
||||
kInfoHeader.biSizeImage = 0;
|
||||
kInfoHeader.biXPelsPerMeter = 0;
|
||||
kInfoHeader.biYPelsPerMeter = 0;
|
||||
kInfoHeader.biClrUsed = 0;
|
||||
kInfoHeader.biClrImportant = 0;
|
||||
// Convert QrCode bits to bmp pixels
|
||||
pSourceData = pQRC->data;
|
||||
|
||||
//因为是放在内存 所以简化了一些
|
||||
outFileData.resize(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + unDataBytes);
|
||||
byte* ptr = (byte*)outFileData.c_str();
|
||||
::memcpy(ptr, (char*)&kFileHeader, sizeof(kFileHeader));
|
||||
ptr += sizeof(kFileHeader);
|
||||
::memcpy(ptr, (char*)&kInfoHeader, sizeof(kInfoHeader));
|
||||
ptr += sizeof(kInfoHeader);
|
||||
byte* pRGBData = ptr;
|
||||
// Preset to white
|
||||
::memset(pRGBData, 0xff, unDataBytes);
|
||||
|
||||
for (y = 0; y < unWidth; y++)
|
||||
{
|
||||
pDestData = pRGBData + unWidthAdjusted * y * 8;
|
||||
for (x = 0; x < unWidth; x++)
|
||||
{
|
||||
if (*pSourceData & 1)
|
||||
{
|
||||
for (l = 0; l < 8; l++)
|
||||
{
|
||||
for (n = 0; n < 8; n++)
|
||||
{
|
||||
//以下三行是设置三基色,三基色都设置为0x00,则生成的二维码图片就是黑色的了,要什么颜色自己调整
|
||||
*(pDestData + n * 3 + unWidthAdjusted * l) = 0x00;
|
||||
*(pDestData + 1 + n * 3 + unWidthAdjusted * l) = 0x00;
|
||||
*(pDestData + 2 + n * 3 + unWidthAdjusted * l) = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
pDestData += 3 * 8;
|
||||
pSourceData++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (false);
|
||||
if (pQRC) {
|
||||
QRcode_free(pQRC);
|
||||
}
|
||||
return !outFileData.empty();
|
||||
}
|
||||
};
|
||||
16
demo/kugou/include/Common/include/Random.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <random>
|
||||
class Random {
|
||||
std::mt19937 randomer;
|
||||
public:
|
||||
Random() :randomer(std::random_device()()) {
|
||||
}
|
||||
int Next(int lower, int upper) {
|
||||
std::uniform_int_distribution<int> distribution(lower, upper);
|
||||
return distribution(randomer);
|
||||
}
|
||||
float Next(float lower, float upper) {
|
||||
std::uniform_real_distribution<float> distribution(lower, upper);
|
||||
return distribution(randomer);
|
||||
}
|
||||
};
|
||||
168
demo/kugou/include/Common/include/Regedit.hpp
Normal file
@@ -0,0 +1,168 @@
|
||||
//#pragma once
|
||||
//#include <windows.h>
|
||||
//#include <stdio.h>
|
||||
//#include <strsafe.h>
|
||||
//
|
||||
//namespace Regedit {
|
||||
// //删除指定key
|
||||
// BOOL DelKey(HKEY keyRoot, LPTSTR keyPath);
|
||||
// //判断是否存在key
|
||||
// BOOL Exist(HKEY keyRoot, LPTSTR keyPath);
|
||||
//
|
||||
// bool SetValue(HKEY hKey, const TString&key, const TString&value = TEXT(""));
|
||||
// void SetValueEx(HKEY hKey, const TString&key, const TString&value);
|
||||
// HKEY CreateKey(HKEY rootKey, const TString&keyPath, const TString&defaultValue = TEXT(""));
|
||||
//};
|
||||
//
|
||||
//namespace Regedit {
|
||||
// inline bool SetValue(HKEY hKey, const TString&key, const TString&value) {
|
||||
// return !::RegSetValue(hKey, key.c_str(), REG_SZ, value.c_str(), value.size());
|
||||
// }
|
||||
// inline void SetValueEx(HKEY hKey, const TString&key, const TString&value) {
|
||||
// RegSetValueEx(hKey, key.c_str(), NULL, REG_SZ, (BYTE*)value.c_str(), value.size());
|
||||
// }
|
||||
// inline HKEY CreateKey(HKEY rootKey, const TString&keyPath, const TString&defaultValue) {
|
||||
// HKEY hKey;
|
||||
// RegCreateKey(rootKey, keyPath.c_str(), &hKey);
|
||||
// SetValue(hKey, TEXT(""), defaultValue);
|
||||
// return hKey;
|
||||
// }
|
||||
//
|
||||
// inline BOOL DelKey(HKEY hKeyRoot, LPTSTR lpSubKey)
|
||||
// {
|
||||
// LPTSTR lpEnd;
|
||||
// LONG lResult;
|
||||
// DWORD dwSize;
|
||||
// TCHAR szName[MAX_PATH];
|
||||
// HKEY hKey;
|
||||
// FILETIME ftWrite;
|
||||
// // First, see if we can delete the key without having
|
||||
// // to recurse.
|
||||
// lResult = RegDeleteKey(hKeyRoot, lpSubKey);
|
||||
// if (lResult == ERROR_SUCCESS) {
|
||||
// return TRUE;
|
||||
// }
|
||||
// lResult = RegOpenKeyEx(hKeyRoot, lpSubKey, 0, KEY_READ, &hKey);
|
||||
//
|
||||
// if (lResult != ERROR_SUCCESS)
|
||||
// {
|
||||
// if (lResult == ERROR_FILE_NOT_FOUND) {
|
||||
// printf("Key not found.\n");
|
||||
// return TRUE;
|
||||
// }
|
||||
// else {
|
||||
// printf("Error opening key.\n");
|
||||
// return FALSE;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Check for an ending slash and add one if it is missing.
|
||||
//
|
||||
// lpEnd = lpSubKey + lstrlen(lpSubKey);
|
||||
//
|
||||
// if (*(lpEnd - 1) != TEXT('\\'))
|
||||
// {
|
||||
// *lpEnd = TEXT('\\');
|
||||
// lpEnd++;
|
||||
// *lpEnd = TEXT('\0');
|
||||
// }
|
||||
//
|
||||
// // Enumerate the keys
|
||||
//
|
||||
// dwSize = MAX_PATH;
|
||||
// lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
|
||||
// NULL, NULL, &ftWrite);
|
||||
//
|
||||
// if (lResult == ERROR_SUCCESS)
|
||||
// {
|
||||
// do {
|
||||
//
|
||||
// StringCchCopy(lpEnd, MAX_PATH * 2, szName);
|
||||
//
|
||||
// if (!DelKey(hKeyRoot, lpSubKey)) {
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// dwSize = MAX_PATH;
|
||||
//
|
||||
// lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
|
||||
// NULL, NULL, &ftWrite);
|
||||
//
|
||||
// } while (lResult == ERROR_SUCCESS);
|
||||
// }
|
||||
//
|
||||
// lpEnd--;
|
||||
// *lpEnd = TEXT('\0');
|
||||
//
|
||||
// RegCloseKey(hKey);
|
||||
// // Try again to delete the key.
|
||||
// lResult = RegDeleteKey(hKeyRoot, lpSubKey);
|
||||
//
|
||||
// if (lResult == ERROR_SUCCESS)
|
||||
// return TRUE;
|
||||
//
|
||||
// return FALSE;
|
||||
// }
|
||||
// inline BOOL Exist(HKEY keyRoot, LPTSTR keyPath)
|
||||
// {
|
||||
// HKEY hExtKey;
|
||||
// if (RegOpenKey(keyRoot, keyPath, &hExtKey) == ERROR_SUCCESS)
|
||||
// {
|
||||
// RegCloseKey(hExtKey);
|
||||
// return TRUE;
|
||||
// }
|
||||
// return FALSE;
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//
|
||||
//struct Version {
|
||||
// WORD v1, v2, v3, v4;
|
||||
//};
|
||||
//struct Product {
|
||||
//private:
|
||||
// HKEY hExtKey = NULL;
|
||||
// TString ProductName;
|
||||
// DWORD type = REG_SZ;
|
||||
// DWORD dwLen = MAX_PATH;
|
||||
//public:
|
||||
// Product(const TString&ProductName) {
|
||||
// this->ProductName = ProductName;
|
||||
// if (RegOpenKey(HKEY_CLASSES_ROOT, ProductName.c_str(), &hExtKey) != ERROR_SUCCESS)//如果打不开
|
||||
// {
|
||||
// hExtKey = ::Regedit::CreateKey(HKEY_CLASSES_ROOT, ProductName);//就创建
|
||||
// }
|
||||
// }
|
||||
// void SetValue(const TString&key, const TString&value) {
|
||||
// Regedit::SetValueEx(hExtKey, key, value);
|
||||
// }
|
||||
// TString GetValue(const TString&key, const TString&defaulValue = "") {
|
||||
// TCHAR bufStr[MAX_PATH]{ 0 };
|
||||
// if (::RegQueryValueEx(hExtKey, key.c_str(), 0, &type, (LPBYTE)bufStr, &dwLen) != ERROR_SUCCESS) {
|
||||
// auto code = ::GetLastError();
|
||||
// SetValue(key, defaulValue);
|
||||
// return defaulValue;
|
||||
// }
|
||||
// return bufStr;
|
||||
// }
|
||||
// Version GetVersion() {//从注册表中获取程序版本
|
||||
// TString localVer = GetValue("ver", "0.0.0.0");
|
||||
// Version ver{ 0,0,0,0 };//当前程序版本
|
||||
// auto vers = Text::Split(localVer, ".");
|
||||
// ver.v1 = (WORD)std::stoi(vers.at(0));
|
||||
// ver.v2 = (WORD)std::stoi(vers.at(1));
|
||||
// ver.v3 = (WORD)std::stoi(vers.at(2));
|
||||
// ver.v4 = (WORD)std::stoi(vers.at(3));
|
||||
// return ver;
|
||||
// }
|
||||
// void SetVersion(const Version&ver) {//设置新版本
|
||||
// TCHAR newVer[MAX_PATH] = { 0 };
|
||||
// Text::Format(newVer, MAX_PATH, "%d.%d.%d.%d", ver.v1, ver.v2, ver.v3, ver.v4);
|
||||
// SetValue("ver", newVer);
|
||||
// }
|
||||
// ~Product() {
|
||||
// if (hExtKey) {
|
||||
// ::RegCloseKey(hExtKey);
|
||||
// }
|
||||
// }
|
||||
//};
|
||||
37
demo/kugou/include/Common/include/Socket.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h> // 先包含 winsock2.h,避免冲突
|
||||
#include <windows.h> // 再包含 windows.h
|
||||
#include <ws2tcpip.h> // ws2tcpip.h 依赖 winsock2.h,可以放在后面
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#endif
|
||||
|
||||
class Socket
|
||||
{
|
||||
private:
|
||||
SOCKET socket = NULL;
|
||||
sockaddr_in sockaddr = {};
|
||||
public:
|
||||
static std::vector<std::string> GetIpByName(const std::string& hostname);
|
||||
public:
|
||||
size_t Port = 0;
|
||||
std::string Address;
|
||||
int Receive(char* outBuf, size_t recvLen, int flags = 0) const;
|
||||
bool Connect(const std::string& ip, size_t port);
|
||||
bool Bind(const std::string& ip, size_t port);
|
||||
bool Listen(int backlog = 5);
|
||||
Socket Accep() const;
|
||||
int Write(const char* buff, int size)const;
|
||||
void Close() const;
|
||||
Socket();
|
||||
Socket(SOCKET socket);
|
||||
virtual ~Socket();
|
||||
};
|
||||
|
||||
84
demo/kugou/include/Common/include/Text.h
Normal file
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
|
||||
#ifdef _WINDLL
|
||||
#define UI_EXPORT __declspec(dllexport)
|
||||
#define UI_VAR_EXPORT UI_EXPORT
|
||||
#else
|
||||
#define UI_EXPORT
|
||||
#define UI_VAR_EXPORT __declspec(dllimport)
|
||||
#endif // _WINDLL
|
||||
|
||||
namespace Text {
|
||||
|
||||
//-----------------------------------------------Copy Start-----------------------------------------------
|
||||
/// <summary>
|
||||
/// utf8字符串
|
||||
/// </summary>
|
||||
class UI_EXPORT String :public std::string {
|
||||
public:
|
||||
String();
|
||||
virtual ~String();
|
||||
String(const String& _right)noexcept;
|
||||
String(String&& _right)noexcept;
|
||||
String& operator=(const String& _right)noexcept;
|
||||
String& operator=(String&& _right)noexcept;
|
||||
String(const std::string& str)noexcept;
|
||||
String(const char* szbuf)noexcept;
|
||||
String(const wchar_t* szbuf)noexcept;
|
||||
String(const std::wstring& wstr)noexcept;
|
||||
//获取utf8字符串的字符串长度
|
||||
virtual size_t length() const final;
|
||||
std::wstring unicode() const;
|
||||
std::string ansi() const;
|
||||
void erase(char _ch);
|
||||
void erase(size_t pos, size_t count);
|
||||
String replace(char oldChar, char newChar)const;
|
||||
String replace(const String& oldText, const String& newText, bool allReplace = true)const;
|
||||
String toLower()const;
|
||||
String toUpper()const;
|
||||
//去除前后空格
|
||||
String trim()const;
|
||||
//find value count
|
||||
size_t count(const String& value);
|
||||
std::vector<String> split(const String& ch)const;
|
||||
bool operator==(const wchar_t* szbuf)const;
|
||||
bool operator==(const std::wstring& wStr)const;
|
||||
|
||||
template<typename ...T>
|
||||
inline String format(const T &...args) {
|
||||
auto bufSize = ::snprintf(nullptr, 0, this->c_str(), std::forward<const T&>(args)...) + 1; // +1是为了'结束符\0'
|
||||
char* buf = new char[bufSize] {0};
|
||||
auto count = ::sprintf_s(buf, bufSize, this->c_str(), std::forward<const T&>(args)...);
|
||||
String ret(buf);
|
||||
delete[] buf;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
//base convert
|
||||
UI_EXPORT void AnyToUnicode(const std::string& src_str, UINT codePage, std::wstring* out_wstr);
|
||||
UI_EXPORT void UnicodeToAny(const std::wstring& unicode_wstr, UINT codePage, std::string* out_str);
|
||||
//
|
||||
UI_EXPORT void GBKToUTF8(const std::string& str, std::string* outStr);
|
||||
UI_EXPORT void UTF8ToGBK(const std::string& str, std::string* outStr);
|
||||
UI_EXPORT void ANSIToUniCode(const std::string& str, std::wstring* outStr);
|
||||
UI_EXPORT void ANSIToUTF8(const std::string& str, std::string* outStr);
|
||||
UI_EXPORT void UnicodeToANSI(const std::wstring& wstr, std::string* outStr);
|
||||
UI_EXPORT void UnicodeToUTF8(const std::wstring& wstr, std::string* outStr);
|
||||
UI_EXPORT void UTF8ToANSI(const std::string& str, std::string* outStr);
|
||||
UI_EXPORT void UTF8ToUnicode(const std::string& str, std::wstring* outStr);
|
||||
//
|
||||
UI_EXPORT void Tolower(std::string* str_in_out);
|
||||
UI_EXPORT void Toupper(std::string* str_in_out);
|
||||
UI_EXPORT void Erase(std::string* str_in_out, char ch);
|
||||
UI_EXPORT void Replace(std::string* str_in_out, char oldChar, char newChar);
|
||||
UI_EXPORT size_t Replace(std::string* str_in_out, const std::string& oldText, const std::string& newText, bool replaceAll = true);
|
||||
UI_EXPORT void Split(const std::string& str_in, const std::string& ch, std::vector<std::string>* strs_out);
|
||||
//
|
||||
UI_EXPORT String ToString(double number, size_t keepBitSize);
|
||||
//-----------------------------------------------Copy End-----------------------------------------------
|
||||
};
|
||||
using u8String = Text::String;
|
||||
137
demo/kugou/include/Common/include/ThreadPool.hpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <future>
|
||||
#include <list>
|
||||
|
||||
class Thread {
|
||||
bool _bStop = false;
|
||||
std::thread* _task = NULL;
|
||||
bool _bJoin = false;
|
||||
std::mutex _mtx;
|
||||
std::condition_variable _codv;
|
||||
private:
|
||||
Thread(const Thread&) = delete;
|
||||
public:
|
||||
template<class Func, class... Args>
|
||||
Thread(Func&& f, Args&& ...args) {
|
||||
std::function<void()>* func = new std::function<void()>(std::bind(std::forward<Func>(f), std::forward<Args>(args)...));
|
||||
_task = new std::thread([this, func]() mutable {
|
||||
(*func)();
|
||||
delete func;
|
||||
{
|
||||
std::unique_lock<std::mutex> autoLock(_mtx);
|
||||
_bStop = true;
|
||||
}
|
||||
_codv.notify_all();
|
||||
});
|
||||
}
|
||||
void Wait() {
|
||||
if (!_bJoin)
|
||||
{
|
||||
_bJoin = true;
|
||||
std::unique_lock<std::mutex> autoLock(_mtx);
|
||||
_codv.wait(autoLock, [this]() ->bool {
|
||||
return _bStop;
|
||||
});
|
||||
_task->join();
|
||||
}
|
||||
}
|
||||
bool IsStopped() {
|
||||
std::unique_lock<std::mutex> autoLock(_mtx);
|
||||
return _bStop;
|
||||
}
|
||||
virtual ~Thread() {
|
||||
Wait();
|
||||
delete _task;
|
||||
}
|
||||
};
|
||||
|
||||
class ThreadPool {
|
||||
bool bStop = false;
|
||||
std::list<Thread*> tasks;
|
||||
std::list<std::function<void()>> funcs;
|
||||
std::mutex mtx;
|
||||
std::condition_variable codv;
|
||||
//用于等待任务清空的锁和条件变量
|
||||
std::mutex mtx2;
|
||||
std::condition_variable codv2;
|
||||
private:
|
||||
ThreadPool(const ThreadPool&) = delete;
|
||||
public:
|
||||
ThreadPool(int maxTaskCount = 50) {
|
||||
for (size_t i = 0; i < maxTaskCount; ++i)
|
||||
{
|
||||
tasks.push_back(new Thread([this]() {
|
||||
while (true)
|
||||
{
|
||||
std::function<void()> task;
|
||||
{
|
||||
std::unique_lock<std::mutex> autoLock(this->mtx);
|
||||
this->codv.wait(autoLock, [this]()->bool {
|
||||
return this->bStop || !this->funcs.empty();
|
||||
});
|
||||
if (funcs.empty()) {
|
||||
this->codv2.notify_all();
|
||||
}
|
||||
if (this->bStop && funcs.empty()) {
|
||||
break;
|
||||
}
|
||||
task = std::move(*funcs.begin());
|
||||
funcs.pop_front();
|
||||
}
|
||||
task();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
void WaitAll() {
|
||||
codv.notify_all();
|
||||
std::unique_lock<std::mutex> lock2(this->mtx2);
|
||||
this->codv2.wait(lock2, [this]()->bool {
|
||||
return funcs.empty();
|
||||
});
|
||||
}
|
||||
virtual ~ThreadPool() {
|
||||
{
|
||||
std::unique_lock<std::mutex> autoLock(mtx);
|
||||
bStop = true;
|
||||
}
|
||||
WaitAll();
|
||||
while (!tasks.empty())
|
||||
{
|
||||
for (auto itor = tasks.begin(); itor != tasks.end(); )
|
||||
{
|
||||
if ((*itor)->IsStopped()) {
|
||||
(*itor)->Wait();
|
||||
delete (*itor);
|
||||
itor = tasks.erase(itor);
|
||||
}
|
||||
else {
|
||||
++itor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//添加到任务队列中的末尾(先后顺序执行)
|
||||
template<class Func, class... Args>
|
||||
void Add(Func&& f, Args&& ...args) {
|
||||
{
|
||||
std::unique_lock<std::mutex> autoLock(mtx);
|
||||
funcs.emplace_back(std::bind(std::forward<Func>(f), std::forward<Args>(args)...));
|
||||
}
|
||||
codv.notify_one();
|
||||
}
|
||||
//添加至任务队列的第一位(优先执行)
|
||||
template<class Func, class... Args>
|
||||
void AddToFrist(Func&& f, Args&& ...args) {
|
||||
{
|
||||
std::unique_lock<std::mutex> autoLock(mtx);
|
||||
funcs.emplace_front(std::bind(std::forward<Func>(f), std::forward<Args>(args)...));
|
||||
}
|
||||
codv.notify_one();
|
||||
}
|
||||
};
|
||||
83
demo/kugou/include/Common/include/Time.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <time.h>
|
||||
#include <string>
|
||||
#include "Text.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
class Time {
|
||||
time_t _time;
|
||||
public:
|
||||
static Time Now() {
|
||||
return Time(::time(NULL));
|
||||
}
|
||||
public:
|
||||
Time(time_t second) {
|
||||
_time = second;
|
||||
}
|
||||
Time(const std::string& timeStr, const std::string& format = "yyyy-MM-dd HH:mm:ss") {
|
||||
std::string formatStr = format;
|
||||
Text::Replace(&formatStr, "yyyy", "%Y");
|
||||
Text::Replace(&formatStr, "MM", "%m");
|
||||
Text::Replace(&formatStr, "dd", "%d");
|
||||
Text::Replace(&formatStr, "HH", "%H");
|
||||
Text::Replace(&formatStr, "mm", "%M");
|
||||
Text::Replace(&formatStr, "ss", "%S");
|
||||
|
||||
std::tm tm{};
|
||||
std::istringstream ss(timeStr);
|
||||
ss >> std::get_time(&tm, formatStr.c_str());
|
||||
tm.tm_isdst = -1; // Enable daylight saving time
|
||||
|
||||
std::time_t timeStamp = std::mktime(&tm);
|
||||
if (timeStamp == -1) {
|
||||
throw std::runtime_error("Error converting time string to timestamp.");
|
||||
}
|
||||
this->_time = timeStamp;
|
||||
}
|
||||
std::string ToString(const std::string& format = "yyyy-MM-dd HH:mm:ss") const{
|
||||
std::string formatStr = format;
|
||||
Text::Replace(&formatStr, "yyyy", "%Y");
|
||||
Text::Replace(&formatStr, "MM", "%m");
|
||||
Text::Replace(&formatStr, "dd", "%d");
|
||||
Text::Replace(&formatStr, "HH", "%H");
|
||||
Text::Replace(&formatStr, "mm", "%M");
|
||||
Text::Replace(&formatStr, "ss", "%S");
|
||||
|
||||
char timeStr[128]{ 0 };
|
||||
time_t t = _time;
|
||||
struct tm* ttime = std::localtime(&t);
|
||||
std::strftime(timeStr, sizeof(timeStr), formatStr.c_str(), ttime);
|
||||
return timeStr;
|
||||
}
|
||||
time_t operator - (const Time& right) {
|
||||
return this->_time - right._time;
|
||||
}
|
||||
bool operator == (const Time& right) {
|
||||
return this->_time == right._time;
|
||||
}
|
||||
bool operator != (const Time& right) {
|
||||
return this->_time != right._time;
|
||||
}
|
||||
bool operator > (const Time& right) {
|
||||
return this->_time > right._time;
|
||||
}
|
||||
bool operator < (const Time& right) {
|
||||
return this->_time < right._time;
|
||||
}
|
||||
Time& operator += (time_t right) {
|
||||
this->_time += right;
|
||||
return *this;
|
||||
}
|
||||
Time& operator -= (time_t right) {
|
||||
this->_time -= right;
|
||||
return *this;
|
||||
}
|
||||
Time operator + (time_t right) {
|
||||
return Time(this->_time + right);
|
||||
}
|
||||
Time operator - (time_t right) {
|
||||
return Time(this->_time - right);
|
||||
}
|
||||
};
|
||||
81
demo/kugou/include/Common/include/UnZiper.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
#include "Text.h"
|
||||
#include "FileSystem.h"
|
||||
|
||||
DECLARE_HANDLE(HZIP_U);
|
||||
|
||||
struct ZipItem
|
||||
{
|
||||
int index; // index of this file within the zip
|
||||
TCHAR name[MAX_PATH]; // filename within the zip
|
||||
DWORD attr; // attributes, as in GetFileAttributes.
|
||||
FILETIME atime, ctime, mtime;// access, create, modify filetimes
|
||||
long comp_size; // sizes of item, compressed and uncompressed. These
|
||||
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
||||
bool isDir()const {
|
||||
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 专门负责解压缩的类
|
||||
/// </summary>
|
||||
class UnZiper {
|
||||
HZIP_U ptr = NULL;
|
||||
int itemCount = 0;
|
||||
public:
|
||||
UnZiper(const std::wstring& fileName, const std::string& password = "");
|
||||
UnZiper(const char* fileData, unsigned int size, const std::string& password = "");
|
||||
bool Find(const std::string& itemName, ZipItem* item);
|
||||
bool Find(int index, ZipItem* item);
|
||||
bool UnZipItem(const ZipItem& item, byte** data);
|
||||
int GetCount();
|
||||
virtual ~UnZiper();
|
||||
public:
|
||||
static bool UnZip(UnZiper* zip, const Text::String& outDir, const std::string& password = "", std::function<void(const Text::String&, int total, int index, bool& stop)> callback = NULL) {
|
||||
bool ok = true;
|
||||
for (int i = 0; i < zip->GetCount(); i++)
|
||||
{
|
||||
ZipItem ze;
|
||||
zip->Find(i, &ze);
|
||||
Text::String itemName = outDir + "/" + Text::String(ze.name);
|
||||
if (ze.isDir()) {
|
||||
if (!Directory::Create(itemName)) {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
File::Delete(itemName);
|
||||
byte* data = NULL;
|
||||
zip->UnZipItem(ze, &data);
|
||||
std::ofstream ofs(itemName.unicode(), std::ios::binary);
|
||||
ofs.write((char*)data, ze.unc_size);
|
||||
ofs.flush();
|
||||
ofs.close();
|
||||
if (!ofs.good()) {
|
||||
ok = false;
|
||||
}
|
||||
if (data) {
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
bool stop = false;
|
||||
callback(itemName, zip->GetCount(), i, stop);
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool UnZip(const Text::String& zipFileName, const Text::String& outDir, const std::string& password = "", std::function<void(const Text::String&, int total, int index, bool& stop)> callback = NULL) {
|
||||
Directory::Create(outDir);
|
||||
UnZiper zip(zipFileName.unicode(), password);
|
||||
return UnZip(&zip, outDir, password, callback);
|
||||
}
|
||||
};
|
||||
30
demo/kugou/include/Common/include/Util.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
namespace Util {
|
||||
//文件的md5
|
||||
std::string MD5FromFile(const std::wstring& filename);
|
||||
//字符串的md5
|
||||
std::string MD5FromString(const std::string& string);
|
||||
//base64编码
|
||||
std::string Base64Encode(const char* str, int strLen);
|
||||
//base64编码
|
||||
std::string Base64Encode(const std::string& string);
|
||||
//base64解码
|
||||
std::string Base64Decode(const char* base64Str, int strLen);
|
||||
//base64解码
|
||||
std::string Base64Decode(const std::string& string);
|
||||
//url编码
|
||||
std::string UrlEncode(const std::string& str);
|
||||
//url解码
|
||||
std::string UrlDecode(const std::string& str, bool convert_plus_to_space = false);
|
||||
//少一个GZIP
|
||||
|
||||
namespace XOR {
|
||||
//XOR加密 必须输入密码才能加密
|
||||
std::string EnCode(const std::string& data, const std::string& password);
|
||||
//XOR解密
|
||||
std::string DeCode(const std::string& data, const std::string& password);
|
||||
}
|
||||
};
|
||||
76
demo/kugou/include/Common/include/WebClient.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include "FileSystem.h"
|
||||
#include "Text.h"
|
||||
|
||||
#define USECURL 1 //是否使用curl 使用curl会导致库变得很大
|
||||
|
||||
#if USECURL
|
||||
namespace PostForm {
|
||||
//字段类型
|
||||
enum FieldType :char
|
||||
{
|
||||
None,
|
||||
Text,
|
||||
File
|
||||
};
|
||||
class Field {
|
||||
public:
|
||||
FieldType FieldType = FieldType::None;
|
||||
std::string FieldName;
|
||||
std::string FieldValue;
|
||||
|
||||
std::string FileName;
|
||||
Field(const std::string& FieldName, const std::string& ValueOrFullFileName, PostForm::FieldType FieldType = PostForm::FieldType::Text) {
|
||||
this->FieldName = FieldName;
|
||||
this->FieldType = FieldType;
|
||||
if (FieldType == PostForm::FieldType::File) {
|
||||
this->FieldValue = Path::GetFileName(ValueOrFullFileName);
|
||||
this->FileName = ValueOrFullFileName;
|
||||
}
|
||||
else {
|
||||
this->FieldValue = ValueOrFullFileName;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class WebClient
|
||||
{
|
||||
public:
|
||||
struct Content
|
||||
{
|
||||
void* tag = NULL;
|
||||
bool cancel = false;
|
||||
int type = 0;//0:正常请求 1:下载文件
|
||||
};
|
||||
private:
|
||||
Content content;
|
||||
public:
|
||||
std::function<size_t(char* contents, size_t size, size_t nmemb, void* respone)> CallBack = NULL;
|
||||
private:
|
||||
void* Init(const std::string& url, std::string* resp, int timeOut);
|
||||
long CleanUp(void* curl, int code);
|
||||
std::map<std::string, std::string> Header;
|
||||
void* curl_header = NULL;//类型参见 curl_slist
|
||||
public:
|
||||
std::string Cookies;
|
||||
std::string Proxy;
|
||||
WebClient();
|
||||
virtual ~WebClient();
|
||||
//取消请求/下载
|
||||
void Cancel();
|
||||
void AddHeader(const std::string& key, const std::string& value);
|
||||
void RemoveHeader(const std::string& key);
|
||||
int HttpGet(const std::string& strUrl, std::string* response = NULL, int nTimeout = 60);
|
||||
int HttpPost(const std::string& strUrl, const std::string& data = "", std::string* response = NULL, int nTimeout = 60);
|
||||
int DownloadFile(const std::string& strUrl, const std::wstring& filename, const std::function<void(long long dltotal, long long dlnow)>& progressCallback = NULL, int nTimeout = 99999);
|
||||
int FtpDownLoad(const std::string& strUrl, const std::string& user, const std::string& pwd, const std::wstring& outFileName, int nTimeout = 99999);
|
||||
int UploadFile(const std::string& strUrl, const std::string& filename, const std::string& field, std::string* response = NULL, const std::function<void(long long dltotal, long long dlnow)>& progressCallback = NULL, int nTimeout = 99999);
|
||||
int SubmitForm(const std::string& strUrl, const std::vector<PostForm::Field>& fieldValues, std::string* response = NULL, int nTimeout = 99999);
|
||||
};
|
||||
#endif
|
||||
172
demo/kugou/include/Common/include/WinTool.h
Normal file
@@ -0,0 +1,172 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <Windows.h>
|
||||
#include <TlHelp32.h>
|
||||
|
||||
#include "Text.h"
|
||||
|
||||
#ifdef GetUserName
|
||||
#undef GetUserName
|
||||
inline void GetUserName(LPSTR lpBuffer, LPDWORD pcbBuffer) {
|
||||
::GetUserNameA(lpBuffer, pcbBuffer);
|
||||
}
|
||||
inline void GetUserName(LPWSTR lpBuffer, LPDWORD pcbBuffer) {
|
||||
::GetUserNameW(lpBuffer, pcbBuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GetComputerName
|
||||
#undef GetComputerName
|
||||
inline void GetComputerName(LPSTR lpBuffer, LPDWORD pcbBuffer) {
|
||||
::GetComputerNameA(lpBuffer, pcbBuffer);
|
||||
}
|
||||
inline void GetComputerName(LPWSTR lpBuffer, LPDWORD pcbBuffer) {
|
||||
::GetComputerNameW(lpBuffer, pcbBuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace WinTool {
|
||||
/// <summary>
|
||||
/// 路由信息
|
||||
/// </summary>
|
||||
struct RouterInfo {
|
||||
Text::String IP;
|
||||
Text::String MAC;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned long processId;
|
||||
HWND best_handle;
|
||||
}handle_data;
|
||||
|
||||
typedef struct _MyAdpterInfo
|
||||
{
|
||||
std::vector<std::string> Ip;
|
||||
std::string MacAddress;
|
||||
std::string Description;
|
||||
std::string Name;
|
||||
UINT Type;
|
||||
}MyAdpterInfo;
|
||||
|
||||
struct AppInfo {
|
||||
/// app名称
|
||||
Text::String DisplayName;
|
||||
/// 版本号
|
||||
Text::String DisplayVersion;
|
||||
//显示图标
|
||||
Text::String DisplayIcon;
|
||||
// 发布者
|
||||
Text::String Publisher;
|
||||
//软件安装路径
|
||||
Text::String InstallLocation;
|
||||
// 主程序启动完整路径 C:\\Program Files\\xxx\xxx.exe
|
||||
Text::String PragmaFile;
|
||||
// 卸载执行的命令行
|
||||
Text::String UninstallString;
|
||||
// 产品帮助链接
|
||||
Text::String HelpLink;
|
||||
//帮助说明[这是一款桌面工具]
|
||||
Text::String Comments;
|
||||
//产品官网
|
||||
Text::String URLInfoAbout;
|
||||
//是否禁用控制面板修改按钮
|
||||
bool NoModify = false;
|
||||
//是否禁用控制面板修复按钮
|
||||
bool NoRepair = false;
|
||||
// 是否创建桌面快捷方式
|
||||
bool DesktopLink = true;
|
||||
// 是否开机启动
|
||||
bool AutoBoot = false;
|
||||
//为所有用户注册
|
||||
bool AllUsers = true;
|
||||
};
|
||||
//给进程提权
|
||||
extern BOOL EnablePrivilege(HANDLE process = NULL);
|
||||
//创捷快捷方式
|
||||
extern bool CreateLink(const Text::String& pragmaFilename, const Text::String& outDir, const Text::String& LnkName = L"", const Text::String& cmdline = L"", const Text::String& iconFilename = L"");
|
||||
//删除快捷方式
|
||||
extern void DeleteLink(const Text::String& linkDir, const Text::String& pragmaFilename, const Text::String& LnkName = "");
|
||||
/// 删除注册表中某个项及其子项和值
|
||||
extern void DeleteKeyRecursively(HKEY hKeyParent, const wchar_t* subKey);
|
||||
//获取软件相关信息
|
||||
extern Text::String GetAppValue(const Text::String& appName_en, const Text::String& key);
|
||||
//根据软件名称修改一些信息
|
||||
extern bool SetAppValue(const Text::String& appName_en, const Text::String& key, const Text::String& value);
|
||||
//注册软件到电脑
|
||||
extern bool RegisterApp(const AppInfo& appInfo);
|
||||
//从电脑上注销软件
|
||||
extern void UnRegisterApp(const Text::String& appName_en);
|
||||
//给软件注册许可
|
||||
extern bool RegisterLicenser(const Text::String& exeFilename, const Text::String& softwareData);
|
||||
//获取软件许可证书
|
||||
extern Text::String FindLicenser(const Text::String& exeFilename);
|
||||
//设置程序自启动 rootKey参数:HKEY_CURRENT_USER(当前用户), HKEY_LOCAL_MACHINE//所有用户(需要管理员)
|
||||
extern bool SetAutoBoot(const Text::String& filename = L"", bool enable = true, HKEY rootKey = HKEY_CURRENT_USER);
|
||||
//获取程序自启动状态 rootKey参数:HKEY_CURRENT_USER(当前用户), HKEY_LOCAL_MACHINE//所有用户(需要管理员)
|
||||
extern bool IsAutoBoot(const Text::String& _keyName, HKEY rootKey = HKEY_CURRENT_USER);
|
||||
//检查计划任务
|
||||
extern bool IsInTask(const Text::String& _taskName);
|
||||
//添加到启动计划任务
|
||||
extern bool AddBootTask(const Text::String& _taskName, const Text::String& _exeFile);
|
||||
//寻找进程中的窗口
|
||||
extern HWND FindMainWindow(DWORD processId);
|
||||
//获取进程信息
|
||||
extern std::vector<PROCESSENTRY32W> FindProcessInfo(const Text::String& _proccname);
|
||||
//根据进程名称打开进程
|
||||
extern HANDLE OpenProcess(const Text::String& _proccname);
|
||||
//获取进程ID集合
|
||||
extern std::vector<DWORD> FindProcessId(const Text::String& proccname);
|
||||
//获取进程文件路径
|
||||
extern Text::String FindProcessFilename(DWORD processId);
|
||||
//关闭所有进程
|
||||
extern int CloseProcess(const std::vector<DWORD>& processIds);
|
||||
//使用进程ID关闭进程
|
||||
extern bool CloseProcess(DWORD processId);
|
||||
//使用句柄关闭进程
|
||||
extern bool CloseProcess(HANDLE hProcess, UINT exitCode = 0);
|
||||
//获取进程是不是64位的
|
||||
extern bool Is64BitPorcess(DWORD processId);
|
||||
//获取进程是不是32位的
|
||||
extern bool Is86BitPorcess(DWORD processId);
|
||||
//获取当前进程ID
|
||||
extern DWORD GetCurrentProcessId();
|
||||
//获取系统位数
|
||||
extern int GetSystemBits();
|
||||
//获取计算机唯一识别码
|
||||
extern Text::String GetComputerID();
|
||||
//用户当前用户名称
|
||||
extern Text::String GetUserName();
|
||||
//获取计算机名称
|
||||
extern Text::String GetComputerName();
|
||||
//获取网卡相关
|
||||
extern int GetAdptersInfo(std::vector<MyAdpterInfo>& adpterInfo);
|
||||
/// 获取磁盘可以用空间单位:GB
|
||||
extern double GetDiskFreeSize(const Text::String& path);
|
||||
/// 直接执行可执行文件并获取返回内容
|
||||
extern Text::String ExecuteCMD(const Text::String& cmdStr, std::function<void(const Text::String&)> callback = NULL, HANDLE* outHandle = NULL);
|
||||
///获取首选网卡的mac地址
|
||||
extern Text::String GetMacAddress();
|
||||
/// 获取操作系统的版本号
|
||||
extern Text::String GetWinVersion();
|
||||
/// 弹出选择文件对话框(filter传入参数的方式存在问题 以后改)
|
||||
extern Text::String ShowFileDialog(HWND ownerWnd = NULL, const Text::String& defaultPath = "", const Text::String& title = "Select a File", const Text::String& filter = "All Files\0*.*\0");
|
||||
/// 弹出选择目录对话框
|
||||
extern Text::String ShowFolderDialog(HWND ownerWnd = NULL, const Text::String& defaultPath = "", const Text::String& title = "Select a directory");
|
||||
/// 获取路由信息
|
||||
extern RouterInfo GetRouterInfo();
|
||||
/// 获取电脑的com端口名称
|
||||
extern std::vector<Text::String> GetComPorts();
|
||||
/// 安装带有.inf文件的驱动
|
||||
extern bool InstallDriver(const Text::String& infPath, bool* needReboot = NULL);
|
||||
/// 获取已安装的应用
|
||||
extern std::map<Text::String, Text::String> GetApps();
|
||||
/// 检测程序是否被调试
|
||||
extern bool CheckDebug();
|
||||
/// 检查程序是否正在运行 使用文件独占方式
|
||||
extern bool IsRunning(const Text::String& productName = "", bool lock = true);
|
||||
/// 添加一个程序到防火墙规则 ps:需要管理员权限运行
|
||||
extern void AddFirewallRule(const Text::String& programFile);
|
||||
//是否接管异常(仅限正式环境调用 使用vs启动会被vs接管异常)
|
||||
extern bool IsExceptionHijacked();
|
||||
};
|
||||
43
demo/kugou/include/Common/include/Ziper.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include "Text.h"
|
||||
#include "FileSystem.h"
|
||||
#include <Windows.h>
|
||||
|
||||
DECLARE_HANDLE(HZIP_Z);
|
||||
|
||||
/// <summary>
|
||||
/// 专门负责压缩的库
|
||||
/// </summary>
|
||||
class Ziper {
|
||||
HZIP_Z ptr = NULL;
|
||||
public:
|
||||
Ziper(const std::wstring& createFileName, const std::string& pwd = "");
|
||||
void AddFile(const std::wstring& showFileName, const std::wstring& localFileName);
|
||||
void AddFolder(const std::wstring& showFolder);
|
||||
void Close();
|
||||
virtual ~Ziper();
|
||||
public:
|
||||
static void Zip(const Text::String& _dirName, const Text::String& outFileName, const Text::String& pwd = "", std::function<bool(const Text::String&, int, int)> callback = NULL) {
|
||||
std::vector<FileSystem::FileInfo> result;
|
||||
Ziper zip(outFileName.unicode(), pwd);
|
||||
Text::String dirName = _dirName + "/";
|
||||
dirName = Path::Format(dirName);
|
||||
Directory::Find(dirName, result, "*.*", true);
|
||||
for (int i = 0; i < result.size(); i++)
|
||||
{
|
||||
Text::String ItemNmae = result[i].FileName.replace(dirName, "");
|
||||
if (result[i].IsFile()) {
|
||||
zip.AddFile(ItemNmae.unicode(), result[i].FileName.unicode());
|
||||
}
|
||||
else {
|
||||
zip.AddFolder(ItemNmae.unicode());
|
||||
}
|
||||
if (callback) {
|
||||
if (callback(ItemNmae, i, result.size())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
35
demo/kugou/include/Common/include/base64.h
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// base64 encoding and decoding with C++.
|
||||
// Version: 2.rc.09 (release candidate)
|
||||
//
|
||||
|
||||
#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
|
||||
#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
|
||||
|
||||
#include <string>
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#include <string_view>
|
||||
#endif // __cplusplus >= 201703L
|
||||
|
||||
std::string base64_encode (std::string const& s, bool url = false);
|
||||
std::string base64_encode_pem (std::string const& s);
|
||||
std::string base64_encode_mime(std::string const& s);
|
||||
|
||||
std::string base64_decode(std::string const& s, bool remove_linebreaks = false);
|
||||
std::string base64_encode(unsigned char const*, size_t len, bool url = false);
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
//
|
||||
// Interface with std::string_view rather than const std::string&
|
||||
// Requires C++17
|
||||
// Provided by Yannic Bonenberger (https://github.com/Yannic)
|
||||
//
|
||||
std::string base64_encode (std::string_view s, bool url = false);
|
||||
std::string base64_encode_pem (std::string_view s);
|
||||
std::string base64_encode_mime(std::string_view s);
|
||||
|
||||
std::string base64_decode(std::string_view s, bool remove_linebreaks = false);
|
||||
#endif // __cplusplus >= 201703L
|
||||
|
||||
#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */
|
||||
39
demo/kugou/include/Common/include/curl/Makefile.am
Normal file
@@ -0,0 +1,39 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
pkginclude_HEADERS = \
|
||||
curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \
|
||||
typecheck-gcc.h system.h urlapi.h options.h
|
||||
|
||||
pkgincludedir= $(includedir)/curl
|
||||
|
||||
CHECKSRC = $(CS_$(V))
|
||||
CS_0 = @echo " RUN " $@;
|
||||
CS_1 =
|
||||
CS_ = $(CS_0)
|
||||
|
||||
checksrc:
|
||||
$(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/include/curl $(pkginclude_HEADERS)
|
||||
|
||||
if CURLDEBUG
|
||||
# for debug builds, we scan the sources on all regular make invokes
|
||||
all-local: checksrc
|
||||
endif
|
||||
714
demo/kugou/include/Common/include/curl/Makefile.in
Normal file
@@ -0,0 +1,714 @@
|
||||
# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = include/curl
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compile_check_sizeof.m4 \
|
||||
$(top_srcdir)/m4/curl-amissl.m4 \
|
||||
$(top_srcdir)/m4/curl-bearssl.m4 \
|
||||
$(top_srcdir)/m4/curl-compilers.m4 \
|
||||
$(top_srcdir)/m4/curl-confopts.m4 \
|
||||
$(top_srcdir)/m4/curl-functions.m4 \
|
||||
$(top_srcdir)/m4/curl-gnutls.m4 \
|
||||
$(top_srcdir)/m4/curl-mbedtls.m4 \
|
||||
$(top_srcdir)/m4/curl-mesalink.m4 $(top_srcdir)/m4/curl-nss.m4 \
|
||||
$(top_srcdir)/m4/curl-openssl.m4 \
|
||||
$(top_srcdir)/m4/curl-override.m4 \
|
||||
$(top_srcdir)/m4/curl-reentrant.m4 \
|
||||
$(top_srcdir)/m4/curl-rustls.m4 \
|
||||
$(top_srcdir)/m4/curl-schannel.m4 \
|
||||
$(top_srcdir)/m4/curl-sectransp.m4 \
|
||||
$(top_srcdir)/m4/curl-sysconfig.m4 \
|
||||
$(top_srcdir)/m4/curl-wolfssl.m4 $(top_srcdir)/m4/libtool.m4 \
|
||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/m4/xc-am-iface.m4 \
|
||||
$(top_srcdir)/m4/xc-cc-check.m4 \
|
||||
$(top_srcdir)/m4/xc-lt-iface.m4 \
|
||||
$(top_srcdir)/m4/xc-translit.m4 \
|
||||
$(top_srcdir)/m4/xc-val-flgs.m4 \
|
||||
$(top_srcdir)/m4/zz40-xc-ovr.m4 \
|
||||
$(top_srcdir)/m4/zz50-xc-ovr.m4 \
|
||||
$(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \
|
||||
$(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/lib/curl_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(pkgincludedir)"
|
||||
HEADERS = $(pkginclude_HEADERS)
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
'
|
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
pkgincludedir = $(includedir)/curl
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AR_FLAGS = @AR_FLAGS@
|
||||
AS = @AS@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BLANK_AT_MAKETIME = @BLANK_AT_MAKETIME@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@
|
||||
CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CURLVERSION = @CURLVERSION@
|
||||
CURL_CA_BUNDLE = @CURL_CA_BUNDLE@
|
||||
CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@
|
||||
CURL_DISABLE_DICT = @CURL_DISABLE_DICT@
|
||||
CURL_DISABLE_FILE = @CURL_DISABLE_FILE@
|
||||
CURL_DISABLE_FTP = @CURL_DISABLE_FTP@
|
||||
CURL_DISABLE_GOPHER = @CURL_DISABLE_GOPHER@
|
||||
CURL_DISABLE_HTTP = @CURL_DISABLE_HTTP@
|
||||
CURL_DISABLE_IMAP = @CURL_DISABLE_IMAP@
|
||||
CURL_DISABLE_LDAP = @CURL_DISABLE_LDAP@
|
||||
CURL_DISABLE_LDAPS = @CURL_DISABLE_LDAPS@
|
||||
CURL_DISABLE_MQTT = @CURL_DISABLE_MQTT@
|
||||
CURL_DISABLE_POP3 = @CURL_DISABLE_POP3@
|
||||
CURL_DISABLE_PROXY = @CURL_DISABLE_PROXY@
|
||||
CURL_DISABLE_RTSP = @CURL_DISABLE_RTSP@
|
||||
CURL_DISABLE_SMB = @CURL_DISABLE_SMB@
|
||||
CURL_DISABLE_SMTP = @CURL_DISABLE_SMTP@
|
||||
CURL_DISABLE_TELNET = @CURL_DISABLE_TELNET@
|
||||
CURL_DISABLE_TFTP = @CURL_DISABLE_TFTP@
|
||||
CURL_LT_SHLIB_VERSIONED_FLAVOUR = @CURL_LT_SHLIB_VERSIONED_FLAVOUR@
|
||||
CURL_NETWORK_AND_TIME_LIBS = @CURL_NETWORK_AND_TIME_LIBS@
|
||||
CURL_NETWORK_LIBS = @CURL_NETWORK_LIBS@
|
||||
CURL_WITH_MULTI_SSL = @CURL_WITH_MULTI_SSL@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFAULT_SSL_BACKEND = @DEFAULT_SSL_BACKEND@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ENABLE_SHARED = @ENABLE_SHARED@
|
||||
ENABLE_STATIC = @ENABLE_STATIC@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@
|
||||
GCOV = @GCOV@
|
||||
GREP = @GREP@
|
||||
HAVE_BROTLI = @HAVE_BROTLI@
|
||||
HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@
|
||||
HAVE_LDAP_SSL = @HAVE_LDAP_SSL@
|
||||
HAVE_LIBZ = @HAVE_LIBZ@
|
||||
HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@
|
||||
HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@
|
||||
HAVE_ZSTD = @HAVE_ZSTD@
|
||||
IDN_ENABLED = @IDN_ENABLED@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
IPV6_ENABLED = @IPV6_ENABLED@
|
||||
LCOV = @LCOV@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBCURL_LIBS = @LIBCURL_LIBS@
|
||||
LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MANOPT = @MANOPT@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
NROFF = @NROFF@
|
||||
NSS_LIBS = @NSS_LIBS@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PERL = @PERL@
|
||||
PKGADD_NAME = @PKGADD_NAME@
|
||||
PKGADD_PKG = @PKGADD_PKG@
|
||||
PKGADD_VENDOR = @PKGADD_VENDOR@
|
||||
PKGCONFIG = @PKGCONFIG@
|
||||
RANDOM_FILE = @RANDOM_FILE@
|
||||
RANLIB = @RANLIB@
|
||||
REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
SSL_BACKENDS = @SSL_BACKENDS@
|
||||
SSL_ENABLED = @SSL_ENABLED@
|
||||
SSL_LIBS = @SSL_LIBS@
|
||||
STRIP = @STRIP@
|
||||
SUPPORT_FEATURES = @SUPPORT_FEATURES@
|
||||
SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@
|
||||
USE_ARES = @USE_ARES@
|
||||
USE_BEARSSL = @USE_BEARSSL@
|
||||
USE_GNUTLS = @USE_GNUTLS@
|
||||
USE_HYPER = @USE_HYPER@
|
||||
USE_LIBRTMP = @USE_LIBRTMP@
|
||||
USE_LIBSSH = @USE_LIBSSH@
|
||||
USE_LIBSSH2 = @USE_LIBSSH2@
|
||||
USE_MBEDTLS = @USE_MBEDTLS@
|
||||
USE_MESALINK = @USE_MESALINK@
|
||||
USE_NGHTTP2 = @USE_NGHTTP2@
|
||||
USE_NGHTTP3 = @USE_NGHTTP3@
|
||||
USE_NGTCP2 = @USE_NGTCP2@
|
||||
USE_NGTCP2_CRYPTO_GNUTLS = @USE_NGTCP2_CRYPTO_GNUTLS@
|
||||
USE_NGTCP2_CRYPTO_OPENSSL = @USE_NGTCP2_CRYPTO_OPENSSL@
|
||||
USE_NSS = @USE_NSS@
|
||||
USE_OPENLDAP = @USE_OPENLDAP@
|
||||
USE_QUICHE = @USE_QUICHE@
|
||||
USE_RUSTLS = @USE_RUSTLS@
|
||||
USE_SCHANNEL = @USE_SCHANNEL@
|
||||
USE_SECTRANSP = @USE_SECTRANSP@
|
||||
USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@
|
||||
USE_WIN32_CRYPTO = @USE_WIN32_CRYPTO@
|
||||
USE_WIN32_LARGE_FILES = @USE_WIN32_LARGE_FILES@
|
||||
USE_WIN32_SMALL_FILES = @USE_WIN32_SMALL_FILES@
|
||||
USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@
|
||||
USE_WOLFSSH = @USE_WOLFSSH@
|
||||
USE_WOLFSSL = @USE_WOLFSSL@
|
||||
VERSION = @VERSION@
|
||||
VERSIONNUM = @VERSIONNUM@
|
||||
ZLIB_LIBS = @ZLIB_LIBS@
|
||||
ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
libext = @libext@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
subdirs = @subdirs@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
pkginclude_HEADERS = \
|
||||
curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \
|
||||
typecheck-gcc.h system.h urlapi.h options.h
|
||||
|
||||
CHECKSRC = $(CS_$(V))
|
||||
CS_0 = @echo " RUN " $@;
|
||||
CS_1 =
|
||||
CS_ = $(CS_0)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/curl/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign include/curl/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
|
||||
$(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-pkgincludeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-am
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-am
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-am
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
@CURLDEBUG_FALSE@all-local:
|
||||
all-am: Makefile $(HEADERS) all-local
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(pkgincludedir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-pkgincludeHEADERS
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-pkgincludeHEADERS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am all-local check check-am clean \
|
||||
clean-generic clean-libtool cscopelist-am ctags ctags-am \
|
||||
distclean distclean-generic distclean-libtool distclean-tags \
|
||||
distdir dvi dvi-am html html-am info info-am install \
|
||||
install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-pkgincludeHEADERS \
|
||||
install-ps install-ps-am install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
|
||||
uninstall-am uninstall-pkgincludeHEADERS
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
checksrc:
|
||||
$(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/include/curl $(pkginclude_HEADERS)
|
||||
|
||||
# for debug builds, we scan the sources on all regular make invokes
|
||||
@CURLDEBUG_TRUE@all-local: checksrc
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
3097
demo/kugou/include/Common/include/curl/curl.h
Normal file
77
demo/kugou/include/Common/include/curl/curlver.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#ifndef CURLINC_CURLVER_H
|
||||
#define CURLINC_CURLVER_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* This header file contains nothing but libcurl version info, generated by
|
||||
a script at release-time. This was made its own header file in 7.11.2 */
|
||||
|
||||
/* This is the global package copyright */
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2021 Daniel Stenberg, <daniel@haxx.se>."
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.80.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 80
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
|
||||
always follow this syntax:
|
||||
|
||||
0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal (using 8 bits each). All three numbers are always represented
|
||||
using two digits. 1.2 would appear as "0x010200" while version 9.11.7
|
||||
appears as "0x090b07".
|
||||
|
||||
This 6-digit (24 bits) hexadecimal number does not show pre-release number,
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
|
||||
Note: This define is the full hex number and _does not_ use the
|
||||
CURL_VERSION_BITS() macro since curl's own configure script greps for it
|
||||
and needs it to contain the full number.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x075000
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
* timestamp is not stored in git, as the timestamp is properly set in the
|
||||
* tarballs by the maketgz script.
|
||||
*
|
||||
* The format of the date follows this template:
|
||||
*
|
||||
* "2007-11-23"
|
||||
*/
|
||||
#define LIBCURL_TIMESTAMP "2021-11-10"
|
||||
|
||||
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
|
||||
#define CURL_AT_LEAST_VERSION(x,y,z) \
|
||||
(LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
|
||||
|
||||
#endif /* CURLINC_CURLVER_H */
|
||||
123
demo/kugou/include/Common/include/curl/easy.h
Normal file
@@ -0,0 +1,123 @@
|
||||
#ifndef CURLINC_EASY_H
|
||||
#define CURLINC_EASY_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Flag bits in the curl_blob struct: */
|
||||
#define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */
|
||||
#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */
|
||||
|
||||
struct curl_blob {
|
||||
void *data;
|
||||
size_t len;
|
||||
unsigned int flags; /* bit 0 is defined, the rest are reserved and should be
|
||||
left zeroes */
|
||||
};
|
||||
|
||||
CURL_EXTERN CURL *curl_easy_init(void);
|
||||
CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
|
||||
CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
|
||||
CURL_EXTERN void curl_easy_cleanup(CURL *curl);
|
||||
|
||||
/*
|
||||
* NAME curl_easy_getinfo()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Request internal information from the curl session with this function. The
|
||||
* third argument MUST be a pointer to a long, a pointer to a char * or a
|
||||
* pointer to a double (as the documentation describes elsewhere). The data
|
||||
* pointed to will be filled in accordingly and can be relied upon only if the
|
||||
* function returns CURLE_OK. This function is intended to get used *AFTER* a
|
||||
* performed transfer, all results from this function are undefined until the
|
||||
* transfer is completed.
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
|
||||
|
||||
|
||||
/*
|
||||
* NAME curl_easy_duphandle()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Creates a new curl session handle with the same options set for the handle
|
||||
* passed in. Duplicating a handle could only be a matter of cloning data and
|
||||
* options, internal state info and things like persistent connections cannot
|
||||
* be transferred. It is useful in multithreaded applications when you can run
|
||||
* curl_easy_duphandle() for each new thread to avoid a series of identical
|
||||
* curl_easy_setopt() invokes in every thread.
|
||||
*/
|
||||
CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
|
||||
|
||||
/*
|
||||
* NAME curl_easy_reset()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Re-initializes a CURL handle to the default values. This puts back the
|
||||
* handle to the same state as it was in when it was just created.
|
||||
*
|
||||
* It does keep: live connections, the Session ID cache, the DNS cache and the
|
||||
* cookies.
|
||||
*/
|
||||
CURL_EXTERN void curl_easy_reset(CURL *curl);
|
||||
|
||||
/*
|
||||
* NAME curl_easy_recv()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Receives data from the connected socket. Use after successful
|
||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
|
||||
size_t *n);
|
||||
|
||||
/*
|
||||
* NAME curl_easy_send()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Sends data over the connected socket. Use after successful
|
||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
|
||||
size_t buflen, size_t *n);
|
||||
|
||||
|
||||
/*
|
||||
* NAME curl_easy_upkeep()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Performs connection upkeep for the given session handle.
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
50
demo/kugou/include/Common/include/curl/mprintf.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef CURLINC_MPRINTF_H
|
||||
#define CURLINC_MPRINTF_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h> /* needed for FILE */
|
||||
#include "curl.h" /* for CURL_EXTERN */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CURL_EXTERN int curl_mprintf(const char *format, ...);
|
||||
CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
|
||||
CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
|
||||
CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
|
||||
const char *format, ...);
|
||||
CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
|
||||
CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
|
||||
CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
|
||||
CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
|
||||
const char *format, va_list args);
|
||||
CURL_EXTERN char *curl_maprintf(const char *format, ...);
|
||||
CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CURLINC_MPRINTF_H */
|
||||
456
demo/kugou/include/Common/include/curl/multi.h
Normal file
@@ -0,0 +1,456 @@
|
||||
#ifndef CURLINC_MULTI_H
|
||||
#define CURLINC_MULTI_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/*
|
||||
This is an "external" header file. Don't give away any internals here!
|
||||
|
||||
GOALS
|
||||
|
||||
o Enable a "pull" interface. The application that uses libcurl decides where
|
||||
and when to ask libcurl to get/send data.
|
||||
|
||||
o Enable multiple simultaneous transfers in the same thread without making it
|
||||
complicated for the application.
|
||||
|
||||
o Enable the application to select() on its own file descriptors and curl's
|
||||
file descriptors simultaneous easily.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* This header file should not really need to include "curl.h" since curl.h
|
||||
* itself includes this file and we expect user applications to do #include
|
||||
* <curl/curl.h> without the need for especially including multi.h.
|
||||
*
|
||||
* For some reason we added this include here at one point, and rather than to
|
||||
* break existing (wrongly written) libcurl applications, we leave it as-is
|
||||
* but with this warning attached.
|
||||
*/
|
||||
#include "curl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
|
||||
typedef struct Curl_multi CURLM;
|
||||
#else
|
||||
typedef void CURLM;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
|
||||
curl_multi_socket*() soon */
|
||||
CURLM_OK,
|
||||
CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
|
||||
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
||||
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
||||
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
||||
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
|
||||
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
|
||||
CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
|
||||
attempted to get added - again */
|
||||
CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
|
||||
callback */
|
||||
CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */
|
||||
CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */
|
||||
CURLM_LAST
|
||||
} CURLMcode;
|
||||
|
||||
/* just to make code nicer when using curl_multi_socket() you can now check
|
||||
for CURLM_CALL_MULTI_SOCKET too in the same style it works for
|
||||
curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
|
||||
#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
|
||||
|
||||
/* bitmask bits for CURLMOPT_PIPELINING */
|
||||
#define CURLPIPE_NOTHING 0L
|
||||
#define CURLPIPE_HTTP1 1L
|
||||
#define CURLPIPE_MULTIPLEX 2L
|
||||
|
||||
typedef enum {
|
||||
CURLMSG_NONE, /* first, not used */
|
||||
CURLMSG_DONE, /* This easy handle has completed. 'result' contains
|
||||
the CURLcode of the transfer */
|
||||
CURLMSG_LAST /* last, not used */
|
||||
} CURLMSG;
|
||||
|
||||
struct CURLMsg {
|
||||
CURLMSG msg; /* what this message means */
|
||||
CURL *easy_handle; /* the handle it concerns */
|
||||
union {
|
||||
void *whatever; /* message-specific data */
|
||||
CURLcode result; /* return code for transfer */
|
||||
} data;
|
||||
};
|
||||
typedef struct CURLMsg CURLMsg;
|
||||
|
||||
/* Based on poll(2) structure and values.
|
||||
* We don't use pollfd and POLL* constants explicitly
|
||||
* to cover platforms without poll(). */
|
||||
#define CURL_WAIT_POLLIN 0x0001
|
||||
#define CURL_WAIT_POLLPRI 0x0002
|
||||
#define CURL_WAIT_POLLOUT 0x0004
|
||||
|
||||
struct curl_waitfd {
|
||||
curl_socket_t fd;
|
||||
short events;
|
||||
short revents; /* not supported yet */
|
||||
};
|
||||
|
||||
/*
|
||||
* Name: curl_multi_init()
|
||||
*
|
||||
* Desc: inititalize multi-style curl usage
|
||||
*
|
||||
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
|
||||
*/
|
||||
CURL_EXTERN CURLM *curl_multi_init(void);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_add_handle()
|
||||
*
|
||||
* Desc: add a standard curl handle to the multi stack
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_remove_handle()
|
||||
*
|
||||
* Desc: removes a curl handle from the multi stack again
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_fdset()
|
||||
*
|
||||
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
||||
* poll() on. We want curl_multi_perform() called as soon as one of
|
||||
* them are ready.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
fd_set *exc_fd_set,
|
||||
int *max_fd);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_wait()
|
||||
*
|
||||
* Desc: Poll on all fds within a CURLM set as well as any
|
||||
* additional fds passed to the function.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
|
||||
struct curl_waitfd extra_fds[],
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *ret);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_poll()
|
||||
*
|
||||
* Desc: Poll on all fds within a CURLM set as well as any
|
||||
* additional fds passed to the function.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
|
||||
struct curl_waitfd extra_fds[],
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *ret);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_wakeup()
|
||||
*
|
||||
* Desc: wakes up a sleeping curl_multi_poll call.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_perform()
|
||||
*
|
||||
* Desc: When the app thinks there's data available for curl it calls this
|
||||
* function to read/write whatever there is right now. This returns
|
||||
* as soon as the reads and writes are done. This function does not
|
||||
* require that there actually is data available for reading or that
|
||||
* data can be written, it can be called just in case. It returns
|
||||
* the number of handles that still transfer data in the second
|
||||
* argument's integer-pointer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code. *NOTE* that this only
|
||||
* returns errors etc regarding the whole multi stack. There might
|
||||
* still have occurred problems on individual transfers even when
|
||||
* this returns OK.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
|
||||
int *running_handles);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_cleanup()
|
||||
*
|
||||
* Desc: Cleans up and removes a whole multi stack. It does not free or
|
||||
* touch any individual easy handles in any way. We need to define
|
||||
* in what state those handles will be if this function is called
|
||||
* in the middle of a transfer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_info_read()
|
||||
*
|
||||
* Desc: Ask the multi handle if there's any messages/informationals from
|
||||
* the individual transfers. Messages include informationals such as
|
||||
* error code from the transfer or just the fact that a transfer is
|
||||
* completed. More details on these should be written down as well.
|
||||
*
|
||||
* Repeated calls to this function will return a new struct each
|
||||
* time, until a special "end of msgs" struct is returned as a signal
|
||||
* that there is no more to get at this point.
|
||||
*
|
||||
* The data the returned pointer points to will not survive calling
|
||||
* curl_multi_cleanup().
|
||||
*
|
||||
* The 'CURLMsg' struct is meant to be very simple and only contain
|
||||
* very basic information. If more involved information is wanted,
|
||||
* we will provide the particular "transfer handle" in that struct
|
||||
* and that should/could/would be used in subsequent
|
||||
* curl_easy_getinfo() calls (or similar). The point being that we
|
||||
* must never expose complex structs to applications, as then we'll
|
||||
* undoubtably get backwards compatibility problems in the future.
|
||||
*
|
||||
* Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
|
||||
* of structs. It also writes the number of messages left in the
|
||||
* queue (after this read) in the integer the second argument points
|
||||
* to.
|
||||
*/
|
||||
CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
||||
int *msgs_in_queue);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_strerror()
|
||||
*
|
||||
* Desc: The curl_multi_strerror function may be used to turn a CURLMcode
|
||||
* value into the equivalent human readable error string. This is
|
||||
* useful for printing meaningful error messages.
|
||||
*
|
||||
* Returns: A pointer to a null-terminated error message.
|
||||
*/
|
||||
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_socket() and
|
||||
* curl_multi_socket_all()
|
||||
*
|
||||
* Desc: An alternative version of curl_multi_perform() that allows the
|
||||
* application to pass in one of the file descriptors that have been
|
||||
* detected to have "action" on them and let libcurl perform.
|
||||
* See man page for details.
|
||||
*/
|
||||
#define CURL_POLL_NONE 0
|
||||
#define CURL_POLL_IN 1
|
||||
#define CURL_POLL_OUT 2
|
||||
#define CURL_POLL_INOUT 3
|
||||
#define CURL_POLL_REMOVE 4
|
||||
|
||||
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
||||
|
||||
#define CURL_CSELECT_IN 0x01
|
||||
#define CURL_CSELECT_OUT 0x02
|
||||
#define CURL_CSELECT_ERR 0x04
|
||||
|
||||
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
||||
curl_socket_t s, /* socket */
|
||||
int what, /* see above */
|
||||
void *userp, /* private callback
|
||||
pointer */
|
||||
void *socketp); /* private socket
|
||||
pointer */
|
||||
/*
|
||||
* Name: curl_multi_timer_callback
|
||||
*
|
||||
* Desc: Called by libcurl whenever the library detects a change in the
|
||||
* maximum number of milliseconds the app is allowed to wait before
|
||||
* curl_multi_socket() or curl_multi_perform() must be called
|
||||
* (to allow libcurl's timed events to take place).
|
||||
*
|
||||
* Returns: The callback should return zero.
|
||||
*/
|
||||
typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
|
||||
long timeout_ms, /* see above */
|
||||
void *userp); /* private callback
|
||||
pointer */
|
||||
|
||||
CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
|
||||
int *running_handles);
|
||||
|
||||
CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
|
||||
curl_socket_t s,
|
||||
int ev_bitmask,
|
||||
int *running_handles);
|
||||
|
||||
CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
|
||||
int *running_handles);
|
||||
|
||||
#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
|
||||
/* This macro below was added in 7.16.3 to push users who recompile to use
|
||||
the new curl_multi_socket_action() instead of the old curl_multi_socket()
|
||||
*/
|
||||
#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Name: curl_multi_timeout()
|
||||
*
|
||||
* Desc: Returns the maximum number of milliseconds the app is allowed to
|
||||
* wait before curl_multi_socket() or curl_multi_perform() must be
|
||||
* called (to allow libcurl's timed events to take place).
|
||||
*
|
||||
* Returns: CURLM error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
|
||||
long *milliseconds);
|
||||
|
||||
typedef enum {
|
||||
/* This is the socket callback function pointer */
|
||||
CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1),
|
||||
|
||||
/* This is the argument passed to the socket callback */
|
||||
CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2),
|
||||
|
||||
/* set to 1 to enable pipelining for this multi handle */
|
||||
CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3),
|
||||
|
||||
/* This is the timer callback function pointer */
|
||||
CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4),
|
||||
|
||||
/* This is the argument passed to the timer callback */
|
||||
CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5),
|
||||
|
||||
/* maximum number of entries in the connection cache */
|
||||
CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6),
|
||||
|
||||
/* maximum number of (pipelining) connections to one host */
|
||||
CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7),
|
||||
|
||||
/* maximum number of requests in a pipeline */
|
||||
CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8),
|
||||
|
||||
/* a connection with a content-length longer than this
|
||||
will not be considered for pipelining */
|
||||
CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9),
|
||||
|
||||
/* a connection with a chunk length longer than this
|
||||
will not be considered for pipelining */
|
||||
CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10),
|
||||
|
||||
/* a list of site names(+port) that are blocked from pipelining */
|
||||
CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11),
|
||||
|
||||
/* a list of server types that are blocked from pipelining */
|
||||
CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12),
|
||||
|
||||
/* maximum number of open connections in total */
|
||||
CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13),
|
||||
|
||||
/* This is the server push callback function pointer */
|
||||
CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14),
|
||||
|
||||
/* This is the argument passed to the server push callback */
|
||||
CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15),
|
||||
|
||||
/* maximum number of concurrent streams to support on a connection */
|
||||
CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16),
|
||||
|
||||
CURLMOPT_LASTENTRY /* the last unused */
|
||||
} CURLMoption;
|
||||
|
||||
|
||||
/*
|
||||
* Name: curl_multi_setopt()
|
||||
*
|
||||
* Desc: Sets options for the multi handle.
|
||||
*
|
||||
* Returns: CURLM error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||
CURLMoption option, ...);
|
||||
|
||||
|
||||
/*
|
||||
* Name: curl_multi_assign()
|
||||
*
|
||||
* Desc: This function sets an association in the multi handle between the
|
||||
* given socket and a private pointer of the application. This is
|
||||
* (only) useful for curl_multi_socket uses.
|
||||
*
|
||||
* Returns: CURLM error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
curl_socket_t sockfd, void *sockp);
|
||||
|
||||
|
||||
/*
|
||||
* Name: curl_push_callback
|
||||
*
|
||||
* Desc: This callback gets called when a new stream is being pushed by the
|
||||
* server. It approves or denies the new stream. It can also decide
|
||||
* to completely fail the connection.
|
||||
*
|
||||
* Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT
|
||||
*/
|
||||
#define CURL_PUSH_OK 0
|
||||
#define CURL_PUSH_DENY 1
|
||||
#define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */
|
||||
|
||||
struct curl_pushheaders; /* forward declaration only */
|
||||
|
||||
CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
|
||||
size_t num);
|
||||
CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
|
||||
const char *name);
|
||||
|
||||
typedef int (*curl_push_callback)(CURL *parent,
|
||||
CURL *easy,
|
||||
size_t num_headers,
|
||||
struct curl_pushheaders *headers,
|
||||
void *userp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
68
demo/kugou/include/Common/include/curl/options.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef CURLINC_OPTIONS_H
|
||||
#define CURLINC_OPTIONS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CURLOT_LONG, /* long (a range of values) */
|
||||
CURLOT_VALUES, /* (a defined set or bitmask) */
|
||||
CURLOT_OFF_T, /* curl_off_t (a range of values) */
|
||||
CURLOT_OBJECT, /* pointer (void *) */
|
||||
CURLOT_STRING, /* (char * to zero terminated buffer) */
|
||||
CURLOT_SLIST, /* (struct curl_slist *) */
|
||||
CURLOT_CBPTR, /* (void * passed as-is to a callback) */
|
||||
CURLOT_BLOB, /* blob (struct curl_blob *) */
|
||||
CURLOT_FUNCTION /* function pointer */
|
||||
} curl_easytype;
|
||||
|
||||
/* Flag bits */
|
||||
|
||||
/* "alias" means it is provided for old programs to remain functional,
|
||||
we prefer another name */
|
||||
#define CURLOT_FLAG_ALIAS (1<<0)
|
||||
|
||||
/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size
|
||||
to use for curl_easy_setopt() for the given id */
|
||||
struct curl_easyoption {
|
||||
const char *name;
|
||||
CURLoption id;
|
||||
curl_easytype type;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
CURL_EXTERN const struct curl_easyoption *
|
||||
curl_easy_option_by_name(const char *name);
|
||||
|
||||
CURL_EXTERN const struct curl_easyoption *
|
||||
curl_easy_option_by_id (CURLoption id);
|
||||
|
||||
CURL_EXTERN const struct curl_easyoption *
|
||||
curl_easy_option_next(const struct curl_easyoption *prev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
#endif /* CURLINC_OPTIONS_H */
|
||||
33
demo/kugou/include/Common/include/curl/stdcheaders.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef CURLINC_STDCHEADERS_H
|
||||
#define CURLINC_STDCHEADERS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
size_t fread(void *, size_t, size_t, FILE *);
|
||||
size_t fwrite(const void *, size_t, size_t, FILE *);
|
||||
|
||||
int strcasecmp(const char *, const char *);
|
||||
int strncasecmp(const char *, const char *, size_t);
|
||||
|
||||
#endif /* CURLINC_STDCHEADERS_H */
|
||||
504
demo/kugou/include/Common/include/curl/system.h
Normal file
@@ -0,0 +1,504 @@
|
||||
#ifndef CURLINC_SYSTEM_H
|
||||
#define CURLINC_SYSTEM_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Try to keep one section per platform, compiler and architecture, otherwise,
|
||||
* if an existing section is reused for a different one and later on the
|
||||
* original is adjusted, probably the piggybacking one can be adversely
|
||||
* changed.
|
||||
*
|
||||
* In order to differentiate between platforms/compilers/architectures use
|
||||
* only compiler built in predefined preprocessor symbols.
|
||||
*
|
||||
* curl_off_t
|
||||
* ----------
|
||||
*
|
||||
* For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
|
||||
* wide signed integral data type. The width of this data type must remain
|
||||
* constant and independent of any possible large file support settings.
|
||||
*
|
||||
* As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
|
||||
* wide signed integral data type if there is no 64-bit type.
|
||||
*
|
||||
* As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
|
||||
* only be violated if off_t is the only 64-bit data type available and the
|
||||
* size of off_t is independent of large file support settings. Keep your
|
||||
* build on the safe side avoiding an off_t gating. If you have a 64-bit
|
||||
* off_t then take for sure that another 64-bit data type exists, dig deeper
|
||||
* and you will find it.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__DJGPP__) || defined(__GO32__)
|
||||
# if defined(__DJGPP__) && (__DJGPP__ > 1)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__SALFORDC__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
# if (__BORLANDC__ < 0x520)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__TURBOC__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
# if defined(__386__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__POCC__)
|
||||
# if (__POCC__ < 280)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# elif defined(_MSC_VER)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__LCC__)
|
||||
# if defined(__e2k__) /* MCST eLbrus C Compiler */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
# else /* Local (or Little) C Compiler */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
# endif
|
||||
|
||||
#elif defined(__SYMBIAN32__)
|
||||
# if defined(__EABI__) /* Treat all ARM compilers equally */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__CW32__)
|
||||
# pragma longlong on
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__VC32__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
|
||||
|
||||
#elif defined(__MWERKS__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(_WIN32_WCE)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_WS2TCPIP_H 1
|
||||
|
||||
#elif defined(__VMS)
|
||||
# if defined(__VAX)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
|
||||
|
||||
#elif defined(__OS400__)
|
||||
# if defined(__ILEC400__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
# endif
|
||||
|
||||
#elif defined(__MVS__)
|
||||
# if defined(__IBMC__) || defined(__IBMCPP__)
|
||||
# if defined(_ILP32)
|
||||
# elif defined(_LP64)
|
||||
# endif
|
||||
# if defined(_LONG_LONG)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(_LP64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
# endif
|
||||
|
||||
#elif defined(__370__)
|
||||
# if defined(__IBMC__) || defined(__IBMCPP__)
|
||||
# if defined(_ILP32)
|
||||
# elif defined(_LP64)
|
||||
# endif
|
||||
# if defined(_LONG_LONG)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(_LP64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
# endif
|
||||
|
||||
#elif defined(TPF)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__TINYC__) /* also known as tcc */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
|
||||
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */
|
||||
# if !defined(__LP64) && (defined(__ILP32) || \
|
||||
defined(__i386) || \
|
||||
defined(__sparcv8) || \
|
||||
defined(__sparcv8plus))
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__LP64) || \
|
||||
defined(__amd64) || defined(__sparcv9)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
|
||||
#elif defined(__xlc__) /* IBM xlc compiler */
|
||||
# if !defined(_LP64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
|
||||
/* ===================================== */
|
||||
/* KEEP MSVC THE PENULTIMATE ENTRY */
|
||||
/* ===================================== */
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
/* ===================================== */
|
||||
/* KEEP GENERIC GCC THE LAST ENTRY */
|
||||
/* ===================================== */
|
||||
|
||||
#elif defined(__GNUC__) && !defined(_SCO_DS)
|
||||
# if !defined(__LP64__) && \
|
||||
(defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \
|
||||
defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \
|
||||
defined(__sparc__) || defined(__mips__) || defined(__sh__) || \
|
||||
defined(__XTENSA__) || \
|
||||
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \
|
||||
(defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L))
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__LP64__) || \
|
||||
defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
|
||||
defined(__e2k__) || \
|
||||
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
|
||||
(defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
|
||||
#else
|
||||
/* generic "safe guess" on old 32 bit style */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
/* AIX needs <sys/poll.h> */
|
||||
#define CURL_PULL_SYS_POLL_H
|
||||
#endif
|
||||
|
||||
|
||||
/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */
|
||||
/* ws2tcpip.h is required here to properly make type definitions below. */
|
||||
#ifdef CURL_PULL_WS2TCPIP_H
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */
|
||||
/* sys/types.h is required here to properly make type definitions below. */
|
||||
#ifdef CURL_PULL_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
|
||||
/* sys/socket.h is required here to properly make type definitions below. */
|
||||
#ifdef CURL_PULL_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */
|
||||
/* sys/poll.h is required here to properly make type definitions below. */
|
||||
#ifdef CURL_PULL_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
/* Data type definition of curl_socklen_t. */
|
||||
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
||||
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
|
||||
#endif
|
||||
|
||||
/* Data type definition of curl_off_t. */
|
||||
|
||||
#ifdef CURL_TYPEOF_CURL_OFF_T
|
||||
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
|
||||
* these to be visible and exported by the external libcurl interface API,
|
||||
* while also making them visible to the library internals, simply including
|
||||
* curl_setup.h, without actually needing to include curl.h internally.
|
||||
* If some day this section would grow big enough, all this should be moved
|
||||
* to its own header file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Figure out if we can use the ## preprocessor operator, which is supported
|
||||
* by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
|
||||
* or __cplusplus so we need to carefully check for them too.
|
||||
*/
|
||||
|
||||
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
||||
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
|
||||
defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
|
||||
defined(__ILEC400__)
|
||||
/* This compiler is believed to have an ISO compatible preprocessor */
|
||||
#define CURL_ISOCPP
|
||||
#else
|
||||
/* This compiler is believed NOT to have an ISO compatible preprocessor */
|
||||
#undef CURL_ISOCPP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros for minimum-width signed and unsigned curl_off_t integer constants.
|
||||
*/
|
||||
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
|
||||
# define CURLINC_OFF_T_C_HLPR2(x) x
|
||||
# define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x)
|
||||
# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
|
||||
CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
|
||||
# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
|
||||
CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
|
||||
#else
|
||||
# ifdef CURL_ISOCPP
|
||||
# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
|
||||
# else
|
||||
# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
|
||||
# endif
|
||||
# define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix)
|
||||
# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
|
||||
# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
|
||||
#endif
|
||||
|
||||
#endif /* CURLINC_SYSTEM_H */
|
||||
707
demo/kugou/include/Common/include/curl/typecheck-gcc.h
Normal file
@@ -0,0 +1,707 @@
|
||||
#ifndef CURLINC_TYPECHECK_GCC_H
|
||||
#define CURLINC_TYPECHECK_GCC_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* wraps curl_easy_setopt() with typechecking */
|
||||
|
||||
/* To add a new kind of warning, add an
|
||||
* if(curlcheck_sometype_option(_curl_opt))
|
||||
* if(!curlcheck_sometype(value))
|
||||
* _curl_easy_setopt_err_sometype();
|
||||
* block and define curlcheck_sometype_option, curlcheck_sometype and
|
||||
* _curl_easy_setopt_err_sometype below
|
||||
*
|
||||
* NOTE: We use two nested 'if' statements here instead of the && operator, in
|
||||
* order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
|
||||
* when compiling with -Wlogical-op.
|
||||
*
|
||||
* To add an option that uses the same type as an existing option, you'll just
|
||||
* need to extend the appropriate _curl_*_option macro
|
||||
*/
|
||||
#define curl_easy_setopt(handle, option, value) \
|
||||
__extension__({ \
|
||||
__typeof__(option) _curl_opt = option; \
|
||||
if(__builtin_constant_p(_curl_opt)) { \
|
||||
if(curlcheck_long_option(_curl_opt)) \
|
||||
if(!curlcheck_long(value)) \
|
||||
_curl_easy_setopt_err_long(); \
|
||||
if(curlcheck_off_t_option(_curl_opt)) \
|
||||
if(!curlcheck_off_t(value)) \
|
||||
_curl_easy_setopt_err_curl_off_t(); \
|
||||
if(curlcheck_string_option(_curl_opt)) \
|
||||
if(!curlcheck_string(value)) \
|
||||
_curl_easy_setopt_err_string(); \
|
||||
if(curlcheck_write_cb_option(_curl_opt)) \
|
||||
if(!curlcheck_write_cb(value)) \
|
||||
_curl_easy_setopt_err_write_callback(); \
|
||||
if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION) \
|
||||
if(!curlcheck_resolver_start_callback(value)) \
|
||||
_curl_easy_setopt_err_resolver_start_callback(); \
|
||||
if((_curl_opt) == CURLOPT_READFUNCTION) \
|
||||
if(!curlcheck_read_cb(value)) \
|
||||
_curl_easy_setopt_err_read_cb(); \
|
||||
if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
|
||||
if(!curlcheck_ioctl_cb(value)) \
|
||||
_curl_easy_setopt_err_ioctl_cb(); \
|
||||
if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
|
||||
if(!curlcheck_sockopt_cb(value)) \
|
||||
_curl_easy_setopt_err_sockopt_cb(); \
|
||||
if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
|
||||
if(!curlcheck_opensocket_cb(value)) \
|
||||
_curl_easy_setopt_err_opensocket_cb(); \
|
||||
if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
|
||||
if(!curlcheck_progress_cb(value)) \
|
||||
_curl_easy_setopt_err_progress_cb(); \
|
||||
if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
|
||||
if(!curlcheck_debug_cb(value)) \
|
||||
_curl_easy_setopt_err_debug_cb(); \
|
||||
if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
|
||||
if(!curlcheck_ssl_ctx_cb(value)) \
|
||||
_curl_easy_setopt_err_ssl_ctx_cb(); \
|
||||
if(curlcheck_conv_cb_option(_curl_opt)) \
|
||||
if(!curlcheck_conv_cb(value)) \
|
||||
_curl_easy_setopt_err_conv_cb(); \
|
||||
if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
|
||||
if(!curlcheck_seek_cb(value)) \
|
||||
_curl_easy_setopt_err_seek_cb(); \
|
||||
if(curlcheck_cb_data_option(_curl_opt)) \
|
||||
if(!curlcheck_cb_data(value)) \
|
||||
_curl_easy_setopt_err_cb_data(); \
|
||||
if((_curl_opt) == CURLOPT_ERRORBUFFER) \
|
||||
if(!curlcheck_error_buffer(value)) \
|
||||
_curl_easy_setopt_err_error_buffer(); \
|
||||
if((_curl_opt) == CURLOPT_STDERR) \
|
||||
if(!curlcheck_FILE(value)) \
|
||||
_curl_easy_setopt_err_FILE(); \
|
||||
if(curlcheck_postfields_option(_curl_opt)) \
|
||||
if(!curlcheck_postfields(value)) \
|
||||
_curl_easy_setopt_err_postfields(); \
|
||||
if((_curl_opt) == CURLOPT_HTTPPOST) \
|
||||
if(!curlcheck_arr((value), struct curl_httppost)) \
|
||||
_curl_easy_setopt_err_curl_httpost(); \
|
||||
if((_curl_opt) == CURLOPT_MIMEPOST) \
|
||||
if(!curlcheck_ptr((value), curl_mime)) \
|
||||
_curl_easy_setopt_err_curl_mimepost(); \
|
||||
if(curlcheck_slist_option(_curl_opt)) \
|
||||
if(!curlcheck_arr((value), struct curl_slist)) \
|
||||
_curl_easy_setopt_err_curl_slist(); \
|
||||
if((_curl_opt) == CURLOPT_SHARE) \
|
||||
if(!curlcheck_ptr((value), CURLSH)) \
|
||||
_curl_easy_setopt_err_CURLSH(); \
|
||||
} \
|
||||
curl_easy_setopt(handle, _curl_opt, value); \
|
||||
})
|
||||
|
||||
/* wraps curl_easy_getinfo() with typechecking */
|
||||
#define curl_easy_getinfo(handle, info, arg) \
|
||||
__extension__({ \
|
||||
__typeof__(info) _curl_info = info; \
|
||||
if(__builtin_constant_p(_curl_info)) { \
|
||||
if(curlcheck_string_info(_curl_info)) \
|
||||
if(!curlcheck_arr((arg), char *)) \
|
||||
_curl_easy_getinfo_err_string(); \
|
||||
if(curlcheck_long_info(_curl_info)) \
|
||||
if(!curlcheck_arr((arg), long)) \
|
||||
_curl_easy_getinfo_err_long(); \
|
||||
if(curlcheck_double_info(_curl_info)) \
|
||||
if(!curlcheck_arr((arg), double)) \
|
||||
_curl_easy_getinfo_err_double(); \
|
||||
if(curlcheck_slist_info(_curl_info)) \
|
||||
if(!curlcheck_arr((arg), struct curl_slist *)) \
|
||||
_curl_easy_getinfo_err_curl_slist(); \
|
||||
if(curlcheck_tlssessioninfo_info(_curl_info)) \
|
||||
if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \
|
||||
_curl_easy_getinfo_err_curl_tlssesssioninfo(); \
|
||||
if(curlcheck_certinfo_info(_curl_info)) \
|
||||
if(!curlcheck_arr((arg), struct curl_certinfo *)) \
|
||||
_curl_easy_getinfo_err_curl_certinfo(); \
|
||||
if(curlcheck_socket_info(_curl_info)) \
|
||||
if(!curlcheck_arr((arg), curl_socket_t)) \
|
||||
_curl_easy_getinfo_err_curl_socket(); \
|
||||
if(curlcheck_off_t_info(_curl_info)) \
|
||||
if(!curlcheck_arr((arg), curl_off_t)) \
|
||||
_curl_easy_getinfo_err_curl_off_t(); \
|
||||
} \
|
||||
curl_easy_getinfo(handle, _curl_info, arg); \
|
||||
})
|
||||
|
||||
/*
|
||||
* For now, just make sure that the functions are called with three arguments
|
||||
*/
|
||||
#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
|
||||
#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
|
||||
|
||||
|
||||
/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
|
||||
* functions */
|
||||
|
||||
/* To define a new warning, use _CURL_WARNING(identifier, "message") */
|
||||
#define CURLWARNING(id, message) \
|
||||
static void __attribute__((__warning__(message))) \
|
||||
__attribute__((__unused__)) __attribute__((__noinline__)) \
|
||||
id(void) { __asm__(""); }
|
||||
|
||||
CURLWARNING(_curl_easy_setopt_err_long,
|
||||
"curl_easy_setopt expects a long argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_curl_off_t,
|
||||
"curl_easy_setopt expects a curl_off_t argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_string,
|
||||
"curl_easy_setopt expects a "
|
||||
"string ('char *' or char[]) argument for this option"
|
||||
)
|
||||
CURLWARNING(_curl_easy_setopt_err_write_callback,
|
||||
"curl_easy_setopt expects a curl_write_callback argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
|
||||
"curl_easy_setopt expects a "
|
||||
"curl_resolver_start_callback argument for this option"
|
||||
)
|
||||
CURLWARNING(_curl_easy_setopt_err_read_cb,
|
||||
"curl_easy_setopt expects a curl_read_callback argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
|
||||
"curl_easy_setopt expects a curl_ioctl_callback argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
|
||||
"curl_easy_setopt expects a curl_sockopt_callback argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
|
||||
"curl_easy_setopt expects a "
|
||||
"curl_opensocket_callback argument for this option"
|
||||
)
|
||||
CURLWARNING(_curl_easy_setopt_err_progress_cb,
|
||||
"curl_easy_setopt expects a curl_progress_callback argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_debug_cb,
|
||||
"curl_easy_setopt expects a curl_debug_callback argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
|
||||
"curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_conv_cb,
|
||||
"curl_easy_setopt expects a curl_conv_callback argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_seek_cb,
|
||||
"curl_easy_setopt expects a curl_seek_callback argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_cb_data,
|
||||
"curl_easy_setopt expects a "
|
||||
"private data pointer as argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_error_buffer,
|
||||
"curl_easy_setopt expects a "
|
||||
"char buffer of CURL_ERROR_SIZE as argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_FILE,
|
||||
"curl_easy_setopt expects a 'FILE *' argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_postfields,
|
||||
"curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_curl_httpost,
|
||||
"curl_easy_setopt expects a 'struct curl_httppost *' "
|
||||
"argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
|
||||
"curl_easy_setopt expects a 'curl_mime *' "
|
||||
"argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_curl_slist,
|
||||
"curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
|
||||
CURLWARNING(_curl_easy_setopt_err_CURLSH,
|
||||
"curl_easy_setopt expects a CURLSH* argument for this option")
|
||||
|
||||
CURLWARNING(_curl_easy_getinfo_err_string,
|
||||
"curl_easy_getinfo expects a pointer to 'char *' for this info")
|
||||
CURLWARNING(_curl_easy_getinfo_err_long,
|
||||
"curl_easy_getinfo expects a pointer to long for this info")
|
||||
CURLWARNING(_curl_easy_getinfo_err_double,
|
||||
"curl_easy_getinfo expects a pointer to double for this info")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_slist,
|
||||
"curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
|
||||
"curl_easy_getinfo expects a pointer to "
|
||||
"'struct curl_tlssessioninfo *' for this info")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
|
||||
"curl_easy_getinfo expects a pointer to "
|
||||
"'struct curl_certinfo *' for this info")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_socket,
|
||||
"curl_easy_getinfo expects a pointer to curl_socket_t for this info")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
"curl_easy_getinfo expects a pointer to curl_off_t for this info")
|
||||
|
||||
/* groups of curl_easy_setops options that take the same type of argument */
|
||||
|
||||
/* To add a new option to one of the groups, just add
|
||||
* (option) == CURLOPT_SOMETHING
|
||||
* to the or-expression. If the option takes a long or curl_off_t, you don't
|
||||
* have to do anything
|
||||
*/
|
||||
|
||||
/* evaluates to true if option takes a long argument */
|
||||
#define curlcheck_long_option(option) \
|
||||
(0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
|
||||
|
||||
#define curlcheck_off_t_option(option) \
|
||||
(((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
|
||||
|
||||
/* evaluates to true if option takes a char* argument */
|
||||
#define curlcheck_string_option(option) \
|
||||
((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
|
||||
(option) == CURLOPT_ACCEPT_ENCODING || \
|
||||
(option) == CURLOPT_ALTSVC || \
|
||||
(option) == CURLOPT_CAINFO || \
|
||||
(option) == CURLOPT_CAPATH || \
|
||||
(option) == CURLOPT_COOKIE || \
|
||||
(option) == CURLOPT_COOKIEFILE || \
|
||||
(option) == CURLOPT_COOKIEJAR || \
|
||||
(option) == CURLOPT_COOKIELIST || \
|
||||
(option) == CURLOPT_CRLFILE || \
|
||||
(option) == CURLOPT_CUSTOMREQUEST || \
|
||||
(option) == CURLOPT_DEFAULT_PROTOCOL || \
|
||||
(option) == CURLOPT_DNS_INTERFACE || \
|
||||
(option) == CURLOPT_DNS_LOCAL_IP4 || \
|
||||
(option) == CURLOPT_DNS_LOCAL_IP6 || \
|
||||
(option) == CURLOPT_DNS_SERVERS || \
|
||||
(option) == CURLOPT_DOH_URL || \
|
||||
(option) == CURLOPT_EGDSOCKET || \
|
||||
(option) == CURLOPT_FTPPORT || \
|
||||
(option) == CURLOPT_FTP_ACCOUNT || \
|
||||
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
|
||||
(option) == CURLOPT_HSTS || \
|
||||
(option) == CURLOPT_INTERFACE || \
|
||||
(option) == CURLOPT_ISSUERCERT || \
|
||||
(option) == CURLOPT_KEYPASSWD || \
|
||||
(option) == CURLOPT_KRBLEVEL || \
|
||||
(option) == CURLOPT_LOGIN_OPTIONS || \
|
||||
(option) == CURLOPT_MAIL_AUTH || \
|
||||
(option) == CURLOPT_MAIL_FROM || \
|
||||
(option) == CURLOPT_NETRC_FILE || \
|
||||
(option) == CURLOPT_NOPROXY || \
|
||||
(option) == CURLOPT_PASSWORD || \
|
||||
(option) == CURLOPT_PINNEDPUBLICKEY || \
|
||||
(option) == CURLOPT_PRE_PROXY || \
|
||||
(option) == CURLOPT_PROXY || \
|
||||
(option) == CURLOPT_PROXYPASSWORD || \
|
||||
(option) == CURLOPT_PROXYUSERNAME || \
|
||||
(option) == CURLOPT_PROXYUSERPWD || \
|
||||
(option) == CURLOPT_PROXY_CAINFO || \
|
||||
(option) == CURLOPT_PROXY_CAPATH || \
|
||||
(option) == CURLOPT_PROXY_CRLFILE || \
|
||||
(option) == CURLOPT_PROXY_ISSUERCERT || \
|
||||
(option) == CURLOPT_PROXY_KEYPASSWD || \
|
||||
(option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \
|
||||
(option) == CURLOPT_PROXY_SERVICE_NAME || \
|
||||
(option) == CURLOPT_PROXY_SSLCERT || \
|
||||
(option) == CURLOPT_PROXY_SSLCERTTYPE || \
|
||||
(option) == CURLOPT_PROXY_SSLKEY || \
|
||||
(option) == CURLOPT_PROXY_SSLKEYTYPE || \
|
||||
(option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \
|
||||
(option) == CURLOPT_PROXY_TLS13_CIPHERS || \
|
||||
(option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \
|
||||
(option) == CURLOPT_PROXY_TLSAUTH_TYPE || \
|
||||
(option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \
|
||||
(option) == CURLOPT_RANDOM_FILE || \
|
||||
(option) == CURLOPT_RANGE || \
|
||||
(option) == CURLOPT_REFERER || \
|
||||
(option) == CURLOPT_REQUEST_TARGET || \
|
||||
(option) == CURLOPT_RTSP_SESSION_ID || \
|
||||
(option) == CURLOPT_RTSP_STREAM_URI || \
|
||||
(option) == CURLOPT_RTSP_TRANSPORT || \
|
||||
(option) == CURLOPT_SASL_AUTHZID || \
|
||||
(option) == CURLOPT_SERVICE_NAME || \
|
||||
(option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
|
||||
(option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
|
||||
(option) == CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 || \
|
||||
(option) == CURLOPT_SSH_KNOWNHOSTS || \
|
||||
(option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
|
||||
(option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
|
||||
(option) == CURLOPT_SSLCERT || \
|
||||
(option) == CURLOPT_SSLCERTTYPE || \
|
||||
(option) == CURLOPT_SSLENGINE || \
|
||||
(option) == CURLOPT_SSLKEY || \
|
||||
(option) == CURLOPT_SSLKEYTYPE || \
|
||||
(option) == CURLOPT_SSL_CIPHER_LIST || \
|
||||
(option) == CURLOPT_TLS13_CIPHERS || \
|
||||
(option) == CURLOPT_TLSAUTH_PASSWORD || \
|
||||
(option) == CURLOPT_TLSAUTH_TYPE || \
|
||||
(option) == CURLOPT_TLSAUTH_USERNAME || \
|
||||
(option) == CURLOPT_UNIX_SOCKET_PATH || \
|
||||
(option) == CURLOPT_URL || \
|
||||
(option) == CURLOPT_USERAGENT || \
|
||||
(option) == CURLOPT_USERNAME || \
|
||||
(option) == CURLOPT_AWS_SIGV4 || \
|
||||
(option) == CURLOPT_USERPWD || \
|
||||
(option) == CURLOPT_XOAUTH2_BEARER || \
|
||||
(option) == CURLOPT_SSL_EC_CURVES || \
|
||||
0)
|
||||
|
||||
/* evaluates to true if option takes a curl_write_callback argument */
|
||||
#define curlcheck_write_cb_option(option) \
|
||||
((option) == CURLOPT_HEADERFUNCTION || \
|
||||
(option) == CURLOPT_WRITEFUNCTION)
|
||||
|
||||
/* evaluates to true if option takes a curl_conv_callback argument */
|
||||
#define curlcheck_conv_cb_option(option) \
|
||||
((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
|
||||
(option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
|
||||
(option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
|
||||
|
||||
/* evaluates to true if option takes a data argument to pass to a callback */
|
||||
#define curlcheck_cb_data_option(option) \
|
||||
((option) == CURLOPT_CHUNK_DATA || \
|
||||
(option) == CURLOPT_CLOSESOCKETDATA || \
|
||||
(option) == CURLOPT_DEBUGDATA || \
|
||||
(option) == CURLOPT_FNMATCH_DATA || \
|
||||
(option) == CURLOPT_HEADERDATA || \
|
||||
(option) == CURLOPT_HSTSREADDATA || \
|
||||
(option) == CURLOPT_HSTSWRITEDATA || \
|
||||
(option) == CURLOPT_INTERLEAVEDATA || \
|
||||
(option) == CURLOPT_IOCTLDATA || \
|
||||
(option) == CURLOPT_OPENSOCKETDATA || \
|
||||
(option) == CURLOPT_PREREQDATA || \
|
||||
(option) == CURLOPT_PROGRESSDATA || \
|
||||
(option) == CURLOPT_READDATA || \
|
||||
(option) == CURLOPT_SEEKDATA || \
|
||||
(option) == CURLOPT_SOCKOPTDATA || \
|
||||
(option) == CURLOPT_SSH_KEYDATA || \
|
||||
(option) == CURLOPT_SSL_CTX_DATA || \
|
||||
(option) == CURLOPT_WRITEDATA || \
|
||||
(option) == CURLOPT_RESOLVER_START_DATA || \
|
||||
(option) == CURLOPT_TRAILERDATA || \
|
||||
0)
|
||||
|
||||
/* evaluates to true if option takes a POST data argument (void* or char*) */
|
||||
#define curlcheck_postfields_option(option) \
|
||||
((option) == CURLOPT_POSTFIELDS || \
|
||||
(option) == CURLOPT_COPYPOSTFIELDS || \
|
||||
0)
|
||||
|
||||
/* evaluates to true if option takes a struct curl_slist * argument */
|
||||
#define curlcheck_slist_option(option) \
|
||||
((option) == CURLOPT_HTTP200ALIASES || \
|
||||
(option) == CURLOPT_HTTPHEADER || \
|
||||
(option) == CURLOPT_MAIL_RCPT || \
|
||||
(option) == CURLOPT_POSTQUOTE || \
|
||||
(option) == CURLOPT_PREQUOTE || \
|
||||
(option) == CURLOPT_PROXYHEADER || \
|
||||
(option) == CURLOPT_QUOTE || \
|
||||
(option) == CURLOPT_RESOLVE || \
|
||||
(option) == CURLOPT_TELNETOPTIONS || \
|
||||
(option) == CURLOPT_CONNECT_TO || \
|
||||
0)
|
||||
|
||||
/* groups of curl_easy_getinfo infos that take the same type of argument */
|
||||
|
||||
/* evaluates to true if info expects a pointer to char * argument */
|
||||
#define curlcheck_string_info(info) \
|
||||
(CURLINFO_STRING < (info) && (info) < CURLINFO_LONG && \
|
||||
(info) != CURLINFO_PRIVATE)
|
||||
|
||||
/* evaluates to true if info expects a pointer to long argument */
|
||||
#define curlcheck_long_info(info) \
|
||||
(CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
|
||||
|
||||
/* evaluates to true if info expects a pointer to double argument */
|
||||
#define curlcheck_double_info(info) \
|
||||
(CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
|
||||
|
||||
/* true if info expects a pointer to struct curl_slist * argument */
|
||||
#define curlcheck_slist_info(info) \
|
||||
(((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
|
||||
|
||||
/* true if info expects a pointer to struct curl_tlssessioninfo * argument */
|
||||
#define curlcheck_tlssessioninfo_info(info) \
|
||||
(((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
|
||||
|
||||
/* true if info expects a pointer to struct curl_certinfo * argument */
|
||||
#define curlcheck_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
|
||||
|
||||
/* true if info expects a pointer to struct curl_socket_t argument */
|
||||
#define curlcheck_socket_info(info) \
|
||||
(CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
|
||||
|
||||
/* true if info expects a pointer to curl_off_t argument */
|
||||
#define curlcheck_off_t_info(info) \
|
||||
(CURLINFO_OFF_T < (info))
|
||||
|
||||
|
||||
/* typecheck helpers -- check whether given expression has requested type*/
|
||||
|
||||
/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros,
|
||||
* otherwise define a new macro. Search for __builtin_types_compatible_p
|
||||
* in the GCC manual.
|
||||
* NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
|
||||
* the actual expression passed to the curl_easy_setopt macro. This
|
||||
* means that you can only apply the sizeof and __typeof__ operators, no
|
||||
* == or whatsoever.
|
||||
*/
|
||||
|
||||
/* XXX: should evaluate to true if expr is a pointer */
|
||||
#define curlcheck_any_ptr(expr) \
|
||||
(sizeof(expr) == sizeof(void *))
|
||||
|
||||
/* evaluates to true if expr is NULL */
|
||||
/* XXX: must not evaluate expr, so this check is not accurate */
|
||||
#define curlcheck_NULL(expr) \
|
||||
(__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
|
||||
|
||||
/* evaluates to true if expr is type*, const type* or NULL */
|
||||
#define curlcheck_ptr(expr, type) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), type *) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), const type *))
|
||||
|
||||
/* evaluates to true if expr is one of type[], type*, NULL or const type* */
|
||||
#define curlcheck_arr(expr, type) \
|
||||
(curlcheck_ptr((expr), type) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), type []))
|
||||
|
||||
/* evaluates to true if expr is a string */
|
||||
#define curlcheck_string(expr) \
|
||||
(curlcheck_arr((expr), char) || \
|
||||
curlcheck_arr((expr), signed char) || \
|
||||
curlcheck_arr((expr), unsigned char))
|
||||
|
||||
/* evaluates to true if expr is a long (no matter the signedness)
|
||||
* XXX: for now, int is also accepted (and therefore short and char, which
|
||||
* are promoted to int when passed to a variadic function) */
|
||||
#define curlcheck_long(expr) \
|
||||
(__builtin_types_compatible_p(__typeof__(expr), long) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), signed long) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), int) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), signed int) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), short) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), signed short) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), char) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), signed char) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), unsigned char))
|
||||
|
||||
/* evaluates to true if expr is of type curl_off_t */
|
||||
#define curlcheck_off_t(expr) \
|
||||
(__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
|
||||
|
||||
/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
|
||||
/* XXX: also check size of an char[] array? */
|
||||
#define curlcheck_error_buffer(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), char *) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), char[]))
|
||||
|
||||
/* evaluates to true if expr is of type (const) void* or (const) FILE* */
|
||||
#if 0
|
||||
#define curlcheck_cb_data(expr) \
|
||||
(curlcheck_ptr((expr), void) || \
|
||||
curlcheck_ptr((expr), FILE))
|
||||
#else /* be less strict */
|
||||
#define curlcheck_cb_data(expr) \
|
||||
curlcheck_any_ptr(expr)
|
||||
#endif
|
||||
|
||||
/* evaluates to true if expr is of type FILE* */
|
||||
#define curlcheck_FILE(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
(__builtin_types_compatible_p(__typeof__(expr), FILE *)))
|
||||
|
||||
/* evaluates to true if expr can be passed as POST data (void* or char*) */
|
||||
#define curlcheck_postfields(expr) \
|
||||
(curlcheck_ptr((expr), void) || \
|
||||
curlcheck_arr((expr), char) || \
|
||||
curlcheck_arr((expr), unsigned char))
|
||||
|
||||
/* helper: __builtin_types_compatible_p distinguishes between functions and
|
||||
* function pointers, hide it */
|
||||
#define curlcheck_cb_compatible(func, type) \
|
||||
(__builtin_types_compatible_p(__typeof__(func), type) || \
|
||||
__builtin_types_compatible_p(__typeof__(func) *, type))
|
||||
|
||||
/* evaluates to true if expr is of type curl_resolver_start_callback */
|
||||
#define curlcheck_resolver_start_callback(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_resolver_start_callback))
|
||||
|
||||
/* evaluates to true if expr is of type curl_read_callback or "similar" */
|
||||
#define curlcheck_read_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), __typeof__(fread) *) || \
|
||||
curlcheck_cb_compatible((expr), curl_read_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback4) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback5) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback6))
|
||||
typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
|
||||
typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
|
||||
typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
|
||||
typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *);
|
||||
typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
|
||||
typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_write_callback or "similar" */
|
||||
#define curlcheck_write_cb(expr) \
|
||||
(curlcheck_read_cb(expr) || \
|
||||
curlcheck_cb_compatible((expr), __typeof__(fwrite) *) || \
|
||||
curlcheck_cb_compatible((expr), curl_write_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback4) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback5) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback6))
|
||||
typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
|
||||
typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
|
||||
const void *);
|
||||
typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *);
|
||||
typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *);
|
||||
typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
|
||||
const void *);
|
||||
typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
|
||||
#define curlcheck_ioctl_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_ioctl_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback4))
|
||||
typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
|
||||
typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
|
||||
typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
|
||||
typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
|
||||
#define curlcheck_sockopt_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_sockopt_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_sockopt_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_sockopt_callback2))
|
||||
typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
|
||||
typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
|
||||
curlsocktype);
|
||||
|
||||
/* evaluates to true if expr is of type curl_opensocket_callback or
|
||||
"similar" */
|
||||
#define curlcheck_opensocket_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_opensocket_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback4))
|
||||
typedef curl_socket_t (*_curl_opensocket_callback1)
|
||||
(void *, curlsocktype, struct curl_sockaddr *);
|
||||
typedef curl_socket_t (*_curl_opensocket_callback2)
|
||||
(void *, curlsocktype, const struct curl_sockaddr *);
|
||||
typedef curl_socket_t (*_curl_opensocket_callback3)
|
||||
(const void *, curlsocktype, struct curl_sockaddr *);
|
||||
typedef curl_socket_t (*_curl_opensocket_callback4)
|
||||
(const void *, curlsocktype, const struct curl_sockaddr *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_progress_callback or "similar" */
|
||||
#define curlcheck_progress_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_progress_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_progress_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_progress_callback2))
|
||||
typedef int (*_curl_progress_callback1)(void *,
|
||||
double, double, double, double);
|
||||
typedef int (*_curl_progress_callback2)(const void *,
|
||||
double, double, double, double);
|
||||
|
||||
/* evaluates to true if expr is of type curl_debug_callback or "similar" */
|
||||
#define curlcheck_debug_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_debug_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback4) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback5) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback6) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback7) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback8))
|
||||
typedef int (*_curl_debug_callback1) (CURL *,
|
||||
curl_infotype, char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback2) (CURL *,
|
||||
curl_infotype, char *, size_t, const void *);
|
||||
typedef int (*_curl_debug_callback3) (CURL *,
|
||||
curl_infotype, const char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback4) (CURL *,
|
||||
curl_infotype, const char *, size_t, const void *);
|
||||
typedef int (*_curl_debug_callback5) (CURL *,
|
||||
curl_infotype, unsigned char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback6) (CURL *,
|
||||
curl_infotype, unsigned char *, size_t, const void *);
|
||||
typedef int (*_curl_debug_callback7) (CURL *,
|
||||
curl_infotype, const unsigned char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback8) (CURL *,
|
||||
curl_infotype, const unsigned char *, size_t, const void *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
|
||||
/* this is getting even messier... */
|
||||
#define curlcheck_ssl_ctx_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback8))
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *,
|
||||
const void *);
|
||||
#ifdef HEADER_SSL_H
|
||||
/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
|
||||
* this will of course break if we're included before OpenSSL headers...
|
||||
*/
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX *, void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX *, const void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX *, void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX *,
|
||||
const void *);
|
||||
#else
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
|
||||
#endif
|
||||
|
||||
/* evaluates to true if expr is of type curl_conv_callback or "similar" */
|
||||
#define curlcheck_conv_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_conv_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_conv_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_conv_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_conv_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_conv_callback4))
|
||||
typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
|
||||
typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
|
||||
typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
|
||||
typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
|
||||
|
||||
/* evaluates to true if expr is of type curl_seek_callback or "similar" */
|
||||
#define curlcheck_seek_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_seek_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_seek_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_seek_callback2))
|
||||
typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
|
||||
typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
|
||||
|
||||
|
||||
#endif /* CURLINC_TYPECHECK_GCC_H */
|
||||
133
demo/kugou/include/Common/include/curl/urlapi.h
Normal file
@@ -0,0 +1,133 @@
|
||||
#ifndef CURLINC_URLAPI_H
|
||||
#define CURLINC_URLAPI_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* the error codes for the URL API */
|
||||
typedef enum {
|
||||
CURLUE_OK,
|
||||
CURLUE_BAD_HANDLE, /* 1 */
|
||||
CURLUE_BAD_PARTPOINTER, /* 2 */
|
||||
CURLUE_MALFORMED_INPUT, /* 3 */
|
||||
CURLUE_BAD_PORT_NUMBER, /* 4 */
|
||||
CURLUE_UNSUPPORTED_SCHEME, /* 5 */
|
||||
CURLUE_URLDECODE, /* 6 */
|
||||
CURLUE_OUT_OF_MEMORY, /* 7 */
|
||||
CURLUE_USER_NOT_ALLOWED, /* 8 */
|
||||
CURLUE_UNKNOWN_PART, /* 9 */
|
||||
CURLUE_NO_SCHEME, /* 10 */
|
||||
CURLUE_NO_USER, /* 11 */
|
||||
CURLUE_NO_PASSWORD, /* 12 */
|
||||
CURLUE_NO_OPTIONS, /* 13 */
|
||||
CURLUE_NO_HOST, /* 14 */
|
||||
CURLUE_NO_PORT, /* 15 */
|
||||
CURLUE_NO_QUERY, /* 16 */
|
||||
CURLUE_NO_FRAGMENT, /* 17 */
|
||||
CURLUE_LAST
|
||||
} CURLUcode;
|
||||
|
||||
typedef enum {
|
||||
CURLUPART_URL,
|
||||
CURLUPART_SCHEME,
|
||||
CURLUPART_USER,
|
||||
CURLUPART_PASSWORD,
|
||||
CURLUPART_OPTIONS,
|
||||
CURLUPART_HOST,
|
||||
CURLUPART_PORT,
|
||||
CURLUPART_PATH,
|
||||
CURLUPART_QUERY,
|
||||
CURLUPART_FRAGMENT,
|
||||
CURLUPART_ZONEID /* added in 7.65.0 */
|
||||
} CURLUPart;
|
||||
|
||||
#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
|
||||
#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set,
|
||||
if the port number matches the
|
||||
default for the scheme */
|
||||
#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if
|
||||
missing */
|
||||
#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */
|
||||
#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */
|
||||
#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */
|
||||
#define CURLU_URLDECODE (1<<6) /* URL decode on get */
|
||||
#define CURLU_URLENCODE (1<<7) /* URL encode on set */
|
||||
#define CURLU_APPENDQUERY (1<<8) /* append a form style part */
|
||||
#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
|
||||
#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
|
||||
scheme is unknown. */
|
||||
#define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */
|
||||
|
||||
typedef struct Curl_URL CURLU;
|
||||
|
||||
/*
|
||||
* curl_url() creates a new CURLU handle and returns a pointer to it.
|
||||
* Must be freed with curl_url_cleanup().
|
||||
*/
|
||||
CURL_EXTERN CURLU *curl_url(void);
|
||||
|
||||
/*
|
||||
* curl_url_cleanup() frees the CURLU handle and related resources used for
|
||||
* the URL parsing. It will not free strings previously returned with the URL
|
||||
* API.
|
||||
*/
|
||||
CURL_EXTERN void curl_url_cleanup(CURLU *handle);
|
||||
|
||||
/*
|
||||
* curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
|
||||
* handle must also be freed with curl_url_cleanup().
|
||||
*/
|
||||
CURL_EXTERN CURLU *curl_url_dup(CURLU *in);
|
||||
|
||||
/*
|
||||
* curl_url_get() extracts a specific part of the URL from a CURLU
|
||||
* handle. Returns error code. The returned pointer MUST be freed with
|
||||
* curl_free() afterwards.
|
||||
*/
|
||||
CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what,
|
||||
char **part, unsigned int flags);
|
||||
|
||||
/*
|
||||
* curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
|
||||
* error code. The passed in string will be copied. Passing a NULL instead of
|
||||
* a part string, clears that part.
|
||||
*/
|
||||
CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
|
||||
const char *part, unsigned int flags);
|
||||
|
||||
/*
|
||||
* curl_url_strerror() turns a CURLUcode value into the equivalent human
|
||||
* readable error string. This is useful for printing meaningful error
|
||||
* messages.
|
||||
*/
|
||||
CURL_EXTERN const char *curl_url_strerror(CURLUcode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* CURLINC_URLAPI_H */
|
||||
113
demo/kugou/include/Common/include/gzip/compress.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#include <gzip/config.hpp>
|
||||
|
||||
// zlib
|
||||
#include "zlib.h"
|
||||
|
||||
// std
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace gzip {
|
||||
|
||||
class Compressor
|
||||
{
|
||||
std::size_t max_;
|
||||
int level_;
|
||||
|
||||
public:
|
||||
Compressor(int level = Z_DEFAULT_COMPRESSION,
|
||||
std::size_t max_bytes = 2000000000) // by default refuse operation if uncompressed data is > 2GB
|
||||
: max_(max_bytes),
|
||||
level_(level)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename InputType>
|
||||
void compress(InputType& output,
|
||||
const char* data,
|
||||
std::size_t size) const
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
// Verify if size input will fit into unsigned int, type used for zlib's avail_in
|
||||
if (size > std::numeric_limits<unsigned int>::max())
|
||||
{
|
||||
throw std::runtime_error("size arg is too large to fit into unsigned int type");
|
||||
}
|
||||
#endif
|
||||
if (size > max_)
|
||||
{
|
||||
throw std::runtime_error("size may use more memory than intended when decompressing");
|
||||
}
|
||||
|
||||
z_stream deflate_s;
|
||||
deflate_s.zalloc = Z_NULL;
|
||||
deflate_s.zfree = Z_NULL;
|
||||
deflate_s.opaque = Z_NULL;
|
||||
deflate_s.avail_in = 0;
|
||||
deflate_s.next_in = Z_NULL;
|
||||
|
||||
// The windowBits parameter is the base two logarithm of the window size (the size of the history buffer).
|
||||
// It should be in the range 8..15 for this version of the library.
|
||||
// Larger values of this parameter result in better compression at the expense of memory usage.
|
||||
// This range of values also changes the decoding type:
|
||||
// -8 to -15 for raw deflate
|
||||
// 8 to 15 for zlib
|
||||
// (8 to 15) + 16 for gzip
|
||||
// (8 to 15) + 32 to automatically detect gzip/zlib header (decompression/inflate only)
|
||||
constexpr int window_bits = 15 + 16; // gzip with windowbits of 15
|
||||
|
||||
constexpr int mem_level = 8;
|
||||
// The memory requirements for deflate are (in bytes):
|
||||
// (1 << (window_bits+2)) + (1 << (mem_level+9))
|
||||
// with a default value of 8 for mem_level and our window_bits of 15
|
||||
// this is 128Kb
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
if (deflateInit2(&deflate_s, level_, Z_DEFLATED, window_bits, mem_level, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
{
|
||||
throw std::runtime_error("deflate init failed");
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
deflate_s.next_in = reinterpret_cast<z_const Bytef*>(data);
|
||||
deflate_s.avail_in = static_cast<unsigned int>(size);
|
||||
|
||||
std::size_t size_compressed = 0;
|
||||
do
|
||||
{
|
||||
size_t increase = size / 2 + 1024;
|
||||
if (output.size() < (size_compressed + increase))
|
||||
{
|
||||
output.resize(size_compressed + increase);
|
||||
}
|
||||
// There is no way we see that "increase" would not fit in an unsigned int,
|
||||
// hence we use static cast here to avoid -Wshorten-64-to-32 error
|
||||
deflate_s.avail_out = static_cast<unsigned int>(increase);
|
||||
deflate_s.next_out = reinterpret_cast<Bytef*>((&output[0] + size_compressed));
|
||||
// From http://www.zlib.net/zlib_how.html
|
||||
// "deflate() has a return value that can indicate errors, yet we do not check it here.
|
||||
// Why not? Well, it turns out that deflate() can do no wrong here."
|
||||
// Basically only possible error is from deflateInit not working properly
|
||||
deflate(&deflate_s, Z_FINISH);
|
||||
size_compressed += (increase - deflate_s.avail_out);
|
||||
} while (deflate_s.avail_out == 0);
|
||||
|
||||
deflateEnd(&deflate_s);
|
||||
output.resize(size_compressed);
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string compress(const char* data,
|
||||
std::size_t size,
|
||||
int level = Z_DEFAULT_COMPRESSION)
|
||||
{
|
||||
Compressor comp(level);
|
||||
std::string output;
|
||||
comp.compress(output, data, size);
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace gzip
|
||||
5
demo/kugou/include/Common/include/gzip/config.hpp
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ZLIB_CONST
|
||||
#define ZLIB_CONST
|
||||
#endif
|
||||
105
demo/kugou/include/Common/include/gzip/decompress.hpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#include <gzip/config.hpp>
|
||||
|
||||
// zlib
|
||||
#include "zlib.h"
|
||||
|
||||
// std
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace gzip {
|
||||
|
||||
class Decompressor
|
||||
{
|
||||
std::size_t max_;
|
||||
|
||||
public:
|
||||
Decompressor(std::size_t max_bytes = 1000000000) // by default refuse operation if compressed data is > 1GB
|
||||
: max_(max_bytes)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename OutputType>
|
||||
void decompress(OutputType& output,
|
||||
const char* data,
|
||||
std::size_t size) const
|
||||
{
|
||||
z_stream inflate_s;
|
||||
|
||||
inflate_s.zalloc = Z_NULL;
|
||||
inflate_s.zfree = Z_NULL;
|
||||
inflate_s.opaque = Z_NULL;
|
||||
inflate_s.avail_in = 0;
|
||||
inflate_s.next_in = Z_NULL;
|
||||
|
||||
// The windowBits parameter is the base two logarithm of the window size (the size of the history buffer).
|
||||
// It should be in the range 8..15 for this version of the library.
|
||||
// Larger values of this parameter result in better compression at the expense of memory usage.
|
||||
// This range of values also changes the decoding type:
|
||||
// -8 to -15 for raw deflate
|
||||
// 8 to 15 for zlib
|
||||
// (8 to 15) + 16 for gzip
|
||||
// (8 to 15) + 32 to automatically detect gzip/zlib header
|
||||
constexpr int window_bits = 15 + 32; // auto with windowbits of 15
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
if (inflateInit2(&inflate_s, window_bits) != Z_OK)
|
||||
{
|
||||
throw std::runtime_error("inflate init failed");
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
inflate_s.next_in = reinterpret_cast<z_const Bytef*>(data);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Verify if size (long type) input will fit into unsigned int, type used for zlib's avail_in
|
||||
std::uint64_t size_64 = size * 2;
|
||||
if (size_64 > std::numeric_limits<unsigned int>::max())
|
||||
{
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error("size arg is too large to fit into unsigned int type x2");
|
||||
}
|
||||
#endif
|
||||
if (size > max_ || (size * 2) > max_)
|
||||
{
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error("size may use more memory than intended when decompressing");
|
||||
}
|
||||
inflate_s.avail_in = static_cast<unsigned int>(size);
|
||||
std::size_t size_uncompressed = 0;
|
||||
do
|
||||
{
|
||||
std::size_t resize_to = size_uncompressed + 2 * size;
|
||||
if (resize_to > max_)
|
||||
{
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error("size of output string will use more memory then intended when decompressing");
|
||||
}
|
||||
output.resize(resize_to);
|
||||
inflate_s.avail_out = static_cast<unsigned int>(2 * size);
|
||||
inflate_s.next_out = reinterpret_cast<Bytef*>(&output[0] + size_uncompressed);
|
||||
int ret = inflate(&inflate_s, Z_FINISH);
|
||||
if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR)
|
||||
{
|
||||
std::string error_msg = inflate_s.msg;
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error(error_msg);
|
||||
}
|
||||
|
||||
size_uncompressed += (2 * size - inflate_s.avail_out);
|
||||
} while (inflate_s.avail_out == 0);
|
||||
inflateEnd(&inflate_s);
|
||||
output.resize(size_uncompressed);
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string decompress(const char* data, std::size_t size)
|
||||
{
|
||||
Decompressor decomp;
|
||||
std::string output;
|
||||
decomp.decompress(output, data, size);
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace gzip
|
||||
22
demo/kugou/include/Common/include/gzip/utils.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <cstdlib>
|
||||
|
||||
namespace gzip {
|
||||
|
||||
// These live in gzip.hpp because it doesnt need to use deps.
|
||||
// Otherwise, they would need to live in impl files if these methods used
|
||||
// zlib structures or functions like inflate/deflate)
|
||||
inline bool is_compressed(const char* data, std::size_t size)
|
||||
{
|
||||
return size > 2 &&
|
||||
(
|
||||
// zlib
|
||||
(
|
||||
static_cast<uint8_t>(data[0]) == 0x78 &&
|
||||
(static_cast<uint8_t>(data[1]) == 0x9C ||
|
||||
static_cast<uint8_t>(data[1]) == 0x01 ||
|
||||
static_cast<uint8_t>(data[1]) == 0xDA ||
|
||||
static_cast<uint8_t>(data[1]) == 0x5E)) ||
|
||||
// gzip
|
||||
(static_cast<uint8_t>(data[0]) == 0x1F && static_cast<uint8_t>(data[1]) == 0x8B));
|
||||
}
|
||||
} // namespace gzip
|
||||
16
demo/kugou/include/Common/include/gzip/version.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
/// The major version number
|
||||
#define GZIP_VERSION_MAJOR 1
|
||||
|
||||
/// The minor version number
|
||||
#define GZIP_VERSION_MINOR 0
|
||||
|
||||
/// The patch number
|
||||
#define GZIP_VERSION_PATCH 0
|
||||
|
||||
/// The complete version number
|
||||
#define GZIP_VERSION_CODE (GZIP_VERSION_MAJOR * 10000 + GZIP_VERSION_MINOR * 100 + GZIP_VERSION_PATCH)
|
||||
|
||||
/// Version number as string
|
||||
#define GZIP_VERSION_STRING "1.0.0"
|
||||
10523
demo/kugou/include/Common/include/httplib.h
Normal file
89
demo/kugou/include/Common/include/json/allocator.h
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||
// Distributed under MIT license, or public domain if desired and
|
||||
// recognized in your jurisdiction.
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#ifndef JSON_ALLOCATOR_H_INCLUDED
|
||||
#define JSON_ALLOCATOR_H_INCLUDED
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack()
|
||||
|
||||
namespace Json {
|
||||
template <typename T> class SecureAllocator {
|
||||
public:
|
||||
// Type definitions
|
||||
using value_type = T;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
/**
|
||||
* Allocate memory for N items using the standard allocator.
|
||||
*/
|
||||
pointer allocate(size_type n) {
|
||||
// allocate using "global operator new"
|
||||
return static_cast<pointer>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Release memory which was allocated for N items at pointer P.
|
||||
*
|
||||
* The memory block is filled with zeroes before being released.
|
||||
*/
|
||||
void deallocate(pointer p, size_type n) {
|
||||
// memset_s is used because memset may be optimized away by the compiler
|
||||
memset_s(p, n * sizeof(T), 0, n * sizeof(T));
|
||||
// free using "global operator delete"
|
||||
::operator delete(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an item in-place at pointer P.
|
||||
*/
|
||||
template <typename... Args> void construct(pointer p, Args&&... args) {
|
||||
// construct using "placement new" and "perfect forwarding"
|
||||
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
size_type max_size() const { return size_t(-1) / sizeof(T); }
|
||||
|
||||
pointer address(reference x) const { return std::addressof(x); }
|
||||
|
||||
const_pointer address(const_reference x) const { return std::addressof(x); }
|
||||
|
||||
/**
|
||||
* Destroy an item in-place at pointer P.
|
||||
*/
|
||||
void destroy(pointer p) {
|
||||
// destroy using "explicit destructor"
|
||||
p->~T();
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
SecureAllocator() {}
|
||||
template <typename U> SecureAllocator(const SecureAllocator<U>&) {}
|
||||
template <typename U> struct rebind { using other = SecureAllocator<U>; };
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Json
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // JSON_ALLOCATOR_H_INCLUDED
|
||||
61
demo/kugou/include/Common/include/json/assertions.h
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||
// Distributed under MIT license, or public domain if desired and
|
||||
// recognized in your jurisdiction.
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#ifndef JSON_ASSERTIONS_H_INCLUDED
|
||||
#define JSON_ASSERTIONS_H_INCLUDED
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "config.h"
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
|
||||
/** It should not be possible for a maliciously designed file to
|
||||
* cause an abort() or seg-fault, so these macros are used only
|
||||
* for pre-condition violations and internal logic errors.
|
||||
*/
|
||||
#if JSON_USE_EXCEPTION
|
||||
|
||||
// @todo <= add detail about condition in exception
|
||||
#define JSON_ASSERT(condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
Json::throwLogicError("assert json failed"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define JSON_FAIL_MESSAGE(message) \
|
||||
do { \
|
||||
OStringStream oss; \
|
||||
oss << message; \
|
||||
Json::throwLogicError(oss.str()); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
#else // JSON_USE_EXCEPTION
|
||||
|
||||
#define JSON_ASSERT(condition) assert(condition)
|
||||
|
||||
// The call to assert() will show the failure message in debug builds. In
|
||||
// release builds we abort, for a core-dump or debugger.
|
||||
#define JSON_FAIL_MESSAGE(message) \
|
||||
{ \
|
||||
OStringStream oss; \
|
||||
oss << message; \
|
||||
assert(false && oss.str().c_str()); \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define JSON_ASSERT_MESSAGE(condition, message) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
JSON_FAIL_MESSAGE(message); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif // JSON_ASSERTIONS_H_INCLUDED
|
||||
150
demo/kugou/include/Common/include/json/config.h
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||
// Distributed under MIT license, or public domain if desired and
|
||||
// recognized in your jurisdiction.
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#ifndef JSON_CONFIG_H_INCLUDED
|
||||
#define JSON_CONFIG_H_INCLUDED
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
// If non-zero, the library uses exceptions to report bad input instead of C
|
||||
// assertion macros. The default is to use exceptions.
|
||||
#ifndef JSON_USE_EXCEPTION
|
||||
#define JSON_USE_EXCEPTION 1
|
||||
#endif
|
||||
|
||||
// Temporary, tracked for removal with issue #982.
|
||||
#ifndef JSON_USE_NULLREF
|
||||
#define JSON_USE_NULLREF 1
|
||||
#endif
|
||||
|
||||
/// If defined, indicates that the source file is amalgamated
|
||||
/// to prevent private header inclusion.
|
||||
/// Remarks: it is automatically defined in the generated amalgamated header.
|
||||
// #define JSON_IS_AMALGAMATION
|
||||
|
||||
// Export macros for DLL visibility
|
||||
#if defined(JSON_DLL_BUILD)
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#define JSON_API __declspec(dllexport)
|
||||
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#define JSON_API __attribute__((visibility("default")))
|
||||
#endif // if defined(_MSC_VER)
|
||||
|
||||
#elif defined(JSON_DLL)
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#define JSON_API __declspec(dllimport)
|
||||
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
|
||||
#endif // if defined(_MSC_VER)
|
||||
#endif // ifdef JSON_DLL_BUILD
|
||||
|
||||
#if !defined(JSON_API)
|
||||
#define JSON_API
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
#error \
|
||||
"ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
// As recommended at
|
||||
// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
|
||||
extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size,
|
||||
const char* format, ...);
|
||||
#define jsoncpp_snprintf msvc_pre1900_c99_snprintf
|
||||
#else
|
||||
#define jsoncpp_snprintf std::snprintf
|
||||
#endif
|
||||
|
||||
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
|
||||
// integer
|
||||
// Storages, and 64 bits integer support is disabled.
|
||||
// #define JSON_NO_INT64 1
|
||||
|
||||
// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools.
|
||||
// C++11 should be used directly in JSONCPP.
|
||||
#define JSONCPP_OVERRIDE override
|
||||
|
||||
#ifdef __clang__
|
||||
#if __has_extension(attribute_deprecated_with_message)
|
||||
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
#endif
|
||||
#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc)
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
|
||||
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
|
||||
#endif // GNUC version
|
||||
#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates
|
||||
// MSVC)
|
||||
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
|
||||
#endif // __clang__ || __GNUC__ || _MSC_VER
|
||||
|
||||
#if !defined(JSONCPP_DEPRECATED)
|
||||
#define JSONCPP_DEPRECATED(message)
|
||||
#endif // if !defined(JSONCPP_DEPRECATED)
|
||||
|
||||
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6))
|
||||
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
|
||||
#endif
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
|
||||
#include "allocator.h"
|
||||
#include "version.h"
|
||||
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
|
||||
namespace Json {
|
||||
using Int = int;
|
||||
using UInt = unsigned int;
|
||||
#if defined(JSON_NO_INT64)
|
||||
using LargestInt = int;
|
||||
using LargestUInt = unsigned int;
|
||||
#undef JSON_HAS_INT64
|
||||
#else // if defined(JSON_NO_INT64)
|
||||
// For Microsoft Visual use specific types as long long is not supported
|
||||
#if defined(_MSC_VER) // Microsoft Visual Studio
|
||||
using Int64 = __int64;
|
||||
using UInt64 = unsigned __int64;
|
||||
#else // if defined(_MSC_VER) // Other platforms, use long long
|
||||
using Int64 = int64_t;
|
||||
using UInt64 = uint64_t;
|
||||
#endif // if defined(_MSC_VER)
|
||||
using LargestInt = Int64;
|
||||
using LargestUInt = UInt64;
|
||||
#define JSON_HAS_INT64
|
||||
#endif // if defined(JSON_NO_INT64)
|
||||
|
||||
template <typename T>
|
||||
using Allocator =
|
||||
typename std::conditional<JSONCPP_USING_SECURE_MEMORY, SecureAllocator<T>,
|
||||
std::allocator<T>>::type;
|
||||
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
|
||||
using IStringStream =
|
||||
std::basic_istringstream<String::value_type, String::traits_type,
|
||||
String::allocator_type>;
|
||||
using OStringStream =
|
||||
std::basic_ostringstream<String::value_type, String::traits_type,
|
||||
String::allocator_type>;
|
||||
using IStream = std::istream;
|
||||
using OStream = std::ostream;
|
||||
} // namespace Json
|
||||
|
||||
// Legacy names (formerly macros).
|
||||
using JSONCPP_STRING = Json::String;
|
||||
using JSONCPP_ISTRINGSTREAM = Json::IStringStream;
|
||||
using JSONCPP_OSTRINGSTREAM = Json::OStringStream;
|
||||
using JSONCPP_ISTREAM = Json::IStream;
|
||||
using JSONCPP_OSTREAM = Json::OStream;
|
||||
|
||||
#endif // JSON_CONFIG_H_INCLUDED
|
||||
43
demo/kugou/include/Common/include/json/forwards.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||
// Distributed under MIT license, or public domain if desired and
|
||||
// recognized in your jurisdiction.
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#ifndef JSON_FORWARDS_H_INCLUDED
|
||||
#define JSON_FORWARDS_H_INCLUDED
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "config.h"
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
|
||||
namespace Json {
|
||||
|
||||
// writer.h
|
||||
class StreamWriter;
|
||||
class StreamWriterBuilder;
|
||||
class Writer;
|
||||
class FastWriter;
|
||||
class StyledWriter;
|
||||
class StyledStreamWriter;
|
||||
|
||||
// reader.h
|
||||
class Reader;
|
||||
class CharReader;
|
||||
class CharReaderBuilder;
|
||||
|
||||
// json_features.h
|
||||
class Features;
|
||||
|
||||
// value.h
|
||||
using ArrayIndex = unsigned int;
|
||||
class StaticString;
|
||||
class Path;
|
||||
class PathArgument;
|
||||
class Value;
|
||||
class ValueIteratorBase;
|
||||
class ValueIterator;
|
||||
class ValueConstIterator;
|
||||
|
||||
} // namespace Json
|
||||
|
||||
#endif // JSON_FORWARDS_H_INCLUDED
|
||||
15
demo/kugou/include/Common/include/json/json.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||
// Distributed under MIT license, or public domain if desired and
|
||||
// recognized in your jurisdiction.
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#ifndef JSON_JSON_H_INCLUDED
|
||||
#define JSON_JSON_H_INCLUDED
|
||||
|
||||
#include "config.h"
|
||||
#include "json_features.h"
|
||||
#include "reader.h"
|
||||
#include "value.h"
|
||||
#include "writer.h"
|
||||
|
||||
#endif // JSON_JSON_H_INCLUDED
|
||||
62
demo/kugou/include/Common/include/json/json_features.h
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||
// Distributed under MIT license, or public domain if desired and
|
||||
// recognized in your jurisdiction.
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#ifndef JSON_FEATURES_H_INCLUDED
|
||||
#define JSON_FEATURES_H_INCLUDED
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "forwards.h"
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack()
|
||||
|
||||
namespace Json {
|
||||
|
||||
/** \brief Configuration passed to reader and writer.
|
||||
* This configuration object can be used to force the Reader or Writer
|
||||
* to behave in a standard conforming way.
|
||||
*/
|
||||
class JSON_API Features {
|
||||
public:
|
||||
/** \brief A configuration that allows all features and assumes all strings
|
||||
* are UTF-8.
|
||||
* - C & C++ comments are allowed
|
||||
* - Root object can be any JSON value
|
||||
* - Assumes Value strings are encoded in UTF-8
|
||||
*/
|
||||
static Features all();
|
||||
|
||||
/** \brief A configuration that is strictly compatible with the JSON
|
||||
* specification.
|
||||
* - Comments are forbidden.
|
||||
* - Root object must be either an array or an object value.
|
||||
* - Assumes Value strings are encoded in UTF-8
|
||||
*/
|
||||
static Features strictMode();
|
||||
|
||||
/** \brief Initialize the configuration like JsonConfig::allFeatures;
|
||||
*/
|
||||
Features();
|
||||
|
||||
/// \c true if comments are allowed. Default: \c true.
|
||||
bool allowComments_{true};
|
||||
|
||||
/// \c true if root must be either an array or an object value. Default: \c
|
||||
/// false.
|
||||
bool strictRoot_{false};
|
||||
|
||||
/// \c true if dropped null placeholders are allowed. Default: \c false.
|
||||
bool allowDroppedNullPlaceholders_{false};
|
||||
|
||||
/// \c true if numeric object key are allowed. Default: \c false.
|
||||
bool allowNumericKeys_{false};
|
||||
};
|
||||
|
||||
} // namespace Json
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // JSON_FEATURES_H_INCLUDED
|
||||
406
demo/kugou/include/Common/include/json/reader.h
Normal file
@@ -0,0 +1,406 @@
|
||||
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||
// Distributed under MIT license, or public domain if desired and
|
||||
// recognized in your jurisdiction.
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#ifndef JSON_READER_H_INCLUDED
|
||||
#define JSON_READER_H_INCLUDED
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "json_features.h"
|
||||
#include "value.h"
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
#include <deque>
|
||||
#include <iosfwd>
|
||||
#include <istream>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
|
||||
// be used by...
|
||||
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4251)
|
||||
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack()
|
||||
|
||||
namespace Json {
|
||||
|
||||
/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
|
||||
* Value.
|
||||
*
|
||||
* \deprecated Use CharReader and CharReaderBuilder.
|
||||
*/
|
||||
|
||||
class JSON_API Reader {
|
||||
public:
|
||||
using Char = char;
|
||||
using Location = const Char*;
|
||||
|
||||
/** \brief An error tagged with where in the JSON text it was encountered.
|
||||
*
|
||||
* The offsets give the [start, limit) range of bytes within the text. Note
|
||||
* that this is bytes, not codepoints.
|
||||
*/
|
||||
struct StructuredError {
|
||||
ptrdiff_t offset_start;
|
||||
ptrdiff_t offset_limit;
|
||||
String message;
|
||||
};
|
||||
|
||||
/** \brief Constructs a Reader allowing all features for parsing.
|
||||
* \deprecated Use CharReader and CharReaderBuilder.
|
||||
*/
|
||||
Reader();
|
||||
|
||||
/** \brief Constructs a Reader allowing the specified feature set for parsing.
|
||||
* \deprecated Use CharReader and CharReaderBuilder.
|
||||
*/
|
||||
Reader(const Features& features);
|
||||
|
||||
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
|
||||
* document.
|
||||
*
|
||||
* \param document UTF-8 encoded string containing the document
|
||||
* to read.
|
||||
* \param[out] root Contains the root value of the document if it
|
||||
* was successfully parsed.
|
||||
* \param collectComments \c true to collect comment and allow writing
|
||||
* them back during serialization, \c false to
|
||||
* discard comments. This parameter is ignored
|
||||
* if Features::allowComments_ is \c false.
|
||||
* \return \c true if the document was successfully parsed, \c false if an
|
||||
* error occurred.
|
||||
*/
|
||||
bool parse(const std::string& document, Value& root,
|
||||
bool collectComments = true);
|
||||
|
||||
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
|
||||
* document.
|
||||
*
|
||||
* \param beginDoc Pointer on the beginning of the UTF-8 encoded
|
||||
* string of the document to read.
|
||||
* \param endDoc Pointer on the end of the UTF-8 encoded string
|
||||
* of the document to read. Must be >= beginDoc.
|
||||
* \param[out] root Contains the root value of the document if it
|
||||
* was successfully parsed.
|
||||
* \param collectComments \c true to collect comment and allow writing
|
||||
* them back during serialization, \c false to
|
||||
* discard comments. This parameter is ignored
|
||||
* if Features::allowComments_ is \c false.
|
||||
* \return \c true if the document was successfully parsed, \c false if an
|
||||
* error occurred.
|
||||
*/
|
||||
bool parse(const char* beginDoc, const char* endDoc, Value& root,
|
||||
bool collectComments = true);
|
||||
|
||||
/// \brief Parse from input stream.
|
||||
/// \see Json::operator>>(std::istream&, Json::Value&).
|
||||
bool parse(IStream& is, Value& root, bool collectComments = true);
|
||||
|
||||
/** \brief Returns a user friendly string that list errors in the parsed
|
||||
* document.
|
||||
*
|
||||
* \return Formatted error message with the list of errors with their
|
||||
* location in the parsed document. An empty string is returned if no error
|
||||
* occurred during parsing.
|
||||
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
|
||||
*/
|
||||
JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
|
||||
String getFormatedErrorMessages() const;
|
||||
|
||||
/** \brief Returns a user friendly string that list errors in the parsed
|
||||
* document.
|
||||
*
|
||||
* \return Formatted error message with the list of errors with their
|
||||
* location in the parsed document. An empty string is returned if no error
|
||||
* occurred during parsing.
|
||||
*/
|
||||
String getFormattedErrorMessages() const;
|
||||
|
||||
/** \brief Returns a vector of structured errors encountered while parsing.
|
||||
*
|
||||
* \return A (possibly empty) vector of StructuredError objects. Currently
|
||||
* only one error can be returned, but the caller should tolerate multiple
|
||||
* errors. This can occur if the parser recovers from a non-fatal parse
|
||||
* error and then encounters additional errors.
|
||||
*/
|
||||
std::vector<StructuredError> getStructuredErrors() const;
|
||||
|
||||
/** \brief Add a semantic error message.
|
||||
*
|
||||
* \param value JSON Value location associated with the error
|
||||
* \param message The error message.
|
||||
* \return \c true if the error was successfully added, \c false if the Value
|
||||
* offset exceeds the document size.
|
||||
*/
|
||||
bool pushError(const Value& value, const String& message);
|
||||
|
||||
/** \brief Add a semantic error message with extra context.
|
||||
*
|
||||
* \param value JSON Value location associated with the error
|
||||
* \param message The error message.
|
||||
* \param extra Additional JSON Value location to contextualize the error
|
||||
* \return \c true if the error was successfully added, \c false if either
|
||||
* Value offset exceeds the document size.
|
||||
*/
|
||||
bool pushError(const Value& value, const String& message, const Value& extra);
|
||||
|
||||
/** \brief Return whether there are any errors.
|
||||
*
|
||||
* \return \c true if there are no errors to report \c false if errors have
|
||||
* occurred.
|
||||
*/
|
||||
bool good() const;
|
||||
|
||||
private:
|
||||
enum TokenType {
|
||||
tokenEndOfStream = 0,
|
||||
tokenObjectBegin,
|
||||
tokenObjectEnd,
|
||||
tokenArrayBegin,
|
||||
tokenArrayEnd,
|
||||
tokenString,
|
||||
tokenNumber,
|
||||
tokenTrue,
|
||||
tokenFalse,
|
||||
tokenNull,
|
||||
tokenArraySeparator,
|
||||
tokenMemberSeparator,
|
||||
tokenComment,
|
||||
tokenError
|
||||
};
|
||||
|
||||
class Token {
|
||||
public:
|
||||
TokenType type_;
|
||||
Location start_;
|
||||
Location end_;
|
||||
};
|
||||
|
||||
class ErrorInfo {
|
||||
public:
|
||||
Token token_;
|
||||
String message_;
|
||||
Location extra_;
|
||||
};
|
||||
|
||||
using Errors = std::deque<ErrorInfo>;
|
||||
|
||||
bool readToken(Token& token);
|
||||
void skipSpaces();
|
||||
bool match(const Char* pattern, int patternLength);
|
||||
bool readComment();
|
||||
bool readCStyleComment();
|
||||
bool readCppStyleComment();
|
||||
bool readString();
|
||||
void readNumber();
|
||||
bool readValue();
|
||||
bool readObject(Token& token);
|
||||
bool readArray(Token& token);
|
||||
bool decodeNumber(Token& token);
|
||||
bool decodeNumber(Token& token, Value& decoded);
|
||||
bool decodeString(Token& token);
|
||||
bool decodeString(Token& token, String& decoded);
|
||||
bool decodeDouble(Token& token);
|
||||
bool decodeDouble(Token& token, Value& decoded);
|
||||
bool decodeUnicodeCodePoint(Token& token, Location& current, Location end,
|
||||
unsigned int& unicode);
|
||||
bool decodeUnicodeEscapeSequence(Token& token, Location& current,
|
||||
Location end, unsigned int& unicode);
|
||||
bool addError(const String& message, Token& token, Location extra = nullptr);
|
||||
bool recoverFromError(TokenType skipUntilToken);
|
||||
bool addErrorAndRecover(const String& message, Token& token,
|
||||
TokenType skipUntilToken);
|
||||
void skipUntilSpace();
|
||||
Value& currentValue();
|
||||
Char getNextChar();
|
||||
void getLocationLineAndColumn(Location location, int& line,
|
||||
int& column) const;
|
||||
String getLocationLineAndColumn(Location location) const;
|
||||
void addComment(Location begin, Location end, CommentPlacement placement);
|
||||
void skipCommentTokens(Token& token);
|
||||
|
||||
static bool containsNewLine(Location begin, Location end);
|
||||
static String normalizeEOL(Location begin, Location end);
|
||||
|
||||
using Nodes = std::stack<Value*>;
|
||||
Nodes nodes_;
|
||||
Errors errors_;
|
||||
String document_;
|
||||
Location begin_{};
|
||||
Location end_{};
|
||||
Location current_{};
|
||||
Location lastValueEnd_{};
|
||||
Value* lastValue_{};
|
||||
String commentsBefore_;
|
||||
Features features_;
|
||||
bool collectComments_{};
|
||||
}; // Reader
|
||||
|
||||
/** Interface for reading JSON from a char array.
|
||||
*/
|
||||
class JSON_API CharReader {
|
||||
public:
|
||||
virtual ~CharReader() = default;
|
||||
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
|
||||
* document. The document must be a UTF-8 encoded string containing the
|
||||
* document to read.
|
||||
*
|
||||
* \param beginDoc Pointer on the beginning of the UTF-8 encoded string
|
||||
* of the document to read.
|
||||
* \param endDoc Pointer on the end of the UTF-8 encoded string of the
|
||||
* document to read. Must be >= beginDoc.
|
||||
* \param[out] root Contains the root value of the document if it was
|
||||
* successfully parsed.
|
||||
* \param[out] errs Formatted error messages (if not NULL) a user
|
||||
* friendly string that lists errors in the parsed
|
||||
* document.
|
||||
* \return \c true if the document was successfully parsed, \c false if an
|
||||
* error occurred.
|
||||
*/
|
||||
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
|
||||
String* errs) = 0;
|
||||
|
||||
class JSON_API Factory {
|
||||
public:
|
||||
virtual ~Factory() = default;
|
||||
/** \brief Allocate a CharReader via operator new().
|
||||
* \throw std::exception if something goes wrong (e.g. invalid settings)
|
||||
*/
|
||||
virtual CharReader* newCharReader() const = 0;
|
||||
}; // Factory
|
||||
}; // CharReader
|
||||
|
||||
/** \brief Build a CharReader implementation.
|
||||
*
|
||||
* Usage:
|
||||
* \code
|
||||
* using namespace Json;
|
||||
* CharReaderBuilder builder;
|
||||
* builder["collectComments"] = false;
|
||||
* Value value;
|
||||
* String errs;
|
||||
* bool ok = parseFromStream(builder, std::cin, &value, &errs);
|
||||
* \endcode
|
||||
*/
|
||||
class JSON_API CharReaderBuilder : public CharReader::Factory {
|
||||
public:
|
||||
// Note: We use a Json::Value so that we can add data-members to this class
|
||||
// without a major version bump.
|
||||
/** Configuration of this builder.
|
||||
* These are case-sensitive.
|
||||
* Available settings (case-sensitive):
|
||||
* - `"collectComments": false or true`
|
||||
* - true to collect comment and allow writing them back during
|
||||
* serialization, false to discard comments. This parameter is ignored
|
||||
* if allowComments is false.
|
||||
* - `"allowComments": false or true`
|
||||
* - true if comments are allowed.
|
||||
* - `"allowTrailingCommas": false or true`
|
||||
* - true if trailing commas in objects and arrays are allowed.
|
||||
* - `"strictRoot": false or true`
|
||||
* - true if root must be either an array or an object value
|
||||
* - `"allowDroppedNullPlaceholders": false or true`
|
||||
* - true if dropped null placeholders are allowed. (See
|
||||
* StreamWriterBuilder.)
|
||||
* - `"allowNumericKeys": false or true`
|
||||
* - true if numeric object keys are allowed.
|
||||
* - `"allowSingleQuotes": false or true`
|
||||
* - true if '' are allowed for strings (both keys and values)
|
||||
* - `"stackLimit": integer`
|
||||
* - Exceeding stackLimit (recursive depth of `readValue()`) will cause an
|
||||
* exception.
|
||||
* - This is a security issue (seg-faults caused by deeply nested JSON), so
|
||||
* the default is low.
|
||||
* - `"failIfExtra": false or true`
|
||||
* - If true, `parse()` returns false when extra non-whitespace trails the
|
||||
* JSON value in the input string.
|
||||
* - `"rejectDupKeys": false or true`
|
||||
* - If true, `parse()` returns false when a key is duplicated within an
|
||||
* object.
|
||||
* - `"allowSpecialFloats": false or true`
|
||||
* - If true, special float values (NaNs and infinities) are allowed and
|
||||
* their values are lossfree restorable.
|
||||
* - `"skipBom": false or true`
|
||||
* - If true, if the input starts with the Unicode byte order mark (BOM),
|
||||
* it is skipped.
|
||||
*
|
||||
* You can examine 'settings_` yourself to see the defaults. You can also
|
||||
* write and read them just like any JSON Value.
|
||||
* \sa setDefaults()
|
||||
*/
|
||||
Json::Value settings_;
|
||||
|
||||
CharReaderBuilder();
|
||||
~CharReaderBuilder() override;
|
||||
|
||||
CharReader* newCharReader() const override;
|
||||
|
||||
/** \return true if 'settings' are legal and consistent;
|
||||
* otherwise, indicate bad settings via 'invalid'.
|
||||
*/
|
||||
bool validate(Json::Value* invalid) const;
|
||||
|
||||
/** A simple way to update a specific setting.
|
||||
*/
|
||||
Value& operator[](const String& key);
|
||||
|
||||
/** Called by ctor, but you can use this to reset settings_.
|
||||
* \pre 'settings' != NULL (but Json::null is fine)
|
||||
* \remark Defaults:
|
||||
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
|
||||
*/
|
||||
static void setDefaults(Json::Value* settings);
|
||||
/** Same as old Features::strictMode().
|
||||
* \pre 'settings' != NULL (but Json::null is fine)
|
||||
* \remark Defaults:
|
||||
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
|
||||
*/
|
||||
static void strictMode(Json::Value* settings);
|
||||
};
|
||||
|
||||
/** Consume entire stream and use its begin/end.
|
||||
* Someday we might have a real StreamReader, but for now this
|
||||
* is convenient.
|
||||
*/
|
||||
bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root,
|
||||
String* errs);
|
||||
|
||||
/** \brief Read from 'sin' into 'root'.
|
||||
*
|
||||
* Always keep comments from the input JSON.
|
||||
*
|
||||
* This can be used to read a file into a particular sub-object.
|
||||
* For example:
|
||||
* \code
|
||||
* Json::Value root;
|
||||
* cin >> root["dir"]["file"];
|
||||
* cout << root;
|
||||
* \endcode
|
||||
* Result:
|
||||
* \verbatim
|
||||
* {
|
||||
* "dir": {
|
||||
* "file": {
|
||||
* // The input stream JSON would be nested here.
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* \endverbatim
|
||||
* \throw std::exception on parse error.
|
||||
* \see Json::operator<<()
|
||||
*/
|
||||
JSON_API IStream& operator>>(IStream&, Value&);
|
||||
|
||||
} // namespace Json
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
#pragma warning(pop)
|
||||
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
|
||||
#endif // JSON_READER_H_INCLUDED
|
||||
961
demo/kugou/include/Common/include/json/value.h
Normal file
@@ -0,0 +1,961 @@
|
||||
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||
// Distributed under MIT license, or public domain if desired and
|
||||
// recognized in your jurisdiction.
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#ifndef JSON_H_INCLUDED
|
||||
#define JSON_H_INCLUDED
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "forwards.h"
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
|
||||
// Conditional NORETURN attribute on the throw functions would:
|
||||
// a) suppress false positives from static code analysis
|
||||
// b) possibly improve optimization opportunities.
|
||||
#if !defined(JSONCPP_NORETURN)
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1800
|
||||
#define JSONCPP_NORETURN __declspec(noreturn)
|
||||
#else
|
||||
#define JSONCPP_NORETURN [[noreturn]]
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Support for '= delete' with template declarations was a late addition
|
||||
// to the c++11 standard and is rejected by clang 3.8 and Apple clang 8.2
|
||||
// even though these declare themselves to be c++11 compilers.
|
||||
#if !defined(JSONCPP_TEMPLATE_DELETE)
|
||||
#if defined(__clang__) && defined(__apple_build_version__)
|
||||
#if __apple_build_version__ <= 8000042
|
||||
#define JSONCPP_TEMPLATE_DELETE
|
||||
#endif
|
||||
#elif defined(__clang__)
|
||||
#if __clang_major__ == 3 && __clang_minor__ <= 8
|
||||
#define JSONCPP_TEMPLATE_DELETE
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(JSONCPP_TEMPLATE_DELETE)
|
||||
#define JSONCPP_TEMPLATE_DELETE = delete
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
|
||||
// be used by...
|
||||
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4251 4275)
|
||||
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack()
|
||||
|
||||
/** \brief JSON (JavaScript Object Notation).
|
||||
*/
|
||||
namespace Json {
|
||||
|
||||
#if JSON_USE_EXCEPTION
|
||||
/** Base class for all exceptions we throw.
|
||||
*
|
||||
* We use nothing but these internally. Of course, STL can throw others.
|
||||
*/
|
||||
class JSON_API Exception : public std::exception {
|
||||
public:
|
||||
Exception(String msg);
|
||||
~Exception() noexcept override;
|
||||
char const* what() const noexcept override;
|
||||
|
||||
protected:
|
||||
String msg_;
|
||||
};
|
||||
|
||||
/** Exceptions which the user cannot easily avoid.
|
||||
*
|
||||
* E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
|
||||
*
|
||||
* \remark derived from Json::Exception
|
||||
*/
|
||||
class JSON_API RuntimeError : public Exception {
|
||||
public:
|
||||
RuntimeError(String const& msg);
|
||||
};
|
||||
|
||||
/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
|
||||
*
|
||||
* These are precondition-violations (user bugs) and internal errors (our bugs).
|
||||
*
|
||||
* \remark derived from Json::Exception
|
||||
*/
|
||||
class JSON_API LogicError : public Exception {
|
||||
public:
|
||||
LogicError(String const& msg);
|
||||
};
|
||||
#endif
|
||||
|
||||
/// used internally
|
||||
JSONCPP_NORETURN void throwRuntimeError(String const& msg);
|
||||
/// used internally
|
||||
JSONCPP_NORETURN void throwLogicError(String const& msg);
|
||||
|
||||
/** \brief Type of the value held by a Value object.
|
||||
*/
|
||||
enum ValueType {
|
||||
nullValue = 0, ///< 'null' value
|
||||
intValue, ///< signed integer value
|
||||
uintValue, ///< unsigned integer value
|
||||
realValue, ///< double value
|
||||
stringValue, ///< UTF-8 string value
|
||||
booleanValue, ///< bool value
|
||||
arrayValue, ///< array value (ordered list)
|
||||
objectValue ///< object value (collection of name/value pairs).
|
||||
};
|
||||
|
||||
enum CommentPlacement {
|
||||
commentBefore = 0, ///< a comment placed on the line before a value
|
||||
commentAfterOnSameLine, ///< a comment just after a value on the same line
|
||||
commentAfter, ///< a comment on the line after a value (only make sense for
|
||||
/// root value)
|
||||
numberOfCommentPlacement
|
||||
};
|
||||
|
||||
/** \brief Type of precision for formatting of real values.
|
||||
*/
|
||||
enum PrecisionType {
|
||||
significantDigits = 0, ///< we set max number of significant digits in string
|
||||
decimalPlaces ///< we set max number of digits after "." in string
|
||||
};
|
||||
|
||||
/** \brief Lightweight wrapper to tag static string.
|
||||
*
|
||||
* Value constructor and objectValue member assignment takes advantage of the
|
||||
* StaticString and avoid the cost of string duplication when storing the
|
||||
* string or the member name.
|
||||
*
|
||||
* Example of usage:
|
||||
* \code
|
||||
* Json::Value aValue( StaticString("some text") );
|
||||
* Json::Value object;
|
||||
* static const StaticString code("code");
|
||||
* object[code] = 1234;
|
||||
* \endcode
|
||||
*/
|
||||
class JSON_API StaticString {
|
||||
public:
|
||||
explicit StaticString(const char* czstring) : c_str_(czstring) {}
|
||||
|
||||
operator const char*() const { return c_str_; }
|
||||
|
||||
const char* c_str() const { return c_str_; }
|
||||
|
||||
private:
|
||||
const char* c_str_;
|
||||
};
|
||||
|
||||
/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
|
||||
*
|
||||
* This class is a discriminated union wrapper that can represents a:
|
||||
* - signed integer [range: Value::minInt - Value::maxInt]
|
||||
* - unsigned integer (range: 0 - Value::maxUInt)
|
||||
* - double
|
||||
* - UTF-8 string
|
||||
* - boolean
|
||||
* - 'null'
|
||||
* - an ordered list of Value
|
||||
* - collection of name/value pairs (javascript object)
|
||||
*
|
||||
* The type of the held value is represented by a #ValueType and
|
||||
* can be obtained using type().
|
||||
*
|
||||
* Values of an #objectValue or #arrayValue can be accessed using operator[]()
|
||||
* methods.
|
||||
* Non-const methods will automatically create the a #nullValue element
|
||||
* if it does not exist.
|
||||
* The sequence of an #arrayValue will be automatically resized and initialized
|
||||
* with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
|
||||
*
|
||||
* The get() methods can be used to obtain default value in the case the
|
||||
* required element does not exist.
|
||||
*
|
||||
* It is possible to iterate over the list of member keys of an object using
|
||||
* the getMemberNames() method.
|
||||
*
|
||||
* \note #Value string-length fit in size_t, but keys must be < 2^30.
|
||||
* (The reason is an implementation detail.) A #CharReader will raise an
|
||||
* exception if a bound is exceeded to avoid security holes in your app,
|
||||
* but the Value API does *not* check bounds. That is the responsibility
|
||||
* of the caller.
|
||||
*/
|
||||
class JSON_API Value {
|
||||
friend class ValueIteratorBase;
|
||||
|
||||
public:
|
||||
using Members = std::vector<String>;
|
||||
using iterator = ValueIterator;
|
||||
using const_iterator = ValueConstIterator;
|
||||
using UInt = Json::UInt;
|
||||
using Int = Json::Int;
|
||||
#if defined(JSON_HAS_INT64)
|
||||
using UInt64 = Json::UInt64;
|
||||
using Int64 = Json::Int64;
|
||||
#endif // defined(JSON_HAS_INT64)
|
||||
using LargestInt = Json::LargestInt;
|
||||
using LargestUInt = Json::LargestUInt;
|
||||
using ArrayIndex = Json::ArrayIndex;
|
||||
|
||||
// Required for boost integration, e. g. BOOST_TEST
|
||||
using value_type = std::string;
|
||||
|
||||
#if JSON_USE_NULLREF
|
||||
// Binary compatibility kludges, do not use.
|
||||
static const Value& null;
|
||||
static const Value& nullRef;
|
||||
#endif
|
||||
|
||||
// null and nullRef are deprecated, use this instead.
|
||||
static Value const& nullSingleton();
|
||||
|
||||
/// Minimum signed integer value that can be stored in a Json::Value.
|
||||
static constexpr LargestInt minLargestInt =
|
||||
LargestInt(~(LargestUInt(-1) / 2));
|
||||
/// Maximum signed integer value that can be stored in a Json::Value.
|
||||
static constexpr LargestInt maxLargestInt = LargestInt(LargestUInt(-1) / 2);
|
||||
/// Maximum unsigned integer value that can be stored in a Json::Value.
|
||||
static constexpr LargestUInt maxLargestUInt = LargestUInt(-1);
|
||||
|
||||
/// Minimum signed int value that can be stored in a Json::Value.
|
||||
static constexpr Int minInt = Int(~(UInt(-1) / 2));
|
||||
/// Maximum signed int value that can be stored in a Json::Value.
|
||||
static constexpr Int maxInt = Int(UInt(-1) / 2);
|
||||
/// Maximum unsigned int value that can be stored in a Json::Value.
|
||||
static constexpr UInt maxUInt = UInt(-1);
|
||||
|
||||
#if defined(JSON_HAS_INT64)
|
||||
/// Minimum signed 64 bits int value that can be stored in a Json::Value.
|
||||
static constexpr Int64 minInt64 = Int64(~(UInt64(-1) / 2));
|
||||
/// Maximum signed 64 bits int value that can be stored in a Json::Value.
|
||||
static constexpr Int64 maxInt64 = Int64(UInt64(-1) / 2);
|
||||
/// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
|
||||
static constexpr UInt64 maxUInt64 = UInt64(-1);
|
||||
#endif // defined(JSON_HAS_INT64)
|
||||
/// Default precision for real value for string representation.
|
||||
static constexpr UInt defaultRealPrecision = 17;
|
||||
// The constant is hard-coded because some compiler have trouble
|
||||
// converting Value::maxUInt64 to a double correctly (AIX/xlC).
|
||||
// Assumes that UInt64 is a 64 bits integer.
|
||||
static constexpr double maxUInt64AsDouble = 18446744073709551615.0;
|
||||
// Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler
|
||||
// when using gcc and clang backend compilers. CZString
|
||||
// cannot be defined as private. See issue #486
|
||||
#ifdef __NVCC__
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
#endif
|
||||
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
|
||||
class CZString {
|
||||
public:
|
||||
enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
|
||||
CZString(ArrayIndex index);
|
||||
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
|
||||
CZString(CZString const& other);
|
||||
CZString(CZString&& other) noexcept;
|
||||
~CZString();
|
||||
CZString& operator=(const CZString& other);
|
||||
CZString& operator=(CZString&& other) noexcept;
|
||||
|
||||
bool operator<(CZString const& other) const;
|
||||
bool operator==(CZString const& other) const;
|
||||
ArrayIndex index() const;
|
||||
// const char* c_str() const; ///< \deprecated
|
||||
char const* data() const;
|
||||
unsigned length() const;
|
||||
bool isStaticString() const;
|
||||
|
||||
private:
|
||||
void swap(CZString& other);
|
||||
|
||||
struct StringStorage {
|
||||
unsigned policy_ : 2;
|
||||
unsigned length_ : 30; // 1GB max
|
||||
};
|
||||
|
||||
char const* cstr_; // actually, a prefixed string, unless policy is noDup
|
||||
union {
|
||||
ArrayIndex index_;
|
||||
StringStorage storage_;
|
||||
};
|
||||
};
|
||||
|
||||
public:
|
||||
typedef std::map<CZString, Value> ObjectValues;
|
||||
#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Create a default Value of the given type.
|
||||
*
|
||||
* This is a very useful constructor.
|
||||
* To create an empty array, pass arrayValue.
|
||||
* To create an empty object, pass objectValue.
|
||||
* Another Value can then be set to this one by assignment.
|
||||
* This is useful since clear() and resize() will not alter types.
|
||||
*
|
||||
* Examples:
|
||||
* \code
|
||||
* Json::Value null_value; // null
|
||||
* Json::Value arr_value(Json::arrayValue); // []
|
||||
* Json::Value obj_value(Json::objectValue); // {}
|
||||
* \endcode
|
||||
*/
|
||||
Value(ValueType type = nullValue);
|
||||
Value(Int value);
|
||||
Value(UInt value);
|
||||
#if defined(JSON_HAS_INT64)
|
||||
Value(Int64 value);
|
||||
Value(UInt64 value);
|
||||
#endif // if defined(JSON_HAS_INT64)
|
||||
Value(double value);
|
||||
Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
|
||||
Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
|
||||
/**
|
||||
* \brief Constructs a value from a static string.
|
||||
*
|
||||
* Like other value string constructor but do not duplicate the string for
|
||||
* internal storage. The given string must remain alive after the call to
|
||||
* this constructor.
|
||||
*
|
||||
* \note This works only for null-terminated strings. (We cannot change the
|
||||
* size of this class, so we have nowhere to store the length, which might be
|
||||
* computed later for various operations.)
|
||||
*
|
||||
* Example of usage:
|
||||
* \code
|
||||
* static StaticString foo("some text");
|
||||
* Json::Value aValue(foo);
|
||||
* \endcode
|
||||
*/
|
||||
Value(const StaticString& value);
|
||||
Value(const String& value);
|
||||
Value(bool value);
|
||||
Value(std::nullptr_t ptr) = delete;
|
||||
Value(const Value& other);
|
||||
Value(Value&& other) noexcept;
|
||||
~Value();
|
||||
|
||||
/// \note Overwrite existing comments. To preserve comments, use
|
||||
/// #swapPayload().
|
||||
Value& operator=(const Value& other);
|
||||
Value& operator=(Value&& other) noexcept;
|
||||
|
||||
/// Swap everything.
|
||||
void swap(Value& other);
|
||||
/// Swap values but leave comments and source offsets in place.
|
||||
void swapPayload(Value& other);
|
||||
|
||||
/// copy everything.
|
||||
void copy(const Value& other);
|
||||
/// copy values but leave comments and source offsets in place.
|
||||
void copyPayload(const Value& other);
|
||||
|
||||
ValueType type() const;
|
||||
|
||||
/// Compare payload only, not comments etc.
|
||||
bool operator<(const Value& other) const;
|
||||
bool operator<=(const Value& other) const;
|
||||
bool operator>=(const Value& other) const;
|
||||
bool operator>(const Value& other) const;
|
||||
bool operator==(const Value& other) const;
|
||||
bool operator!=(const Value& other) const;
|
||||
int compare(const Value& other) const;
|
||||
|
||||
const char* asCString() const; ///< Embedded zeroes could cause you trouble!
|
||||
#if JSONCPP_USING_SECURE_MEMORY
|
||||
unsigned getCStringLength() const; // Allows you to understand the length of
|
||||
// the CString
|
||||
#endif
|
||||
String asString() const; ///< Embedded zeroes are possible.
|
||||
/** Get raw char* of string-value.
|
||||
* \return false if !string. (Seg-fault if str or end are NULL.)
|
||||
*/
|
||||
bool getString(char const** begin, char const** end) const;
|
||||
Int asInt() const;
|
||||
UInt asUInt() const;
|
||||
#if defined(JSON_HAS_INT64)
|
||||
Int64 asInt64() const;
|
||||
UInt64 asUInt64() const;
|
||||
#endif // if defined(JSON_HAS_INT64)
|
||||
LargestInt asLargestInt() const;
|
||||
LargestUInt asLargestUInt() const;
|
||||
float asFloat() const;
|
||||
double asDouble() const;
|
||||
bool asBool() const;
|
||||
|
||||
bool isNull() const;
|
||||
bool isBool() const;
|
||||
bool isInt() const;
|
||||
bool isInt64() const;
|
||||
bool isUInt() const;
|
||||
bool isUInt64() const;
|
||||
bool isIntegral() const;
|
||||
bool isDouble() const;
|
||||
bool isNumeric() const;
|
||||
bool isString() const;
|
||||
bool isArray() const;
|
||||
bool isObject() const;
|
||||
|
||||
/// The `as<T>` and `is<T>` member function templates and specializations.
|
||||
template <typename T> T as() const JSONCPP_TEMPLATE_DELETE;
|
||||
template <typename T> bool is() const JSONCPP_TEMPLATE_DELETE;
|
||||
|
||||
bool isConvertibleTo(ValueType other) const;
|
||||
|
||||
/// Number of values in array or object
|
||||
ArrayIndex size() const;
|
||||
|
||||
/// \brief Return true if empty array, empty object, or null;
|
||||
/// otherwise, false.
|
||||
bool empty() const;
|
||||
|
||||
/// Return !isNull()
|
||||
explicit operator bool() const;
|
||||
|
||||
/// Remove all object members and array elements.
|
||||
/// \pre type() is arrayValue, objectValue, or nullValue
|
||||
/// \post type() is unchanged
|
||||
void clear();
|
||||
|
||||
/// Resize the array to newSize elements.
|
||||
/// New elements are initialized to null.
|
||||
/// May only be called on nullValue or arrayValue.
|
||||
/// \pre type() is arrayValue or nullValue
|
||||
/// \post type() is arrayValue
|
||||
void resize(ArrayIndex newSize);
|
||||
|
||||
///@{
|
||||
/// Access an array element (zero based index). If the array contains less
|
||||
/// than index element, then null value are inserted in the array so that
|
||||
/// its size is index+1.
|
||||
/// (You may need to say 'value[0u]' to get your compiler to distinguish
|
||||
/// this from the operator[] which takes a string.)
|
||||
Value& operator[](ArrayIndex index);
|
||||
Value& operator[](int index);
|
||||
///@}
|
||||
|
||||
///@{
|
||||
/// Access an array element (zero based index).
|
||||
/// (You may need to say 'value[0u]' to get your compiler to distinguish
|
||||
/// this from the operator[] which takes a string.)
|
||||
const Value& operator[](ArrayIndex index) const;
|
||||
const Value& operator[](int index) const;
|
||||
///@}
|
||||
|
||||
/// If the array contains at least index+1 elements, returns the element
|
||||
/// value, otherwise returns defaultValue.
|
||||
Value get(ArrayIndex index, const Value& defaultValue) const;
|
||||
/// Return true if index < size().
|
||||
bool isValidIndex(ArrayIndex index) const;
|
||||
/// \brief Append value to array at the end.
|
||||
///
|
||||
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
|
||||
Value& append(const Value& value);
|
||||
Value& append(Value&& value);
|
||||
|
||||
/// \brief Insert value in array at specific index
|
||||
bool insert(ArrayIndex index, const Value& newValue);
|
||||
bool insert(ArrayIndex index, Value&& newValue);
|
||||
|
||||
/// Access an object value by name, create a null member if it does not exist.
|
||||
/// \note Because of our implementation, keys are limited to 2^30 -1 chars.
|
||||
/// Exceeding that will cause an exception.
|
||||
Value& operator[](const char* key);
|
||||
/// Access an object value by name, returns null if there is no member with
|
||||
/// that name.
|
||||
const Value& operator[](const char* key) const;
|
||||
/// Access an object value by name, create a null member if it does not exist.
|
||||
/// \param key may contain embedded nulls.
|
||||
Value& operator[](const String& key);
|
||||
/// Access an object value by name, returns null if there is no member with
|
||||
/// that name.
|
||||
/// \param key may contain embedded nulls.
|
||||
const Value& operator[](const String& key) const;
|
||||
/** \brief Access an object value by name, create a null member if it does not
|
||||
* exist.
|
||||
*
|
||||
* If the object has no entry for that name, then the member name used to
|
||||
* store the new entry is not duplicated.
|
||||
* Example of use:
|
||||
* \code
|
||||
* Json::Value object;
|
||||
* static const StaticString code("code");
|
||||
* object[code] = 1234;
|
||||
* \endcode
|
||||
*/
|
||||
Value& operator[](const StaticString& key);
|
||||
/// Return the member named key if it exist, defaultValue otherwise.
|
||||
/// \note deep copy
|
||||
Value get(const char* key, const Value& defaultValue) const;
|
||||
/// Return the member named key if it exist, defaultValue otherwise.
|
||||
/// \note deep copy
|
||||
/// \note key may contain embedded nulls.
|
||||
Value get(const char* begin, const char* end,
|
||||
const Value& defaultValue) const;
|
||||
/// Return the member named key if it exist, defaultValue otherwise.
|
||||
/// \note deep copy
|
||||
/// \param key may contain embedded nulls.
|
||||
Value get(const String& key, const Value& defaultValue) const;
|
||||
/// Most general and efficient version of isMember()const, get()const,
|
||||
/// and operator[]const
|
||||
/// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
|
||||
Value const* find(char const* begin, char const* end) const;
|
||||
/// Most general and efficient version of object-mutators.
|
||||
/// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
|
||||
/// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
|
||||
Value* demand(char const* begin, char const* end);
|
||||
/// \brief Remove and return the named member.
|
||||
///
|
||||
/// Do nothing if it did not exist.
|
||||
/// \pre type() is objectValue or nullValue
|
||||
/// \post type() is unchanged
|
||||
void removeMember(const char* key);
|
||||
/// Same as removeMember(const char*)
|
||||
/// \param key may contain embedded nulls.
|
||||
void removeMember(const String& key);
|
||||
/// Same as removeMember(const char* begin, const char* end, Value* removed),
|
||||
/// but 'key' is null-terminated.
|
||||
bool removeMember(const char* key, Value* removed);
|
||||
/** \brief Remove the named map member.
|
||||
*
|
||||
* Update 'removed' iff removed.
|
||||
* \param key may contain embedded nulls.
|
||||
* \return true iff removed (no exceptions)
|
||||
*/
|
||||
bool removeMember(String const& key, Value* removed);
|
||||
/// Same as removeMember(String const& key, Value* removed)
|
||||
bool removeMember(const char* begin, const char* end, Value* removed);
|
||||
/** \brief Remove the indexed array element.
|
||||
*
|
||||
* O(n) expensive operations.
|
||||
* Update 'removed' iff removed.
|
||||
* \return true if removed (no exceptions)
|
||||
*/
|
||||
bool removeIndex(ArrayIndex index, Value* removed);
|
||||
|
||||
/// Return true if the object has a member named key.
|
||||
/// \note 'key' must be null-terminated.
|
||||
bool isMember(const char* key) const;
|
||||
/// Return true if the object has a member named key.
|
||||
/// \param key may contain embedded nulls.
|
||||
bool isMember(const String& key) const;
|
||||
/// Same as isMember(String const& key)const
|
||||
bool isMember(const char* begin, const char* end) const;
|
||||
|
||||
/// \brief Return a list of the member names.
|
||||
///
|
||||
/// If null, return an empty list.
|
||||
/// \pre type() is objectValue or nullValue
|
||||
/// \post if type() was nullValue, it remains nullValue
|
||||
Members getMemberNames() const;
|
||||
|
||||
/// \deprecated Always pass len.
|
||||
JSONCPP_DEPRECATED("Use setComment(String const&) instead.")
|
||||
void setComment(const char* comment, CommentPlacement placement) {
|
||||
setComment(String(comment, strlen(comment)), placement);
|
||||
}
|
||||
/// Comments must be //... or /* ... */
|
||||
void setComment(const char* comment, size_t len, CommentPlacement placement) {
|
||||
setComment(String(comment, len), placement);
|
||||
}
|
||||
/// Comments must be //... or /* ... */
|
||||
void setComment(String comment, CommentPlacement placement);
|
||||
bool hasComment(CommentPlacement placement) const;
|
||||
/// Include delimiters and embedded newlines.
|
||||
String getComment(CommentPlacement placement) const;
|
||||
|
||||
String toString() const;
|
||||
String toStyledString() const;
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
|
||||
/// \brief Returns a reference to the first element in the `Value`.
|
||||
/// Requires that this value holds an array or json object, with at least one element.
|
||||
const Value& front() const;
|
||||
|
||||
/// \brief Returns a reference to the first element in the `Value`.
|
||||
/// Requires that this value holds an array or json object, with at least one element.
|
||||
Value& front();
|
||||
|
||||
/// \brief Returns a reference to the last element in the `Value`.
|
||||
/// Requires that value holds an array or json object, with at least one element.
|
||||
const Value& back() const;
|
||||
|
||||
/// \brief Returns a reference to the last element in the `Value`.
|
||||
/// Requires that this value holds an array or json object, with at least one element.
|
||||
Value& back();
|
||||
|
||||
// Accessors for the [start, limit) range of bytes within the JSON text from
|
||||
// which this value was parsed, if any.
|
||||
void setOffsetStart(ptrdiff_t start);
|
||||
void setOffsetLimit(ptrdiff_t limit);
|
||||
ptrdiff_t getOffsetStart() const;
|
||||
ptrdiff_t getOffsetLimit() const;
|
||||
|
||||
private:
|
||||
void setType(ValueType v) {
|
||||
bits_.value_type_ = static_cast<unsigned char>(v);
|
||||
}
|
||||
bool isAllocated() const { return bits_.allocated_; }
|
||||
void setIsAllocated(bool v) { bits_.allocated_ = v; }
|
||||
|
||||
void initBasic(ValueType type, bool allocated = false);
|
||||
void dupPayload(const Value& other);
|
||||
void releasePayload();
|
||||
void dupMeta(const Value& other);
|
||||
|
||||
Value& resolveReference(const char* key);
|
||||
Value& resolveReference(const char* key, const char* end);
|
||||
|
||||
// struct MemberNamesTransform
|
||||
//{
|
||||
// typedef const char *result_type;
|
||||
// const char *operator()( const CZString &name ) const
|
||||
// {
|
||||
// return name.c_str();
|
||||
// }
|
||||
//};
|
||||
|
||||
union ValueHolder {
|
||||
LargestInt int_;
|
||||
LargestUInt uint_;
|
||||
double real_;
|
||||
bool bool_;
|
||||
char* string_; // if allocated_, ptr to { unsigned, char[] }.
|
||||
ObjectValues* map_;
|
||||
} value_;
|
||||
|
||||
struct {
|
||||
// Really a ValueType, but types should agree for bitfield packing.
|
||||
unsigned int value_type_ : 8;
|
||||
// Unless allocated_, string_ must be null-terminated.
|
||||
unsigned int allocated_ : 1;
|
||||
} bits_;
|
||||
|
||||
class Comments {
|
||||
public:
|
||||
Comments() = default;
|
||||
Comments(const Comments& that);
|
||||
Comments(Comments&& that) noexcept;
|
||||
Comments& operator=(const Comments& that);
|
||||
Comments& operator=(Comments&& that) noexcept;
|
||||
bool has(CommentPlacement slot) const;
|
||||
String get(CommentPlacement slot) const;
|
||||
void set(CommentPlacement slot, String comment);
|
||||
|
||||
private:
|
||||
using Array = std::array<String, numberOfCommentPlacement>;
|
||||
std::unique_ptr<Array> ptr_;
|
||||
};
|
||||
Comments comments_;
|
||||
|
||||
// [start, limit) byte offsets in the source JSON text from which this Value
|
||||
// was extracted.
|
||||
ptrdiff_t start_;
|
||||
ptrdiff_t limit_;
|
||||
};
|
||||
|
||||
template <> inline bool Value::as<bool>() const { return asBool(); }
|
||||
template <> inline bool Value::is<bool>() const { return isBool(); }
|
||||
|
||||
template <> inline Int Value::as<Int>() const { return asInt(); }
|
||||
template <> inline bool Value::is<Int>() const { return isInt(); }
|
||||
|
||||
template <> inline UInt Value::as<UInt>() const { return asUInt(); }
|
||||
template <> inline bool Value::is<UInt>() const { return isUInt(); }
|
||||
|
||||
#if defined(JSON_HAS_INT64)
|
||||
template <> inline Int64 Value::as<Int64>() const { return asInt64(); }
|
||||
template <> inline bool Value::is<Int64>() const { return isInt64(); }
|
||||
|
||||
template <> inline UInt64 Value::as<UInt64>() const { return asUInt64(); }
|
||||
template <> inline bool Value::is<UInt64>() const { return isUInt64(); }
|
||||
#endif
|
||||
|
||||
template <> inline double Value::as<double>() const { return asDouble(); }
|
||||
template <> inline bool Value::is<double>() const { return isDouble(); }
|
||||
|
||||
template <> inline String Value::as<String>() const { return asString(); }
|
||||
template <> inline bool Value::is<String>() const { return isString(); }
|
||||
|
||||
/// These `as` specializations are type conversions, and do not have a
|
||||
/// corresponding `is`.
|
||||
template <> inline float Value::as<float>() const { return asFloat(); }
|
||||
template <> inline const char* Value::as<const char*>() const {
|
||||
return asCString();
|
||||
}
|
||||
|
||||
/** \brief Experimental and untested: represents an element of the "path" to
|
||||
* access a node.
|
||||
*/
|
||||
class JSON_API PathArgument {
|
||||
public:
|
||||
friend class Path;
|
||||
|
||||
PathArgument();
|
||||
PathArgument(ArrayIndex index);
|
||||
PathArgument(const char* key);
|
||||
PathArgument(String key);
|
||||
|
||||
private:
|
||||
enum Kind { kindNone = 0, kindIndex, kindKey };
|
||||
String key_;
|
||||
ArrayIndex index_{};
|
||||
Kind kind_{kindNone};
|
||||
};
|
||||
|
||||
/** \brief Experimental and untested: represents a "path" to access a node.
|
||||
*
|
||||
* Syntax:
|
||||
* - "." => root node
|
||||
* - ".[n]" => elements at index 'n' of root node (an array value)
|
||||
* - ".name" => member named 'name' of root node (an object value)
|
||||
* - ".name1.name2.name3"
|
||||
* - ".[0][1][2].name1[3]"
|
||||
* - ".%" => member name is provided as parameter
|
||||
* - ".[%]" => index is provided as parameter
|
||||
*/
|
||||
class JSON_API Path {
|
||||
public:
|
||||
Path(const String& path, const PathArgument& a1 = PathArgument(),
|
||||
const PathArgument& a2 = PathArgument(),
|
||||
const PathArgument& a3 = PathArgument(),
|
||||
const PathArgument& a4 = PathArgument(),
|
||||
const PathArgument& a5 = PathArgument());
|
||||
|
||||
const Value& resolve(const Value& root) const;
|
||||
Value resolve(const Value& root, const Value& defaultValue) const;
|
||||
/// Creates the "path" to access the specified node and returns a reference on
|
||||
/// the node.
|
||||
Value& make(Value& root) const;
|
||||
|
||||
private:
|
||||
using InArgs = std::vector<const PathArgument*>;
|
||||
using Args = std::vector<PathArgument>;
|
||||
|
||||
void makePath(const String& path, const InArgs& in);
|
||||
void addPathInArg(const String& path, const InArgs& in,
|
||||
InArgs::const_iterator& itInArg, PathArgument::Kind kind);
|
||||
static void invalidPath(const String& path, int location);
|
||||
|
||||
Args args_;
|
||||
};
|
||||
|
||||
/** \brief base class for Value iterators.
|
||||
*
|
||||
*/
|
||||
class JSON_API ValueIteratorBase {
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using size_t = unsigned int;
|
||||
using difference_type = int;
|
||||
using SelfType = ValueIteratorBase;
|
||||
|
||||
bool operator==(const SelfType& other) const { return isEqual(other); }
|
||||
|
||||
bool operator!=(const SelfType& other) const { return !isEqual(other); }
|
||||
|
||||
difference_type operator-(const SelfType& other) const {
|
||||
return other.computeDistance(*this);
|
||||
}
|
||||
|
||||
/// Return either the index or the member name of the referenced value as a
|
||||
/// Value.
|
||||
Value key() const;
|
||||
|
||||
/// Return the index of the referenced Value, or -1 if it is not an
|
||||
/// arrayValue.
|
||||
UInt index() const;
|
||||
|
||||
/// Return the member name of the referenced Value, or "" if it is not an
|
||||
/// objectValue.
|
||||
/// \note Avoid `c_str()` on result, as embedded zeroes are possible.
|
||||
String name() const;
|
||||
|
||||
/// Return the member name of the referenced Value. "" if it is not an
|
||||
/// objectValue.
|
||||
/// \deprecated This cannot be used for UTF-8 strings, since there can be
|
||||
/// embedded nulls.
|
||||
JSONCPP_DEPRECATED("Use `key = name();` instead.")
|
||||
char const* memberName() const;
|
||||
/// Return the member name of the referenced Value, or NULL if it is not an
|
||||
/// objectValue.
|
||||
/// \note Better version than memberName(). Allows embedded nulls.
|
||||
char const* memberName(char const** end) const;
|
||||
|
||||
protected:
|
||||
/*! Internal utility functions to assist with implementing
|
||||
* other iterator functions. The const and non-const versions
|
||||
* of the "deref" protected methods expose the protected
|
||||
* current_ member variable in a way that can often be
|
||||
* optimized away by the compiler.
|
||||
*/
|
||||
const Value& deref() const;
|
||||
Value& deref();
|
||||
|
||||
void increment();
|
||||
|
||||
void decrement();
|
||||
|
||||
difference_type computeDistance(const SelfType& other) const;
|
||||
|
||||
bool isEqual(const SelfType& other) const;
|
||||
|
||||
void copy(const SelfType& other);
|
||||
|
||||
private:
|
||||
Value::ObjectValues::iterator current_;
|
||||
// Indicates that iterator is for a null value.
|
||||
bool isNull_{true};
|
||||
|
||||
public:
|
||||
// For some reason, BORLAND needs these at the end, rather
|
||||
// than earlier. No idea why.
|
||||
ValueIteratorBase();
|
||||
explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
|
||||
};
|
||||
|
||||
/** \brief const iterator for object and array value.
|
||||
*
|
||||
*/
|
||||
class JSON_API ValueConstIterator : public ValueIteratorBase {
|
||||
friend class Value;
|
||||
|
||||
public:
|
||||
using value_type = const Value;
|
||||
// typedef unsigned int size_t;
|
||||
// typedef int difference_type;
|
||||
using reference = const Value&;
|
||||
using pointer = const Value*;
|
||||
using SelfType = ValueConstIterator;
|
||||
|
||||
ValueConstIterator();
|
||||
ValueConstIterator(ValueIterator const& other);
|
||||
|
||||
private:
|
||||
/*! \internal Use by Value to create an iterator.
|
||||
*/
|
||||
explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
|
||||
|
||||
public:
|
||||
SelfType& operator=(const ValueIteratorBase& other);
|
||||
|
||||
SelfType operator++(int) {
|
||||
SelfType temp(*this);
|
||||
++*this;
|
||||
return temp;
|
||||
}
|
||||
|
||||
SelfType operator--(int) {
|
||||
SelfType temp(*this);
|
||||
--*this;
|
||||
return temp;
|
||||
}
|
||||
|
||||
SelfType& operator--() {
|
||||
decrement();
|
||||
return *this;
|
||||
}
|
||||
|
||||
SelfType& operator++() {
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference operator*() const { return deref(); }
|
||||
|
||||
pointer operator->() const { return &deref(); }
|
||||
};
|
||||
|
||||
/** \brief Iterator for object and array value.
|
||||
*/
|
||||
class JSON_API ValueIterator : public ValueIteratorBase {
|
||||
friend class Value;
|
||||
|
||||
public:
|
||||
using value_type = Value;
|
||||
using size_t = unsigned int;
|
||||
using difference_type = int;
|
||||
using reference = Value&;
|
||||
using pointer = Value*;
|
||||
using SelfType = ValueIterator;
|
||||
|
||||
ValueIterator();
|
||||
explicit ValueIterator(const ValueConstIterator& other);
|
||||
ValueIterator(const ValueIterator& other);
|
||||
|
||||
private:
|
||||
/*! \internal Use by Value to create an iterator.
|
||||
*/
|
||||
explicit ValueIterator(const Value::ObjectValues::iterator& current);
|
||||
|
||||
public:
|
||||
SelfType& operator=(const SelfType& other);
|
||||
|
||||
SelfType operator++(int) {
|
||||
SelfType temp(*this);
|
||||
++*this;
|
||||
return temp;
|
||||
}
|
||||
|
||||
SelfType operator--(int) {
|
||||
SelfType temp(*this);
|
||||
--*this;
|
||||
return temp;
|
||||
}
|
||||
|
||||
SelfType& operator--() {
|
||||
decrement();
|
||||
return *this;
|
||||
}
|
||||
|
||||
SelfType& operator++() {
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! The return value of non-const iterators can be
|
||||
* changed, so the these functions are not const
|
||||
* because the returned references/pointers can be used
|
||||
* to change state of the base class.
|
||||
*/
|
||||
reference operator*() const { return const_cast<reference>(deref()); }
|
||||
pointer operator->() const { return const_cast<pointer>(&deref()); }
|
||||
};
|
||||
|
||||
inline void swap(Value& a, Value& b) { a.swap(b); }
|
||||
|
||||
inline const Value& Value::front() const { return *begin(); }
|
||||
|
||||
inline Value& Value::front() { return *begin(); }
|
||||
|
||||
inline const Value& Value::back() const { return *(--end()); }
|
||||
|
||||
inline Value& Value::back() { return *(--end()); }
|
||||
|
||||
} // namespace Json
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
#pragma warning(pop)
|
||||
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
|
||||
#endif // JSON_H_INCLUDED
|
||||
28
demo/kugou/include/Common/include/json/version.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef JSON_VERSION_H_INCLUDED
|
||||
#define JSON_VERSION_H_INCLUDED
|
||||
|
||||
// Note: version must be updated in three places when doing a release. This
|
||||
// annoying process ensures that amalgamate, CMake, and meson all report the
|
||||
// correct version.
|
||||
// 1. /meson.build
|
||||
// 2. /include/json/version.h
|
||||
// 3. /CMakeLists.txt
|
||||
// IMPORTANT: also update the SOVERSION!!
|
||||
|
||||
#define JSONCPP_VERSION_STRING "1.9.5"
|
||||
#define JSONCPP_VERSION_MAJOR 1
|
||||
#define JSONCPP_VERSION_MINOR 9
|
||||
#define JSONCPP_VERSION_PATCH 5
|
||||
#define JSONCPP_VERSION_QUALIFIER
|
||||
#define JSONCPP_VERSION_HEXA \
|
||||
((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
|
||||
(JSONCPP_VERSION_PATCH << 8))
|
||||
|
||||
#ifdef JSONCPP_USING_SECURE_MEMORY
|
||||
#undef JSONCPP_USING_SECURE_MEMORY
|
||||
#endif
|
||||
#define JSONCPP_USING_SECURE_MEMORY 0
|
||||
// If non-zero, the library zeroes any memory that it has allocated before
|
||||
// it frees its memory.
|
||||
|
||||
#endif // JSON_VERSION_H_INCLUDED
|
||||
370
demo/kugou/include/Common/include/json/writer.h
Normal file
@@ -0,0 +1,370 @@
|
||||
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
|
||||
// Distributed under MIT license, or public domain if desired and
|
||||
// recognized in your jurisdiction.
|
||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||
|
||||
#ifndef JSON_WRITER_H_INCLUDED
|
||||
#define JSON_WRITER_H_INCLUDED
|
||||
|
||||
#if !defined(JSON_IS_AMALGAMATION)
|
||||
#include "value.h"
|
||||
#endif // if !defined(JSON_IS_AMALGAMATION)
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
|
||||
// be used by...
|
||||
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4251)
|
||||
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack()
|
||||
|
||||
namespace Json {
|
||||
|
||||
class Value;
|
||||
|
||||
/**
|
||||
*
|
||||
* Usage:
|
||||
* \code
|
||||
* using namespace Json;
|
||||
* void writeToStdout(StreamWriter::Factory const& factory, Value const& value)
|
||||
* { std::unique_ptr<StreamWriter> const writer( factory.newStreamWriter());
|
||||
* writer->write(value, &std::cout);
|
||||
* std::cout << std::endl; // add lf and flush
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
class JSON_API StreamWriter {
|
||||
protected:
|
||||
OStream* sout_; // not owned; will not delete
|
||||
public:
|
||||
StreamWriter();
|
||||
virtual ~StreamWriter();
|
||||
/** Write Value into document as configured in sub-class.
|
||||
* Do not take ownership of sout, but maintain a reference during function.
|
||||
* \pre sout != NULL
|
||||
* \return zero on success (For now, we always return zero, so check the
|
||||
* stream instead.) \throw std::exception possibly, depending on
|
||||
* configuration
|
||||
*/
|
||||
virtual int write(Value const& root, OStream* sout) = 0;
|
||||
|
||||
/** \brief A simple abstract factory.
|
||||
*/
|
||||
class JSON_API Factory {
|
||||
public:
|
||||
virtual ~Factory();
|
||||
/** \brief Allocate a CharReader via operator new().
|
||||
* \throw std::exception if something goes wrong (e.g. invalid settings)
|
||||
*/
|
||||
virtual StreamWriter* newStreamWriter() const = 0;
|
||||
}; // Factory
|
||||
}; // StreamWriter
|
||||
|
||||
/** \brief Write into stringstream, then return string, for convenience.
|
||||
* A StreamWriter will be created from the factory, used, and then deleted.
|
||||
*/
|
||||
String JSON_API writeString(StreamWriter::Factory const& factory,
|
||||
Value const& root);
|
||||
|
||||
/** \brief Build a StreamWriter implementation.
|
||||
|
||||
* Usage:
|
||||
* \code
|
||||
* using namespace Json;
|
||||
* Value value = ...;
|
||||
* StreamWriterBuilder builder;
|
||||
* builder["commentStyle"] = "None";
|
||||
* builder["indentation"] = " "; // or whatever you like
|
||||
* std::unique_ptr<Json::StreamWriter> writer(
|
||||
* builder.newStreamWriter());
|
||||
* writer->write(value, &std::cout);
|
||||
* std::cout << std::endl; // add lf and flush
|
||||
* \endcode
|
||||
*/
|
||||
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
|
||||
public:
|
||||
// Note: We use a Json::Value so that we can add data-members to this class
|
||||
// without a major version bump.
|
||||
/** Configuration of this builder.
|
||||
* Available settings (case-sensitive):
|
||||
* - "commentStyle": "None" or "All"
|
||||
* - "indentation": "<anything>".
|
||||
* - Setting this to an empty string also omits newline characters.
|
||||
* - "enableYAMLCompatibility": false or true
|
||||
* - slightly change the whitespace around colons
|
||||
* - "dropNullPlaceholders": false or true
|
||||
* - Drop the "null" string from the writer's output for nullValues.
|
||||
* Strictly speaking, this is not valid JSON. But when the output is being
|
||||
* fed to a browser's JavaScript, it makes for smaller output and the
|
||||
* browser can handle the output just fine.
|
||||
* - "useSpecialFloats": false or true
|
||||
* - If true, outputs non-finite floating point values in the following way:
|
||||
* NaN values as "NaN", positive infinity as "Infinity", and negative
|
||||
* infinity as "-Infinity".
|
||||
* - "precision": int
|
||||
* - Number of precision digits for formatting of real values.
|
||||
* - "precisionType": "significant"(default) or "decimal"
|
||||
* - Type of precision for formatting of real values.
|
||||
* - "emitUTF8": false or true
|
||||
* - If true, outputs raw UTF8 strings instead of escaping them.
|
||||
|
||||
* You can examine 'settings_` yourself
|
||||
* to see the defaults. You can also write and read them just like any
|
||||
* JSON Value.
|
||||
* \sa setDefaults()
|
||||
*/
|
||||
Json::Value settings_;
|
||||
|
||||
StreamWriterBuilder();
|
||||
~StreamWriterBuilder() override;
|
||||
|
||||
/**
|
||||
* \throw std::exception if something goes wrong (e.g. invalid settings)
|
||||
*/
|
||||
StreamWriter* newStreamWriter() const override;
|
||||
|
||||
/** \return true if 'settings' are legal and consistent;
|
||||
* otherwise, indicate bad settings via 'invalid'.
|
||||
*/
|
||||
bool validate(Json::Value* invalid) const;
|
||||
/** A simple way to update a specific setting.
|
||||
*/
|
||||
Value& operator[](const String& key);
|
||||
|
||||
/** Called by ctor, but you can use this to reset settings_.
|
||||
* \pre 'settings' != NULL (but Json::null is fine)
|
||||
* \remark Defaults:
|
||||
* \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
|
||||
*/
|
||||
static void setDefaults(Json::Value* settings);
|
||||
};
|
||||
|
||||
/** \brief Abstract class for writers.
|
||||
* \deprecated Use StreamWriter. (And really, this is an implementation detail.)
|
||||
*/
|
||||
class JSON_API Writer {
|
||||
public:
|
||||
virtual ~Writer();
|
||||
|
||||
virtual String write(const Value& root) = 0;
|
||||
};
|
||||
|
||||
/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
|
||||
*without formatting (not human friendly).
|
||||
*
|
||||
* The JSON document is written in a single line. It is not intended for 'human'
|
||||
*consumption,
|
||||
* but may be useful to support feature such as RPC where bandwidth is limited.
|
||||
* \sa Reader, Value
|
||||
* \deprecated Use StreamWriterBuilder.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996) // Deriving from deprecated class
|
||||
#endif
|
||||
class JSON_API FastWriter
|
||||
: public Writer {
|
||||
public:
|
||||
FastWriter();
|
||||
~FastWriter() override = default;
|
||||
|
||||
void enableYAMLCompatibility();
|
||||
|
||||
/** \brief Drop the "null" string from the writer's output for nullValues.
|
||||
* Strictly speaking, this is not valid JSON. But when the output is being
|
||||
* fed to a browser's JavaScript, it makes for smaller output and the
|
||||
* browser can handle the output just fine.
|
||||
*/
|
||||
void dropNullPlaceholders();
|
||||
|
||||
void omitEndingLineFeed();
|
||||
|
||||
public: // overridden from Writer
|
||||
String write(const Value& root) override;
|
||||
|
||||
private:
|
||||
void writeValue(const Value& value);
|
||||
|
||||
String document_;
|
||||
bool yamlCompatibilityEnabled_{false};
|
||||
bool dropNullPlaceholders_{false};
|
||||
bool omitEndingLineFeed_{false};
|
||||
};
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
|
||||
*human friendly way.
|
||||
*
|
||||
* The rules for line break and indent are as follow:
|
||||
* - Object value:
|
||||
* - if empty then print {} without indent and line break
|
||||
* - if not empty the print '{', line break & indent, print one value per
|
||||
*line
|
||||
* and then unindent and line break and print '}'.
|
||||
* - Array value:
|
||||
* - if empty then print [] without indent and line break
|
||||
* - if the array contains no object value, empty array or some other value
|
||||
*types,
|
||||
* and all the values fit on one lines, then print the array on a single
|
||||
*line.
|
||||
* - otherwise, it the values do not fit on one line, or the array contains
|
||||
* object or non empty array, then print one value per line.
|
||||
*
|
||||
* If the Value have comments then they are outputted according to their
|
||||
*#CommentPlacement.
|
||||
*
|
||||
* \sa Reader, Value, Value::setComment()
|
||||
* \deprecated Use StreamWriterBuilder.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996) // Deriving from deprecated class
|
||||
#endif
|
||||
class JSON_API
|
||||
StyledWriter : public Writer {
|
||||
public:
|
||||
StyledWriter();
|
||||
~StyledWriter() override = default;
|
||||
|
||||
public: // overridden from Writer
|
||||
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
|
||||
* \param root Value to serialize.
|
||||
* \return String containing the JSON document that represents the root value.
|
||||
*/
|
||||
String write(const Value& root) override;
|
||||
|
||||
private:
|
||||
void writeValue(const Value& value);
|
||||
void writeArrayValue(const Value& value);
|
||||
bool isMultilineArray(const Value& value);
|
||||
void pushValue(const String& value);
|
||||
void writeIndent();
|
||||
void writeWithIndent(const String& value);
|
||||
void indent();
|
||||
void unindent();
|
||||
void writeCommentBeforeValue(const Value& root);
|
||||
void writeCommentAfterValueOnSameLine(const Value& root);
|
||||
static bool hasCommentForValue(const Value& value);
|
||||
static String normalizeEOL(const String& text);
|
||||
|
||||
using ChildValues = std::vector<String>;
|
||||
|
||||
ChildValues childValues_;
|
||||
String document_;
|
||||
String indentString_;
|
||||
unsigned int rightMargin_{74};
|
||||
unsigned int indentSize_{3};
|
||||
bool addChildValues_{false};
|
||||
};
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
|
||||
human friendly way,
|
||||
to a stream rather than to a string.
|
||||
*
|
||||
* The rules for line break and indent are as follow:
|
||||
* - Object value:
|
||||
* - if empty then print {} without indent and line break
|
||||
* - if not empty the print '{', line break & indent, print one value per
|
||||
line
|
||||
* and then unindent and line break and print '}'.
|
||||
* - Array value:
|
||||
* - if empty then print [] without indent and line break
|
||||
* - if the array contains no object value, empty array or some other value
|
||||
types,
|
||||
* and all the values fit on one lines, then print the array on a single
|
||||
line.
|
||||
* - otherwise, it the values do not fit on one line, or the array contains
|
||||
* object or non empty array, then print one value per line.
|
||||
*
|
||||
* If the Value have comments then they are outputted according to their
|
||||
#CommentPlacement.
|
||||
*
|
||||
* \sa Reader, Value, Value::setComment()
|
||||
* \deprecated Use StreamWriterBuilder.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996) // Deriving from deprecated class
|
||||
#endif
|
||||
class JSON_API
|
||||
StyledStreamWriter {
|
||||
public:
|
||||
/**
|
||||
* \param indentation Each level will be indented by this amount extra.
|
||||
*/
|
||||
StyledStreamWriter(String indentation = "\t");
|
||||
~StyledStreamWriter() = default;
|
||||
|
||||
public:
|
||||
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
|
||||
* \param out Stream to write to. (Can be ostringstream, e.g.)
|
||||
* \param root Value to serialize.
|
||||
* \note There is no point in deriving from Writer, since write() should not
|
||||
* return a value.
|
||||
*/
|
||||
void write(OStream& out, const Value& root);
|
||||
|
||||
private:
|
||||
void writeValue(const Value& value);
|
||||
void writeArrayValue(const Value& value);
|
||||
bool isMultilineArray(const Value& value);
|
||||
void pushValue(const String& value);
|
||||
void writeIndent();
|
||||
void writeWithIndent(const String& value);
|
||||
void indent();
|
||||
void unindent();
|
||||
void writeCommentBeforeValue(const Value& root);
|
||||
void writeCommentAfterValueOnSameLine(const Value& root);
|
||||
static bool hasCommentForValue(const Value& value);
|
||||
static String normalizeEOL(const String& text);
|
||||
|
||||
using ChildValues = std::vector<String>;
|
||||
|
||||
ChildValues childValues_;
|
||||
OStream* document_;
|
||||
String indentString_;
|
||||
unsigned int rightMargin_{74};
|
||||
String indentation_;
|
||||
bool addChildValues_ : 1;
|
||||
bool indented_ : 1;
|
||||
};
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#if defined(JSON_HAS_INT64)
|
||||
String JSON_API valueToString(Int value);
|
||||
String JSON_API valueToString(UInt value);
|
||||
#endif // if defined(JSON_HAS_INT64)
|
||||
String JSON_API valueToString(LargestInt value);
|
||||
String JSON_API valueToString(LargestUInt value);
|
||||
String JSON_API valueToString(
|
||||
double value, unsigned int precision = Value::defaultRealPrecision,
|
||||
PrecisionType precisionType = PrecisionType::significantDigits);
|
||||
String JSON_API valueToString(bool value);
|
||||
String JSON_API valueToQuotedString(const char* value);
|
||||
|
||||
/// \brief Output using the StyledStreamWriter.
|
||||
/// \see Json::operator>>()
|
||||
JSON_API OStream& operator<<(OStream&, const Value& root);
|
||||
|
||||
} // namespace Json
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
#pragma warning(pop)
|
||||
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
|
||||
|
||||
#endif // JSON_WRITER_H_INCLUDED
|
||||