Browse Source
Merge remote-tracking branch 'upstream/master' into int-flags
remotes/1778439668340191200/nce_cpp
Merge remote-tracking branch 'upstream/master' into int-flags
remotes/1778439668340191200/nce_cpp
912 changed files with 90766 additions and 25145 deletions
-
4.ci/scripts/common/post-upload.sh
-
3.ci/scripts/common/pre-upload.sh
-
44.ci/scripts/linux/docker.sh
-
5.ci/scripts/linux/upload.sh
-
2.ci/scripts/windows/docker.sh
-
4.ci/templates/build-msvc.yml
-
1.ci/yuzu-patreon-step2.yml
-
5.gitmodules
-
10.travis/linux-mingw/docker.sh
-
2.travis/linux/build.sh
-
2.travis/linux/docker.sh
-
3.travis/macos/build.sh
-
134CMakeLists.txt
-
10CMakeModules/CopyYuzuFFmpegDeps.cmake
-
9CMakeModules/CopyYuzuUnicornDeps.cmake
-
1README.md
-
4749dist/languages/de.ts
-
4757dist/languages/es.ts
-
4732dist/languages/fr.ts
-
4724dist/languages/it.ts
-
4752dist/languages/ja_JP.ts
-
4719dist/languages/nl.ts
-
4713dist/languages/pl.ts
-
4757dist/languages/pt_BR.ts
-
4725dist/languages/pt_PT.ts
-
4720dist/languages/ru_RU.ts
-
4747dist/languages/zh_CN.ts
-
14dist/qt_themes/default/style.qss
-
86dist/qt_themes/qdarkstyle/style.qss
-
95dist/qt_themes/qdarkstyle_midnight_blue/style.qss
-
32externals/CMakeLists.txt
-
2externals/cubeb
-
2externals/dynarmic
-
100externals/find-modules/FindFFmpeg.cmake
-
2externals/httplib/README.md
-
4880externals/httplib/httplib.h
-
2externals/inih/inih
-
2externals/libressl
-
8externals/lurlparser/CMakeLists.txt
-
265externals/lurlparser/LUrlParser.cpp
-
78externals/lurlparser/LUrlParser.h
-
19externals/lurlparser/README.md
-
18externals/microprofile/microprofile.h
-
1externals/unicorn
-
16src/CMakeLists.txt
-
18src/audio_core/CMakeLists.txt
-
9src/audio_core/algorithm/filter.cpp
-
4src/audio_core/algorithm/filter.h
-
7src/audio_core/algorithm/interpolate.cpp
-
4src/audio_core/audio_out.cpp
-
3src/audio_core/audio_out.h
-
131src/audio_core/audio_renderer.cpp
-
29src/audio_core/audio_renderer.h
-
6src/audio_core/behavior_info.cpp
-
30src/audio_core/behavior_info.h
-
2src/audio_core/buffer.h
-
5src/audio_core/codec.cpp
-
2src/audio_core/codec.h
-
47src/audio_core/command_generator.cpp
-
23src/audio_core/command_generator.h
-
3src/audio_core/common.h
-
26src/audio_core/cubeb_sink.cpp
-
68src/audio_core/effect_context.cpp
-
53src/audio_core/effect_context.h
-
37src/audio_core/info_updater.cpp
-
4src/audio_core/info_updater.h
-
13src/audio_core/memory_pool.cpp
-
11src/audio_core/memory_pool.h
-
4src/audio_core/mix_context.cpp
-
26src/audio_core/mix_context.h
-
20src/audio_core/sink_context.cpp
-
29src/audio_core/sink_context.h
-
28src/audio_core/splitter_context.cpp
-
20src/audio_core/splitter_context.h
-
31src/audio_core/stream.cpp
-
25src/audio_core/stream.h
-
16src/audio_core/voice_context.cpp
-
10src/audio_core/voice_context.h
-
34src/common/CMakeLists.txt
-
22src/common/bit_cast.h
-
99src/common/bit_set.h
-
4src/common/concepts.h
-
26src/common/div_ceil.h
-
194src/common/fiber.cpp
-
29src/common/fiber.h
-
31src/common/file_util.cpp
-
2src/common/file_util.h
-
10src/common/hex_util.h
-
17src/common/logging/backend.cpp
-
1src/common/logging/log.h
-
8src/common/math_util.h
-
11src/common/memory_hook.cpp
-
47src/common/memory_hook.h
-
15src/common/misc.cpp
-
345src/common/multi_level_queue.h
-
12src/common/page_table.cpp
-
100src/common/page_table.h
-
2src/common/scope_exit.h
-
8src/common/spin_lock.h
-
47src/common/stream.cpp
@ -1,14 +1,54 @@ |
|||
#!/bin/bash -ex |
|||
|
|||
# Exit on error, rather than continuing with the rest of the script. |
|||
set -e |
|||
|
|||
cd /yuzu |
|||
|
|||
ccache -s |
|||
|
|||
mkdir build || true && cd build |
|||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON |
|||
cmake .. -DDISPLAY_VERSION=$1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DCMAKE_INSTALL_PREFIX="/usr" |
|||
|
|||
ninja |
|||
make -j$(nproc) |
|||
|
|||
ccache -s |
|||
|
|||
ctest -VV -C Release |
|||
|
|||
make install DESTDIR=AppDir |
|||
rm -vf AppDir/usr/bin/yuzu-cmd AppDir/usr/bin/yuzu-tester |
|||
|
|||
# Download tools needed to build an AppImage |
|||
wget -nc https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage |
|||
wget -nc https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage |
|||
wget -nc https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage |
|||
wget -nc https://github.com/darealshinji/AppImageKit-checkrt/releases/download/continuous/AppRun-patched-x86_64 |
|||
wget -nc https://github.com/darealshinji/AppImageKit-checkrt/releases/download/continuous/exec-x86_64.so |
|||
# Set executable bit |
|||
chmod 755 \ |
|||
appimagetool-x86_64.AppImage \ |
|||
AppRun-patched-x86_64 \ |
|||
exec-x86_64.so \ |
|||
linuxdeploy-x86_64.AppImage \ |
|||
linuxdeploy-plugin-qt-x86_64.AppImage |
|||
|
|||
# Workaround for https://github.com/AppImage/AppImageKit/issues/828 |
|||
export APPIMAGE_EXTRACT_AND_RUN=1 |
|||
|
|||
mkdir -p AppDir/usr/optional |
|||
mkdir -p AppDir/usr/optional/libstdc++ |
|||
mkdir -p AppDir/usr/optional/libgcc_s |
|||
|
|||
# Deploy yuzu's needed dependencies |
|||
./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin qt |
|||
|
|||
# Workaround for building yuzu with GCC 10 but also trying to distribute it to Ubuntu 18.04 et al. |
|||
# See https://github.com/darealshinji/AppImageKit-checkrt |
|||
cp exec-x86_64.so AppDir/usr/optional/exec.so |
|||
cp AppRun-patched-x86_64 AppDir/AppRun |
|||
cp --dereference /usr/lib/x86_64-linux-gnu/libstdc++.so.6 AppDir/usr/optional/libstdc++/libstdc++.so.6 |
|||
cp --dereference /lib/x86_64-linux-gnu/libgcc_s.so.1 AppDir/usr/optional/libgcc_s/libgcc_s.so.1 |
|||
|
|||
# Build the AppImage |
|||
./appimagetool-x86_64.AppImage AppDir |
|||
@ -1,4 +1,4 @@ |
|||
#!/bin/bash -ex |
|||
|
|||
mkdir -p "$HOME/.ccache" |
|||
docker run -e ENABLE_COMPATIBILITY_REPORTING --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/root/.ccache yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.travis/linux/docker.sh |
|||
docker run -e ENABLE_COMPATIBILITY_REPORTING --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/home/yuzu/.ccache yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.travis/linux/docker.sh |
|||
@ -0,0 +1,10 @@ |
|||
function(copy_yuzu_FFmpeg_deps target_dir) |
|||
include(WindowsCopyFiles) |
|||
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/") |
|||
windows_copy_files(${target_dir} ${FFMPEG_DLL_DIR} ${DLL_DEST} |
|||
avcodec-58.dll |
|||
avutil-56.dll |
|||
swresample-3.dll |
|||
swscale-5.dll |
|||
) |
|||
endfunction(copy_yuzu_FFmpeg_deps) |
|||
@ -1,9 +0,0 @@ |
|||
function(copy_yuzu_unicorn_deps target_dir) |
|||
include(WindowsCopyFiles) |
|||
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/") |
|||
windows_copy_files(${target_dir} ${UNICORN_DLL_DIR} ${DLL_DEST} |
|||
libgcc_s_seh-1.dll |
|||
libwinpthread-1.dll |
|||
unicorn.dll |
|||
) |
|||
endfunction(copy_yuzu_unicorn_deps) |
|||
4749
dist/languages/de.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4757
dist/languages/es.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4732
dist/languages/fr.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4724
dist/languages/it.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4752
dist/languages/ja_JP.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4719
dist/languages/nl.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4713
dist/languages/pl.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4757
dist/languages/pt_BR.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4725
dist/languages/pt_PT.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4720
dist/languages/ru_RU.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
4747
dist/languages/zh_CN.ts
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1 +1 @@ |
|||
Subproject commit 616d773441b5355800ce64197a699e6cd6b36172 |
|||
Subproject commit 1d66483ad2b93f0e00e175f9480c771af90003a7 |
|||
@ -1 +1 @@ |
|||
Subproject commit 0e1112b7df77ae55a62a51622940d5c8f9e8c84c |
|||
Subproject commit 3806284cbefc4115436dcdc687776a45ec313093 |
|||
@ -0,0 +1,100 @@ |
|||
# - Try to find ffmpeg libraries (libavcodec, libavformat and libavutil) |
|||
# Once done this will define |
|||
# |
|||
# FFMPEG_FOUND - system has ffmpeg or libav |
|||
# FFMPEG_INCLUDE_DIR - the ffmpeg include directory |
|||
# FFMPEG_LIBRARIES - Link these to use ffmpeg |
|||
# FFMPEG_LIBAVCODEC |
|||
# FFMPEG_LIBAVFORMAT |
|||
# FFMPEG_LIBAVUTIL |
|||
# |
|||
# Copyright (c) 2008 Andreas Schneider <mail@cynapses.org> |
|||
# Modified for other libraries by Lasse Kärkkäinen <tronic> |
|||
# Modified for Hedgewars by Stepik777 |
|||
# Modified for FFmpeg-example Tuukka Pasanen 2018 |
|||
# Modified for yuzu toastUnlimted 2020 |
|||
# |
|||
# Redistribution and use is allowed according to the terms of the New |
|||
# BSD license. |
|||
# |
|||
|
|||
include(FindPackageHandleStandardArgs) |
|||
|
|||
find_package_handle_standard_args(FFMPEG |
|||
FOUND_VAR FFMPEG_FOUND |
|||
REQUIRED_VARS |
|||
FFMPEG_LIBRARY |
|||
FFMPEG_INCLUDE_DIR |
|||
VERSION_VAR FFMPEG_VERSION |
|||
) |
|||
|
|||
if(FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR) |
|||
# in cache already |
|||
set(FFMPEG_FOUND TRUE) |
|||
else() |
|||
# use pkg-config to get the directories and then use these values |
|||
# in the FIND_PATH() and FIND_LIBRARY() calls |
|||
find_package(PkgConfig) |
|||
if(PKG_CONFIG_FOUND) |
|||
pkg_check_modules(_FFMPEG_AVCODEC libavcodec) |
|||
pkg_check_modules(_FFMPEG_AVUTIL libavutil) |
|||
pkg_check_modules(_FFMPEG_SWSCALE libswscale) |
|||
endif() |
|||
|
|||
find_path(FFMPEG_AVCODEC_INCLUDE_DIR |
|||
NAMES libavcodec/avcodec.h |
|||
PATHS ${_FFMPEG_AVCODEC_INCLUDE_DIRS} |
|||
/usr/include |
|||
/usr/local/include |
|||
/opt/local/include |
|||
/sw/include |
|||
PATH_SUFFIXES ffmpeg libav) |
|||
|
|||
find_library(FFMPEG_LIBAVCODEC |
|||
NAMES avcodec |
|||
PATHS ${_FFMPEG_AVCODEC_LIBRARY_DIRS} |
|||
/usr/lib |
|||
/usr/local/lib |
|||
/opt/local/lib |
|||
/sw/lib) |
|||
|
|||
find_library(FFMPEG_LIBAVUTIL |
|||
NAMES avutil |
|||
PATHS ${_FFMPEG_AVUTIL_LIBRARY_DIRS} |
|||
/usr/lib |
|||
/usr/local/lib |
|||
/opt/local/lib |
|||
/sw/lib) |
|||
|
|||
find_library(FFMPEG_LIBSWSCALE |
|||
NAMES swscale |
|||
PATHS ${_FFMPEG_SWSCALE_LIBRARY_DIRS} |
|||
/usr/lib |
|||
/usr/local/lib |
|||
/opt/local/lib |
|||
/sw/lib) |
|||
|
|||
if(FFMPEG_LIBAVCODEC AND FFMPEG_LIBAVUTIL AND FFMPEG_LIBSWSCALE) |
|||
set(FFMPEG_FOUND TRUE) |
|||
endif() |
|||
|
|||
if(FFMPEG_FOUND) |
|||
set(FFMPEG_INCLUDE_DIR ${FFMPEG_AVCODEC_INCLUDE_DIR}) |
|||
set(FFMPEG_LIBRARIES |
|||
${FFMPEG_LIBAVCODEC} |
|||
${FFMPEG_LIBAVUTIL} |
|||
${FFMPEG_LIBSWSCALE}) |
|||
endif() |
|||
|
|||
if(FFMPEG_FOUND) |
|||
if(NOT FFMPEG_FIND_QUIETLY) |
|||
message(STATUS |
|||
"Found FFMPEG or Libav: ${FFMPEG_LIBRARIES}, ${FFMPEG_INCLUDE_DIR}") |
|||
endif() |
|||
else() |
|||
if(FFMPEG_FIND_REQUIRED) |
|||
message(FATAL_ERROR |
|||
"Could not find libavcodec or libavutil or libswscale") |
|||
endif() |
|||
endif() |
|||
endif() |
|||
4880
externals/httplib/httplib.h
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1 +1 @@ |
|||
Subproject commit 603729dec89aaca42d7bd08f08bc333165b7d5d1 |
|||
Subproject commit 1e80a47dffbda813604f0913e2ad68c7054c14e4 |
|||
@ -1 +1 @@ |
|||
Subproject commit 7d01cb01cb1a926ecb4c9c98b107ef3c26f59dfb |
|||
Subproject commit 8289d0d07de6553bf4b900bf60e808ea3f7f59da |
|||
@ -1,8 +0,0 @@ |
|||
add_library(lurlparser |
|||
LUrlParser.cpp |
|||
LUrlParser.h |
|||
) |
|||
|
|||
create_target_directory_groups(lurlparser) |
|||
|
|||
target_include_directories(lurlparser INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) |
|||
@ -1,265 +0,0 @@ |
|||
/*
|
|||
* Lightweight URL & URI parser (RFC 1738, RFC 3986) |
|||
* https://github.com/corporateshark/LUrlParser
|
|||
* |
|||
* The MIT License (MIT) |
|||
* |
|||
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com) |
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to deal |
|||
* in the Software without restriction, including without limitation the rights |
|||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
* copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in all |
|||
* copies or substantial portions of the Software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
* SOFTWARE. |
|||
*/ |
|||
|
|||
#include "LUrlParser.h"
|
|||
|
|||
#include <algorithm>
|
|||
#include <cstring>
|
|||
#include <stdlib.h>
|
|||
|
|||
// check if the scheme name is valid
|
|||
static bool IsSchemeValid( const std::string& SchemeName ) |
|||
{ |
|||
for ( auto c : SchemeName ) |
|||
{ |
|||
if ( !isalpha( c ) && c != '+' && c != '-' && c != '.' ) return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
bool LUrlParser::clParseURL::GetPort( int* OutPort ) const |
|||
{ |
|||
if ( !IsValid() ) { return false; } |
|||
|
|||
int Port = atoi( m_Port.c_str() ); |
|||
|
|||
if ( Port <= 0 || Port > 65535 ) { return false; } |
|||
|
|||
if ( OutPort ) { *OutPort = Port; } |
|||
|
|||
return true; |
|||
} |
|||
|
|||
// based on RFC 1738 and RFC 3986
|
|||
LUrlParser::clParseURL LUrlParser::clParseURL::ParseURL( const std::string& URL ) |
|||
{ |
|||
LUrlParser::clParseURL Result; |
|||
|
|||
const char* CurrentString = URL.c_str(); |
|||
|
|||
/*
|
|||
* <scheme>:<scheme-specific-part> |
|||
* <scheme> := [a-z\+\-\.]+ |
|||
* For resiliency, programs interpreting URLs should treat upper case letters as equivalent to lower case in scheme names |
|||
*/ |
|||
|
|||
// try to read scheme
|
|||
{ |
|||
const char* LocalString = strchr( CurrentString, ':' ); |
|||
|
|||
if ( !LocalString ) |
|||
{ |
|||
return clParseURL( LUrlParserError_NoUrlCharacter ); |
|||
} |
|||
|
|||
// save the scheme name
|
|||
Result.m_Scheme = std::string( CurrentString, LocalString - CurrentString ); |
|||
|
|||
if ( !IsSchemeValid( Result.m_Scheme ) ) |
|||
{ |
|||
return clParseURL( LUrlParserError_InvalidSchemeName ); |
|||
} |
|||
|
|||
// scheme should be lowercase
|
|||
std::transform( Result.m_Scheme.begin(), Result.m_Scheme.end(), Result.m_Scheme.begin(), ::tolower ); |
|||
|
|||
// skip ':'
|
|||
CurrentString = LocalString+1; |
|||
} |
|||
|
|||
/*
|
|||
* //<user>:<password>@<host>:<port>/<url-path>
|
|||
* any ":", "@" and "/" must be normalized |
|||
*/ |
|||
|
|||
// skip "//"
|
|||
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash ); |
|||
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash ); |
|||
|
|||
// check if the user name and password are specified
|
|||
bool bHasUserName = false; |
|||
|
|||
const char* LocalString = CurrentString; |
|||
|
|||
while ( *LocalString ) |
|||
{ |
|||
if ( *LocalString == '@' ) |
|||
{ |
|||
// user name and password are specified
|
|||
bHasUserName = true; |
|||
break; |
|||
} |
|||
else if ( *LocalString == '/' ) |
|||
{ |
|||
// end of <host>:<port> specification
|
|||
bHasUserName = false; |
|||
break; |
|||
} |
|||
|
|||
LocalString++; |
|||
} |
|||
|
|||
// user name and password
|
|||
LocalString = CurrentString; |
|||
|
|||
if ( bHasUserName ) |
|||
{ |
|||
// read user name
|
|||
while ( *LocalString && *LocalString != ':' && *LocalString != '@' ) LocalString++; |
|||
|
|||
Result.m_UserName = std::string( CurrentString, LocalString - CurrentString ); |
|||
|
|||
// proceed with the current pointer
|
|||
CurrentString = LocalString; |
|||
|
|||
if ( *CurrentString == ':' ) |
|||
{ |
|||
// skip ':'
|
|||
CurrentString++; |
|||
|
|||
// read password
|
|||
LocalString = CurrentString; |
|||
|
|||
while ( *LocalString && *LocalString != '@' ) LocalString++; |
|||
|
|||
Result.m_Password = std::string( CurrentString, LocalString - CurrentString ); |
|||
|
|||
CurrentString = LocalString; |
|||
} |
|||
|
|||
// skip '@'
|
|||
if ( *CurrentString != '@' ) |
|||
{ |
|||
return clParseURL( LUrlParserError_NoAtSign ); |
|||
} |
|||
|
|||
CurrentString++; |
|||
} |
|||
|
|||
bool bHasBracket = ( *CurrentString == '[' ); |
|||
|
|||
// go ahead, read the host name
|
|||
LocalString = CurrentString; |
|||
|
|||
while ( *LocalString ) |
|||
{ |
|||
if ( bHasBracket && *LocalString == ']' ) |
|||
{ |
|||
// end of IPv6 address
|
|||
LocalString++; |
|||
break; |
|||
} |
|||
else if ( !bHasBracket && ( *LocalString == ':' || *LocalString == '/' ) ) |
|||
{ |
|||
// port number is specified
|
|||
break; |
|||
} |
|||
|
|||
LocalString++; |
|||
} |
|||
|
|||
Result.m_Host = std::string( CurrentString, LocalString - CurrentString ); |
|||
|
|||
CurrentString = LocalString; |
|||
|
|||
// is port number specified?
|
|||
if ( *CurrentString == ':' ) |
|||
{ |
|||
CurrentString++; |
|||
|
|||
// read port number
|
|||
LocalString = CurrentString; |
|||
|
|||
while ( *LocalString && *LocalString != '/' ) LocalString++; |
|||
|
|||
Result.m_Port = std::string( CurrentString, LocalString - CurrentString ); |
|||
|
|||
CurrentString = LocalString; |
|||
} |
|||
|
|||
// end of string
|
|||
if ( !*CurrentString ) |
|||
{ |
|||
Result.m_ErrorCode = LUrlParserError_Ok; |
|||
|
|||
return Result; |
|||
} |
|||
|
|||
// skip '/'
|
|||
if ( *CurrentString != '/' ) |
|||
{ |
|||
return clParseURL( LUrlParserError_NoSlash ); |
|||
} |
|||
|
|||
CurrentString++; |
|||
|
|||
// parse the path
|
|||
LocalString = CurrentString; |
|||
|
|||
while ( *LocalString && *LocalString != '#' && *LocalString != '?' ) LocalString++; |
|||
|
|||
Result.m_Path = std::string( CurrentString, LocalString - CurrentString ); |
|||
|
|||
CurrentString = LocalString; |
|||
|
|||
// check for query
|
|||
if ( *CurrentString == '?' ) |
|||
{ |
|||
// skip '?'
|
|||
CurrentString++; |
|||
|
|||
// read query
|
|||
LocalString = CurrentString; |
|||
|
|||
while ( *LocalString && *LocalString != '#' ) LocalString++; |
|||
|
|||
Result.m_Query = std::string( CurrentString, LocalString - CurrentString ); |
|||
|
|||
CurrentString = LocalString; |
|||
} |
|||
|
|||
// check for fragment
|
|||
if ( *CurrentString == '#' ) |
|||
{ |
|||
// skip '#'
|
|||
CurrentString++; |
|||
|
|||
// read fragment
|
|||
LocalString = CurrentString; |
|||
|
|||
while ( *LocalString ) LocalString++; |
|||
|
|||
Result.m_Fragment = std::string( CurrentString, LocalString - CurrentString ); |
|||
|
|||
CurrentString = LocalString; |
|||
} |
|||
|
|||
Result.m_ErrorCode = LUrlParserError_Ok; |
|||
|
|||
return Result; |
|||
} |
|||
@ -1,78 +0,0 @@ |
|||
/* |
|||
* Lightweight URL & URI parser (RFC 1738, RFC 3986) |
|||
* https://github.com/corporateshark/LUrlParser |
|||
* |
|||
* The MIT License (MIT) |
|||
* |
|||
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com) |
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to deal |
|||
* in the Software without restriction, including without limitation the rights |
|||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
* copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in all |
|||
* copies or substantial portions of the Software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
* SOFTWARE. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <string> |
|||
|
|||
namespace LUrlParser |
|||
{ |
|||
enum LUrlParserError |
|||
{ |
|||
LUrlParserError_Ok = 0, |
|||
LUrlParserError_Uninitialized = 1, |
|||
LUrlParserError_NoUrlCharacter = 2, |
|||
LUrlParserError_InvalidSchemeName = 3, |
|||
LUrlParserError_NoDoubleSlash = 4, |
|||
LUrlParserError_NoAtSign = 5, |
|||
LUrlParserError_UnexpectedEndOfLine = 6, |
|||
LUrlParserError_NoSlash = 7, |
|||
}; |
|||
|
|||
class clParseURL |
|||
{ |
|||
public: |
|||
LUrlParserError m_ErrorCode; |
|||
std::string m_Scheme; |
|||
std::string m_Host; |
|||
std::string m_Port; |
|||
std::string m_Path; |
|||
std::string m_Query; |
|||
std::string m_Fragment; |
|||
std::string m_UserName; |
|||
std::string m_Password; |
|||
|
|||
clParseURL() |
|||
: m_ErrorCode( LUrlParserError_Uninitialized ) |
|||
{} |
|||
|
|||
/// return 'true' if the parsing was successful |
|||
bool IsValid() const { return m_ErrorCode == LUrlParserError_Ok; } |
|||
|
|||
/// helper to convert the port number to int, return 'true' if the port is valid (within the 0..65535 range) |
|||
bool GetPort( int* OutPort ) const; |
|||
|
|||
/// parse the URL |
|||
static clParseURL ParseURL( const std::string& URL ); |
|||
|
|||
private: |
|||
explicit clParseURL( LUrlParserError ErrorCode ) |
|||
: m_ErrorCode( ErrorCode ) |
|||
{} |
|||
}; |
|||
|
|||
} // namespace LUrlParser |
|||
@ -1,19 +0,0 @@ |
|||
From https://github.com/corporateshark/LUrlParser/commit/455d5e2d27e3946f11ad0328fee9ee2628e6a8e2 |
|||
|
|||
MIT License |
|||
|
|||
=== |
|||
|
|||
Lightweight URL & URI parser (RFC 1738, RFC 3986) |
|||
|
|||
(C) Sergey Kosarevsky, 2015 |
|||
|
|||
@corporateshark sk@linderdaum.com |
|||
|
|||
http://www.linderdaum.com |
|||
|
|||
http://blog.linderdaum.com |
|||
|
|||
============================= |
|||
|
|||
A tiny and lightweight URL & URI parser (RFC 1738, RFC 3986) written in C++. |
|||
@ -0,0 +1,22 @@ |
|||
// Copyright 2020 yuzu emulator team |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <cstring> |
|||
#include <type_traits> |
|||
|
|||
namespace Common { |
|||
|
|||
template <typename To, typename From> |
|||
[[nodiscard]] std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> && |
|||
std::is_trivially_copyable_v<To>, |
|||
To> |
|||
BitCast(const From& src) noexcept { |
|||
To dst; |
|||
std::memcpy(&dst, &src, sizeof(To)); |
|||
return dst; |
|||
} |
|||
|
|||
} // namespace Common |
|||
@ -0,0 +1,99 @@ |
|||
/* |
|||
* Copyright (c) 2018-2020 Atmosphère-NX |
|||
* |
|||
* This program is free software; you can redistribute it and/or modify it |
|||
* under the terms and conditions of the GNU General Public License, |
|||
* version 2, as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope it will be useful, but WITHOUT |
|||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|||
* more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <bit> |
|||
|
|||
#include "common/alignment.h" |
|||
#include "common/bit_util.h" |
|||
#include "common/common_types.h" |
|||
|
|||
namespace Common { |
|||
|
|||
namespace impl { |
|||
|
|||
template <typename Storage, size_t N> |
|||
class BitSet { |
|||
|
|||
public: |
|||
constexpr BitSet() = default; |
|||
|
|||
constexpr void SetBit(size_t i) { |
|||
this->words[i / FlagsPerWord] |= GetBitMask(i % FlagsPerWord); |
|||
} |
|||
|
|||
constexpr void ClearBit(size_t i) { |
|||
this->words[i / FlagsPerWord] &= ~GetBitMask(i % FlagsPerWord); |
|||
} |
|||
|
|||
constexpr size_t CountLeadingZero() const { |
|||
for (size_t i = 0; i < NumWords; i++) { |
|||
if (this->words[i]) { |
|||
return FlagsPerWord * i + CountLeadingZeroImpl(this->words[i]); |
|||
} |
|||
} |
|||
return FlagsPerWord * NumWords; |
|||
} |
|||
|
|||
constexpr size_t GetNextSet(size_t n) const { |
|||
for (size_t i = (n + 1) / FlagsPerWord; i < NumWords; i++) { |
|||
Storage word = this->words[i]; |
|||
if (!IsAligned(n + 1, FlagsPerWord)) { |
|||
word &= GetBitMask(n % FlagsPerWord) - 1; |
|||
} |
|||
if (word) { |
|||
return FlagsPerWord * i + CountLeadingZeroImpl(word); |
|||
} |
|||
} |
|||
return FlagsPerWord * NumWords; |
|||
} |
|||
|
|||
private: |
|||
static_assert(std::is_unsigned_v<Storage>); |
|||
static_assert(sizeof(Storage) <= sizeof(u64)); |
|||
|
|||
static constexpr size_t FlagsPerWord = BitSize<Storage>(); |
|||
static constexpr size_t NumWords = AlignUp(N, FlagsPerWord) / FlagsPerWord; |
|||
|
|||
static constexpr auto CountLeadingZeroImpl(Storage word) { |
|||
return std::countl_zero(static_cast<unsigned long long>(word)) - |
|||
(BitSize<unsigned long long>() - FlagsPerWord); |
|||
} |
|||
|
|||
static constexpr Storage GetBitMask(size_t bit) { |
|||
return Storage(1) << (FlagsPerWord - 1 - bit); |
|||
} |
|||
|
|||
std::array<Storage, NumWords> words{}; |
|||
}; |
|||
|
|||
} // namespace impl |
|||
|
|||
template <size_t N> |
|||
using BitSet8 = impl::BitSet<u8, N>; |
|||
|
|||
template <size_t N> |
|||
using BitSet16 = impl::BitSet<u16, N>; |
|||
|
|||
template <size_t N> |
|||
using BitSet32 = impl::BitSet<u32, N>; |
|||
|
|||
template <size_t N> |
|||
using BitSet64 = impl::BitSet<u64, N>; |
|||
|
|||
} // namespace Common |
|||
@ -0,0 +1,26 @@ |
|||
// Copyright 2020 yuzu emulator team |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <cstddef> |
|||
#include <type_traits> |
|||
|
|||
namespace Common { |
|||
|
|||
/// Ceiled integer division. |
|||
template <typename N, typename D> |
|||
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeil(N number, |
|||
D divisor) { |
|||
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor); |
|||
} |
|||
|
|||
/// Ceiled integer division with logarithmic divisor in base 2 |
|||
template <typename N, typename D> |
|||
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeilLog2( |
|||
N value, D alignment_log2) { |
|||
return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2); |
|||
} |
|||
|
|||
} // namespace Common |
|||
@ -1,11 +0,0 @@ |
|||
// Copyright 2018 Citra Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include "common/memory_hook.h"
|
|||
|
|||
namespace Common { |
|||
|
|||
MemoryHook::~MemoryHook() = default; |
|||
|
|||
} // namespace Common
|
|||
@ -1,47 +0,0 @@ |
|||
// Copyright 2016 Citra Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
#include <optional> |
|||
|
|||
#include "common/common_types.h" |
|||
|
|||
namespace Common { |
|||
|
|||
/** |
|||
* Memory hooks have two purposes: |
|||
* 1. To allow reads and writes to a region of memory to be intercepted. This is used to implement |
|||
* texture forwarding and memory breakpoints for debugging. |
|||
* 2. To allow for the implementation of MMIO devices. |
|||
* |
|||
* A hook may be mapped to multiple regions of memory. |
|||
* |
|||
* If a std::nullopt or false is returned from a function, the read/write request is passed through |
|||
* to the underlying memory region. |
|||
*/ |
|||
class MemoryHook { |
|||
public: |
|||
virtual ~MemoryHook(); |
|||
|
|||
virtual std::optional<bool> IsValidAddress(VAddr addr) = 0; |
|||
|
|||
virtual std::optional<u8> Read8(VAddr addr) = 0; |
|||
virtual std::optional<u16> Read16(VAddr addr) = 0; |
|||
virtual std::optional<u32> Read32(VAddr addr) = 0; |
|||
virtual std::optional<u64> Read64(VAddr addr) = 0; |
|||
|
|||
virtual bool ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) = 0; |
|||
|
|||
virtual bool Write8(VAddr addr, u8 data) = 0; |
|||
virtual bool Write16(VAddr addr, u16 data) = 0; |
|||
virtual bool Write32(VAddr addr, u32 data) = 0; |
|||
virtual bool Write64(VAddr addr, u64 data) = 0; |
|||
|
|||
virtual bool WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size) = 0; |
|||
}; |
|||
|
|||
using MemoryHookPointer = std::shared_ptr<MemoryHook>; |
|||
} // namespace Common |
|||
@ -1,345 +0,0 @@ |
|||
// Copyright 2019 TuxSH |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <iterator> |
|||
#include <list> |
|||
#include <utility> |
|||
|
|||
#include "common/bit_util.h" |
|||
#include "common/common_types.h" |
|||
|
|||
namespace Common { |
|||
|
|||
/** |
|||
* A MultiLevelQueue is a type of priority queue which has the following characteristics: |
|||
* - iteratable through each of its elements. |
|||
* - back can be obtained. |
|||
* - O(1) add, lookup (both front and back) |
|||
* - discrete priorities and a max of 64 priorities (limited domain) |
|||
* This type of priority queue is normaly used for managing threads within an scheduler |
|||
*/ |
|||
template <typename T, std::size_t Depth> |
|||
class MultiLevelQueue { |
|||
public: |
|||
using value_type = T; |
|||
using reference = value_type&; |
|||
using const_reference = const value_type&; |
|||
using pointer = value_type*; |
|||
using const_pointer = const value_type*; |
|||
|
|||
using difference_type = typename std::pointer_traits<pointer>::difference_type; |
|||
using size_type = std::size_t; |
|||
|
|||
template <bool is_constant> |
|||
class iterator_impl { |
|||
public: |
|||
using iterator_category = std::bidirectional_iterator_tag; |
|||
using value_type = T; |
|||
using pointer = std::conditional_t<is_constant, T*, const T*>; |
|||
using reference = std::conditional_t<is_constant, const T&, T&>; |
|||
using difference_type = typename std::pointer_traits<pointer>::difference_type; |
|||
|
|||
friend bool operator==(const iterator_impl& lhs, const iterator_impl& rhs) { |
|||
if (lhs.IsEnd() && rhs.IsEnd()) |
|||
return true; |
|||
return std::tie(lhs.current_priority, lhs.it) == std::tie(rhs.current_priority, rhs.it); |
|||
} |
|||
|
|||
friend bool operator!=(const iterator_impl& lhs, const iterator_impl& rhs) { |
|||
return !operator==(lhs, rhs); |
|||
} |
|||
|
|||
reference operator*() const { |
|||
return *it; |
|||
} |
|||
|
|||
pointer operator->() const { |
|||
return it.operator->(); |
|||
} |
|||
|
|||
iterator_impl& operator++() { |
|||
if (IsEnd()) { |
|||
return *this; |
|||
} |
|||
|
|||
++it; |
|||
|
|||
if (it == GetEndItForPrio()) { |
|||
u64 prios = mlq.used_priorities; |
|||
prios &= ~((1ULL << (current_priority + 1)) - 1); |
|||
if (prios == 0) { |
|||
current_priority = static_cast<u32>(mlq.depth()); |
|||
} else { |
|||
current_priority = CountTrailingZeroes64(prios); |
|||
it = GetBeginItForPrio(); |
|||
} |
|||
} |
|||
return *this; |
|||
} |
|||
|
|||
iterator_impl& operator--() { |
|||
if (IsEnd()) { |
|||
if (mlq.used_priorities != 0) { |
|||
current_priority = 63 - CountLeadingZeroes64(mlq.used_priorities); |
|||
it = GetEndItForPrio(); |
|||
--it; |
|||
} |
|||
} else if (it == GetBeginItForPrio()) { |
|||
u64 prios = mlq.used_priorities; |
|||
prios &= (1ULL << current_priority) - 1; |
|||
if (prios != 0) { |
|||
current_priority = CountTrailingZeroes64(prios); |
|||
it = GetEndItForPrio(); |
|||
--it; |
|||
} |
|||
} else { |
|||
--it; |
|||
} |
|||
return *this; |
|||
} |
|||
|
|||
iterator_impl operator++(int) { |
|||
const iterator_impl v{*this}; |
|||
++(*this); |
|||
return v; |
|||
} |
|||
|
|||
iterator_impl operator--(int) { |
|||
const iterator_impl v{*this}; |
|||
--(*this); |
|||
return v; |
|||
} |
|||
|
|||
// allow implicit const->non-const |
|||
iterator_impl(const iterator_impl<false>& other) |
|||
: mlq(other.mlq), it(other.it), current_priority(other.current_priority) {} |
|||
|
|||
iterator_impl(const iterator_impl<true>& other) |
|||
: mlq(other.mlq), it(other.it), current_priority(other.current_priority) {} |
|||
|
|||
iterator_impl& operator=(const iterator_impl<false>& other) { |
|||
mlq = other.mlq; |
|||
it = other.it; |
|||
current_priority = other.current_priority; |
|||
return *this; |
|||
} |
|||
|
|||
friend class iterator_impl<true>; |
|||
iterator_impl() = default; |
|||
|
|||
private: |
|||
friend class MultiLevelQueue; |
|||
using container_ref = |
|||
std::conditional_t<is_constant, const MultiLevelQueue&, MultiLevelQueue&>; |
|||
using list_iterator = std::conditional_t<is_constant, typename std::list<T>::const_iterator, |
|||
typename std::list<T>::iterator>; |
|||
|
|||
explicit iterator_impl(container_ref mlq, list_iterator it, u32 current_priority) |
|||
: mlq(mlq), it(it), current_priority(current_priority) {} |
|||
explicit iterator_impl(container_ref mlq, u32 current_priority) |
|||
: mlq(mlq), it(), current_priority(current_priority) {} |
|||
|
|||
bool IsEnd() const { |
|||
return current_priority == mlq.depth(); |
|||
} |
|||
|
|||
list_iterator GetBeginItForPrio() const { |
|||
return mlq.levels[current_priority].begin(); |
|||
} |
|||
|
|||
list_iterator GetEndItForPrio() const { |
|||
return mlq.levels[current_priority].end(); |
|||
} |
|||
|
|||
container_ref mlq; |
|||
list_iterator it; |
|||
u32 current_priority; |
|||
}; |
|||
|
|||
using iterator = iterator_impl<false>; |
|||
using const_iterator = iterator_impl<true>; |
|||
|
|||
void add(const T& element, u32 priority, bool send_back = true) { |
|||
if (send_back) |
|||
levels[priority].push_back(element); |
|||
else |
|||
levels[priority].push_front(element); |
|||
used_priorities |= 1ULL << priority; |
|||
} |
|||
|
|||
void remove(const T& element, u32 priority) { |
|||
auto it = ListIterateTo(levels[priority], element); |
|||
if (it == levels[priority].end()) |
|||
return; |
|||
levels[priority].erase(it); |
|||
if (levels[priority].empty()) { |
|||
used_priorities &= ~(1ULL << priority); |
|||
} |
|||
} |
|||
|
|||
void adjust(const T& element, u32 old_priority, u32 new_priority, bool adjust_front = false) { |
|||
remove(element, old_priority); |
|||
add(element, new_priority, !adjust_front); |
|||
} |
|||
void adjust(const_iterator it, u32 old_priority, u32 new_priority, bool adjust_front = false) { |
|||
adjust(*it, old_priority, new_priority, adjust_front); |
|||
} |
|||
|
|||
void transfer_to_front(const T& element, u32 priority, MultiLevelQueue& other) { |
|||
ListSplice(other.levels[priority], other.levels[priority].begin(), levels[priority], |
|||
ListIterateTo(levels[priority], element)); |
|||
|
|||
other.used_priorities |= 1ULL << priority; |
|||
|
|||
if (levels[priority].empty()) { |
|||
used_priorities &= ~(1ULL << priority); |
|||
} |
|||
} |
|||
|
|||
void transfer_to_front(const_iterator it, u32 priority, MultiLevelQueue& other) { |
|||
transfer_to_front(*it, priority, other); |
|||
} |
|||
|
|||
void transfer_to_back(const T& element, u32 priority, MultiLevelQueue& other) { |
|||
ListSplice(other.levels[priority], other.levels[priority].end(), levels[priority], |
|||
ListIterateTo(levels[priority], element)); |
|||
|
|||
other.used_priorities |= 1ULL << priority; |
|||
|
|||
if (levels[priority].empty()) { |
|||
used_priorities &= ~(1ULL << priority); |
|||
} |
|||
} |
|||
|
|||
void transfer_to_back(const_iterator it, u32 priority, MultiLevelQueue& other) { |
|||
transfer_to_back(*it, priority, other); |
|||
} |
|||
|
|||
void yield(u32 priority, std::size_t n = 1) { |
|||
ListShiftForward(levels[priority], n); |
|||
} |
|||
|
|||
[[nodiscard]] std::size_t depth() const { |
|||
return Depth; |
|||
} |
|||
|
|||
[[nodiscard]] std::size_t size(u32 priority) const { |
|||
return levels[priority].size(); |
|||
} |
|||
|
|||
[[nodiscard]] std::size_t size() const { |
|||
u64 priorities = used_priorities; |
|||
std::size_t size = 0; |
|||
while (priorities != 0) { |
|||
const u64 current_priority = CountTrailingZeroes64(priorities); |
|||
size += levels[current_priority].size(); |
|||
priorities &= ~(1ULL << current_priority); |
|||
} |
|||
return size; |
|||
} |
|||
|
|||
[[nodiscard]] bool empty() const { |
|||
return used_priorities == 0; |
|||
} |
|||
|
|||
[[nodiscard]] bool empty(u32 priority) const { |
|||
return (used_priorities & (1ULL << priority)) == 0; |
|||
} |
|||
|
|||
[[nodiscard]] u32 highest_priority_set(u32 max_priority = 0) const { |
|||
const u64 priorities = |
|||
max_priority == 0 ? used_priorities : (used_priorities & ~((1ULL << max_priority) - 1)); |
|||
return priorities == 0 ? Depth : static_cast<u32>(CountTrailingZeroes64(priorities)); |
|||
} |
|||
|
|||
[[nodiscard]] u32 lowest_priority_set(u32 min_priority = Depth - 1) const { |
|||
const u64 priorities = min_priority >= Depth - 1 |
|||
? used_priorities |
|||
: (used_priorities & ((1ULL << (min_priority + 1)) - 1)); |
|||
return priorities == 0 ? Depth : 63 - CountLeadingZeroes64(priorities); |
|||
} |
|||
|
|||
[[nodiscard]] const_iterator cbegin(u32 max_prio = 0) const { |
|||
const u32 priority = highest_priority_set(max_prio); |
|||
return priority == Depth ? cend() |
|||
: const_iterator{*this, levels[priority].cbegin(), priority}; |
|||
} |
|||
[[nodiscard]] const_iterator begin(u32 max_prio = 0) const { |
|||
return cbegin(max_prio); |
|||
} |
|||
[[nodiscard]] iterator begin(u32 max_prio = 0) { |
|||
const u32 priority = highest_priority_set(max_prio); |
|||
return priority == Depth ? end() : iterator{*this, levels[priority].begin(), priority}; |
|||
} |
|||
|
|||
[[nodiscard]] const_iterator cend(u32 min_prio = Depth - 1) const { |
|||
return min_prio == Depth - 1 ? const_iterator{*this, Depth} : cbegin(min_prio + 1); |
|||
} |
|||
[[nodiscard]] const_iterator end(u32 min_prio = Depth - 1) const { |
|||
return cend(min_prio); |
|||
} |
|||
[[nodiscard]] iterator end(u32 min_prio = Depth - 1) { |
|||
return min_prio == Depth - 1 ? iterator{*this, Depth} : begin(min_prio + 1); |
|||
} |
|||
|
|||
[[nodiscard]] T& front(u32 max_priority = 0) { |
|||
const u32 priority = highest_priority_set(max_priority); |
|||
return levels[priority == Depth ? 0 : priority].front(); |
|||
} |
|||
[[nodiscard]] const T& front(u32 max_priority = 0) const { |
|||
const u32 priority = highest_priority_set(max_priority); |
|||
return levels[priority == Depth ? 0 : priority].front(); |
|||
} |
|||
|
|||
[[nodiscard]] T& back(u32 min_priority = Depth - 1) { |
|||
const u32 priority = lowest_priority_set(min_priority); // intended |
|||
return levels[priority == Depth ? 63 : priority].back(); |
|||
} |
|||
[[nodiscard]] const T& back(u32 min_priority = Depth - 1) const { |
|||
const u32 priority = lowest_priority_set(min_priority); // intended |
|||
return levels[priority == Depth ? 63 : priority].back(); |
|||
} |
|||
|
|||
void clear() { |
|||
used_priorities = 0; |
|||
for (std::size_t i = 0; i < Depth; i++) { |
|||
levels[i].clear(); |
|||
} |
|||
} |
|||
|
|||
private: |
|||
using const_list_iterator = typename std::list<T>::const_iterator; |
|||
|
|||
static void ListShiftForward(std::list<T>& list, const std::size_t shift = 1) { |
|||
if (shift >= list.size()) { |
|||
return; |
|||
} |
|||
|
|||
const auto begin_range = list.begin(); |
|||
const auto end_range = std::next(begin_range, shift); |
|||
list.splice(list.end(), list, begin_range, end_range); |
|||
} |
|||
|
|||
static void ListSplice(std::list<T>& in_list, const_list_iterator position, |
|||
std::list<T>& out_list, const_list_iterator element) { |
|||
in_list.splice(position, out_list, element); |
|||
} |
|||
|
|||
[[nodiscard]] static const_list_iterator ListIterateTo(const std::list<T>& list, |
|||
const T& element) { |
|||
auto it = list.cbegin(); |
|||
while (it != list.cend() && *it != element) { |
|||
++it; |
|||
} |
|||
return it; |
|||
} |
|||
|
|||
std::array<std::list<T>, Depth> levels; |
|||
u64 used_priorities = 0; |
|||
}; |
|||
|
|||
} // namespace Common |
|||
@ -0,0 +1,47 @@ |
|||
// Copyright 2020 yuzu Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <stdexcept>
|
|||
#include "common/common_types.h"
|
|||
#include "common/stream.h"
|
|||
|
|||
namespace Common { |
|||
|
|||
Stream::Stream() = default; |
|||
Stream::~Stream() = default; |
|||
|
|||
void Stream::Seek(s32 offset, SeekOrigin origin) { |
|||
if (origin == SeekOrigin::SetOrigin) { |
|||
if (offset < 0) { |
|||
position = 0; |
|||
} else if (position >= buffer.size()) { |
|||
position = buffer.size(); |
|||
} else { |
|||
position = offset; |
|||
} |
|||
} else if (origin == SeekOrigin::FromCurrentPos) { |
|||
Seek(static_cast<s32>(position) + offset, SeekOrigin::SetOrigin); |
|||
} else if (origin == SeekOrigin::FromEnd) { |
|||
Seek(static_cast<s32>(buffer.size()) - offset, SeekOrigin::SetOrigin); |
|||
} |
|||
} |
|||
|
|||
u8 Stream::ReadByte() { |
|||
if (position < buffer.size()) { |
|||
return buffer[position++]; |
|||
} else { |
|||
throw std::out_of_range("Attempting to read a byte not within the buffer range"); |
|||
} |
|||
} |
|||
|
|||
void Stream::WriteByte(u8 byte) { |
|||
if (position == buffer.size()) { |
|||
buffer.push_back(byte); |
|||
position++; |
|||
} else { |
|||
buffer.insert(buffer.begin() + position, byte); |
|||
} |
|||
} |
|||
|
|||
} // namespace Common
|
|||
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue