#  File src/library/utils/R/URLencode.R
#  Part of the R package, https://www.R-project.org
#
#  Copyright (C) 1995-2015 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/

URLencode <- function(URL, reserved = FALSE, repeated = FALSE)
{
    vapply(URL, function(URL) {
        if(!repeated && grepl("%[[:xdigit:]]{2}", URL, useBytes = TRUE))
            return(URL)
        ## It is unsafe to use ranges here as collation is locale-dependent.
        ## We want to do this on characters and not on bytes.
        OK <- paste0("[^",
                    if(!reserved) "][!$&'()*+,;=:/?@#",
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
                    "abcdefghijklmnopqrstuvwxyz0123456789._~-",
                    "]")
        x <- strsplit(URL, "")[[1L]]
        z <- grep(OK, x)
        if(length(z)) {
            y <- vapply(x[z],
                        function(x)
                            paste0("%", toupper(as.character(charToRaw(x))),
                                collapse = ""),
                        "")
            x[z] <- y
        }
        paste(x, collapse = "")
    }, character(1), USE.NAMES = FALSE)
}

URLdecode <- function(URL)
{
    vapply(URL, function(URL) {
        x <- charToRaw(URL)
        pc <- charToRaw("%")
        out <- raw(0L)
        i <- 1L
        while(i <= length(x)) {
            if(x[i] != pc) {
                out <- c(out, x[i])
                i <- i + 1L
            } else {
                y <- as.integer(x[i + 1L:2L])
                y[y > 96L] <- y[y > 96L] - 32L # a-f -> A-F
                y[y > 57L] <- y[y > 57L] - 7L  # A-F
                y <- sum((y - 48L) * c(16L, 1L))
                out <- c(out, as.raw(as.character(y)))
                i <- i + 3L
            }
        }
        rawToChar(out)
    }, character(1), USE.NAMES = FALSE)
}
