Split of work into more files.
[idzebra-moved-to-github.git] / index / extract.c
1 /*
2  * Copyright (C) 1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: extract.c,v $
7  * Revision 1.1  1995-09-01 14:06:35  adam
8  * Split of work into more files.
9  *
10  */
11 #include <stdio.h>
12 #include <assert.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <ctype.h>
16
17 #include <util.h>
18 #include "index.h"
19
20 #define KEY_BUF_SIZE 100000
21
22 static Dict file_idx;
23 static SYSNO sysno_next;
24 static int key_fd = -1;
25 static char *key_buf;
26 static int key_offset;
27
28 void key_open (const char *fname)
29 {
30     void *file_key;
31     if (key_fd != -1)
32         return;
33     if ((key_fd = open (fname, O_RDWR|O_CREAT, 0666)) == -1)
34     {
35         log (LOG_FATAL|LOG_ERRNO, "Creat %s", fname);
36         exit (1);
37     }
38     if (!(key_buf = malloc (KEY_BUF_SIZE)))
39     {
40         log (LOG_FATAL|LOG_ERRNO, "malloc");
41         exit (1);
42     }
43     key_offset = 0;
44     if (!(file_idx = dict_open ("fileidx", 10, 1)))
45     {
46         log (LOG_FATAL, "dict_open fail of %s", "fileidx");
47         exit (1);
48     }
49     file_key = dict_lookup (file_idx, ".");
50     if (file_key)
51         memcpy (&sysno_next, (char*)file_key+1, sizeof(sysno_next));
52     else
53         sysno_next = 1;
54 }
55
56 void key_close (void)
57 {
58     if (key_fd == -1)
59         return;
60     close (key_fd);
61     dict_insert (file_idx, ".", sizeof(sysno_next), &sysno_next);
62     dict_close (file_idx);
63     key_fd = -1;
64 }
65
66 void key_flush (void)
67 {
68     size_t i = 0;
69     int w;
70     
71     while (i < key_offset)
72     {
73         w = write (key_fd, key_buf + i, key_offset - i);
74         if (w == -1)
75         {
76             log (LOG_FATAL|LOG_ERRNO, "Write key fail");
77             exit (1);
78         }
79         i += w;
80     }
81     key_offset = 0;
82 }
83
84 void key_write (int cmd, struct it_key *k, const char *str)
85 {
86     char x = cmd;
87     size_t slen = strlen(str);
88
89     if (key_offset + sizeof(*k) + slen >= KEY_BUF_SIZE - 2)
90         key_flush ();
91     memcpy (key_buf + key_offset, &x, 1);
92     key_offset++;
93     memcpy (key_buf + key_offset, k, sizeof(*k));
94     key_offset += sizeof(*k);
95     memcpy (key_buf + key_offset, str, slen+1);
96     key_offset += slen+1;
97 }
98
99 void text_extract (SYSNO sysno, int cmd, const char *fname)
100 {
101     FILE *inf;
102     struct it_key k;
103     int seqno = 1;
104     int c;
105     char w[256];
106
107     log (LOG_DEBUG, "Text extract of %d", sysno);
108     k.sysno = sysno;
109     inf = fopen (fname, "r");
110     if (!inf)
111     {
112         log (LOG_WARN|LOG_ERRNO, "open %s", fname);
113         return;
114     }
115     while ((c=getc (inf)) != EOF)
116     {
117         int i = 0;
118         while (i < 254 && c != EOF && isalnum(c))
119         {
120             w[i++] = c;
121             c = getc (inf);
122         }
123         if (i)
124         {
125             w[i] = 0;
126             
127             k.seqno = seqno++;
128             k.field = 0;
129             key_write (cmd, &k, w);
130         }
131         if (c == EOF)
132             break;
133     }
134     fclose (inf);
135 }
136
137 void file_extract (int cmd, const char *fname, const char *kname)
138 {
139     int i;
140     char ext[128];
141     SYSNO sysno;
142     char ext_res[128];
143     const char *file_type;
144     void *file_info;
145
146     log (LOG_DEBUG, "%c %s k=%s", cmd, fname, kname);
147     for (i = strlen(fname); --i >= 0; )
148         if (fname[i] == '/')
149         {
150             strcpy (ext, "");
151             break;
152         }
153         else if (fname[i] == '.')
154         {
155             strcpy (ext, fname+i+1);
156             break;
157         }
158     sprintf (ext_res, "fileExtension.%s", ext);
159     if (!(file_type = res_get (common_resource, ext_res)))
160         return;
161     
162     file_info = dict_lookup (file_idx, kname);
163     if (!file_info)
164     {
165         sysno = sysno_next++;
166         dict_insert (file_idx, kname, sizeof(sysno), &sysno);
167     }
168     else
169         memcpy (&sysno, (char*) file_info+1, sizeof(sysno));
170     if (!strcmp (file_type, "text"))
171         text_extract (sysno, cmd, fname);
172 }
173
174