Skip to content

Commit

Permalink
Add usage of canary NDK for builds
Browse files Browse the repository at this point in the history
  • Loading branch information
sc2ad committed Oct 16, 2023
1 parent 827b819 commit 1f027e6
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 85 deletions.
35 changes: 35 additions & 0 deletions .github/actions/canary-ndk/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: "Setup canary ndk"
description: "Sets up canary ndk"
outputs:
ndk-path:
value: ${{ steps.path.outputs.path }}
description: "Output path of the ndk"
cache-hit:
value: ${{ steps.cache.outputs.cache-hit }}
description: "Whether a cache hit occurred for the ndk"
runs:
using: "composite"
steps:
- name: NDK cache
id: cache
uses: actions/cache@v3
with:
path: ${HOME}/android-ndk-r27-canary/
key: ${{ runner.os }}-ndk-r27-canary

- name: Download canary ndk
if: ${{ !steps.cache.outputs.cache-hit }}
env:
CANARY_URL: https://github.com/QuestPackageManager/ndk-canary-archive/releases/download/27.0.1/android-ndk-10883340-linux-x86_64.zip
run: wget ${CANARY_URL} -O ${HOME}/ndk.zip
shell: bash

- name: Unzip ndk
if: ${{ !steps.cache.outputs.cache-hit }}
run: 7z x "${HOME}/ndk.zip" -o"${HOME}/"
shell: bash

- name: Set output
id: path
shell: bash
run: echo "path=${HOME}/android-ndk-r27-canary" >> ${GITHUB_OUTPUT}
6 changes: 6 additions & 0 deletions .github/workflows/build-ndk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ jobs:
lfs: true

- uses: seanmiddleditch/gha-setup-ninja@v3

# Use canary NDK to avoid lesser known compile bugs
- name: Setup canary NDK
id: setup-ndk
uses: ./.github/actions/canary-ndk

- name: Create ndkpath.txt
run: |
echo "$ANDROID_NDK_LATEST_HOME" > ${GITHUB_WORKSPACE}/ndkpath.txt
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ jobs:

- uses: seanmiddleditch/gha-setup-ninja@v3

# Use canary NDK to avoid lesser known compile bugs
- name: Setup canary NDK
id: setup-ndk
uses: ./.github/actions/canary-ndk

- name: Create ndkpath.txt
run: |
echo "$ANDROID_NDK_LATEST_HOME" > ${GITHUB_WORKSPACE}/ndkpath.txt
Expand Down
183 changes: 98 additions & 85 deletions shared/utils/typedefs-string.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#pragma once

#include "utils-functions.h"
#include "il2cpp-type-check.hpp"
#include "il2cpp-utils-exceptions.hpp"
#include <string_view>
#include <string>
#include <stdexcept>
#include <locale>
#include <codecvt>
#include <span>
#include <stdexcept>
#include <string>
#include <string_view>
#include "il2cpp-type-check.hpp"
#include "il2cpp-utils-exceptions.hpp"
#include "utils-functions.h"


struct UseBeforeInitError : il2cpp_utils::exceptions::StackTraceException {
UseBeforeInitError(const char* v) : il2cpp_utils::exceptions::StackTraceException(v) {}
Expand All @@ -18,38 +18,38 @@ struct Il2CppString;

namespace il2cpp_utils {
namespace detail {
void convstr(char const* inp, char16_t* outp, int sz);
std::size_t convstr(char16_t const* inp, char* outp, int isz, int osz);

Il2CppString* alloc_str(std::string_view str);
Il2CppString* alloc_str(std::u16string_view str);

Il2CppString* strappend(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;
Il2CppString* strappend(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
Il2CppString* strappend(Il2CppString const* lhs, std::string_view const rhs) noexcept;
Il2CppString* strappend(std::string_view const lhs, Il2CppString const* rhs) noexcept;
Il2CppString* strappend(std::u16string_view const lhs, Il2CppString const* rhs) noexcept;

bool strcomp(Il2CppString const* lhs, std::string_view const rhs) noexcept;
bool strcomp(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
bool strcomp(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;

bool strless(Il2CppString const* lhs, std::string_view const rhs) noexcept;
bool strless(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
bool strless(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;
bool strstart(Il2CppString const* lhs, std::string_view const rhs) noexcept;
bool strstart(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
bool strstart(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;

bool strend(Il2CppString const* lhs, std::string_view const rhs) noexcept;
bool strend(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
bool strend(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;
}
}
void convstr(char const* inp, char16_t* outp, int sz);
std::size_t convstr(char16_t const* inp, char* outp, int isz, int osz);

Il2CppString* alloc_str(std::string_view str);
Il2CppString* alloc_str(std::u16string_view str);

Il2CppString* strappend(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;
Il2CppString* strappend(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
Il2CppString* strappend(Il2CppString const* lhs, std::string_view const rhs) noexcept;
Il2CppString* strappend(std::string_view const lhs, Il2CppString const* rhs) noexcept;
Il2CppString* strappend(std::u16string_view const lhs, Il2CppString const* rhs) noexcept;

bool strcomp(Il2CppString const* lhs, std::string_view const rhs) noexcept;
bool strcomp(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
bool strcomp(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;

bool strless(Il2CppString const* lhs, std::string_view const rhs) noexcept;
bool strless(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
bool strless(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;

bool strstart(Il2CppString const* lhs, std::string_view const rhs) noexcept;
bool strstart(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
bool strstart(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;

bool strend(Il2CppString const* lhs, std::string_view const rhs) noexcept;
bool strend(Il2CppString const* lhs, std::u16string_view const rhs) noexcept;
bool strend(Il2CppString const* lhs, Il2CppString const* rhs) noexcept;
} // namespace detail
} // namespace il2cpp_utils

// C# strings can only have 'int' max length.
template<int sz>
template <int sz>
struct ConstString {
// Manually allocated string, dtor destructs in place
ConstString(const char (&st)[sz]) {
Expand Down Expand Up @@ -112,17 +112,18 @@ struct ConstString {
return val;
}
operator std::u16string() {
return {chars, chars + length};
return { chars, chars + length };
}
operator std::wstring() {
return {chars, chars + length};
return { chars, chars + length };
}
constexpr operator std::u16string_view() {
return {chars, static_cast<std::size_t>(sz)};
return { chars, static_cast<std::size_t>(sz) };
}

friend struct StringW;
private:

private:
void* klass = nullptr;
void* monitor;
int length;
Expand All @@ -131,8 +132,8 @@ struct ConstString {

struct StringW {
// Dynamically allocated string
template<class T>
requires (!std::is_convertible_v<T, Il2CppString*> && (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T>))
template <class T>
requires(!std::is_convertible_v<T, Il2CppString*> && (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T>))
StringW(T str) noexcept : inst(il2cpp_utils::detail::alloc_str(str)) {}
constexpr StringW(void* ins) noexcept : inst(static_cast<Il2CppString*>(ins)) {}
constexpr StringW(Il2CppString* ins) noexcept : inst(ins) {}
Expand Down Expand Up @@ -160,61 +161,73 @@ struct StringW {
return inst;
}
constexpr operator bool() const noexcept {
return inst != nullptr;
return inst != nullptr;
}

constexpr bool operator ==(std::nullptr_t rhs) const noexcept {
constexpr bool operator==(std::nullptr_t rhs) const noexcept {
return inst == rhs;
}

template<typename T>
requires (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
StringW& operator +=(T const& rhs) noexcept {
if constexpr (std::is_same_v<T, StringW>) inst = il2cpp_utils::detail::strappend(inst, rhs.inst);
else inst = il2cpp_utils::detail::strappend(inst, rhs);
template <typename T>
requires(std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
StringW& operator+=(T const& rhs) noexcept {
if constexpr (std::is_same_v<T, StringW>)
inst = il2cpp_utils::detail::strappend(inst, rhs.inst);
else
inst = il2cpp_utils::detail::strappend(inst, rhs);
return *this;
}

template<typename T>
requires (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
StringW operator +(T const& rhs) const noexcept {
if constexpr (std::is_same_v<T, StringW>) return il2cpp_utils::detail::strappend(inst, rhs.inst);
else return il2cpp_utils::detail::strappend(inst, rhs);
template <typename T>
requires(std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
StringW operator+(T const& rhs) const noexcept {
if constexpr (std::is_same_v<T, StringW>)
return il2cpp_utils::detail::strappend(inst, rhs.inst);
else
return il2cpp_utils::detail::strappend(inst, rhs);
}

template<typename T>
requires (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
bool operator <(T const& rhs) const noexcept {
if constexpr (std::is_same_v<T, StringW>) return il2cpp_utils::detail::strless(inst, rhs.inst);
else return il2cpp_utils::detail::strless(inst, rhs);
template <typename T>
requires(std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
bool operator<(T const& rhs) const noexcept {
if constexpr (std::is_same_v<T, StringW>)
return il2cpp_utils::detail::strless(inst, rhs.inst);
else
return il2cpp_utils::detail::strless(inst, rhs);
}

template<int sz>
bool operator ==(ConstString<sz> const& rhs) const noexcept {
template <int sz>
bool operator==(ConstString<sz> const& rhs) const noexcept {
return il2cpp_utils::detail::strcomp(inst, rhs.operator Il2CppString const*());
}

template<typename T>
requires (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
bool operator ==(T const& rhs) const noexcept {
if constexpr (std::is_same_v<T, StringW>) return il2cpp_utils::detail::strcomp(inst, rhs.inst);
else return il2cpp_utils::detail::strcomp(inst, rhs);

template <typename T>
requires(std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
bool operator==(T const& rhs) const noexcept {
if constexpr (std::is_same_v<T, StringW>)
return il2cpp_utils::detail::strcomp(inst, rhs.inst);
else
return il2cpp_utils::detail::strcomp(inst, rhs);
}

template<typename T>
requires (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
template <typename T>
requires(std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
bool starts_with(T const& rhs) const noexcept {
if constexpr (std::is_same_v<T, StringW>) return il2cpp_utils::detail::strstart(inst, rhs.inst);
else return il2cpp_utils::detail::strstart(inst, rhs);
if constexpr (std::is_same_v<T, StringW>)
return il2cpp_utils::detail::strstart(inst, rhs.inst);
else
return il2cpp_utils::detail::strstart(inst, rhs);
}
template<typename T>
requires (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)

template <typename T>
requires(std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T> || std::is_same_v<T, StringW>)
bool ends_with(T const& rhs) const noexcept {
if constexpr (std::is_same_v<T, StringW>) return il2cpp_utils::detail::strend(inst, rhs.inst);
else return il2cpp_utils::detail::strend(inst, rhs);
if constexpr (std::is_same_v<T, StringW>)
return il2cpp_utils::detail::strend(inst, rhs.inst);
else
return il2cpp_utils::detail::strend(inst, rhs);
}

using iterator = Il2CppChar*;
using const_iterator = Il2CppChar const*;

Expand All @@ -223,23 +236,23 @@ struct StringW {
iterator end();
const_iterator end() const;
operator std::span<Il2CppChar>();
operator std::span<Il2CppChar const> const () const;
operator std::span<Il2CppChar const> const() const;

Il2CppChar const& operator [](size_t const& idx) const;
Il2CppChar& operator [](size_t const& idx);
Il2CppChar const& operator[](size_t const& idx) const;
Il2CppChar& operator[](size_t const& idx);
operator std::string() const;
operator std::u16string() const;
operator std::wstring() const;
operator std::u16string_view();
operator std::u16string_view const() const;

private:
private:
Il2CppString* inst;
};

template<typename T>
requires (!std::is_constructible_v<T, StringW> && (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T>))
StringW operator +(T const lhs, StringW const& rhs) noexcept {
template <typename T>
requires(!std::is_constructible_v<T, StringW> && (std::is_constructible_v<std::u16string_view, T> || std::is_constructible_v<std::string_view, T>))
StringW operator+(T const lhs, StringW const& rhs) noexcept {
return il2cpp_utils::detail::strappend(lhs, rhs.operator Il2CppString const*());
}

Expand Down

0 comments on commit 1f027e6

Please sign in to comment.