IDZEBRA 2.2.8
d1_if.c
Go to the documentation of this file.
1/* This file is part of the Zebra server.
2 Copyright (C) Index Data
3
4Zebra is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18*/
19
20#if HAVE_CONFIG_H
21#include <config.h>
22#endif
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include <idzebra/data1.h>
29#include <yaz/log.h>
30
31#include <string.h>
32
33/*
34 * Search for a token in the supplied string up to the supplied list of stop characters or EOL
35 * At the end, return the character causing the break and fill pTokenBuffer with the token string so far
36 * After the scan, *pPosInBuffer will point to the next character after the one causing the break and
37 * pTokenBuffer will contain the actual token
38 */
39char data1_ScanNextToken(char* pBuffer,
40 char** pPosInBuffer,
41 char* pBreakChars,
42 char* pWhitespaceChars,
43 char* pTokenBuffer)
44{
45 char* pBuff = pTokenBuffer;
46 *pBuff = '\0';
47
48 while ( **pPosInBuffer )
49 {
50 if ( strchr(pBreakChars,**pPosInBuffer) != NULL )
51 {
52 /* Current character is a break character */
53 *pBuff++ = '\0';
54 return *((*pPosInBuffer)++);
55 }
56 else
57 {
58 if ( strchr(pWhitespaceChars, **pPosInBuffer) != NULL )
59 (*pPosInBuffer)++;
60 else
61 *pBuff++ = *((*pPosInBuffer)++);
62 }
63 }
64
65 *pBuff++ = *((*pPosInBuffer)++);
66 return(**pPosInBuffer);
67}
68
69/*
70 * Attempt to find a string value given the specified tagpath
71 *
72 * Need to make this safe by passing in a buffer.....
73 *
74 */
75char *data1_getNodeValue(data1_node* node, char* pTagPath)
76{
77 data1_node* n = NULL;
78
79 n = data1_LookupNode(node, pTagPath );
80
81 if ( n )
82 {
83 /* n should be a tag node with some data under it.... */
84 if ( n->child )
85 {
86 if ( n->child->which == DATA1N_data )
87 {
88 return n->child->u.data.data;
89 }
90 else
91 {
92 yaz_log(YLOG_WARN,"Attempting to lookup data for tagpath: Child node is not a data node");
93 }
94 }
95 else
96 {
97 yaz_log(YLOG_WARN,"Found a node matching the tagpath, but it has no child data nodes");
98 }
99 }
100 else
101 {
102 yaz_log(YLOG_WARN,"Unable to lookup a node on the specified tag path");
103 }
104
105 return "";
106}
107
108
109/* Max length of a tag */
110#define MAX_TAG_SIZE 50
111
112/*
113 * data1_LookupNode : Try and find a node as specified by a tagpath
114 */
116{
117 /* Node matching the pattern in the tagpath */
118 data1_node* matched_node = NULL;
119
120 /* Current Child node as we search for nodes matching the pattern in the tagpath */
121 data1_node* current_child = node->child;
122
123 /* Current position in string */
124 char* pCurrCharInPath = pTagPath;
125
126 /* Work buffer */
127 char Buffer[MAX_TAG_SIZE];
128
129 /* The tag type of this node */
130 int iTagType = 0;
131
132 /* for non string tags, the tag value */
133 int iTagValue = 0;
134
135 /* for string tags, the tag value */
136 char StringTagVal[MAX_TAG_SIZE];
137
138 /* Which occurence of that tag under this node */
139 int iOccurences=0;
140
141 /* Character causing a break */
142 char sepchr = '\0';
143 Buffer[0] = '\0';
144 StringTagVal[0] = '\0';
145
146 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",[(."," ", Buffer);
147
148 if ( sepchr == '[' )
149 {
150 /* Next component in node value is [ TagType, TagVal, TagOccurence ] */
151 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ","," ", Buffer);
152 iTagType = atoi(Buffer);
153
154 /* Occurence is optional... */
155 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",]."," ", Buffer);
156
157 if ( iTagType == 3 )
158 strcpy(StringTagVal,Buffer);
159 else
160 iTagValue = atoi(Buffer);
161
162 /* If sepchar was a ',' there should be an instance */
163 if ( sepchr == ',' )
164 {
165 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "]."," ", Buffer);
166 iOccurences = atoi(Buffer);
167 }
168
169 if ( sepchr == ']' )
170 {
171 /* See if we can scan the . for the next component or the end of the line... */
172 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
173 }
174 else
175 {
176 yaz_log(YLOG_FATAL,"Node does not end with a ]");
177 /* Fatal Error */
178 return(NULL);
179 }
180 }
181 else
182 {
183 /* We have a TagName so Read up to ( or . or EOL */
184 iTagType = 3;
185 strcpy(StringTagVal,Buffer);
186
187 if ( sepchr == '(' )
188 {
189 /* Read the occurence */
190 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ")"," ", Buffer);
191 iOccurences = atoi(Buffer);
192
193 /* See if we can find the . at the end of this clause */
194 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
195 }
196
197 }
198
199 yaz_log(YLOG_DEBUG,"search node for child like [%d,%d,%s,%d]",iTagType,iTagValue,StringTagVal,iOccurences);
200
201
202 /* OK.. We have extracted tagtype, Value and Occurence, see if we can find a node */
203 /* Under the current parent matching that description */
204
205 while ( ( current_child ) && ( matched_node == NULL ) )
206 {
207 if ( current_child->which == DATA1N_tag )
208 {
209 if ( iTagType == 3 )
210 {
211 if ( ( current_child->u.tag.element == NULL ) &&
212 ( strcmp(current_child->u.tag.tag, StringTagVal) == 0 ) )
213 {
214 if ( iOccurences )
215 {
216 /* Everything matched, but not yet found the
217 right occurence of the given tag */
218 iOccurences--;
219 }
220 else
221 {
222 /* We have matched a string tag... Is there more to
223 process? */
224 matched_node = current_child;
225 }
226 }
227 }
228 else /* Attempt to match real element */
229 {
230 yaz_log(YLOG_WARN,"Non string tag matching not yet implemented");
231 }
232 }
233 current_child = current_child->next;
234 }
235
236
237 /* If there is more... Continue */
238 if ( ( sepchr == '.' ) && ( matched_node ) )
239 {
240 return data1_LookupNode(matched_node, pCurrCharInPath);
241 }
242 else
243 {
244 return matched_node;
245 }
246}
247
253int data1_CountOccurences(data1_node* node, char* pTagPath)
254{
255 int iRetVal = 0;
256 data1_node* n = NULL;
257 data1_node* pParent = NULL;
258
259 n = data1_LookupNode(node, pTagPath );
260
261
262 if ( ( n ) &&
263 ( n->which == DATA1N_tag ) &&
264 ( n->parent ) )
265 {
266 data1_node* current_child;
267 pParent = n->parent;
268
269 for ( current_child = pParent->child;
270 current_child;
271 current_child = current_child->next )
272 {
273 if ( current_child->which == DATA1N_tag )
274 {
275 if ( current_child->u.tag.element == NULL )
276 {
277 if ( ( n->u.tag.tag ) &&
278 ( current_child->u.tag.tag ) &&
279 ( strcmp(current_child->u.tag.tag, n->u.tag.tag) == 0 ) )
280 {
281 iRetVal++;
282 }
283 }
284 else if ( current_child->u.tag.element == n->u.tag.element )
285 {
286 /* Hmmm... Is the above right for non string tags???? */
287 iRetVal++;
288 }
289 }
290 }
291 }
292
293 return iRetVal;
294}
295/*
296 * Local variables:
297 * c-basic-offset: 4
298 * c-file-style: "Stroustrup"
299 * indent-tabs-mode: nil
300 * End:
301 * vim: shiftwidth=4 tabstop=8 expandtab
302 */
303
char * data1_getNodeValue(data1_node *node, char *pTagPath)
Definition d1_if.c:75
int data1_CountOccurences(data1_node *node, char *pTagPath)
Count the number of occurences of the last instance on a tagpath.
Definition d1_if.c:253
char data1_ScanNextToken(char *pBuffer, char **pPosInBuffer, char *pBreakChars, char *pWhitespaceChars, char *pTokenBuffer)
Definition d1_if.c:39
#define MAX_TAG_SIZE
Definition d1_if.c:110
data1_node * data1_LookupNode(data1_node *node, char *pTagPath)
Definition d1_if.c:115
#define DATA1N_tag
Definition data1.h:276
#define DATA1N_data
Definition data1.h:278
struct data1_node * parent
Definition data1.h:343
struct data1_node * child
Definition data1.h:341
char * tag
Definition data1.h:296
char * data
Definition data1.h:307
struct data1_node * next
Definition data1.h:340
union data1_node::@2 u
int which
Definition data1.h:285