R/File.R

File <- setRefClass("FileClass", fields = list(
  path = "character"
), methods = list(
  initialize = function(filepath) {
    .self$path = filepath
  },
  write = function() {
    dir <- dirname(.self$path)
    if (!dir.exists(dir)) dir.create(dir, showWarnings=FALSE, recursive=TRUE)
  },
  read = function() {},
  exists = function() {
    return(file.exists(.self$path))
  }
))

TextFile <- setRefClass("TextFileClass", contains = "FileClass", methods = list(
  write = function(data, ...) {
    callSuper()
    return(base::write(data, .self$path, ...))
  },
  read = function(...) {
    return(readLines(.self$path, ...))
  }
))

JSONFile <- setRefClass("JSONFileClass", contains = "TextFileClass", methods = list(
  write = function(data, null="null", ...) {
    content <- as.character(jsonlite::toJSON(data, null=null, ...))
    return(callSuper(content))
  },
  read = function(simplifyMatrix=FALSE, ...) {
    return(jsonlite::fromJSON(.self$path, simplifyMatrix=simplifyMatrix, ...))
  }
))

#' Encrypted JSON files
EJSONFile <- setRefClass("EJSONFileClass", contains = "JSONFileClass", fields = list(
  key = "ANY"
), methods = list(
  initialize = function(path, key=NULL) {
    callSuper(path)
    .self$key <- key
  },
  write = function(data, encrypt=FALSE, null="null", ...) {
    if (!encrypt || is.null(.self$key)) return(callSuper(data, null=null, ...))

    iv <- .self$hex2raw(digest::digest(runif(1), algo="md5"))
    aes <- digest::AES(charToRaw(.self$key), mode="CTR", IV=iv)
    raw.content <- charToRaw(jsonlite::toJSON(data, null=null, ...))
    content <- suppressWarnings(aes$encrypt(raw.content))
    content <- list(iv = paste(iv, collapse=""), content = paste(content, collapse=""))
    return(callSuper(content, auto_unbox=TRUE))
  },
  hex2raw = function(text) {
    vals <- matrix(as.integer(as.hexmode(strsplit(text, "")[[1]])), ncol=2, byrow=TRUE)
    vals <- vals %*% c(16, 1)
    return(as.raw(vals))
  },
  read = function(simplifyMatrix=FALSE, ...) {
    data <- jsonlite::fromJSON(.self$path)
    if (!("content" %in% names(data) && "iv" %in% names(data))) {
      return(jsonlite::fromJSON(.self$path, simplifyMatrix=simplifyMatrix, ...))
    }

    aes <- digest::AES(charToRaw(.self$key), mode="CTR", IV=.self$hex2raw(data$iv))
    raw.content <- suppressWarnings(aes$decrypt(.self$hex2raw(data$content)))
    return(jsonlite::fromJSON(raw.content, simplifyMatrix=simplifyMatrix, ...))
  }
))
bioturing/rBCS documentation built on May 18, 2022, 5:26 p.m.