2016-10-16 06:55:21 +00:00
|
|
|
# Wrappers around file system primitives that take a 'resources' object and
|
2016-08-17 00:13:26 +00:00
|
|
|
# are thus easier to test.
|
|
|
|
|
2016-10-16 06:55:21 +00:00
|
|
|
container resources [
|
|
|
|
data:&:@:resource
|
2016-08-21 00:51:58 +00:00
|
|
|
]
|
|
|
|
|
2016-10-16 06:55:21 +00:00
|
|
|
container resource [
|
2016-09-12 07:47:44 +00:00
|
|
|
name:text
|
|
|
|
contents:text
|
2016-08-17 00:13:26 +00:00
|
|
|
]
|
|
|
|
|
2016-10-16 06:55:21 +00:00
|
|
|
def start-reading resources:&:resources, filename:text -> contents:&:source:char [
|
2016-08-17 00:13:26 +00:00
|
|
|
local-scope
|
|
|
|
load-ingredients
|
2016-08-21 01:29:09 +00:00
|
|
|
{
|
2016-10-16 06:55:21 +00:00
|
|
|
break-if resources
|
2016-08-22 15:35:35 +00:00
|
|
|
# real file system
|
2016-09-17 17:28:25 +00:00
|
|
|
file:num <- $open-file-for-reading filename
|
2016-08-21 01:29:09 +00:00
|
|
|
assert file, [file not found]
|
2016-09-17 19:55:10 +00:00
|
|
|
contents:&:source:char, sink:&:sink:char <- new-channel 30
|
2016-10-16 18:11:54 +00:00
|
|
|
start-running receive-from-file file, sink
|
2016-08-21 01:29:09 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
# fake file system
|
2016-09-17 17:28:25 +00:00
|
|
|
i:num <- copy 0
|
2016-10-16 06:55:21 +00:00
|
|
|
data:&:@:resource <- get *resources, data:offset
|
2016-09-17 17:28:25 +00:00
|
|
|
len:num <- length *data
|
2016-08-21 01:29:09 +00:00
|
|
|
{
|
2016-09-17 17:32:57 +00:00
|
|
|
done?:bool <- greater-or-equal i, len
|
2016-08-21 01:29:09 +00:00
|
|
|
break-if done?
|
2016-10-16 06:55:21 +00:00
|
|
|
tmp:resource <- index *data, i
|
2016-08-26 17:45:42 +00:00
|
|
|
i <- add i, 1
|
2016-09-12 07:06:40 +00:00
|
|
|
curr-filename:text <- get tmp, name:offset
|
2016-09-17 17:32:57 +00:00
|
|
|
found?:bool <- equal filename, curr-filename
|
2016-08-21 01:29:09 +00:00
|
|
|
loop-unless found?
|
2016-09-17 19:55:10 +00:00
|
|
|
contents:&:source:char, sink:&:sink:char <- new-channel 30
|
2016-09-12 07:06:40 +00:00
|
|
|
curr-contents:text <- get tmp, contents:offset
|
2016-10-16 18:11:54 +00:00
|
|
|
start-running receive-from-text curr-contents, sink
|
2016-08-21 01:29:09 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
return 0/not-found
|
2016-08-17 00:13:26 +00:00
|
|
|
]
|
|
|
|
|
2016-10-16 18:11:54 +00:00
|
|
|
def receive-from-file file:num, sink:&:sink:char -> sink:&:sink:char [
|
2016-08-17 00:13:26 +00:00
|
|
|
local-scope
|
|
|
|
load-ingredients
|
|
|
|
{
|
2016-09-17 17:32:57 +00:00
|
|
|
c:char, eof?:bool <- $read-from-file file
|
2016-08-21 15:13:44 +00:00
|
|
|
break-if eof?
|
2016-08-17 00:13:26 +00:00
|
|
|
sink <- write sink, c
|
|
|
|
loop
|
|
|
|
}
|
|
|
|
sink <- close sink
|
2016-08-21 15:08:41 +00:00
|
|
|
file <- $close-file file
|
2016-08-19 04:09:27 +00:00
|
|
|
]
|
|
|
|
|
2016-10-16 18:11:54 +00:00
|
|
|
def receive-from-text contents:text, sink:&:sink:char -> sink:&:sink:char [
|
2016-08-21 01:29:09 +00:00
|
|
|
local-scope
|
|
|
|
load-ingredients
|
2016-09-17 17:28:25 +00:00
|
|
|
i:num <- copy 0
|
|
|
|
len:num <- length *contents
|
2016-08-21 01:29:09 +00:00
|
|
|
{
|
2016-09-17 17:32:57 +00:00
|
|
|
done?:bool <- greater-or-equal i, len
|
2016-08-21 01:29:09 +00:00
|
|
|
break-if done?
|
2016-09-17 07:31:55 +00:00
|
|
|
c:char <- index *contents, i
|
2016-08-21 01:29:09 +00:00
|
|
|
sink <- write sink, c
|
|
|
|
i <- add i, 1
|
|
|
|
loop
|
|
|
|
}
|
|
|
|
sink <- close sink
|
|
|
|
]
|
|
|
|
|
2016-10-16 06:55:21 +00:00
|
|
|
def start-writing resources:&:resources, filename:text -> sink:&:sink:char, routine-id:num [
|
2016-08-19 04:09:27 +00:00
|
|
|
local-scope
|
|
|
|
load-ingredients
|
2016-09-17 19:55:10 +00:00
|
|
|
source:&:source:char, sink:&:sink:char <- new-channel 30
|
2016-08-25 21:00:06 +00:00
|
|
|
{
|
2016-10-16 06:55:21 +00:00
|
|
|
break-if resources
|
2016-08-25 21:00:06 +00:00
|
|
|
# real file system
|
2016-09-17 17:28:25 +00:00
|
|
|
file:num <- $open-file-for-writing filename
|
2016-08-25 21:00:06 +00:00
|
|
|
assert file, [no such file]
|
|
|
|
routine-id <- start-running transmit-to-file file, source
|
|
|
|
reply
|
|
|
|
}
|
|
|
|
# fake file system
|
|
|
|
# beware: doesn't support multiple concurrent writes yet
|
2016-10-16 06:55:21 +00:00
|
|
|
routine-id <- start-running transmit-to-fake-file resources, filename, source
|
2016-08-19 04:09:27 +00:00
|
|
|
]
|
|
|
|
|
2016-09-17 19:55:10 +00:00
|
|
|
def transmit-to-file file:num, source:&:source:char -> source:&:source:char [
|
2016-08-19 04:09:27 +00:00
|
|
|
local-scope
|
|
|
|
load-ingredients
|
|
|
|
{
|
2016-09-17 17:32:57 +00:00
|
|
|
c:char, done?:bool, source <- read source
|
2016-08-19 04:09:27 +00:00
|
|
|
break-if done?
|
|
|
|
$write-to-file file, c
|
|
|
|
loop
|
|
|
|
}
|
2016-08-21 15:08:41 +00:00
|
|
|
file <- $close-file file
|
2016-08-17 00:13:26 +00:00
|
|
|
]
|
2016-08-25 21:00:06 +00:00
|
|
|
|
2016-10-16 06:55:21 +00:00
|
|
|
def transmit-to-fake-file resources:&:resources, filename:text, source:&:source:char -> resources:&:resources, source:&:source:char [
|
2016-08-25 21:00:06 +00:00
|
|
|
local-scope
|
|
|
|
load-ingredients
|
|
|
|
# compute new file contents
|
2016-09-17 19:55:10 +00:00
|
|
|
buf:&:buffer <- new-buffer 30
|
2016-08-25 21:00:06 +00:00
|
|
|
{
|
2016-09-17 17:32:57 +00:00
|
|
|
c:char, done?:bool, source <- read source
|
2016-08-25 21:00:06 +00:00
|
|
|
break-if done?
|
|
|
|
buf <- append buf, c
|
|
|
|
loop
|
|
|
|
}
|
2016-09-12 07:06:40 +00:00
|
|
|
contents:text <- buffer-to-array buf
|
2016-10-16 06:55:21 +00:00
|
|
|
new-resource:resource <- merge filename, contents
|
|
|
|
# write to resources
|
2016-09-12 07:06:40 +00:00
|
|
|
curr-filename:text <- copy 0
|
2016-10-16 06:55:21 +00:00
|
|
|
data:&:@:resource <- get *resources, data:offset
|
2016-08-25 21:00:06 +00:00
|
|
|
# replace file contents if it already exists
|
2016-09-17 17:28:25 +00:00
|
|
|
i:num <- copy 0
|
|
|
|
len:num <- length *data
|
2016-08-26 18:27:13 +00:00
|
|
|
{
|
2016-09-17 17:32:57 +00:00
|
|
|
done?:bool <- greater-or-equal i, len
|
2016-08-26 18:27:13 +00:00
|
|
|
break-if done?
|
2016-10-16 06:55:21 +00:00
|
|
|
tmp:resource <- index *data, i
|
2016-08-26 18:27:13 +00:00
|
|
|
curr-filename <- get tmp, name:offset
|
2016-09-17 17:32:57 +00:00
|
|
|
found?:bool <- equal filename, curr-filename
|
2016-08-26 18:27:13 +00:00
|
|
|
loop-unless found?
|
2016-10-16 06:55:21 +00:00
|
|
|
put-index *data, i, new-resource
|
2016-08-26 18:27:13 +00:00
|
|
|
reply
|
|
|
|
}
|
|
|
|
# if file didn't already exist, make room for it
|
2016-09-17 17:28:25 +00:00
|
|
|
new-len:num <- add len, 1
|
2016-10-16 06:55:21 +00:00
|
|
|
new-data:&:@:resource <- new resource:type, new-len
|
|
|
|
put *resources, data:offset, new-data
|
2016-08-25 21:00:06 +00:00
|
|
|
# copy over old files
|
2016-09-17 17:28:25 +00:00
|
|
|
i:num <- copy 0
|
2016-08-25 21:00:06 +00:00
|
|
|
{
|
2016-09-17 17:32:57 +00:00
|
|
|
done?:bool <- greater-or-equal i, len
|
2016-08-25 21:00:06 +00:00
|
|
|
break-if done?
|
2016-10-16 06:55:21 +00:00
|
|
|
tmp:resource <- index *data, i
|
2016-08-25 21:00:06 +00:00
|
|
|
put-index *new-data, i, tmp
|
|
|
|
}
|
|
|
|
# write new file
|
2016-10-16 06:55:21 +00:00
|
|
|
put-index *new-data, len, new-resource
|
2016-08-25 21:00:06 +00:00
|
|
|
]
|