home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / COMM / MISC / SRC26_2.ZIP / SRC / INDEXLIB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-13  |  5.4 KB  |  276 lines

  1. /*
  2.  * indexlib.c: tiny database index library
  3.  *
  4.  * Author: HIRAHO Satoshi
  5.  * (C) 1989  Halca Computer Science Laboratory TM
  6.  *
  7.  * Edition History:
  8.  * 1.1 89/07/14 Halca.Hirano creation for hterm set-up help system
  9.  *    ---- hterm V2.3.-1 distribution ----
  10.  * 1.2 89/08/14 Halca.Hirano binary-tree version (ten times faster than v1.1)
  11.  *     ---- V2.4.0 distribution ----
  12.  * 1.3 90/06/30 Halca.Hirano compress database
  13.  * 1.4 90/07/13 Halca.Hirano check version number
  14.  *
  15.  * HOW TO USE THIS LIBRARY:
  16.  *    % indexer foo.doc foo.db
  17.  *
  18.  *    openIndex("foo.db");        This may be called repeatively.
  19.  *    size = keyGet("my key", nextKey);    returns default next key
  20.  *    while (getRecord(line, size) != -1)
  21.  *        printf(line);
  22.  *    size = keyGet(nextKey, nextKey2);
  23.  *    while (getRecord(line, size) != -1)
  24.  *        printf(line);
  25.  *    .....
  26.  *    closeIndex()
  27.  *
  28.  *
  29.  * $Header: indexlib.cv  1.8  90/07/04 01:27:36  hirano  Exp $
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <string.h>
  34. #include <ctype.h>
  35. #include "indexer.h"
  36.  
  37. #define YES        1
  38. #define NO        0
  39. #define ERR        (-1)
  40. #define    OK        0
  41. #define MAX_LINE    256
  42.  
  43. #ifdef MSDOS
  44. #define IN_ATTR "rb"
  45. #else
  46. #define IN_ATTR "r"
  47. #endif /* MSDOS */
  48.  
  49.  
  50. static FILE *ifp;            /* input file         */
  51. static Index keys;                /* keys            */
  52. static struct _header header;
  53. static opened = NO;
  54. static int keyFound;
  55. static int gotSize;
  56.  
  57. static  int ReadCode(FILE *fp,unsigned short bits);
  58. static  void ResetRead(void );
  59. static  int ReadChar(FILE *fp);
  60.  
  61. int openIndex(file)
  62. /*
  63.  * open index file
  64.  * in:
  65.  *    file    database file name
  66.  * out:
  67.  *    0    OK
  68.  *    -1    error
  69.  */
  70. char *file;
  71. {
  72.     ResetRead();
  73.     if (opened == YES)
  74.         return(OK);
  75.     if ((ifp = fopen(file, IN_ATTR)) == NULL)
  76.         return(ERR);
  77.     if (fread(&header, sizeof(header), 1, ifp) <= 0)
  78.         return(ERR);
  79.     if (!(header.version == I_VERSION && header.revision == I_REVISION))
  80.         return(ERR);
  81.     opened = YES;
  82.     return(OK);
  83. }
  84.  
  85. int closeIndex()
  86. /*
  87.  * close index file
  88.  *
  89.  * out: always 0
  90.  */
  91. {
  92.     if (opened == YES)
  93.         fclose(ifp);
  94.     opened = NO;
  95.     return(OK);
  96. }
  97.  
  98. int getKey(key, nextKey)
  99. /*
  100.  * search record by given key
  101.  *
  102.  * in:
  103.  *    key    key string
  104.  * out:
  105.  *    nextKey    default next key
  106.  * return:
  107.  *    num    record size
  108.  *    -1    error (not found, not opend)
  109.  */
  110. char *key, *nextKey;
  111. {
  112.     int i, gs;
  113.     long at;
  114.  
  115.     if (opened == NO)
  116.         return(ERR);
  117.     fseek(ifp, header.indexOffset, 0);
  118.     for (i = 0; i < header.numIndex; i++) {    /* this condition avoids infinit loop. */
  119.         if (fread(&keys, sizeof(keys), 1, ifp) <= 0)
  120.             return(ERR);
  121.         if ((gs = strcmp(key, keys.key)) == 0) {/* key match    */
  122.             fseek(ifp, keys.offset, 0);
  123.             keyFound = YES;
  124.             strcpy(nextKey, keys.nextKey);
  125.             gotSize = 0;
  126.             ResetRead();
  127.             return((int)keys.size);
  128.         }
  129.         if ((at = gs > 0 ? keys.right : keys.left) == -1) {
  130.             keyFound = NO;
  131.             return(ERR);
  132.         }
  133.         fseek(ifp, at, 0);    /* walk binary-tree        */
  134.     }
  135.     keyFound = NO;
  136.     return(ERR);
  137. }
  138.  
  139. int getRecord(line, n)
  140. /*
  141.  * return record
  142.  *
  143.  * in:
  144.  *    line    record buffer address
  145.  *    n    size of buffer
  146.  * out:
  147.  *    0    if OK (buffer is filled)
  148.  *    -1    error (key not found, end of record, not opened)
  149.  * NOTE:
  150.  *    getKey() must be called before getRecord().
  151.  */
  152. char *line;
  153. int n;
  154. {
  155.     char *p;
  156.  
  157.     if (keyFound == NO)
  158.         return(ERR);
  159.     for (p = line; --n >= 0 && gotSize < keys.size;) {
  160.         *p = ReadChar(ifp);
  161.         /* printf("%c", *p); */
  162.         gotSize++;
  163.         if (*p++ == '\n')
  164.             break;
  165.     }
  166.     *p++ = '\0';
  167.     /* printf("%s", line); */
  168.     if (gotSize >= keys.size)
  169.         keyFound = NO;
  170.     return(OK);
  171. }
  172.     
  173. #ifdef COMPRESS_DB
  174. #include    <stdio.h>
  175.  
  176. static int    BitsLeft;
  177. static int    BitLength;
  178. static unsigned long    BitBuff;
  179. static unsigned short    MaxCode;
  180. static int    NotFirstTime;
  181.  
  182. static unsigned short mask[] = 
  183. {
  184.     0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
  185. };
  186.  
  187. static unsigned char *sp;
  188. static unsigned char stack[1024-256];
  189. static struct {
  190.     unsigned short code;
  191.     unsigned char ch;
  192. } table[1024 - 256];
  193.  
  194. static int ReadCode(FILE *fp, unsigned short bits)
  195. /* Read n-bit code from file.  Return EOF on end of file. */
  196. {
  197.     register int    value, c;
  198.  
  199.     while (BitsLeft < bits) {
  200.         if ((c = getc(fp)) == EOF) {
  201.             return EOF;
  202.         }
  203.         BitBuff = (BitBuff << 8) + (c & 0xff);
  204.         BitsLeft = BitsLeft + 8;
  205.     }
  206.     BitsLeft -= bits;
  207.     value = BitBuff >> BitsLeft;
  208.     BitBuff = BitBuff & mask[BitsLeft];
  209.  
  210.     return value;
  211. }
  212.  
  213. static void ResetRead(void)
  214. {
  215.     extern unsigned char *XFerBuffer;
  216.     
  217.     NotFirstTime = 0;
  218.     BitsLeft = 0;
  219.     BitBuff = 0;
  220.     MaxCode = 255;
  221.     BitLength = 9;
  222.     sp = stack;
  223. }
  224.  
  225. static int ReadChar(FILE *fp)
  226. {
  227.     register unsigned short    s, c;
  228.     register int code;
  229.     static unsigned short LastCode;
  230.  
  231.     if (! NotFirstTime) {
  232.         NotFirstTime = 1;
  233.         LastCode = ReadCode(fp, BitLength);
  234.         return LastCode;
  235.     }
  236.     if (sp > stack)
  237.         return *--sp;
  238.     if ((code = ReadCode(fp, BitLength)) == EOF)
  239.         return EOF;
  240.     if (code > MaxCode) {
  241.         printf("Bad code %d, MaxCode = %d", code, (int) MaxCode);
  242.         return EOF;        /* Ill-formed input file. */
  243.     }
  244.     s = code;
  245.     while (s > 255) {
  246.         c = table[s - 256].ch;
  247.         if (c == 0) {
  248.             printf("Null ch for %d\n", (int)s);
  249.         }
  250.         s = table[s - 256].code;
  251.         *sp++ = c;
  252.     }
  253.     if (s == 0) {
  254.         printf("Null char for %d\n", LastCode);
  255.     }
  256.     /* Add new code to table. */
  257.     if (MaxCode < 1023) {
  258.         MaxCode++;
  259.         if (MaxCode == 511)
  260.             BitLength = 10;
  261.         table[MaxCode - 256].code = LastCode;
  262.         table[MaxCode - 256].ch = s;
  263.     }
  264.     LastCode = code;
  265.     return s;
  266. }
  267. #else
  268. static void ResetRead()
  269. {}
  270. static int ReadChar(fp)
  271. FILE *fp;
  272. {
  273.     return(getc(fp));
  274. }
  275. #endif
  276.