ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /module/palmfile.m/
Palmfile: module {
PATH: con "/dis/lib/palmfile.dis";
DBInfo: adt {
name: string;
attr: int;
dtype: string; # database type (byte[4])
version: int; # defined by application
creator: string; # creating application (byte[4])
ctime: int;
mtime: int;
btime: int; # last backup
modno: int; # modification number: set to zero
uidseed: int; # unique record ID seed (unused, set to zero)
# used internally and by the database access protocol
appinfo: int; # AppInfo offset
sortinfo: int; # SortInfo offset
# the following are used by the database access protocol
index: int;
more: int;
new: fn(name: string, attr: int, dtype: string, version: int, creator: string): ref DBInfo;
};
# file attributes:
Fresource: con 1<<0; # file is .prc not .pdb
Fronly: con 1<<1; # read only
Fappinfodirty: con 1<<2;
Fbackup: con 1<<3; # no conduit exists
Foverwrite: con 1<<4; # overwrite older copy if present
Freset: con 1<<5; # reset after installation
Fprivate: con 1<<6; # don't allow copy of this to be beamed
Record: adt {
id: int; # resource: ID; data: unique record ID
index: int;
name: int; # byte[4]: resource record only
attr: int; # data record only
cat: int; # category
data: array of byte;
# new: fn(size: int): ref Record;
};
Entry: adt {
id: int; # resource: id; record: unique ID
offset: int;
size: int;
name: int; # resource entry only
attr: int; # record entry only
};
# record attributes:
Rdelete: con 16r80; # delete next sync
Rdirty: con 16r40; # record modified
Rinuse: con 16r20; # record in use
Rsecret: con 16r10; # record is secret
Rarchive: con 16r08; # archive next sync
Rmcat: con 16r0F; # mask for category field in Entry.attrs
# common form of category data in appinfo
Categories: adt {
renamed: int; # which categories have been renamed
labels: array of string; # 16 category names
uids: array of int; # corresponding unique IDs
lastuid: int; # last unique ID assigned
appdata: array of byte; # remaining data is application-specific
new: fn(labels: array of string): ref Categories;
unpack: fn(a: array of byte): ref Categories;
pack: fn(c: self ref Categories): array of byte;
mkidmap: fn(c: self ref Categories): array of int;
};
Pfile: adt {
fname: string;
f: ref Bufio->Iobuf;
mode: int;
info: ref DBInfo;
appinfo: array of byte;
sortinfo: array of int;
uidseed: int;
entries: array of ref Entry;
open: fn(nil: string, mode: int): (ref Pfile, string);
# create: fn(nil: string, mode: int, perm: int, nil: ref DBInfo): ref Pfile;
close: fn(nil: self ref Pfile): int;
stat: fn(nil: self ref Pfile): ref DBInfo;
# wstat: fn(nil: self ref Pfile, nil: ref DBInfo);
read: fn(nil: self ref Pfile, index: int): (ref Record, string);
# readid: fn(nil: self ref Pfile, nil: int): (ref Record, string);
# append: fn(nil: self ref Pfile, r: ref Record): int;
# setappinfo: fn(nil: self ref Pfile, nil: array of byte);
# setsortinfo: fn(nil: self ref Pfile, nil: array of int);
};
Doc: adt {
file: ref Pfile;
version: int;
length: int; # uncompressed
nrec: int; # text records only
recsize: int; # uncompressed
position: int;
sizes: array of int; # sizes of uncompressed records
open: fn(file: ref Pfile): (ref Doc, string);
read: fn(nil: self ref Doc, i: int): (string, string);
iscompressed: fn(nil: self ref Doc): int;
unpacktext: fn(d: self ref Doc, a: array of byte): (string, string);
textlength: fn(d: self ref Doc, a: array of byte): int;
};
init: fn(): string;
# name mapping
filename: fn(s: string): string;
dbname: fn(s: string): string;
# Latin-1 to string conversion
gets: fn(a: array of byte): string;
puts: fn(a: array of byte, s: string);
# big-endian conversion
get2: fn(a: array of byte): int;
get3: fn(a: array of byte): int;
get4: fn(a: array of byte): int;
put2: fn(a: array of byte, v: int);
put3: fn(a: array of byte, v: int);
put4: fn(a: array of byte, v: int);
};