1#' Encode/decode data into/from base64 encoding. 2#' 3#' The function \code{base64_encode()} encodes a file or a raw vector into the 4#' base64 encoding. The function \code{base64_decode()} decodes data from the 5#' base64 encoding. 6#' @param x For \code{base64_encode()}, a raw vector. If not raw, it is assumed 7#' to be a file or a connection to be read via \code{readBin()}. For 8#' \code{base64_decode()}, a string. 9#' @param from If provided (and \code{x} is not provided), a connection or file 10#' to be read via \code{readChar()}, and the result will be passed to the 11#' argument \code{x}. 12#' @return \code{base64_encode()} returns a character string. 13#' \code{base64_decode()} returns a raw vector. 14#' @useDynLib xfun, .registration = TRUE 15#' @export 16#' @examples xfun::base64_encode(as.raw(1:10)) 17#' logo = xfun:::R_logo() 18#' xfun::base64_encode(logo) 19base64_encode = function(x) { 20 if (!is.raw(x)) x = read_bin(x) 21 .Call('base64_enc', x, PACKAGE = 'xfun') 22} 23 24#' @export 25#' @rdname base64_encode 26#' @examples xfun::base64_decode("AQIDBAUGBwgJCg==") 27base64_decode = function(x, from = NA) { 28 if (!is.na(from)) { 29 if (!missing(x)) stop("Please provide either 'x' or 'from', but not both.") 30 x = readChar(from, file.size(from), TRUE) 31 } 32 if (!is.character(x) || length(x) != 1) stop("'x' must be a single character string.") 33 .Call('base64_dec', x, PACKAGE = 'xfun') 34} 35 36# an R implementation of base64 encoding by Wush Wu moved from knitr (of 37# historic interest only): https://github.com/yihui/knitr/pull/324 38base64_encode_r = function(x) { 39 if (!is.raw(x)) x = read_bin(x) 40 chars = c(LETTERS, letters, 0:9, '+', '/') 41 n = length(s <- as.integer(x)) 42 res = rep(NA, (n + 2) / 3 * 4) 43 i = 0L # index of res vector 44 j = 1L # index of base64_table 45 while (n > 2L) { 46 res[i <- i + 1L] = chars[s[j] %/% 4L + 1L] 47 res[i <- i + 1L] = chars[16 * (s[j] %% 4L) + s[j + 1L] %/% 16 + 1L] 48 res[i <- i + 1L] = chars[4L * (s[j + 1L] %% 16) + s[j + 2L] %/% 64L + 1L] 49 res[i <- i + 1L] = chars[s[j + 2L] %% 64L + 1L] 50 j = j + 3L 51 n = n - 3L 52 } 53 if (n) { 54 res[i <- i + 1L] = chars[s[j] %/% 4L + 1L] 55 if (n > 1L) { 56 res[i <- i + 1L] = chars[16 * (s[j] %% 4L) + s[j + 1L] %/% 16 + 1L] 57 res[i <- i + 1L] = chars[4L * (s[j + 1L] %% 16) + 1L] 58 res[i <- i + 1L] = '=' 59 } else { 60 res[i <- i + 1L] = chars[16 * (s[j] %% 4L) + 1L] 61 res[i <- i + 1L] = '=' 62 res[i <- i + 1L] = '=' 63 } 64 } 65 paste(res[!is.na(res)], collapse = '') 66} 67 68#' Generate the Data URI for a file 69#' 70#' Encode the file in the base64 encoding, and add the media type. The data URI 71#' can be used to embed data in HTML documents, e.g., in the \code{src} 72#' attribute of the \verb{<img />} tag. 73#' @param x A file path. 74#' @return A string of the form \verb{data:<media type>;base64,<data>}. 75#' @export 76#' @examples 77#' logo = xfun:::R_logo() 78#' img = htmltools::img(src = xfun::base64_uri(logo), alt = 'R logo') 79#' if (interactive()) htmltools::browsable(img) 80base64_uri = function(x) { 81 paste0("data:", mime::guess_type(x), ";base64,", base64_encode(x)) 82} 83