blob: f63cfe621243fa529e3b167d9c45c2662546f391 [file] [log] [blame]
# File src/library/base/R/connections.R
# Part of the R package, https://www.R-project.org
#
# Copyright (C) 1995-2019 The R Core Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of the GNU General Public License is available at
# https://www.R-project.org/Licenses/
stdin <- function() .Internal(stdin())
stdout <- function() .Internal(stdout())
stderr <- function() .Internal(stderr())
nullfile <- function()
if (.Platform$OS.type == "windows") "nul:" else "/dev/null"
isatty <- function(con) {
if (!inherits(con, "terminal")) FALSE
else .Internal(isatty(con))
}
readLines <- function(con = stdin(), n = -1L, ok = TRUE, warn = TRUE,
encoding = "unknown", skipNul = FALSE)
{
if(is.character(con)) {
con <- file(con, "r")
on.exit(close(con))
}
.Internal(readLines(con, n, ok, warn, encoding, skipNul))
}
writeLines <- function(text, con = stdout(), sep = "\n", useBytes = FALSE)
{
if(!is.character(text))
stop("can only write character objects")
if(is.character(con)) {
con <- file(con, "w")
on.exit(close(con))
}
.Internal(writeLines(text, con, sep, useBytes))
}
open <- function(con, ...)
UseMethod("open")
open.connection <- function(con, open = "r", blocking = TRUE, ...)
.Internal(open(con, open, blocking))
isOpen <- function(con, rw = "")
{
rw <- pmatch(rw, c("read", "write"), 0L)
.Internal(isOpen(con, rw))
}
isIncomplete <- function(con)
.Internal(isIncomplete(con))
isSeekable <- function(con)
.Internal(isSeekable(con))
close <- function(con, ...)
UseMethod("close")
close.connection <- function (con, type = "rw", ...)
.Internal(close(con, type))
flush <- function(con) UseMethod("flush")
flush.connection <- function (con)
.Internal(flush(con))
file <- function(description = "", open = "", blocking = TRUE,
encoding = getOption("encoding"), raw = FALSE,
method = getOption("url.method", "default")) {
.Internal(file(description, open, blocking, encoding, method, raw))
}
pipe <- function(description, open = "", encoding = getOption("encoding"))
.Internal(pipe(description, open, encoding))
fifo <- function(description, open = "", blocking = FALSE,
encoding = getOption("encoding"))
.Internal(fifo(description, open, blocking, encoding))
url <- function(description, open = "", blocking = TRUE,
encoding = getOption("encoding"),
method = getOption("url.method", "default"), headers = NULL)
{
method <- match.arg(method, c("default", "internal", "libcurl", "wininet"))
if(!is.null(headers)) {
nh <- names(headers)
if(length(nh) != length(headers) || any(nh == "") || anyNA(headers) || anyNA(nh))
stop("'headers' must have names and must not be NA")
headers <- paste0(nh, ": ", headers)
headers <- list(headers, paste0(headers, "\r\n", collapse = ""))
}
.Internal(url(description, open, blocking, encoding, method, headers))
}
gzfile <- function(description, open = "",
encoding = getOption("encoding"), compression = 6)
.Internal(gzfile(description, open, encoding, compression))
unz <- function(description, filename, open = "",
encoding = getOption("encoding"))
.Internal(unz(paste(description, filename, sep=":"), open, encoding))
bzfile <- function(description, open = "", encoding = getOption("encoding"),
compression = 9)
.Internal(bzfile(description, open, encoding, compression))
xzfile <- function(description, open = "", encoding = getOption("encoding"),
compression = 6)
.Internal(xzfile(description, open, encoding, compression))
socketConnection <- function(host = "localhost", port, server = FALSE,
blocking = FALSE, open = "a+",
encoding = getOption("encoding"),
timeout = getOption("timeout"))
.Internal(socketConnection(host, port, server, blocking, open, encoding,
timeout))
rawConnection <- function(object, open = "r") {
.Internal(rawConnection(deparse(substitute(object)), object, open))
}
rawConnectionValue <- function(con) .Internal(rawConnectionValue(con))
textConnection <- function(object, open = "r", local = FALSE,
encoding = c("", "bytes", "UTF-8"))
{
env <- if (local) parent.frame() else .GlobalEnv
type <- match(match.arg(encoding), c("", "bytes", "UTF-8"))
nm <- deparse(substitute(object))
if(length(nm) != 1)
stop("argument 'object' must deparse to a single character string")
.Internal(textConnection(nm, object, open, env, type))
}
textConnectionValue <- function(con) .Internal(textConnectionValue(con))
seek <- function(con, ...)
UseMethod("seek")
seek.connection <- function(con, where = NA, origin = "start", rw = "", ...)
{
origin <- pmatch(origin, c("start", "current", "end"))
rw <- pmatch(rw, c("read", "write"), 0L)
if(is.na(origin))
stop("'origin' must be one of 'start', 'current' or 'end'")
.Internal(seek(con, as.double(where), origin, rw))
}
truncate <- function(con, ...)
UseMethod("truncate")
truncate.connection <- function(con, ...)
{
if(!isOpen(con)) stop("can only truncate an open connection")
.Internal(truncate(con))
}
pushBack <- function(data, connection, newLine = TRUE,
encoding = c("", "bytes", "UTF-8"))
{
# match.arg doesn't work on "" default
if (length(encoding) > 1L) encoding <- encoding[1]
if (nzchar(encoding)) encoding <- match.arg(encoding)
type <- match(encoding, c("", "bytes", "UTF-8"))
.Internal(pushBack(data, connection, newLine, type))
}
pushBackLength <- function(connection)
.Internal(pushBackLength(connection))
clearPushBack <- function(connection)
.Internal(clearPushBack(connection))
print.connection <- function(x, ...)
{
usumm <- tryCatch(unlist(summary(x)), error = function(e) {})
## could also show as.numeric(x) {as str() currently does}
if(is.null(usumm)) {
cl <- oldClass(x); cl <- cl[cl != "connection"]
cat("A connection, ",
if(length(cl)) paste0("specifically, ",
paste(sQuote(cl), collapse=", "), ", "),
"but invalid.\n", sep = "")
} else {
cat("A connection with") # {newline from print() below}
print(cbind(` ` = usumm), ...)
}
invisible(x)
}
summary.connection <- function(object, ...)
.Internal(summary.connection(object))
showConnections <- function(all = FALSE)
{
gc() # to run finalizers
set <- getAllConnections()
if(!all) set <- set[set > 2L]
ans <- matrix("", length(set), 7L)
for(i in seq_along(set)) ans[i, ] <- unlist(summary.connection(set[i]))
rownames(ans) <- set
colnames(ans) <- c("description", "class", "mode", "text", "isopen",
"can read", "can write")
if(!all) ans[ans[, 5L] == "opened", , drop = FALSE]
else ans[, , drop = FALSE]
}
## undocumented
getAllConnections <- function() .Internal(getAllConnections())
getConnection <- function(what) .Internal(getConnection(what))
closeAllConnections <- function()
{
## first re-divert any diversion of stderr.
i <- sink.number(type = "message")
if(i > 0L) sink(stderr(), type = "message")
## now unwind the sink diversion stack.
n <- sink.number()
if(n > 0L) for(i in seq_len(n)) sink()
gc() # to run finalizers
## get all the open connections.
set <- getAllConnections()
set <- set[set > 2L]
## and close all user connections.
for(i in seq_along(set)) close(getConnection(set[i]))
invisible()
}
readBin <- function(con, what, n = 1L, size = NA_integer_, signed = TRUE,
endian = .Platform$endian)
{
if(is.character(con)) {
con <- file(con, "rb")
on.exit(close(con))
}
swap <- endian != .Platform$endian
if(!is.character(what) || is.na(what) ||
length(what) != 1L || ## hence length(what) == 1:
!any(what == c("numeric", "double", "integer", "int", "logical",
"complex", "character", "raw")))
what <- typeof(what)
.Internal(readBin(con, what, n, size, signed, swap))
}
writeBin <-
function(object, con, size = NA_integer_, endian = .Platform$endian,
useBytes = FALSE)
{
swap <- endian != .Platform$endian
if(!is.vector(object) || mode(object) == "list")
stop("can only write vector objects")
if(is.character(con)) {
con <- file(con, "wb")
on.exit(close(con))
}
.Internal(writeBin(object, con, size, swap, useBytes))
}
readChar <- function(con, nchars, useBytes = FALSE)
{
if(is.character(con)) {
con <- file(con, "rb")
on.exit(close(con))
}
.Internal(readChar(con, as.integer(nchars), useBytes))
}
writeChar <- function(object, con, nchars = nchar(object, type="chars"),
eos = "", useBytes = FALSE)
{
if(!is.character(object))
stop("can only write character objects")
if(is.character(con)) {
con <- file(con, "wb")
on.exit(close(con))
}
.Internal(writeChar(object, con, as.integer(nchars), eos, useBytes))
}
gzcon <- function(con, level = 6, allowNonCompressed = TRUE, text = FALSE)
.Internal(gzcon(con, level, allowNonCompressed, text))
socketSelect <- function(socklist, write = FALSE, timeout = NULL) {
if (is.null(timeout))
timeout <- -1
else if (timeout < 0)
stop("'timeout' must be NULL or a non-negative number")
if (length(write) < length(socklist))
write <- rep_len(write, length(socklist))
.Internal(sockSelect(socklist, write, timeout))
}
memCompress <-
function(from, type = c("gzip", "bzip2", "xz", "none"))
{
if(is.character(from))
from <- charToRaw(paste(from, collapse = "\n"))
else if(!is.raw(from)) stop("'from' must be raw or character")
type <- match(match.arg(type), c("none", "gzip", "bzip2", "xz"))
.Internal(memCompress(from, type))
}
memDecompress <-
function(from,
type = c("unknown", "gzip", "bzip2", "xz", "none"),
asChar = FALSE)
{
type <- match(match.arg(type),
c("none", "gzip", "bzip2", "xz", "unknown"))
ans <- .Internal(memDecompress(from, type))
if(asChar) rawToChar(ans) else ans
}