blob/0000755000176200001440000000000013121241552011164 5ustar liggesusersblob/tests/0000755000176200001440000000000013004404172012325 5ustar liggesusersblob/tests/testthat.R0000644000176200001440000000006413004404172014310 0ustar liggesuserslibrary(testthat) library(blob) test_check("blob") blob/tests/testthat/0000755000176200001440000000000013121241552014166 5ustar liggesusersblob/tests/testthat/test-construction.R0000644000176200001440000000043113004404172020015 0ustar liggesuserscontext("construction") test_that("input must be list of raw blobs", { expect_error(new_blob(1), "must be a list of raw vectors") expect_error(new_blob(list(1)), "must be a list of raw vectors") expect_error(new_blob(list(1, as.raw(1))), "must be a list of raw vectors") }) blob/tests/testthat/test-missing.R0000644000176200001440000000047213005107243016741 0ustar liggesuserscontext("missing") test_that("is.na detects nulls", { x <- blob(as.raw(1), NULL, as.raw(2), NULL) expect_equal(is.na(x), c(FALSE, TRUE, FALSE, TRUE)) }) test_that("is.na<- sets missing values", { x <- as.blob(1:4) is.na(x) <- (1:4 %% 2 == 0) expect_equal(x, blob(as.raw(1), NULL, as.raw(3), NULL)) }) blob/tests/testthat/test-accessors.R0000644000176200001440000000100313005107243017244 0ustar liggesuserscontext("accessors") test_that("subsetting blob returns blob", { x <- as.blob(1:5) expect_s3_class(x[1], "blob") }) test_that("can't insert objects of incorrect type", { x <- as.blob(1:5) expect_error(x[[1]] <- 1, "must be raw vector") expect_error(x[1] <- 1, "must be list of raw vectors") }) test_that("can insert raw or NULL", { x <- as.blob(1:4) x[[1]] <- as.raw(0) x[2] <- list(as.raw(0)) x[[3]] <- NULL x[4] <- list(NULL) expect_equal(x, blob(as.raw(0), as.raw(0), NULL, NULL)) }) blob/tests/testthat/test-format.R0000644000176200001440000000133213121123360016551 0ustar liggesuserscontext("format") expect_format_equal <- function(formatted, result) { expect_equal( paste(formatted, collapse = "\n"), paste(result, collapse = "\n") ) } test_that("unequal sizes", { x <- blob(raw(2 ** 2), raw(2 ** 11), raw(2 ** 20)) expect_format_equal( format(x), c( "blob[4 B]", "blob[2,050 B]", "blob[1,050,000 B]" ) ) expect_format_equal( format(x, trim = FALSE), c( "blob[ 4 B]", "blob[ 2,050 B]", "blob[1,050,000 B]" ) ) }) test_that("similar sizes", { x <- blob(raw(2 ** 10), raw(2 ** 11), raw(2 ** 12)) expect_format_equal( format(x), c( "blob[1 kb]", "blob[2 kb]", "blob[4 kb]" ) ) }) blob/NAMESPACE0000644000176200001440000000105413121121314012374 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method("[",blob) S3method("[<-",blob) S3method("[[<-",blob) S3method("is.na<-",blob) S3method(as.blob,blob) S3method(as.blob,character) S3method(as.blob,integer) S3method(as.blob,list) S3method(as.blob,raw) S3method(as.data.frame,blob) S3method(format,blob) S3method(is.na,blob) S3method(is_vector_s3,blob) S3method(obj_sum,blob) S3method(print,blob) S3method(type_sum,blob) export(as.blob) export(blob) export(new_blob) importFrom(tibble,is_vector_s3) importFrom(tibble,obj_sum) importFrom(tibble,type_sum) blob/NEWS.md0000644000176200001440000000032613121124202012253 0ustar liggesusers# blob 1.1.0 (2017-06-17) - New maintainer: Kirill Müller. - Added `as.blob.blob()`and `as.data.frame.blob()` methods (#3). - Size of very large blobs is displayed correctly. # blob 1.0.0 - Initial release. blob/R/0000755000176200001440000000000013121121314011356 5ustar liggesusersblob/R/accessors.R0000644000176200001440000000074613005107243013503 0ustar liggesusers#' @export `[.blob` <- function(x, i, ...) { new_blob(NextMethod()) } #' @export `[<-.blob` <- function(x, i, ..., value) { if (!is_raw_list(value)) { stop("RHS must be list of raw vectors", call. = FALSE) } NextMethod() } #' @export `[[<-.blob` <- function(x, i, ..., value) { if (!is.raw(value) && !is.null(value)) { stop("RHS must be raw vector or NULL", call. = FALSE) } if (is.null(value)) { x[i] <- list(NULL) x } else { NextMethod() } } blob/R/blob.R0000644000176200001440000000235713121041017012427 0ustar liggesusers#' Construct a blob object #' #' \code{new_blob} is a low-level constructor that takes a list of #' raw vectors. \code{blob} constructs a blob from individual raw vectors, #' and \code{as.blob} is a S3 generic that converts existing objects. #' #' @param ... Individual raw vectors #' @param x A list of raw vectors, or other object to coerce #' @export #' @examples #' x1 <- charToRaw("Good morning") #' x2 <- as.raw(c(0x48, 0x65, 0x6c, 0x6c, 0x6f)) #' #' new_blob(list(x1, x2)) #' blob(x1, x2) #' #' as.blob(c("Good morning", "Good evening")) blob <- function(...) { new_blob(list(...)) } #' @export #' @rdname blob new_blob <- function(x) { if (!is_raw_list(x)) { stop("`x` must be a list of raw vectors", call. = FALSE) } structure(x, class = "blob") } #' @export #' @rdname blob as.blob <- function(x, ...) { UseMethod("as.blob") } #' @export as.blob.blob <- function(x, ...) { x } #' @export as.blob.list <- function(x, ...) { new_blob(x) } #' @export as.blob.raw <- function(x, ...) { new_blob(list(x)) } #' @export as.blob.character <- function(x, ...) { new_blob(lapply(x, charToRaw)) } #' @export as.blob.integer <- function(x, ...) { new_blob(lapply(x, as.raw)) } #' @export as.data.frame.blob <- as.data.frame.difftime blob/R/missing.R0000644000176200001440000000046413005107243013164 0ustar liggesusers#' @export is.na.blob <- function(x) { vapply(x, is.null, logical(1)) } #' @export `is.na<-.blob` <- function(x, value) { if (!is.logical(value) || length(x) != length(value)) { stop("RHS must be a logical the same length as `x`", call. = FALSE) } x[value] <- rep(list(NULL), sum(value)) x } blob/R/format.R0000644000176200001440000000176313121123576013014 0ustar liggesusers#' @export format.blob <- function(x, ...) { if (length(x) == 0) return(character()) ifelse(is.na(x), "", paste0("blob[", blob_size(x, ...) , "]")) } #' @export print.blob <- function(x, ...) { if (length(x) == 0) { cat("blob()\n") } else { print(format(x, ...), quote = FALSE) } } #' @export #' @importFrom tibble type_sum type_sum.blob <- function(x) { "blob" } #' @export #' @importFrom tibble obj_sum obj_sum.blob <- function(x) { format(x, trim = FALSE) } #' @export #' @importFrom tibble is_vector_s3 is_vector_s3.blob <- function(x) TRUE blob_size <- function(x, digits = 3, trim = TRUE, ...) { x <- vapply(x, length, numeric(1)) units <- c("kb", "Mb", "Gb", "Tb") power <- min(floor(log(abs(x), 1000)), length(units)) if (power < 1) { unit <- "B" } else { unit <- units[[power]] x <- x / (1024 ^ power) } x1 <- signif(x, digits = digits %||% 3) x2 <- format(x1, big.mark = ",", scientific = FALSE, trim = trim) paste0(x2, " ", unit) } blob/R/util.R0000644000176200001440000000037313071114606012473 0ustar liggesusersis_raw_list <- function(x) { if (!is.list(x)) return(FALSE) raw <- vapply(x, is.raw, logical(1)) null <- vapply(x, is.null, logical(1)) if (!all(raw | null)) return(FALSE) TRUE } `%||%` <- function(x, y) if (is.null(x)) y else x blob/README.md0000644000176200001440000000246713121117277012462 0ustar liggesusers [![Travis-CI Build Status](https://travis-ci.org/tidyverse/blob.svg?branch=master)](https://travis-ci.org/tidyverse/blob) [![CRAN\_Status\_Badge](http://www.r-pkg.org/badges/version/blob)](https://cran.r-project.org/package=blob) [![Coverage Status](https://codecov.io/gh/tidyverse/blob/branch/master/graph/badge.svg)](https://codecov.io/github/tidyverse/blob?branch=master) blob ==== The goal of blob is to provide a simple S3 class to represent a vector of binary objects, aka blobs. The `blob` class is a lightweight wrapper around a list of raw vectors, suitable for inclusion in a data frame. In most cases you will not need to use this package explicitly: it will be used transparently by packages that need to load BLOB columns from databases or binary file formats. Installation ------------ You can install blob from github with: ``` r # install.packages("devtools") devtools::install_github("tidyverse/blob") ``` Example ------- To create a blob, use `blob()`, `new_blob()` or `as.blob()`: ``` r x1 <- charToRaw("Good morning") x2 <- as.raw(c(0x48, 0x65, 0x6c, 0x6c, 0x6f)) new_blob(list(x1, x2)) #> [1] blob[12 B] blob[5 B] blob(x1, x2) #> [1] blob[12 B] blob[5 B] as.blob(c("Good morning", "Good evening")) #> [1] blob[12 B] blob[12 B] ``` blob/MD50000644000176200001440000000137013121241552011475 0ustar liggesusers7a10119e6809dda7a09988f373fe1979 *DESCRIPTION a70b94cf9c447530d8067af264787859 *NAMESPACE ecbf768d48f1a7ae3d69dbeb3d82724a *NEWS.md 6db389b19ecd09d07b1a43ff03b70740 *R/accessors.R 2f56178958c9a14ad503bbb8bd8fd0d6 *R/blob.R a19880454681cf2ace5b3be0e7b94a3c *R/format.R 4aa476aef7a176a52f9559ba9742e347 *R/missing.R c85552e139c9e7fc2f9d332b86e5e4fc *R/util.R 8fb575be9a5c8c5dbd7234f8b49bd81e *README.md 2478bf628f24a684bf4056188c8715a6 *man/blob.Rd c37a14165e8d4b49908e517ea43960a7 *tests/testthat.R a1448eb53a4e9f79848795c3e8137620 *tests/testthat/test-accessors.R 1a9850bdf5e584fb97ec983449bee362 *tests/testthat/test-construction.R afa75bcf2cbf61caf2ac91047f132c7e *tests/testthat/test-format.R 57ce330853933b01f31f9b4413042b58 *tests/testthat/test-missing.R blob/DESCRIPTION0000644000176200001440000000172613121241552012700 0ustar liggesusersPackage: blob Title: A Simple S3 Class for Representing Vectors of Binary Data ('BLOBS') Version: 1.1.0 Authors@R: c( person("Hadley", "Wickham", role = c("aut")), person("Kirill", "Müller", , "krlmlr+r@mailbox.org", role = c("cre")), person("RStudio", role = "cph") ) Description: R's raw vector is useful for storing a single binary object. What if you want to put a vector of them in a data frame? The blob package provides the blob object, a list of raw vectors, suitable for use as a column in data frame. Imports: tibble License: GPL-3 Encoding: UTF-8 LazyData: true URL: https://github.com/hadley/blob BugReports: https://github.com/hadley/blob/issues Suggests: testthat, covr RoxygenNote: 6.0.1 NeedsCompilation: no Packaged: 2017-06-17 04:01:59 UTC; muelleki Author: Hadley Wickham [aut], Kirill Müller [cre], RStudio [cph] Maintainer: Kirill Müller Repository: CRAN Date/Publication: 2017-06-17 14:57:46 UTC blob/man/0000755000176200001440000000000013071114606011742 5ustar liggesusersblob/man/blob.Rd0000644000176200001440000000132513071114751013151 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/blob.R \name{blob} \alias{blob} \alias{new_blob} \alias{as.blob} \title{Construct a blob object} \usage{ blob(...) new_blob(x) as.blob(x, ...) } \arguments{ \item{...}{Individual raw vectors} \item{x}{A list of raw vectors, or other object to coerce} } \description{ \code{new_blob} is a low-level constructor that takes a list of raw vectors. \code{blob} constructs a blob from individual raw vectors, and \code{as.blob} is a S3 generic that converts existing objects. } \examples{ x1 <- charToRaw("Good morning") x2 <- as.raw(c(0x48, 0x65, 0x6c, 0x6c, 0x6f)) new_blob(list(x1, x2)) blob(x1, x2) as.blob(c("Good morning", "Good evening")) }