implement Dv;
include "sys.m";
sys: Sys;
include "draw.m";
include "styx.m";
styx : Styx;
Rmsg : import styx;
include "styxservers.m";
styxservers: Styxservers;
Styxserver, Navigator: import styxservers;
include "bufio.m";
bufio : Bufio;
Iobuf : import bufio;
include "string.m";
str : String;
include "arg.m";
arg: Arg;
include "bytelib.m";
nametree: Nametree;
Tree: import nametree;
tree : ref Tree;
bitshift : con 32;
Qroot, Qnew, Qmeta_folder, Qframes_folder, Qfilename, Qctl, Qframe, Qrow, Qnumber_of_rows, Q: con big iota; # paths
src_file : adt {
filename : array of byte;
};
frame : adt {
rgb : array of byte;
};
src_files : array of src_file ;
file_count := 0;
frames : array of frame ;
frame_count := 0;
# module definition
Dv: module
{
init: fn(nil: ref Draw->Context, argv: list of string);
Parse_ID : adt {
sct : int;
dsn : int;
fsc : int;
dbn : int;
read_io : fn(id: self ref Parse_ID, io : ref Iobuf);
};
};
init(nil: ref Draw->Context, args: list of string)
{
sys = load Sys Sys->PATH;
arg = load Arg Arg->PATH;
styx = load Styx Styx->PATH;
bufio = load Bufio Bufio->PATH;
treeop : chan of ref Styxservers->Navop;
str = load String String->PATH;
styx->init();
styxservers = load Styxservers Styxservers->PATH;
styxservers->init(styx);
nametree = load Nametree Nametree->PATH;
nametree->init();
sys->pctl(Sys->FORKNS, nil);
(tree, treeop) = nametree->start();
tree.create(Qroot, dir(".", 8r555|Sys->DMDIR, Qroot));
tree.create(Qroot, dir("new", 8r666, Qnew));
starting_filename : string;
arg->init(args);
while((c := arg->opt()) != 0)
case c {
'f' => starting_filename = arg->arg();
* => sys->print("unknown option (%c)\n", c);
}
if(starting_filename != nil)
add_src_file(array of byte starting_filename);
(tchan, srv) := Styxserver.new(sys->fildes(0),Navigator.new(treeop), Qroot);
reply : ref Rmsg;
while((gm := <-tchan) != nil) {
pick m := gm {
Read => {
fid := srv.getfid(m.fid);
qtype := big int(fid.path);
case (qtype) {
Qfilename => {
i := int(fid.path >> bitshift);
reply = styxservers->readbytes(m, src_files[i].filename);
}
}
}
Write => {
fid := srv.getfid(m.fid);
qtype := big int(fid.path);
case (qtype) {
Qnew => {
reply = ref Rmsg.Write(m.tag, len m.data);
}
Qctl => {
reply = ref Rmsg.Write(m.tag, len m.data);
}
}
}
}
if(reply == nil) {
srv.default(gm);
} else {
srv.reply(reply);
reply = nil;
}
}
tree.quit();
}
dir(name: string, perm: int, qid: big): Sys->Dir {
d := sys->zerodir;
d.name = name;
d.uid = "inferno";
d.gid = "inferno";
d.qid.path = qid;
if (perm & Sys->DMDIR)
d.qid.qtype = Sys->QTDIR;
else
d.qid.qtype = Sys->QTFILE;
d.mode = perm;
return d;
}
add_frame(parent : big) {
if (frame_count == len frames)
extend_frames();
frames[frame_count].rgb = nil;
bcc := big frame_count;
bcc = bcc << bitshift;
tree.create(parent, dir(sys->sprint("%d", frame_count), 8r755 | Sys->DMDIR, bcc + Qframe));
frame_count++;
}
extend_frames() {
quarter := 5 + len frames / 4; # formula plucked from thin air
new_frames := array[len frames + quarter] of frame;
if (len frames > 0)
new_frames [0:] = frames;
frames = new_frames ;
}
extend_files() { # grow the files array
quarter := 5 + len src_files / 4; # formula plucked from thin air
new_files := array[len src_files + quarter] of src_file;
if (len src_files > 0)
new_files[0:] = src_files;
src_files = new_files;
}
add_src_file(name : array of byte) {
if (file_count == len src_files)
extend_files();
src_files[file_count] = src_file(name);
add_meta_folder();
file_count++;
}
add_meta_folder() {
bfc := big file_count;
bfc = bfc << bitshift;
m_qid := bfc + Qmeta_folder;
f_qid := bfc + Qframes_folder;
tree.create(Qroot, dir(sys->sprint("%d", file_count), 8r755 | Sys->DMDIR, m_qid));
tree.create(m_qid, dir("frames", 8r555 | Sys->DMDIR, f_qid));
tree.create(m_qid, dir("src_filename", 8r444, bfc + Qfilename));
tree.create(m_qid, dir("ctl", 8r644, bfc +Qctl));
}
Parse_ID.read_io(id : self ref Parse_ID, io : ref Iobuf)
{
}
int8_read(io : ref Iobuf) : int
{
bytes := array[3] of byte;
io.read(bytes, 3);
(nil, value) := bytes_to_int(bytes);
return value;
}
# Put Limbo Dv
|