Skip to content

Instantly share code, notes, and snippets.

@noamross
Last active November 17, 2023 22:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noamross/0cb3708e72c4f18c5ab747a1609468b7 to your computer and use it in GitHub Desktop.
Save noamross/0cb3708e72c4f18c5ab747a1609468b7 to your computer and use it in GitHub Desktop.
Simple R object to base64 conversion. Free to a good home in your R package! If you put it in your package, let me know πŸ™‚
# Copyright 2018 Noam Ross
#
# 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.
#' Convert an R object to a base64 string
#'
#' Turns any R object into a base64 chracter string. Compression and
#' line-wrapping are turned on by default
#'
#' @param object An R object to be seriaized as a base64 string
#' @param compression A compression method. May be one of "xz" (default),
#' "gzip", "bzip2", or "none".
#' @param linewidth Width of lines of the base64 string. Zero or NA denotes no
#' line breaks and values 1 .. 3 are silently treated as 4 since that is the
#' shortest valid line.
#' @param ... Arguments passed to [serialize()]. (`xdr`, `version`, or `refhook`)
#' @return A length-one character vector of class "put64".
#' Printing is facilitated for easy copy-and pasting.
#' @export
#' @importFrom base64enc base64encode
#' @examples
#'
#' x <- put64(iris)
#' y <- get64(x)
#' identical(y, iris)
#' nchar(x)
#' nchar(paste(capture.output(dput(iris)), collapse="\n"))
#'
#' x
put64 <- function(object, compression = "xz", linewidth = 78, ...) {
zz <- rawConnection(raw(0), "r+")
serialize(object, zz, ...)
encoded <- base64enc::base64encode(
memCompress(rawConnectionValue(zz), type = compression),
linewidth = linewidth,
newline="\n"
)
close(zz)
class(encoded) <- c("put64")
return(encoded)
#TODO:should this string be prefixed with 'put64:' 'R64:' or something to
#make it easier to recognize?
}
#' Decode a base64 string created by put64()
#'
#' @param put64 A base64 character string generated by [put64()]
#' @param compression compression type used to generate. "unknown" will
#' generally auto-detect, but if not "gzip", "bzip2", "xz", or "none".
#' @param ... Arguments passed to [serialize()]. (`refhook`)
#'
#' @return An R Object
#' @export
#' @importFrom base64enc base64decode
#' @examples
#'
#' x <- put64(iris)
#' y <- get64(x)
#' identical(y, iris)
#' nchar(x)
#' nchar(paste(capture.output(dput(iris)), collapse="\n"))
#'
#' x
get64 <- function(put64, compression = "unknown", ...) {
err <- function()
tryCatch({
suppressWarnings(unserialize(memDecompress(base64decode(put64))))
},
error = function(e) {
message("Error: Could not decode string. Was it created with put64()?")
}
)
}
#' @export
print.put64 <- function(x) {
cat('"', x, '"', sep="")
invisible(x)
}
@noamross
Copy link
Author

I realize that maybe what this should do is print the base64 code _wrapped in unserialize(memDecompress(base64env::base64decode("STRING")), written or even a compact version of https://coolbutuseless.github.io/2021/12/04/base64-encoding/decoding-in-plain-r/

@noamross
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment