diff options
-rw-r--r-- | 088file.mu | 48 | ||||
-rw-r--r-- | 090scenario_filesystem_test.mu | 31 |
2 files changed, 76 insertions, 3 deletions
diff --git a/088file.mu b/088file.mu index 09d3b0fa..f2dde0a1 100644 --- a/088file.mu +++ b/088file.mu @@ -73,12 +73,21 @@ def transmit-from-text contents:address:array:character, sink:address:sink:chara def start-writing fs:address:filesystem, filename:address:array:character -> sink:address:sink:character, routine-id:number [ local-scope load-ingredients - file:number <- $open-file-for-writing filename source:address:source:character, sink:address:sink:character <- new-channel 30 - routine-id <- start-running transmit-to-file file, source + { + break-if fs + # real file system + file:number <- $open-file-for-writing filename + 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 + routine-id <- start-running transmit-to-fake-file fs, filename, source ] -def transmit-to-file file:number, source:address:source:character -> file:number, source:address:source:character [ +def transmit-to-file file:number, source:address:source:character -> source:address:source:character [ local-scope load-ingredients { @@ -89,3 +98,36 @@ def transmit-to-file file:number, source:address:source:character -> file:number } file <- $close-file file ] + +def transmit-to-fake-file fs:address:filesystem, filename:address:array:character, source:address:source:character -> fs:address:filesystem, source:address:source:character [ + local-scope + load-ingredients + # compute new file contents + buf:address:buffer <- new-buffer 30 + { + c:character, done?:boolean, source <- read source + break-if done? + buf <- append buf, c + loop + } + contents:address:array:character <- buffer-to-array buf + new-file-mapping:file-mapping <- merge filename, contents + # write to filesystem + curr-filename:address:array:character <- copy 0 + data:address:array:file-mapping <- get *fs, data:offset + # replace file contents if it already exists + len:number <- length *data + new-len:number <- add len, 1 + new-data:address:array:file-mapping <- new file-mapping:type, new-len + put *fs, data:offset, new-data + # copy over old files + i:number <- copy 0 + { + done?:boolean <- greater-or-equal i, len + break-if done? + tmp:file-mapping <- index *data, i + put-index *new-data, i, tmp + } + # write new file + put-index *new-data, len, new-file-mapping +] diff --git a/090scenario_filesystem_test.mu b/090scenario_filesystem_test.mu index 4d4624eb..de93a2d9 100644 --- a/090scenario_filesystem_test.mu +++ b/090scenario_filesystem_test.mu @@ -21,3 +21,34 @@ scenario read-from-fake-file [ 5 <- 1 # eof ] ] + +scenario write-to-fake-file [ + local-scope + assume-filesystem [ + #[a] <- [] + ] + sink:address:sink:character, writer:number/routine <- start-writing filesystem:address:filesystem, [a] + sink <- write sink, 120/x + sink <- write sink, 121/y + close sink + wait-for-routine writer + contents-read-back:address:array:character <- slurp filesystem, [a] + 10:boolean/raw <- equal contents-read-back, [xy] + memory-should-contain [ + 10 <- 1 # file contents read back exactly match what was written + ] +] + +def slurp fs:address:filesystem, filename:address:array:character -> contents:address:array:character [ + local-scope + load-ingredients + source:address:source:character <- start-reading fs, filename + buf:address:buffer <- new-buffer 30/capacity + { + c:character, done?:boolean, source <- read source + break-if done? + buf <- append buf, c + loop + } + contents <- buffer-to-array buf +] |