IDZEBRA  2.1.2
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 
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8 
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 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  */
39 char 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  */
75 char *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  */
115 data1_node *data1_LookupNode(data1_node* node, char* pTagPath)
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 
253 int 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 
#define DATA1N_tag
Definition: data1.h:276
char data1_ScanNextToken(char *pBuffer, char **pPosInBuffer, char *pBreakChars, char *pWhitespaceChars, char *pTokenBuffer)
Definition: d1_if.c:39
char * data1_getNodeValue(data1_node *node, char *pTagPath)
Definition: d1_if.c:75
char * tag
Definition: data1.h:296
union data1_node::@2 u
struct data1_node * child
Definition: data1.h:341
int which
Definition: data1.h:285
struct data1_node * parent
Definition: data1.h:343
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
struct data1_node * next
Definition: data1.h:340
char * data
Definition: data1.h:307
data1_node * data1_LookupNode(data1_node *node, char *pTagPath)
Definition: d1_if.c:115
#define DATA1N_data
Definition: data1.h:278
#define MAX_TAG_SIZE
Definition: d1_if.c:110