New functions: iso2709_a_.. for record manipulation.
[egate.git] / util / iso2709a.c
1 /*
2  * Iso2709 record management - anchor utilities
3  *
4  * Europagate, 1995.
5  *
6  * $Log: iso2709a.c,v $
7  * Revision 1.1  1995/03/29 11:44:29  adam
8  * New functions: iso2709_a_.. for record manipulation.
9  *
10  */
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <assert.h>
16
17 #include <iso2709p.h>
18
19 Iso2709Anchor iso2709_a_mk (Iso2709Rec rec)
20 {
21     Iso2709Anchor anchor;
22     
23     anchor = malloc (sizeof(*anchor));
24     if (!anchor)
25         return NULL;
26     anchor->rec = rec;
27     anchor->d0 = &rec->directory;
28     if (*anchor->d0)
29         anchor->f0 = &(*anchor->d0)->fields;
30     return anchor;
31 }
32
33 void iso2709_a_rm (Iso2709Anchor anchor)
34 {
35     free (anchor);
36 }
37
38 int iso2709_a_first (Iso2709Anchor anchor)
39 {
40     anchor->d0 = &anchor->rec->directory;
41     if (*anchor->d0)
42     {
43         anchor->f0 = &(*anchor->d0)->fields;
44         return 1;
45     }
46     return 0;
47 }
48
49 int iso2709_a_next_line (Iso2709Anchor anchor)
50 {
51     if (! *anchor->d0)
52         return 0;
53     anchor->d0 = &(*anchor->d0)->next;
54     if (*anchor->d0)
55         anchor->f0 = &(*anchor->d0)->fields;
56     return 1;
57 }
58
59 int iso2709_a_next_field (Iso2709Anchor anchor)
60 {
61     if (!*anchor->d0 || !*anchor->f0)
62         return 0;
63     if (!(*anchor->f0)->next)
64         return 0;
65     anchor->f0 = &(*anchor->f0)->next;
66     return 1;
67 }
68
69 int iso2709_a_next (Iso2709Anchor anchor)
70 {
71     if (!*anchor->d0 || !*anchor->f0)
72         return iso2709_a_next_line (anchor);
73     anchor->f0 = &(*anchor->f0)->next;
74     if (! *anchor->f0)
75         return iso2709_a_next_line (anchor);
76     return 2;
77 }
78
79 int iso2709_a_info_field (Iso2709Anchor anchor,
80                     char **tag, char **indicator,
81                     char **identifier, char **data)
82 {
83     if (!*anchor->d0 || !*anchor->f0)
84         return 0;
85     if (tag)
86         *tag = (*anchor->d0)->tag;
87     if (indicator)
88         *indicator = (*anchor->d0)->indicator;
89     if (identifier)
90         *identifier = (*anchor->f0)->identifier;
91     if (data)
92         *data = (*anchor->f0)->data;
93     return 1;
94 }
95
96 int iso2709_a_info_line (Iso2709Anchor anchor,
97                     char **tag, char **indicator)
98 {
99     if (!*anchor->d0)
100         return 0;
101     assert (*anchor->f0);
102     return iso2709_a_info_field (anchor, tag, indicator, NULL, NULL);
103 }
104
105 int iso2709_a_delete_field (Iso2709Anchor anchor)
106 {
107     struct iso2709_field *field;
108
109     if (!*anchor->d0)
110         return 0;
111     field = *anchor->f0;
112     *anchor->f0 = field->next;
113     free (field->identifier);
114     free (field->data);
115     free (field);
116     if (!*anchor->f0)
117     {
118         if (! (*anchor->d0)->fields)
119             iso2709_a_delete_line (anchor);
120         iso2709_a_next_line (anchor);
121     }
122     return 1;
123 }
124
125 int iso2709_a_delete_line (Iso2709Anchor anchor)
126 {
127     struct iso2709_dir *dir;
128
129     if (!*anchor->d0)
130         return 0;
131     dir = *anchor->d0;
132     *anchor->d0 = dir->next;
133     free (dir->indicator);
134     free (dir);
135     return 1;
136 }
137
138 static int marc_cmp (const char *field, const char *pattern)
139 {
140     if (*pattern == '*')
141         return 0;
142     if (!field)
143         return -*pattern;
144     for (; *field && *pattern; field++, pattern++)
145     {
146         if (*pattern == '?')
147             continue;
148         if (*pattern != *field)
149             break;
150     }
151     return *field - *pattern;
152 }
153
154 int iso2709_a_search (Iso2709Anchor anchor,
155                       const char *tag_p, const char *indicator_p,
156                       const char *identifier_p)
157 {
158     char *tag;
159     char *indicator;
160     char *identifier;
161     do
162     {
163         if (!iso2709_a_info_field (anchor, &tag, &indicator,
164                                    &identifier, NULL))
165             return 0;
166         if ((!tag_p || !marc_cmp (tag, tag_p)) &&
167             (!indicator_p || !marc_cmp (indicator, indicator_p)) &&
168             (!identifier_p || !marc_cmp (identifier, identifier_p)))
169             return 1;
170     } while (iso2709_a_next (anchor));
171     return 0;
172 }
173
174 int iso2709_a_insert (Iso2709Anchor anchor, 
175                       const char *tag, const char *indicator,
176                       const char *identifier, const char *data)
177 {
178     return 0;
179 }
180