Improved file/stat

This commit is contained in:
JJ Bliss
2026-05-08 12:48:24 -04:00
parent 7d48d5824c
commit 9c60296d21
+67 -96
View File
@@ -5,6 +5,7 @@ use io;
use bytes; use bytes;
use bufio; use bufio;
use strings; use strings;
use strconv;
fn generate_dir_string(name: str) str = { fn generate_dir_string(name: str) str = {
// fmt::println("Generating dir string!")!; // fmt::println("Generating dir string!")!;
@@ -116,109 +117,79 @@ fn read_file_to_addr(fi: u8, state: *uxn) void = {
}; };
return; return;
}; };
export type stattype = enum {
FILE,
DIR,
BIG,
MISS,
};
fn filestat_to_addr(fi: u8, state: *uxn) void = { fn filestat_to_addr(fi: u8, state: *uxn) void = {
const length = if(fi == 0) { yield short_from_bytes(state.dev[0xaa],state.dev[0xab]); } const length = if(fi == 0) { yield short_from_bytes(state.dev[0xaa],state.dev[0xab]); }
else { yield short_from_bytes(state.dev[0xba],state.dev[0xbb]); }; else { yield short_from_bytes(state.dev[0xba],state.dev[0xbb]); };
const destaddr = if(fi == 0) { yield short_from_bytes(state.dev[0xa4],state.dev[0xa5]); } const destaddr = if(fi == 0) { yield short_from_bytes(state.dev[0xa4],state.dev[0xa5]); }
else { yield short_from_bytes(state.dev[0xb4],state.dev[0xb5]); }; else { yield short_from_bytes(state.dev[0xb4],state.dev[0xb5]); };
// fmt::printfln("Reading {} bytes to 0x{:x}", length, destaddr)!;
let bytesread = 0; let bytesread = 0;
const nameaddr = if(fi == 0) { yield short_from_bytes(state.dev[0xa8],state.dev[0xa9]); }
else { yield short_from_bytes(state.dev[0xb8],state.dev[0xb9]); };
const nameslice: []u8 = bytes::cut(state.ram[nameaddr..],0x00).0;
const name: str = match(strings::fromutf8(nameslice)){
case let s: str =>
yield s;
case =>
fmt::fatal("Bad String encoding in filename");
};
if(!state.files[fi].dir){ const fstat = match(os::fstat(state.files[fi].file: io::file)){
const nameaddr = if(fi == 0) { yield short_from_bytes(state.dev[0xa8],state.dev[0xa9]); } case let fstat: fs::filestat =>
else { yield short_from_bytes(state.dev[0xb8],state.dev[0xb9]); }; yield fstat;
const nameslice: []u8 = bytes::cut(state.ram[nameaddr..],0x00).0; case let err: fs::error =>
const name: str = match(strings::fromutf8(nameslice)){ yield void;
case let s: str => };
yield s; const fsize = match(fstat){
case => case let stat: fs::filestat =>
fmt::fatal("Bad String encoding in filename"); yield stat.sz: u32;
case =>
yield void;
};
const ftype: stattype = {
if(state.files[fi].dir) yield stattype::DIR;
yield match(fsize){
case let num: u32 =>
if(num > 0xFFFF) yield stattype::BIG;
yield stattype::FILE;
case void =>
yield stattype::MISS;
}; };
const fstat = match(os::fstat(state.files[fi].file: io::file)){ };
case let fstat: fs::filestat => const sz = match(fsize){
yield fstat; case void =>
case let err: fs::error => yield 0;
yield void; case let s: u32 =>
yield s;
}; };
const fsize = match(fstat){ const modestring: str = switch(ftype){
case let stat: fs::filestat => case stattype::FILE =>
yield stat.sz: u32; yield fmt::asprintf("{%}",sz,&fmt::mods { base = strconv::base::HEX, prec = length, ...})!;
case => case stattype::DIR =>
yield 0: u32; yield fmt::asprintf("{%}","-",&fmt::mods { pad = '-', width = length, ...})!;
case stattype::BIG =>
}; yield fmt::asprintf("{%}","?",&fmt::mods { pad = '?', width = length, ...})!;
const modestring = if(fsize <= 0xFFFF){ case stattype::MISS =>
yield fmt::asprintf("{:x.4}",fsize)!; yield fmt::asprintf("{%}","!",&fmt::mods { pad = '!', width = length, ...})!;
}else { };
yield "????";
}; let modestringiter = strings::iter(modestring);
let modestringiter = strings::iter(modestring); for(let i: u16 =0; i<length; i+=1){
for(let i: u16 =0; i<length; i+=1){ let char: rune = match(strings::next(&modestringiter)){
let char: rune = match(strings::next(&modestringiter)){ case let r: rune =>
case let r: rune => yield r;
yield r; case done =>
case done => fmt::fatal("Stat string messed up");
break;
};
bytesread += 1;
state.ram[destaddr+i] = char: u8;
};
for(let i: u16 =0; i<length; i+=1){
match (bufio::read_byte(state.files[fi].file)){
case let b: u8 =>
bytesread += 1;
// fmt::printfln("Reading byte {}: from file",b)!;
state.ram[destaddr+i] = b;
case let eof: io::EOF =>
state.ram[destaddr+i] = 0; //This might need to be done differently
case let err: io::error =>
fmt::fatalf("Error reading: {}", io::strerror(err));
};
};
}else {
const nameaddr = if(fi == 0) { yield short_from_bytes(state.dev[0xa8],state.dev[0xa9]); }
else { yield short_from_bytes(state.dev[0xb8],state.dev[0xb9]); };
const nameslice: []u8 = bytes::cut(state.ram[nameaddr..],0x00).0;
const name: str = match(strings::fromutf8(nameslice)){
case let s: str =>
yield s;
case =>
fmt::fatal("Bad String encoding in filename");
};
let dfs = os::diropen(name)!;
let df = os::dirfile(dfs);
const stat = os::fstat(df)!;
const fsize = stat.sz: u32;
const modestring = if(fsize <= 0xFFFF){
yield fmt::asprintf("{:x.4}",fsize)!;
}else {
yield "????";
};
let modestringiter = strings::iter(modestring);
for(let i: u16 =0; i<length; i+=1){
let char: rune = match(strings::next(&modestringiter)){
case let r: rune =>
yield r;
case done =>
break;
};
bytesread += 1;
state.ram[destaddr+i] = char: u8;
};
for(let i: u16 =0; i<length; i+=1){
match (bufio::read_byte(state.files[fi].file)){
case let b: u8 =>
bytesread += 1;
// fmt::printfln("Reading byte {}: from file",b)!;
state.ram[destaddr+i] = b;
case let eof: io::EOF =>
state.ram[destaddr+i] = 0; //This might need to be done differently
case let err: io::error =>
fmt::fatalf("Error reading: {}", io::strerror(err));
};
}; };
bytesread += 1;
state.ram[destaddr+i] = char: u8;
}; };
if(fi == 0){ if(fi == 0){
@@ -240,7 +211,7 @@ fn write_file_from_addr(fi: u8,state: *uxn) void = {
const appendf: bool = if(fi == 0) { yield state.dev[0xa7] != 0; } const appendf: bool = if(fi == 0) { yield state.dev[0xa7] != 0; }
else { yield state.dev[0xb7] != 0; }; else { yield state.dev[0xb7] != 0; };
// fmt::printfln("Writing {} bytes from 0x{:x}", length, srcaddr)!; // fmt::printfln("Writing {} bytes from 0x{:x}", length, srcaddr)!;
fmt::printfln("Writing {} bytes from 0x{:x} to 0x{:x}", endaddr-srcaddr, srcaddr,endaddr)!; // fmt::printfln("Writing {} bytes from 0x{:x} to 0x{:x}", endaddr-srcaddr, srcaddr,endaddr)!;
// const bytes: []u8 = state.ram[srcaddr..endaddr]; // const bytes: []u8 = state.ram[srcaddr..endaddr];
const bytes: []u8 = if(endaddr < srcaddr){ const bytes: []u8 = if(endaddr < srcaddr){
yield state.ram[srcaddr..]; yield state.ram[srcaddr..];
@@ -384,7 +355,7 @@ fn write_file_from_addr(fi: u8,state: *uxn) void = {
match (io::write(state.files[fi].file,bytes)){ match (io::write(state.files[fi].file,bytes)){
case let s: size => case let s: size =>
byteswritten += s: u16; byteswritten += s: u16;
fmt::printfln("Writing {} bytes to file",s)!; // fmt::printfln("Writing {} bytes to file",s)!;
case let err: io::error => case let err: io::error =>
fmt::fatalf("Error writing file: {}", io::strerror(err)); fmt::fatalf("Error writing file: {}", io::strerror(err));
}; };