home *** CD-ROM | disk | FTP | other *** search
- /*
- * indexlib.c: tiny database index library
- *
- * Author: HIRAHO Satoshi
- * (C) 1989 Halca Computer Science Laboratory TM
- *
- * Edition History:
- * 1.1 89/07/14 Halca.Hirano creation for hterm set-up help system
- * ---- hterm V2.3.-1 distribution ----
- * 1.2 89/08/14 Halca.Hirano binary-tree version (ten times faster than v1.1)
- * ---- V2.4.0 distribution ----
- * 1.3 90/06/30 Halca.Hirano compress database
- * 1.4 90/07/13 Halca.Hirano check version number
- *
- * HOW TO USE THIS LIBRARY:
- * % indexer foo.doc foo.db
- *
- * openIndex("foo.db"); This may be called repeatively.
- * size = keyGet("my key", nextKey); returns default next key
- * while (getRecord(line, size) != -1)
- * printf(line);
- * size = keyGet(nextKey, nextKey2);
- * while (getRecord(line, size) != -1)
- * printf(line);
- * .....
- * closeIndex()
- *
- *
- * $Header: indexlib.cv 1.8 90/07/04 01:27:36 hirano Exp $
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include "indexer.h"
-
- #define YES 1
- #define NO 0
- #define ERR (-1)
- #define OK 0
- #define MAX_LINE 256
-
- #ifdef MSDOS
- #define IN_ATTR "rb"
- #else
- #define IN_ATTR "r"
- #endif /* MSDOS */
-
-
- static FILE *ifp; /* input file */
- static Index keys; /* keys */
- static struct _header header;
- static opened = NO;
- static int keyFound;
- static int gotSize;
-
- static int ReadCode(FILE *fp,unsigned short bits);
- static void ResetRead(void );
- static int ReadChar(FILE *fp);
-
- int openIndex(file)
- /*
- * open index file
- * in:
- * file database file name
- * out:
- * 0 OK
- * -1 error
- */
- char *file;
- {
- ResetRead();
- if (opened == YES)
- return(OK);
- if ((ifp = fopen(file, IN_ATTR)) == NULL)
- return(ERR);
- if (fread(&header, sizeof(header), 1, ifp) <= 0)
- return(ERR);
- if (!(header.version == I_VERSION && header.revision == I_REVISION))
- return(ERR);
- opened = YES;
- return(OK);
- }
-
- int closeIndex()
- /*
- * close index file
- *
- * out: always 0
- */
- {
- if (opened == YES)
- fclose(ifp);
- opened = NO;
- return(OK);
- }
-
- int getKey(key, nextKey)
- /*
- * search record by given key
- *
- * in:
- * key key string
- * out:
- * nextKey default next key
- * return:
- * num record size
- * -1 error (not found, not opend)
- */
- char *key, *nextKey;
- {
- int i, gs;
- long at;
-
- if (opened == NO)
- return(ERR);
- fseek(ifp, header.indexOffset, 0);
- for (i = 0; i < header.numIndex; i++) { /* this condition avoids infinit loop. */
- if (fread(&keys, sizeof(keys), 1, ifp) <= 0)
- return(ERR);
- if ((gs = strcmp(key, keys.key)) == 0) {/* key match */
- fseek(ifp, keys.offset, 0);
- keyFound = YES;
- strcpy(nextKey, keys.nextKey);
- gotSize = 0;
- ResetRead();
- return((int)keys.size);
- }
- if ((at = gs > 0 ? keys.right : keys.left) == -1) {
- keyFound = NO;
- return(ERR);
- }
- fseek(ifp, at, 0); /* walk binary-tree */
- }
- keyFound = NO;
- return(ERR);
- }
-
- int getRecord(line, n)
- /*
- * return record
- *
- * in:
- * line record buffer address
- * n size of buffer
- * out:
- * 0 if OK (buffer is filled)
- * -1 error (key not found, end of record, not opened)
- * NOTE:
- * getKey() must be called before getRecord().
- */
- char *line;
- int n;
- {
- char *p;
-
- if (keyFound == NO)
- return(ERR);
- for (p = line; --n >= 0 && gotSize < keys.size;) {
- *p = ReadChar(ifp);
- /* printf("%c", *p); */
- gotSize++;
- if (*p++ == '\n')
- break;
- }
- *p++ = '\0';
- /* printf("%s", line); */
- if (gotSize >= keys.size)
- keyFound = NO;
- return(OK);
- }
-
- #ifdef COMPRESS_DB
- #include <stdio.h>
-
- static int BitsLeft;
- static int BitLength;
- static unsigned long BitBuff;
- static unsigned short MaxCode;
- static int NotFirstTime;
-
- static unsigned short mask[] =
- {
- 0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
- };
-
- static unsigned char *sp;
- static unsigned char stack[1024-256];
- static struct {
- unsigned short code;
- unsigned char ch;
- } table[1024 - 256];
-
- static int ReadCode(FILE *fp, unsigned short bits)
- /* Read n-bit code from file. Return EOF on end of file. */
- {
- register int value, c;
-
- while (BitsLeft < bits) {
- if ((c = getc(fp)) == EOF) {
- return EOF;
- }
- BitBuff = (BitBuff << 8) + (c & 0xff);
- BitsLeft = BitsLeft + 8;
- }
- BitsLeft -= bits;
- value = BitBuff >> BitsLeft;
- BitBuff = BitBuff & mask[BitsLeft];
-
- return value;
- }
-
- static void ResetRead(void)
- {
- extern unsigned char *XFerBuffer;
-
- NotFirstTime = 0;
- BitsLeft = 0;
- BitBuff = 0;
- MaxCode = 255;
- BitLength = 9;
- sp = stack;
- }
-
- static int ReadChar(FILE *fp)
- {
- register unsigned short s, c;
- register int code;
- static unsigned short LastCode;
-
- if (! NotFirstTime) {
- NotFirstTime = 1;
- LastCode = ReadCode(fp, BitLength);
- return LastCode;
- }
- if (sp > stack)
- return *--sp;
- if ((code = ReadCode(fp, BitLength)) == EOF)
- return EOF;
- if (code > MaxCode) {
- printf("Bad code %d, MaxCode = %d", code, (int) MaxCode);
- return EOF; /* Ill-formed input file. */
- }
- s = code;
- while (s > 255) {
- c = table[s - 256].ch;
- if (c == 0) {
- printf("Null ch for %d\n", (int)s);
- }
- s = table[s - 256].code;
- *sp++ = c;
- }
- if (s == 0) {
- printf("Null char for %d\n", LastCode);
- }
- /* Add new code to table. */
- if (MaxCode < 1023) {
- MaxCode++;
- if (MaxCode == 511)
- BitLength = 10;
- table[MaxCode - 256].code = LastCode;
- table[MaxCode - 256].ch = s;
- }
- LastCode = code;
- return s;
- }
- #else
- static void ResetRead()
- {}
- static int ReadChar(fp)
- FILE *fp;
- {
- return(getc(fp));
- }
- #endif
-