The adfExplorer2 package has defined several S3 class objects to make interaction with virtual ADF devices easier. This page presents these objects, what they are for and how they can be used.
adf_device
What is it?
Amiga Disk Files (ADF) or file representations of hardware disks. The
adf_device
class is used to represent a connection to such
files. It can be seen as a virtual device. The file remains on disk, the
adf_device
opens a file connection to it. Underneath the S3
class the object has the type externalptr
.
How can it be initialized?
The adf_device
can be initiated by opening an ADF or ADZ
(a zipped ADF) file with connect_adf()
.
library(adfExplorer2, warn.conflicts = FALSE)
adz_file <- system.file("example.adz", package = "adfExplorer2")
my_device <- connect_adf(adz_file)
It can also be initiated by creating a new device with
create_adf_device()
. As the device needs to be stored as a
file, you need to specify its destination path. The example below uses a
temporary file for this purpose.
adf_file <- tempfile(fileext = ".adf")
new_device <- create_adf_device(adf_file)
What can I do with it?
Well, that depends. When you just created a device with
create_adf_device()
, like the object named
new_device
in the example above, it does not contain a file
system (see vignette("file_system_modes")
). Virtual disks
without a file system, could contain unspecified data or a custom track
loader, which can contain instructions running independently from the
operating system. You can inspect those disks by reading and writing blocks, the logical unit of data on a disk.
When a virtual disk does contain a file system, like the one opened
with connect_adf()
stored as the object named
my_device
, you can do a lot more. You can query the files
and directories on the disk. Read, write, copy, move, manipulate and
delete those files. The example below shows how to list the entries
(files and directories) on the disk’s root.
list_adf_entries(my_device)
#> DIR DEWR... Devs
#> DIR DEWR... S
#> DIR DEWR... this
#> DIR DEWR... mods
End of life
As any externalptr
object an adf_device
will be cleaned up automatically by R’s garbage collector when it goes
out of scope. However, as it maintains an open connection to a file on
disk, it is always wise to close()
the device when you are
done with it. Calling close()
on an adf_device
will also automatically close all nested connections to files on the
virtual device (see also adf_file_con
)
close(new_device)
## Let's keep `my_device` open to be used in examples below
adf_file_con
What is it?
It is a connection to a file on a virtual device represented by the
adf_device
class objects. Well…
Technically, it isn’t a connection really, because CRAN’s policy does
not allow to call non API entry points into R. This would be required to
setup a proper connection. Instead, the adf_file_con
is a
mockup using an externalptr
type to mimic R connections. In
essence, it behaves very much like any other connection in R (more
details below).
How can it be initialized?
An adf_file_con
object can be initiated using a call to
adf_file_con()
. For this purpose, you first need to connect
to a virtual device containing a file system. We’ll use
my_device
opened in earlier examples. We can use the path
to a file on a virtual device to open a connection as shown below.
con <- adf_file_con(my_device, "DF0:mods/mod.intro")
summary(con)
#> $description
#> [1] "mod.intro"
#>
#> $class
#> [1] "adf_file_con"
#>
#> $mode
#> [1] "rb"
#>
#> $text
#> [1] "binary"
#>
#> $opened
#> [1] "opened"
#>
#> $`can read`
#> [1] "yes"
#>
#> $`can write`
#> [1] "no"
If you want to open writable connections to a virtual device, you need to initiate the device without write protection. A writable connection can also be used to create new files on the virtual device.
What can I do with it?
Depending on how you set the option writable
when
calling adf_file_con
, you can either read and / or write to
the connection. By default the connection is opened as read-only. You
can use readBin()
to read binary data from the
connection.
readBin(con, "raw", 20L)
#> [1] 69 6e 74 72 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Note that adf_file_con()
always opens the connection as
‘binary’, but you can also use it for reading and writing text. So
basically, readLines()
, writeBin()
and
writeLines()
are all available (the latter two obviously
when the connection is writable).
In addition, you can tell where the current byte offset in the file
is located with seek()
. You can also use it to set the
offset to a specific location.
virtual_path
What is it?
It is a vectorised list
of list
s. The
nested list contains two elements:
- An
adf_device
class object - A
character
string, specifying a path to a file or directory on the virtual device.
The outer list just contains a collection of these.
How can it be initialized?
It can be initialised by calling virtual_path()
.
virtual_path(my_device, "DF0:s/startup-sequence")
#> FILE DEWR---- 0.6 kB Startup-Sequence
virtual_path(my_device, "idontexist")
#> Invalid path
Note that the file does not necessarily have to exist in order to create a virtual path. It doesn’t create any kind of connection to the file, but you can use it to open one.
What can I do with it?
The virtual_path
is a means to refer to files and
directory on a virtual device. It also helps to set up processes with
the pipe operator (|>
). There is a
vignette("virtual_path")
dedicated to describing the object
and its usage in more detail.
End of life
It is just a list. You can just call rm()
on it to get
rid of it.
adf_block
What is it?
A representation of raw
data of a logical unit on a
virtual device of 512 bytes. It is simply a vector
of
raw
data.
How can it be initialized?
A new block block can be created with new_adf_block()
.
It will be initialised with null bytes. You can also coerce a
raw
vector
to an adf_block
.
block1 <- new_adf_block()
## a block with random data
block2 <- as_adf_block(as.raw(sample.int(n=256L, size = 512L, replace = TRUE) - 1L))
You can also intialise a block by reading it from a virtual device
## This will read the initial 'boot' block
## from the virtual device
block3 <- read_adf_block(my_device, 0L)
What can I do with it?
You can read blocks from a virtual disk with
read_adf_block()
and write them to a specific sector on the
virtual disk with write_adf_block()
. But be careful you can
damage the file system or track loader of the virtual disk if you don’t
know what you are doing.