| 90244 |
hornik |
1 |
require("tools")
|
|
|
2 |
|
|
|
3 |
## BOM stripping in .file_append_ensuring_LFs()
|
|
|
4 |
BOM <- as.raw(c(0xEF, 0xBB, 0xBF))
|
|
|
5 |
|
|
|
6 |
collate <- function(files, enc = NA_character_) {
|
|
|
7 |
out <- tempfile(); file.create(out)
|
|
|
8 |
tools:::.file_append_ensuring_LFs(out, files, enc = enc)
|
|
|
9 |
readBin(out, "raw", file.info(out)$size)
|
|
|
10 |
}
|
|
|
11 |
|
|
|
12 |
has_bom <- function(raw) length(grepRaw(BOM, raw, fixed = TRUE)) > 0L
|
|
|
13 |
|
|
|
14 |
## File with BOM
|
|
|
15 |
f_bom <- tempfile(); writeBin(c(BOM, charToRaw("x <- 1\n")), f_bom)
|
|
|
16 |
## File without BOM
|
|
|
17 |
f_plain <- tempfile(); writeBin(charToRaw("y <- 2\n"), f_plain)
|
|
|
18 |
## BOM-only file
|
|
|
19 |
f_bomonly <- tempfile(); writeBin(BOM, f_bomonly)
|
|
|
20 |
## Short file (< 3 bytes)
|
|
|
21 |
f_short <- tempfile(); writeBin(charToRaw("z\n"), f_short)
|
|
|
22 |
|
|
|
23 |
stopifnot(exprs = {
|
|
|
24 |
## enc = NA preserves BOM
|
|
|
25 |
has_bom(collate(f_bom))
|
|
|
26 |
grepl("x <- 1", rawToChar(collate(f_bom)))
|
|
|
27 |
|
|
|
28 |
## enc = "UTF-8" strips BOM
|
|
|
29 |
!has_bom(collate(f_bom, "UTF-8"))
|
|
|
30 |
grepl("x <- 1", rawToChar(collate(f_bom, "UTF-8")))
|
|
|
31 |
|
|
|
32 |
## enc = "UTF-8": output is exactly 3 bytes shorter
|
|
|
33 |
length(collate(f_bom, "UTF-8")) == length(collate(f_bom)) - 3L
|
|
|
34 |
|
|
|
35 |
## no-BOM file copied fully
|
|
|
36 |
grepl("y <- 2", rawToChar(collate(f_plain, "UTF-8")))
|
|
|
37 |
|
|
|
38 |
## multiple files, mixed BOM
|
|
|
39 |
grepl("x <- 1", rawToChar(collate(c(f_bom, f_plain), "UTF-8")))
|
|
|
40 |
grepl("y <- 2", rawToChar(collate(c(f_bom, f_plain), "UTF-8")))
|
|
|
41 |
!has_bom(collate(c(f_bom, f_plain), "UTF-8"))
|
|
|
42 |
|
|
|
43 |
## BOM-only file: stripped, only #line directive remains
|
|
|
44 |
!has_bom(collate(f_bomonly, "UTF-8"))
|
|
|
45 |
|
|
|
46 |
## short file (< 3 bytes): fully copied
|
|
|
47 |
grepl("z", rawToChar(collate(f_short, "UTF-8")))
|
|
|
48 |
})
|
|
|
49 |
|
|
|
50 |
unlink(c(f_bom, f_plain, f_bomonly, f_short))
|