moved file device to seperate file
This commit is contained in:
+473
@@ -0,0 +1,473 @@
|
||||
use fmt;
|
||||
use os;
|
||||
use fs;
|
||||
use io;
|
||||
use bytes;
|
||||
use bufio;
|
||||
use strings;
|
||||
|
||||
fn generate_dir_string(name: str) str = {
|
||||
// fmt::println("Generating dir string!")!;
|
||||
let list: []u8 = [];
|
||||
const fs: *fs::fs = match(os::diropen(name)){
|
||||
case let f: *fs::fs =>
|
||||
yield f;
|
||||
case let err: fs::error =>
|
||||
fmt::fatalf("Error opening directory: {}", fs::strerror(err));
|
||||
|
||||
};
|
||||
let iter: *fs::iterator = match(fs::iter(fs,".")){
|
||||
case let i: *fs::iterator =>
|
||||
yield i;
|
||||
case let err: fs::error =>
|
||||
fmt::fatalf("No iterator in directory: {}", fs::strerror(err));
|
||||
// case null =>
|
||||
// fmt::fatalf("Null pointer when opening directory: {}", name);
|
||||
|
||||
};
|
||||
for(let item => fs::next(iter)){
|
||||
match(item){
|
||||
case let d: fs::dirent =>
|
||||
//001a file.txt
|
||||
//???? large_file.mp4
|
||||
// 0-f A file
|
||||
// - A directory
|
||||
// ? A file that is larger than 64kb
|
||||
// ! A missing file
|
||||
let leftstring = "!!!!";
|
||||
let namestring = d.name;
|
||||
if(d.ftype == fs::mode::DIR){
|
||||
leftstring = "----";
|
||||
namestring = strings::concat(d.name,"/")!;
|
||||
}else{
|
||||
const stat = fs::stat(fs,d.name)!;
|
||||
const fsize = stat.sz: u32;
|
||||
if(fsize <= 0xFFFF){
|
||||
leftstring = fmt::asprintf("{:x.4}",fsize)!;
|
||||
}else {
|
||||
leftstring = "????";
|
||||
};
|
||||
};
|
||||
const wholestring = strings::concat(strings::join(" ", leftstring, d.name)!, "\n")!;
|
||||
const utf8 = strings::toutf8(wholestring);
|
||||
for( let c .. utf8 ){
|
||||
append(list,c)!;
|
||||
};
|
||||
case let err: fs::error =>
|
||||
fmt::fatalf("Error looking in directory: {}", fs::strerror(err));
|
||||
};
|
||||
};
|
||||
return strings::fromutf8(list)!;
|
||||
};
|
||||
|
||||
fn read_file_to_addr(fi: u8, state: *uxn) void = {
|
||||
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]); };
|
||||
const destaddr = if(fi == 0) { yield short_from_bytes(state.dev[0xac],state.dev[0xad]); }
|
||||
else { yield short_from_bytes(state.dev[0xbc],state.dev[0xbd]); };
|
||||
// fmt::printfln("Reading {} bytes to 0x{:x}", length, destaddr)!;
|
||||
let bytesread = 0;
|
||||
|
||||
if(!state.files[fi].dir){
|
||||
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 =>
|
||||
break;
|
||||
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 dirstring = generate_dir_string(name);
|
||||
let dirstringiter = strings::iter(dirstring);
|
||||
for(let i: u16 =0; i<length; i+=1){
|
||||
let char: rune = match(strings::next(&dirstringiter)){
|
||||
case let r: rune =>
|
||||
yield r;
|
||||
case done =>
|
||||
break;
|
||||
};
|
||||
bytesread += 1;
|
||||
state.ram[destaddr+i] = char: u8;
|
||||
};
|
||||
// fmt::printf(dirstring)!;
|
||||
};
|
||||
|
||||
if(fi == 0){
|
||||
state.dev[0xa2] = (bytesread >> 8): u8;
|
||||
state.dev[0xa3] = (bytesread): u8;
|
||||
}else if(fi ==1){
|
||||
state.dev[0xb2] = (bytesread >> 8): u8;
|
||||
state.dev[0xb3] = (bytesread): u8;
|
||||
};
|
||||
return;
|
||||
};
|
||||
fn filestat_to_addr(fi: u8, state: *uxn) void = {
|
||||
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]); };
|
||||
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]); };
|
||||
// fmt::printfln("Reading {} bytes to 0x{:x}", length, destaddr)!;
|
||||
let bytesread = 0;
|
||||
|
||||
if(!state.files[fi].dir){
|
||||
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");
|
||||
};
|
||||
const stat = os::fstat(state.files[fi].file: io::file)!;
|
||||
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));
|
||||
};
|
||||
};
|
||||
|
||||
}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));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if(fi == 0){
|
||||
state.dev[0xa2] = (bytesread >> 8): u8;
|
||||
state.dev[0xa3] = (bytesread): u8;
|
||||
}else if(fi ==1){
|
||||
state.dev[0xb2] = (bytesread >> 8): u8;
|
||||
state.dev[0xb3] = (bytesread): u8;
|
||||
};
|
||||
return;
|
||||
};
|
||||
fn write_file_from_addr(fi: u8,state: *uxn) void = {
|
||||
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]); };
|
||||
const srcaddr = if(fi == 0) { yield short_from_bytes(state.dev[0xae],state.dev[0xaf]); }
|
||||
else { yield short_from_bytes(state.dev[0xbe],state.dev[0xbf]); };
|
||||
const endaddr = srcaddr + length;
|
||||
const appendf: bool = if(fi == 0) { yield state.dev[0xa7] != 0; }
|
||||
else { yield state.dev[0xb7] != 0; };
|
||||
fmt::printfln("Writing {} bytes from 0x{:x}", length, srcaddr)!;
|
||||
const bytes: []u8 = state.ram[srcaddr..endaddr];
|
||||
let byteswritten: u16 = 0;
|
||||
|
||||
if(!state.files[fi].exists){
|
||||
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");
|
||||
};
|
||||
const flags = if(appendf) {
|
||||
state.files[fi].fappend = true;
|
||||
yield (fs::flag::RDWR | fs::flag::APPEND);
|
||||
} else {
|
||||
yield fs::flag::RDWR;
|
||||
};
|
||||
state.files[fi].file = match (os::create(name,fs::mode::USER_RW,flags)){
|
||||
case let f: io::file =>
|
||||
state.files[fi].exists = true;
|
||||
yield f;
|
||||
case let err: fs::error =>
|
||||
fmt::fatalf("Error creating file file: {}", fs::strerror(err));
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
if(appendf && (state.files[fi].fappend == false)){
|
||||
//Rewrite File or adjust pointer
|
||||
io::close(state.files[fi].file)!;
|
||||
|
||||
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");
|
||||
};
|
||||
state.files[fi].file = match (os::open(name,fs::flag::RDWR | fs::flag::APPEND)) {
|
||||
case let file: io::file =>
|
||||
state.files[fi].exists = true;
|
||||
state.files[fi].dir = false;
|
||||
yield file;
|
||||
case let err: fs::error =>
|
||||
//Try opening as dir
|
||||
yield match(os::diropen(name)){
|
||||
case let f: *fs::fs =>
|
||||
let dfs = os::diropen(name)!;
|
||||
let df = os::dirfile(dfs);
|
||||
const stat = os::fstat(df)!;
|
||||
state.files[fi].dir = fs::isdir(stat.mode);
|
||||
if(state.files[fi].dir) {
|
||||
state.files[fi].exists = true;
|
||||
state.files[fi].dir = true;
|
||||
|
||||
};
|
||||
io::close(df)!;
|
||||
yield io::empty;
|
||||
case let err: fs::error =>
|
||||
// fmt::printfln("Error opening {}: {}", name, fs::strerror(err))!;
|
||||
if(fi == 0){
|
||||
state.dev[0xa2] = 0;
|
||||
state.dev[0xa3] = 0;
|
||||
}else if(fi ==1){
|
||||
state.dev[0xb2] = 0;
|
||||
state.dev[0xb3] = 0;
|
||||
};
|
||||
state.files[fi].exists = false;
|
||||
state.files[fi].dir = false;
|
||||
yield io::empty;
|
||||
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
state.files[fi].fappend = true;
|
||||
};
|
||||
|
||||
if(!appendf && (state.files[fi].fappend == true)){
|
||||
|
||||
io::close(state.files[fi].file)!;
|
||||
|
||||
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");
|
||||
};
|
||||
state.files[fi].file = match (os::open(name,fs::flag::RDWR)) {
|
||||
case let file: io::file =>
|
||||
state.files[fi].exists = true;
|
||||
state.files[fi].dir = false;
|
||||
yield file;
|
||||
case let err: fs::error =>
|
||||
//Try opening as dir
|
||||
yield match(os::diropen(name)){
|
||||
case let f: *fs::fs =>
|
||||
let dfs = os::diropen(name)!;
|
||||
let df = os::dirfile(dfs);
|
||||
const stat = os::fstat(df)!;
|
||||
state.files[fi].dir = fs::isdir(stat.mode);
|
||||
if(state.files[fi].dir) {
|
||||
state.files[fi].exists = true;
|
||||
state.files[fi].dir = true;
|
||||
|
||||
};
|
||||
io::close(df)!;
|
||||
yield io::empty;
|
||||
case let err: fs::error =>
|
||||
// fmt::printfln("Error opening {}: {}", name, fs::strerror(err))!;
|
||||
if(fi == 0){
|
||||
state.dev[0xa2] = 0;
|
||||
state.dev[0xa3] = 0;
|
||||
}else if(fi ==1){
|
||||
state.dev[0xb2] = 0;
|
||||
state.dev[0xb3] = 0;
|
||||
};
|
||||
state.files[fi].exists = false;
|
||||
state.files[fi].dir = false;
|
||||
yield io::empty;
|
||||
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
state.files[fi].fappend = false;
|
||||
};
|
||||
|
||||
match (io::write(state.files[fi].file,bytes)){
|
||||
case let s: size =>
|
||||
byteswritten += s: u16;
|
||||
fmt::printfln("Writing {} bytes to file",s)!;
|
||||
case let err: io::error =>
|
||||
fmt::fatalf("Error writing file: {}", io::strerror(err));
|
||||
};
|
||||
|
||||
if(fi == 0){
|
||||
state.dev[0xa2] = (byteswritten >> 8): u8;
|
||||
state.dev[0xa3] = (byteswritten): u8;
|
||||
}else if(fi ==1){
|
||||
state.dev[0xb2] = (byteswritten >> 8): u8;
|
||||
state.dev[0xb3] = (byteswritten): u8;
|
||||
};
|
||||
return;
|
||||
};
|
||||
fn set_file_name(fi: u8, state: *uxn) void = {
|
||||
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");
|
||||
};
|
||||
|
||||
io::close(state.files[fi].file)!;
|
||||
state.files[fi].fappend = false;
|
||||
// fmt::printfln("Opening file: {}",name)!;
|
||||
state.files[fi].file = match (os::open(name,fs::flag::RDWR)) {
|
||||
case let file: io::file =>
|
||||
state.files[fi].exists = true;
|
||||
state.files[fi].dir = false;
|
||||
yield file;
|
||||
case let err: fs::error =>
|
||||
//Try opening as dir
|
||||
yield match(os::diropen(name)){
|
||||
case let f: *fs::fs =>
|
||||
let dfs = os::diropen(name)!;
|
||||
let df = os::dirfile(dfs);
|
||||
const stat = os::fstat(df)!;
|
||||
state.files[fi].dir = fs::isdir(stat.mode);
|
||||
if(state.files[fi].dir) {
|
||||
state.files[fi].exists = true;
|
||||
state.files[fi].dir = true;
|
||||
|
||||
};
|
||||
io::close(df)!;
|
||||
yield io::empty;
|
||||
case let err: fs::error =>
|
||||
// fmt::printfln("Error opening {}: {}", name, fs::strerror(err))!;
|
||||
if(fi == 0){
|
||||
state.dev[0xa2] = 0;
|
||||
state.dev[0xa3] = 0;
|
||||
}else if(fi ==1){
|
||||
state.dev[0xb2] = 0;
|
||||
state.dev[0xb3] = 0;
|
||||
};
|
||||
state.files[fi].exists = false;
|
||||
state.files[fi].dir = false;
|
||||
yield io::empty;
|
||||
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
return;
|
||||
};
|
||||
|
||||
fn delete_file(fi: u8, state: *uxn) void = {
|
||||
let success: u8 = 0;
|
||||
if(state.files[fi].exists){
|
||||
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){
|
||||
match(os::remove(name)) {
|
||||
case void =>
|
||||
success = 1;
|
||||
yield;
|
||||
case let err: fs::error =>
|
||||
fmt::printf("Error deleting file: {}", fs::strerror(err))!;
|
||||
};
|
||||
}else{
|
||||
match(os::rmdir(name)) {
|
||||
case void =>
|
||||
success = 1;
|
||||
yield;
|
||||
case let err: fs::error =>
|
||||
fmt::printf("Error deleting dir: {}", fs::strerror(err))!;
|
||||
};
|
||||
};
|
||||
};
|
||||
if(fi == 0){
|
||||
state.dev[0xa2] = 0;
|
||||
state.dev[0xa3] = success;
|
||||
}else if(fi ==1){
|
||||
state.dev[0xb2] = 0;
|
||||
state.dev[0xb3] = success;
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user