Skip to content

Commit

Permalink
Add functions for lzstring compressing to URI components
Browse files Browse the repository at this point in the history
  • Loading branch information
wch committed Apr 6, 2024
1 parent a5bebbd commit 31cc74e
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 1 deletion.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export(assets_remove)
export(assets_version)
export(export)
importFrom(rlang,is_interactive)
useDynLib(shinylive, .registration = TRUE)
9 changes: 9 additions & 0 deletions R/cpp11.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Generated by cpp11: do not edit by hand

compressToEncodedURIComponent <- function(uncompressed8) {
.Call(`_shinylive_compressToEncodedURIComponent`, uncompressed8)
}

decompressFromEncodedURIComponent <- function(compressed8) {
.Call(`_shinylive_decompressFromEncodedURIComponent`, compressed8)
}
2 changes: 2 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#' @useDynLib shinylive, .registration = TRUE

assert_nzchar_string <- function(x) {
stopifnot(is.character(x) && nchar(x) > 0)
invisible(TRUE)
Expand Down
27 changes: 26 additions & 1 deletion src/code.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
#include <cpp11.hpp>
#include <codecvt>
#include "lz-string.hpp"
using namespace cpp11;

[[cpp11::register]]
void fun() {}
std::string compressToEncodedURIComponent(std::string uncompressed8) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter_8_to_16;
std::u16string uncompressed16 = converter_8_to_16.from_bytes(uncompressed8);

auto compressed16 = lzstring::compressToEncodedURIComponent(lzstring::string(uncompressed16));

std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter_16_to_8;
std::string compressed8 = converter_16_to_8.to_bytes(compressed16);

return compressed8;
}


[[cpp11::register]]
std::string decompressFromEncodedURIComponent(std::string compressed8) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter_8_to_16;
std::u16string compressed16 = converter_8_to_16.from_bytes(compressed8);

auto uncompressed16 = lzstring::decompressFromEncodedURIComponent(lzstring::string(compressed16));

std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter_16_to_8;
std::string uncompressed8 = converter_16_to_8.to_bytes(uncompressed16);

return uncompressed8;
}
35 changes: 35 additions & 0 deletions src/cpp11.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Generated by cpp11: do not edit by hand
// clang-format off


#include "cpp11/declarations.hpp"
#include <R_ext/Visibility.h>

// code.cpp
std::string compressToEncodedURIComponent(std::string uncompressed8);
extern "C" SEXP _shinylive_compressToEncodedURIComponent(SEXP uncompressed8) {
BEGIN_CPP11
return cpp11::as_sexp(compressToEncodedURIComponent(cpp11::as_cpp<cpp11::decay_t<std::string>>(uncompressed8)));
END_CPP11
}
// code.cpp
std::string decompressFromEncodedURIComponent(std::string compressed8);
extern "C" SEXP _shinylive_decompressFromEncodedURIComponent(SEXP compressed8) {
BEGIN_CPP11
return cpp11::as_sexp(decompressFromEncodedURIComponent(cpp11::as_cpp<cpp11::decay_t<std::string>>(compressed8)));
END_CPP11
}

extern "C" {
static const R_CallMethodDef CallEntries[] = {
{"_shinylive_compressToEncodedURIComponent", (DL_FUNC) &_shinylive_compressToEncodedURIComponent, 1},
{"_shinylive_decompressFromEncodedURIComponent", (DL_FUNC) &_shinylive_decompressFromEncodedURIComponent, 1},
{NULL, NULL, 0}
};
}

extern "C" attribute_visible void R_init_shinylive(DllInfo* dll){
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
R_forceSymbols(dll, TRUE);
}
22 changes: 22 additions & 0 deletions src/lz-string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ using string = std::u16string;
namespace __inner
{
const string keyStrBase64{_U("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=")};
const string keyStrUriSafe{_U("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$")};
const string::value_type equal{_U('=')};

int charCodeAt(const string& str, int pos)
Expand Down Expand Up @@ -533,6 +534,27 @@ namespace __inner

} // namespace __inner

string compressToEncodedURIComponent(const string& input)
{
if (input.empty()) return {};
using namespace __inner;
auto res = _compress(input, 6, [](int a) { return keyStrBase64.at(a); });
return res;
}


string decompressFromEncodedURIComponent(const string& input)
{
if (input.empty()) return {};
using namespace __inner;
string input1 = input;
// std::replace(input1.begin(), input1.end(), ' ', '+');
std::unordered_map<string::value_type, int> baseReverseDic;
for (int i = 0; i < keyStrUriSafe.length(); ++i) baseReverseDic[keyStrUriSafe.at(i)] = i;
return _decompress(input1.length(), 32, [&](int index) { return baseReverseDic[input.at(index)]; });
}


// clang-format off
string compressToBase64(const string& input)
{
Expand Down

0 comments on commit 31cc74e

Please sign in to comment.