?? kafs.c
字號:
/****************************************************************
* KAFS.C
*
* Keyed Access File Definitions
*
* Keyed Access File System Version 2.0
*
* 2.0 Revised to contain keys and data in a single file.
* Key Access Files (KAF) are self contained.
* 9/23/92 - Added 'filecommit' function in KAFS.
* 2.1 11/11/92 - Qualified rec value for delete, read_rec, write_rec
*
****************************************************************/
#include <dos.h>
#include <fcntl.h>
#include <stdio.h>
#include <math.h>
#include <sys\stat.h>
/**********************************************************
* Key Access files definitions
**********************************************************/
#define TRUE 1
#define FALSE 0
#define OK 0
#define SOF -1 /* Start of File */
#define FCLOSED -1
#define ERR -1
#define NOTFOUND -2
#define FILEFULL -3
#define KAEOF -4 /* Reached End Of File on Sequential Read */
/**
** KEY ACCESS ERROR CODES - Value held in kaerror global Variable
**
1 - File Already Open
2 - Not a valid KAFSII file
3 - Error Attempting to Open Data File
4 - File Not Open
5 - Seek Error on Data File
6 - Read Error on Data File
7 - Write Error on Data File
8 - Error Reading Hash Index Block
9 - Error Writing Hash Index Block
10 - Invalid Channel Number
11 - Passed Key Argument exceeds keysize
12 - File Name too Long or Invalid
13 - Rec exceeds file's extent
**
**/
#define HBLOCKSIZE 1024
#define KEYSTART 128 /* Start of File's Key Blocks */
#define KEYFILES 16 /* Number of key files allowed */
#define MAXRECSIZE 512 /* Maximum Record Size allowed */
#define MAXKEYSIZE 40 /* Maximum Key Size allowed */
/* ------------- File Definition Structure (Allow 256 Bytes) --------- */
struct fildef {
char signature[7]; /* KAFSII */
char filename[16]; /* User's File Name */
int keysize; /* Size of Key Field */
int recsize; /* Size of a Record */
long records; /* Number of Records */
int kpb; /* Keys per Block */
long hblocks; /* Hash blocks (calculated) */
long dbeg; /* File Position for Data Beginning */
};
/* ------------- File Table Definition ---------------- */
struct ft {
int handle; /* Data File's handle */
int keysize; /* Size of the key field */
int recsize; /* Size of record */
char fname[16];/* Filename (User's) */
long records; /* File defined max records */
long hblocks; /* Hash blocks (calculated) */
int kpb; /* Keys per block (calculated) */
long dbeg; /* File position for beginning of Data */
};
/*********************************************************************
* Function Prototypes
*********************************************************************/
int ka_open(int, char *);
void ka_close_all(void);
void ka_close(int);
int read_key(int, char *, void *);
int read_rec(int, void *);
int read_xrec(int, void *);
int write_key(int, char *, void *);
int write_rec(int, void *);
int write_upd(int, void *);
int rdelete(int, long);
int read_seq(int, void *);
int read_hblk(int, long);
int write_hblk(int, long);
long khash(char *, long);
void filecommit(int);
char hbuf[HBLOCKSIZE]; /* Define the Hash Buffer */
long rec; /* Global Record Number */
int kaerror = 0; /* Global Error Code */
char *kaversion = "V2.01 - 11/11/92"; /* Version 2.0 */
char key[MAXKEYSIZE+1]; /* Global Key 40 chars max */
/* Define the file table structure */
struct ft ftbl[KEYFILES+1]=
{-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0,
-1,0,0,"",0,0,0,0};
struct fildef fdef; /* File Definition structure */
/********************************************************************
* KA_OPEN - Open a keyed access file.
*
* All Keyed Access files have the extension 'KAF'.
*
********************************************************************/
ka_open(int fn, char * fname)
{
unsigned mode;
char buffer[256]; /* Used to build filename & read in file defs */
if(strlen(fname)>76) /* Validate filename parameter */
{
kaerror = 12; /* Filename too Long */
return(ERR);
}
if(fn <0 || fn >= KEYFILES) /* Validate filenumber */
{
kaerror = 10; /* Invalid Channel Number */
return(ERR);
}
if(ftbl[fn].handle != -1)
{
kaerror = 1;
return(ERR); /* File already Open */
}
strcpy(buffer, fname); /* Build the KAF filename */
strcat(buffer, ".KAF");
/*
* Set the mode for opening or for Creating a new file
*/
mode = O_RDWR | O_BINARY | O_DENYNONE;
ftbl[fn].handle = open(buffer, mode ,S_IREAD | S_IWRITE);
if(ftbl[fn].handle==ERR)
{
kaerror = 3; /* Unable to Open File */
return(ERR);
}
/*
* Read the File's Definition and set the file table values
*/
if(read(ftbl[fn].handle, &fdef, sizeof(fdef))==ERR ||
strcmp(fdef.signature, "KAFSII"))
{
kaerror = 2; /* Not a KAFSII file */
return(ERR);
}
ftbl[fn].keysize = fdef.keysize; /* size of key */
ftbl[fn].recsize = fdef.recsize; /* Record size */
ftbl[fn].records = fdef.records;
ftbl[fn].kpb = fdef.kpb; /* Keys per Block */
ftbl[fn].hblocks =fdef.hblocks; /* Number of hash Blocks */
ftbl[fn].dbeg = fdef.dbeg; /* Start of Data Pointer */
strcpy(ftbl[fn].fname, fdef.filename);
return(OK);
}
/** -------- Close Files -------- */
void ka_close_all(void)
{
int i;
for(i=0;i<KEYFILES;i++) ka_close(i);
}
void ka_close(int fn)
{
if(ftbl[fn].handle > -1) close(ftbl[fn].handle);
ftbl[fn].handle = -1;
}
/** -----------------------------------------------------------------
** READ_KEY - Read a key access file by key.
** This function hashes the key to find the record if Rec = SOF
** If Rec != SOF reads for key at rec + 1
** ----------------------------------------------------------------- */
read_key(int fn, char *keyarg, void *buffer)
{
long hblk;
long startblock; /* Starting point for search */
int brec; /* Record number in Block */
char *hp;
key[0]=0; /* Blank Key for Return */
if(ftbl[fn].handle == FCLOSED || fn < 0 || fn >= KEYFILES)
{
kaerror = 4; /* File not open */
return(ERR);
}
if(rec==SOF)
{
hblk = khash(keyarg, ftbl[fn].hblocks); /* Get the Hashed Block */
rec = hblk * ftbl[fn].kpb; /* Calculate record number at beginning */
}
else
{
rec++;
if(rec > ftbl[fn].records) rec = 0; /* Wrap At EOF */
hblk = (long)rec/ftbl[fn].kpb; /* Or block based on rec */
}
if(read_hblk(ftbl[fn].handle, hblk)==ERR) return(ERR);
startblock = hblk; /* Save for wrap-arounds */
brec = rec - (hblk * ftbl[fn].kpb);
hp = hbuf + (brec * ftbl[fn].keysize); /* point to Record in Buffer */
while(TRUE)
{
if(*hp == 0) return(NOTFOUND);
if(!strcmp(hp,keyarg))
{
strcpy(key,hp); /* copy the key */
return(read_xrec(fn, buffer)); /* FOUND */
}
rec++; /* Bump the record number */
brec++; /* Bump the block record number */
hp += ftbl[fn].keysize; /* Move the Pointer to the next key */
if(brec>=ftbl[fn].kpb)
{
hblk++;
if(hblk >= ftbl[fn].hblocks) hblk=0; /* Wrap around at EOF */
if(hblk == startblock) return(NOTFOUND); /* Oops We wrapped around */
if(read_hblk(ftbl[fn].handle, hblk)==ERR) return(ERR); /* Read Nxt Blk */
hp = hbuf; /* Point to beginning of block */
brec = 0;
rec = hblk * ftbl[fn].kpb; /* Calculate Record # */
}
}
}
/** -----------------------------------------------------------------
** READ_REC - External Access to Read a key access file by Record Number.
** This function reads only the Data portion of a record.
** Returns the key for the record in global key.
**
** 2.0 Modified to Add Data Offset
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -