作者itoc, 信區: itoc
標題[文件] rec_*() 的意思
時間04/02/07
作者: itoc (Internet Explorer) 看板: plan
標題: [文件] rec_*() 的意思
時間: Fri Mar 14 10:24:22 2003
fpath: 索引的路徑 (file path)
data: 資料
size: 資料的大小 (單位: bytes)
fchk: 複查的函式 (check function)
fref: 更新的函式 (refresh function)
fsync: 同步的函式 (synchronize function)
pos: 第幾筆位置 (position)
num: 數量 (number)
: rec_add.c (Record Add)
[語法] rec_add(fpath, data, size)
[說明] 把 data 這筆資料,附加在 fpath 最後
[範例] pal_add()
PAL pal;
/* 製造一個 PAL */
memset(&pal, 0, sizeof(PAL));
vget(b_lines, 0, "友誼:", pal.ship, sizeof(pal.ship), DOECHO);
pal.ftype = vans("壞人(Y/N)?[N] ") == 'y' ? PAL_BAD : 0;
strcpy(pal.userid, acct.userid);
pal.userno = userno;
/* 將 PAL 寫入 */
rec_add(xo->dir, &pal, sizeof(PAL));
: rec_bot.c (Record Bottom)
[語法] rec_bot(fpath, data, size)
[說明] 把 data 這筆資料,附加在 fpath 第一筆置底文的前面
[範例] do_unanonymous()
HDR hdr;
/* 製造一個 HDR */
hdr_stamp(folder, HDR_LINK | 'A', &hdr, fpath);
strcpy(hdr.owner, cuser.userid);
strcpy(hdr.title, ve_title);
/* 將 HDR 寫入 */
rec_bot(folder, &hdr, sizeof(HDR));
: rec_del.c (Record Delete)
[語法] rec_del(fpath, size, pos, fchk)
[說明] 把 fpath 的第 pos 筆資料刪除
為避免刪錯資料,刪除前要做 fchk 確認
[範例] pal_delete()
/* 無條件將游標所在這筆資料刪除 */
rec_del(xo->dir, sizeof(PAL), xo->pos, NULL);
[範例] post_delete()
static int currchrono;
int
cmpchrono(hdr)
HDR *hdr;
{
return hdr->chrono == currchrono;
}
static int
post_delete(xo)
XO *xo;
{
/* 將游標所在這筆資料刪除,但刪除前要做 chrono 的 compare
若相同才刪除,以免誤砍 */
currchrono = hdr->chrono;
rec_del(xo->dir, sizeof(HDR), xo->pos, cmpchrono);
}
: rec_get.c (Record Get)
[語法] rec_get(fpath, data, size, pos)
[說明] 把 fpath 的第 pos 筆資料取出放到 data
[範例] pal_loadpal()
PAL pal;
/* 從好友名單中取中第 i 筆資料 */
if (rec_get(fpath, &pal, sizeof(PAL), i) >= 0)
{
/* 如果這筆資料不是壞人,就加入板友名單 */
if (!(pal.ftype & PAL_BAD))
rec_add(dir, &pal, sizeof(PAL));
}
: rec_ins.c (Record Insert)
[語法] rec_ins(fpath, data, size, pos, num)
[說明] 把 data 這 num 筆資料,插入在 fpath 的第 pos 筆位置
[範例] gem_add()
HDR ghdr;
/* 製造一個 HDR */
...
...
/* 詢問要插入的位置 */
ans = vans("存放位置 A)加到最後 I/N)插入目前位置 Q)離開 [A] ");
if (ans == 'i') /* 若選 Insert 則插入目前位置 */
rec_ins(xo->dir, &ghdr, sizeof(HDR), xo->pos, 1);
else if (ans == 'n') /* 若選 Next 則插入下一筆位置 */
rec_ins(xo->dir, &ghdr, sizeof(HDR), xo->pos + 1, 1);
else /* 反之,則附加在最後 */
rec_add(xo->dir, &ghdr, sizeof(HDR));
: rec_num.c (Record Number)
[語法] rec_num(fpath, size)
[說明] 回傳 fpath 總共有幾筆資料
[範例] acct_show()
usr_fpath(buf, uid, fn_dir);
prints(" 個人信件:%d 封", rec_num(buf, sizeof(HDR)));
: rec_put.c (Record Put/Update)
[語法] rec_put(fpath, data, size, pos, fchk)
[說明] 以 data 去更新 fpath 的第 pos 筆資料
為避免更新錯資料,更新前要做 fchk 確認
[範例] pal_change()
PAL *pal;
/* 重新編輯游標所在這筆好友友誼 */
pal = (PAL *) xo_pool + cur;
vget(b_lines, 0, "友誼:", pal->ship, sizeof(pal->ship), GCARRY);
pal->ftype = vans("壞人(Y/N)?[N] ") == 'y' ? PAL_BAD : 0;
/* 無條件更新這筆資料 */
rec_put(xo->dir, pal, sizeof(PAL), pos, NULL);
[範例] post_mark()
HDR *hdr;
/* 加上/去除 mark */
hdr = (HDR *) xo_pool + xo->pos - xo->top;
hdr->xmode ^= POST_MARKED;
/* 將游標所在這筆資料更新,但更新前要做 chrono 的 compare
若相同才更新,以免更新錯篇 */
currchrono = hdr->chrono;
rec_put(xo->dir, hdr, sizeof(HDR), xo->pos, cmpchrono);
: rec_ref.c (Record Refresh/Update)
[語法] rec_ref(fpath, data, size, pos, fchk, fref)
[說明] 以 data 去更新 fpath 的第 pos 筆資料
為避免更新錯資料,更新前要做 fchk 確認
更新時做的動作是 fref
[備註] 這是一個類似 rec_put() 的函式,差別在於多了個 fref
可以拿硬碟中的索引檔直接來改,避免 XO 和 .DIR 不同步的問題
[範例] post_score()
static int curraddscore;
static void
addscore(hdd, ram)
HDR *hdd, *ram;
{
/* 直接把 .DIR 中的 score 更新,不管 XO 裡面的 score 是記錄多少 */
hdd->score += curraddscore;
}
static int
post_score(xo)
XO *xo;
{
HDR *hdr;
...
ans = vans("加減分 1)推文 2)唾棄 Q)取消?[Q] ");
if (ans == '1') /* 加分 */
curraddscore = 1;
else if (ans == '2') /* 扣分 */
curraddscore = -1;
currchrono = hdr->chrono;
rec_ref(dir, hdr, sizeof(HDR), pos, cmpchrono, addscore);
...
}
: rec_sync.c (Record Synchronize)
[語法] rec_sync(fpath, size, fsync, fchk)
[說明] 把 fpath 這個索引檔同步並排序
[範例] pal_sync()
static int
cmppal(a, b)
PAL *a, *b;
{
/* 依 userid 排序 */
return str_cmp(a->userid, b->userid);
}
static int
chkpal(pal)
PAL *pal;
{
/* 檢查好友名單中每筆資料,若 userno 錯誤,刪除該筆資料 */
int userno = pal->userno;
return (userno > 0 && userno == acct_userno(pal->userid));
}
void
pal_sync()
{
/* 檢查好友名單中每筆資料是否 userno 正確,並依 userid 排序 */
usr_fpath(fpath, cuser.userid, fn_pal);
rec_sync(fpath, sizeof(PAL), cmppal, chkpal);
}
: rec_mov.c (Record Move)
rec_mov.c 目前都沒用到
> ---------------------------------------------------------- <
至於要用 HDR hdr; PAL pal; ...
還是用 HDR *hdr; PAL *pal; ... 指標
: 如果要新增/附加一筆資料,就是用 HDR hdr;
HDR hdr;
/* 製造一個 HDR */
hdr.chrono = time(0);
strcpy(hdr.owner, cuser.userid);
/* 寫回硬碟 */
rec_add(folder, &hdr, sizeof(HDR));
: 如果要更新一筆資料,就是用 HDR *hdr;
HDR *hdr;
/* 從 XO 中取出目前游標所在這筆資料的值 */
hdr = (HDR *) xo_pool + xo->pos - xo->top;
/* 更新這筆資料 */
hdr->xmode ^= POST_MARKED;
/* 寫回硬碟 */
currchrono = hdr->chrono;
rec_put(xo->dir, hdr, sizeof(HDR), xo->pos, cmpchrono);
--
□ 本文章由 itoc 從 itoc.Dorm-GD2.NCTU.edu.tw 發表