Skip to content

Commit

Permalink
remove blob dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
etiennebacher committed Jan 16, 2024
1 parent bf22465 commit 272c819
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 41 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.Rproj.user
src/rust/vendor
src/vendor
docs
7 changes: 3 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: b64
Title: Fast and Vectorized Base 64 Engine
Version: 0.1.0
Version: 0.1.0.9000
Authors@R:
person("Josiah", "Parry", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-9910-865X"))
Expand All @@ -14,11 +14,10 @@ License: MIT + file LICENSE
Encoding: UTF-8
Language: en
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
RoxygenNote: 7.3.0
Config/rextendr/version: 0.3.1.9000
SystemRequirements: Cargo (Rust's package manager), rustc
Imports:
blob
Suggests:
blob,
testthat (>= 3.0.0)
Config/testthat/edition: 3
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ export(engine)
export(new_alphabet)
export(new_config)
export(new_engine)
importFrom(blob,blob)
useDynLib(b64, .registration = TRUE)
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# b64 (development version)

* All hard dependencies were removed (#2, @etiennebacher).

# b64 0.1.0

* Initial CRAN submission.
1 change: 0 additions & 1 deletion R/b64-package.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#' @keywords internal
#' @importFrom blob blob
"_PACKAGE"

## usethis namespace: start
Expand Down
2 changes: 0 additions & 2 deletions R/extendr-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ print_config_ <- function(config) .Call(wrap__print_config_, config)
#' chunked
#'
#' b64_wrap(chunked, "\n")
#'
#'
#' @param width a numeric scalar defining the width of the chunks. Must be divisible by 4.
#' @param encoded a character vector of base64 encoded strings.
#' @export
Expand Down
66 changes: 46 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

<!-- README.md is generated from README.Rmd. Please edit that file -->

# b64
# b64 <img src="man/figures/logo.svg" align="right" height="139" alt="" />

<!-- badges: start -->

Expand Down Expand Up @@ -36,8 +36,11 @@ Decode using `decode()`
``` r
decoded <- decode(hello)
decoded
#> <blob[1]>
#> [1] blob[19 B]
#> [[1]]
#> [1] 48 65 6c 6c 6f 2c 20 66 72 6f 6d 20 65 78 74 65 6e 64 72
#>
#> attr(,"class")
#> [1] "blob" "vctrs_list_of" "vctrs_vctr" "list"
```

We can convert the decoded base64 to characters and see how it worked.
Expand All @@ -54,28 +57,50 @@ Both `encode()` and `decode()` are vectorized.
``` r
lorem <- unlist(lorem::ipsum(5, 1, 5))
lorem
#> [1] "Sit ligula senectus litora viverra consequat."
#> [2] "Consectetur vulputate vivamus sapien a ridiculus porta."
#> [3] "Ipsum orci cras posuere lacus."
#> [4] "Lorem nostra hendrerit nascetur vel duis consequat."
#> [5] "Adipiscing dui blandit vestibulum bibendum?"
#> [1] "Dolor malesuada cursus faucibus facilisi accumsan viverra?"
#> [2] "Sit penatibus lobortis at aptent pellentesque!"
#> [3] "Sit euismod accumsan semper ante cubilia nam velit himenaeos!"
#> [4] "Lorem pulvinar augue aliquam!"
#> [5] "Dolor nullam facilisi senectus penatibus."

encoded <- encode(lorem)
encoded
#> [1] "U2l0IGxpZ3VsYSBzZW5lY3R1cyBsaXRvcmEgdml2ZXJyYSBjb25zZXF1YXQu"
#> [2] "Q29uc2VjdGV0dXIgdnVscHV0YXRlIHZpdmFtdXMgc2FwaWVuIGEgcmlkaWN1bHVzIHBvcnRhLg=="
#> [3] "SXBzdW0gb3JjaSBjcmFzIHBvc3VlcmUgbGFjdXMu"
#> [4] "TG9yZW0gbm9zdHJhIGhlbmRyZXJpdCBuYXNjZXR1ciB2ZWwgZHVpcyBjb25zZXF1YXQu"
#> [5] "QWRpcGlzY2luZyBkdWkgYmxhbmRpdCB2ZXN0aWJ1bHVtIGJpYmVuZHVtPw=="
#> [1] "RG9sb3IgbWFsZXN1YWRhIGN1cnN1cyBmYXVjaWJ1cyBmYWNpbGlzaSBhY2N1bXNhbiB2aXZlcnJhPw=="
#> [2] "U2l0IHBlbmF0aWJ1cyBsb2JvcnRpcyBhdCBhcHRlbnQgcGVsbGVudGVzcXVlIQ=="
#> [3] "U2l0IGV1aXNtb2QgYWNjdW1zYW4gc2VtcGVyIGFudGUgY3ViaWxpYSBuYW0gdmVsaXQgaGltZW5hZW9zIQ=="
#> [4] "TG9yZW0gcHVsdmluYXIgYXVndWUgYWxpcXVhbSE="
#> [5] "RG9sb3IgbnVsbGFtIGZhY2lsaXNpIHNlbmVjdHVzIHBlbmF0aWJ1cy4="
```

We can decode all of these using `decode()` as well. This will always
return a `blob` object.

``` r
decode(encoded)
#> <blob[5]>
#> [1] blob[45 B] blob[55 B] blob[30 B] blob[51 B] blob[43 B]
#> [[1]]
#> [1] 44 6f 6c 6f 72 20 6d 61 6c 65 73 75 61 64 61 20 63 75 72 73 75 73 20 66 61
#> [26] 75 63 69 62 75 73 20 66 61 63 69 6c 69 73 69 20 61 63 63 75 6d 73 61 6e 20
#> [51] 76 69 76 65 72 72 61 3f
#>
#> [[2]]
#> [1] 53 69 74 20 70 65 6e 61 74 69 62 75 73 20 6c 6f 62 6f 72 74 69 73 20 61 74
#> [26] 20 61 70 74 65 6e 74 20 70 65 6c 6c 65 6e 74 65 73 71 75 65 21
#>
#> [[3]]
#> [1] 53 69 74 20 65 75 69 73 6d 6f 64 20 61 63 63 75 6d 73 61 6e 20 73 65 6d 70
#> [26] 65 72 20 61 6e 74 65 20 63 75 62 69 6c 69 61 20 6e 61 6d 20 76 65 6c 69 74
#> [51] 20 68 69 6d 65 6e 61 65 6f 73 21
#>
#> [[4]]
#> [1] 4c 6f 72 65 6d 20 70 75 6c 76 69 6e 61 72 20 61 75 67 75 65 20 61 6c 69 71
#> [26] 75 61 6d 21
#>
#> [[5]]
#> [1] 44 6f 6c 6f 72 20 6e 75 6c 6c 61 6d 20 66 61 63 69 6c 69 73 69 20 73 65 6e
#> [26] 65 63 74 75 73 20 70 65 6e 61 74 69 62 75 73 2e
#>
#> attr(,"class")
#> [1] "blob" "vctrs_list_of" "vctrs_vctr" "list"
```

## Encoding and decoding files
Expand All @@ -99,8 +124,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 b64 39.8ms 41.3ms 24.0 24MB 0
#> 2 base64enc 112.1ms 115.2ms 8.56 66.5MB 17.1
#> 1 b64 76.9ms 79.8ms 12.6 24.1MB 0
#> 2 base64enc 189ms 199.7ms 5.07 66.9MB 10.1
```

While the encoding is very impressive, better yet is the decoding
Expand All @@ -122,8 +147,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 b64 16.1ms 16.8ms 56.1 18MB 9.34
#> 2 base64enc 209.1ms 210.7ms 4.75 18MB 0
#> 1 b64 46ms 47.1ms 21.2 18.1MB 5.30
#> 2 base64enc 308ms 314.1ms 3.18 18.1MB 0
```

## Alternative engines
Expand Down Expand Up @@ -153,7 +178,8 @@ We can use our new engine to decode it.
``` r
decode(url_safe_encoded, url_engine)
#> <blob[1]>
#> [1] blob[4 B]
#> [[1]]
#> [1] fa ec 20 55
```

### Custom Engines
Expand Down
5 changes: 3 additions & 2 deletions man/b64-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions man/utils.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 4 additions & 9 deletions src/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,9 @@ fn encode_vectorized_(what: Either<Strings, List>, engine: Robj) -> Strings {
})
.collect::<Strings>(),
Either::Right(r) => {
if !r.inherits("blob") {
throw_r_error("Expected a character vector or an object of class `blob`")
}

r.into_iter()
.map(|(_, b)| {
if b.is_null() {
if !b.inherits("raw") | b.is_null() {
Rstr::na()
} else {
let raw: Raw = b.try_into().unwrap();
Expand Down Expand Up @@ -195,12 +191,11 @@ fn decode_vectorized_(what: Either<Strings, List>, engine: Robj) -> Robj {
.set_class(&["blob", "vctrs_list_of", "vctrs_vctr", "list"])
.unwrap(),
Either::Right(r) => {
if !r.inherits("blob") {
throw_r_error("Expected a character vector or an object of class `blob`")
}
r.into_iter()
.map(|(_, b)| {
if b.is_null() {
if !b.inherits("raw") {
Rstr::na().into_robj()
} else if b.is_null() {
().into_robj()
} else {
let raw: Raw = b.try_into().unwrap();
Expand Down

0 comments on commit 272c819

Please sign in to comment.