📄 findrec.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * findrec.c (file) * * File management * Record retrieval */#include "fileio.h"#include "diskio.h"LOCAL ER getFileName( FileName fname, LINK *lnk, FsInfo *fsinfo );LOCAL ER seekRecord( RCB **rcb, W offset, OFCB *ofcb );LOCAL ER findRecord( RCB **rcb, W fwd, UW typemask, UH subtype, OFCB *ofcb );LOCAL WER matchLinkRecord( RCB *rcb, W mode, LINK *lnk, RIdx *ri, SFN *sfn, FsInfo *fsinfo );LOCAL ER findLinkRecord( RCB **rcb, W fwd, W mode, LINK *lnk, UH subtype, OFCB *ofcb );LOCAL WER startRecord( RCB **rcb, W mode, OFCB *ofcb );LOCAL ER setRecnum( W *recnum, RCB *rcb, OFCB *ofcb );LOCAL ER searchLinkRecord_O( RIdx *ri, W fid, FileName fname, W n, RCB **rcb, OFCB *ofcb );LOCAL ER searchLinkRecord_C( RIdx *ri, W fid, FileName fname, W n, OFCB *ofcb );#define TSD_MLR_POS_0 0#define TSD_MLR_POS_1 1#define TSD_MLR_POS_2 2#define TSD_MLR_POS_3 3#define TSD_MLR_POS_4 4#define TSD_FRE_PTN_0X00000001 0x00000001U#define TSD_FIS_VAL_M1 (-1)#define TSD_FLR_MSK_0X7F00 0x7f00U#define TSD_FFR_MSK_0XF 0xfU#define TSD_SLR_VAL_0X80 (UB)0x80/* * Obtain the file name of lnk. */LOCAL ER getFileName( FileName fname, LINK *lnk, FsInfo *fsinfo ){ ER err; if ( isSameFS(lnk->fs_name, fsinfo) != 0 ) { /* lnk is the current file system. */ err = fmpGetFileName(lnk->f_id, fname, fsinfo); if ( err < E_OK ) { goto err_ret; } } else { /* lnk is a different file system. */ err = fmIGetFileInfo(lnk, fname, NULL, NULL); if ( err < E_OK ) { goto err_ret; } } return E_OK;err_ret: DEBUG_PRINT(("getFileName err = %d\n", err)); return err;}/* * Move the record. * Return the record that has moved from *rcb by offset to *rcb. */LOCAL ER seekRecord( RCB **rcb, W offset, OFCB *ofcb ){ RCB *p = *rcb; if ( offset >= 0 ) { /* Move in the direction of higher record number. */ while ( --offset >= 0 ) { if ( isEndRCB(p, ofcb) ) { return E_REC; } p = nextRCB(p); } } else { /* Move in the direction of lower record number. */ while ( ++offset <= 0 ) { p = prevRCB(p); if ( isEndRCB(p, ofcb) ) { return E_REC; } } } *rcb = p; return E_OK;}/* * Record retrieval * Search from *rcb to fwd, and return the record that matches in typemask/subtype * to *rcb. */LOCAL ER findRecord( RCB **rcb, W fwd, UW typemask, UH subtype, OFCB *ofcb ){ RCB *p = *rcb; ER err; while ( !isEndRCB(p, ofcb) ) { /* Make valid the contents of RCB. */ err = fmpSetRCB(p, ofcb); if ( err < E_OK ) { return err; } /* Record type */ if ( (INT)((TSD_FRE_PTN_0X00000001 << p->rtype) & typemask) != 0 ) { /* Record subtype */ if ( (subtype == 0) || (p->stype == subtype) ) { /* Found */ *rcb = p; return E_OK; } } p = ( fwd == 0 )? prevRCB(p): nextRCB(p); } return E_REC; /* Not found */}/* * Judge the link record search condition. * Perform matching between the record of *rcb and *lnk according to mode. * When matched, return 1. When not matched, return 0. */LOCAL WER matchLinkRecord( RCB *rcb, W mode, LINK *lnk, RIdx *ri, SFN *sfn, FsInfo *fsinfo ){ BOOL match = TRUE; DfRecordIndex *ridx; BOOL bigEndian = fsinfo->bigEndian; ER err; /* Read the record index. */ err = fmpSeekRIdx(ri, &rcb->idxadr); if ( err < E_OK ) { goto err_ret1; } ridx = fmpGetRIdx(ri); if ( ridx == NULL ) { goto err_ret2; } if ( match && ((W)((UW)mode & (UW)F_SFILE) != 0) ) { /* Same file */ FID fid = fmConvEndianH(ridx->l.fid, bigEndian); match = (fid == lnk->f_id); } if ( match && ((W)((UW)mode & (UW)F_SNAME) != 0) ) { /* Same file name */ FID fid = fmConvEndianH(ridx->l.fid, bigEndian); err = fmpMatchSFN(sfn, fid, NULL); if ( err < E_OK ) { goto err_ret1; } match = (BOOL)err; } if ( match && ((W)((UW)mode & (UW)F_SATR1) != 0) ) { /* Same attribute data 1 */ UH atr = fmConvEndianH(ridx->l.atr[TSD_MLR_POS_0], bigEndian); match = (atr == lnk->atr1); } if ( match && ((W)((UW)mode & (UW)F_SATR2) != 0) ) { /* Same attribute data 2 */ UH atr = fmConvEndianH(ridx->l.atr[TSD_MLR_POS_1], bigEndian); match = (atr == lnk->atr2); } if ( match && ((W)((UW)mode & (UW)F_SATR3) != 0) ) { /* Same attribute data 3 */ UH atr = fmConvEndianH(ridx->l.atr[TSD_MLR_POS_2], bigEndian); match = (atr == lnk->atr3); } if ( match && ((W)((UW)mode & (UW)F_SATR4) != 0) ) { /* Same attribute data 4 */ UH atr = fmConvEndianH(ridx->l.atr[TSD_MLR_POS_3], bigEndian); match = (atr == lnk->atr4); } if ( match && ((W)((UW)mode & (UW)F_SATR5) != 0) ) { /* Same attribute data 5 */ UH atr = fmConvEndianH(ridx->l.atr[TSD_MLR_POS_4], bigEndian); match = (atr == lnk->atr5); } return match;err_ret2: err = fmpGetRIdxError(ri);err_ret1: DEBUG_PRINT(("matchLinkRecord err = %d\n", err)); return err;}/* * Link record retrieval * Search from *rcb to fwd according to mode, * and return the record that matches in lnk/subtype to *rcb. */LOCAL ER findLinkRecord( RCB **rcb, W fwd, W mode, LINK *lnk, UH subtype, OFCB *ofcb ){ FsInfo *fsinfo = ofcb->fsinfo; BOOL match = FALSE; RCB *p = *rcb; RIdx ri; SFN sfn; FileName fname; ER err; if ( ((UW)mode & ~TSD_FLR_MSK_0X7F00) != 0U ) { err = E_PAR; goto err_ret1; } /* Prepare to read the record index. */ err = fmpOpenRIdx(&ri, FIRST_RIdx, ofcb); if ( err < E_OK ) { goto err_ret1; } if ( ((UW)mode & (UW)F_SFILE) != 0U ) { if ( !isSameFS(lnk->fs_name, fsinfo) ) { err = E_REC; goto err_ret2; } } if ( ((UW)mode & (UW)F_SNAME) != 0U ) { /* Obtain the file name of lnk. */ err = getFileName(fname, lnk, fsinfo); if ( err < E_OK ) { goto err_ret2; } /* Prepare to retrieve the file name. */ err = fmpOpenSFN(&sfn, fname, fsinfo); if ( err < E_OK ) { goto err_ret2; } } while ( !isEndRCB(p, ofcb) ) { /* Make valid the contents of RCB. */ err = fmpSetRCB(p, ofcb); if ( err < E_OK ) { goto err_ret3; } /* Whether the record type and record subtype match or not. */ if ( isLinkRecord(p->rtype) && ((subtype == 0 )||( p->stype == subtype))) { /* Judge the search condition. */ err = matchLinkRecord(p, mode, lnk, &ri, &sfn, fsinfo); if ( err < E_OK ) { goto err_ret3; } match = (BOOL)err; if ( match != FALSE ) { /* Found */ *rcb = p; break; } } p = ( fwd == 0 )? prevRCB(p): nextRCB(p); } if ( ((UW)mode & (UW)F_SNAME) != 0U ) { err = fmpCloseSFN(&sfn); if ( err < E_OK ) { goto err_ret2; } } err = fmpCloseRIdx(&ri); if ( err < E_OK ) { goto err_ret1; } return ( match != 0 )? E_OK: E_REC;err_ret3: if ( ((UW)mode & (UW)F_SNAME) != 0U ) { (void)fmpCloseSFN(&sfn); }err_ret2: (void)fmpCloseRIdx(&ri);err_ret1: DEBUG_PRINT(("findLinkRecord err = %d\n", err)); return err;}/* * Select a record to start searching from according to the mode specification. * Set *rcb to the current record and call it. * Select a record to start searching from according to mode, and return it to *rcb. * Return the search direction (Forward 1/Backward 0) to the return value. */LOCAL WER startRecord( RCB **rcb, W mode, OFCB *ofcb ){ RCB *p = *rcb; W fwd; switch ( mode ) { case F_FWD: /* Forward search */ fwd = 1; break; case F_BWD: /* Backward search */ fwd = 0; break; case F_NFWD: /* Forward search (from the next) */ if ( isEndRCB(p, ofcb) != 0 ) { return E_REC; } p = nextRCB(p); fwd = 1; break; case F_NBWD: /* Backward search (from the previous) */ p = prevRCB(p); if ( isEndRCB(p, ofcb) != 0 ) { return E_REC; } fwd = 0; break; case F_TOPEND: /* From the start to end */ p = FirstRCB(ofcb); fwd = 1; break; case F_ENDTOP: /* From the end to start */ p = prevRCB(EndRCB(ofcb)); fwd = 0; break; default: return E_PAR; } *rcb = p; return fwd;}/* * Return the record number to recnum. */LOCAL ER setRecnum( W *recnum, RCB *rcb, OFCB *ofcb ){ ER err; if ( recnum != NULL ) { err = CheckSpaceRW(recnum, sizeof(W)); if ( err < E_OK ) { return err; } if ( isEndRCB(rcb, ofcb) != 0 ) { *recnum = ofcb->nrec; } else { err = fmpSetRCB(rcb, ofcb); if ( err < E_OK ) { return err; } *recnum = rcb->recnum; } } return E_OK;}/* * Move the record position. */EXPORT void fmpSeekRecord( FmCmdPkt *pkt ){ FM_SEE_REC_PARA *cmdPara = (FM_SEE_REC_PARA*)pkt->cmd.para; FD *fd; OFCB *ofcb; RCB *rcb; ER err; /* Obtain FD and OFCB. */ fd = getFDp(cmdPara->fd); ofcb = fd->ofcb; /* Start record */ if ( cmdPara->mode == 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -