1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2010 Index Data
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
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
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
25 #include <idzebra/data1.h>
31 * Search for a token in the supplied string up to the supplied list of stop characters or EOL
32 * At the end, return the character causing the break and fill pTokenBuffer with the token string so far
33 * After the scan, *pPosInBuffer will point to the next character after the one causing the break and
34 * pTokenBuffer will contain the actual token
36 char data1_ScanNextToken(char* pBuffer,
39 char* pWhitespaceChars,
42 char* pBuff = pTokenBuffer;
45 while ( **pPosInBuffer )
47 if ( strchr(pBreakChars,**pPosInBuffer) != NULL )
49 /* Current character is a break character */
51 return *((*pPosInBuffer)++);
55 if ( strchr(pWhitespaceChars, **pPosInBuffer) != NULL )
58 *pBuff++ = *((*pPosInBuffer)++);
62 *pBuff++ = *((*pPosInBuffer)++);
63 return(**pPosInBuffer);
67 * Attempt to find a string value given the specified tagpath
69 * Need to make this safe by passing in a buffer.....
72 char *data1_getNodeValue(data1_node* node, char* pTagPath)
76 n = data1_LookupNode(node, pTagPath );
80 /* n should be a tag node with some data under it.... */
83 if ( n->child->which == DATA1N_data )
85 return n->child->u.data.data;
89 yaz_log(YLOG_WARN,"Attempting to lookup data for tagpath: Child node is not a data node");
94 yaz_log(YLOG_WARN,"Found a node matching the tagpath, but it has no child data nodes");
99 yaz_log(YLOG_WARN,"Unable to lookup a node on the specified tag path");
106 /* Max length of a tag */
107 #define MAX_TAG_SIZE 50
110 * data1_LookupNode : Try and find a node as specified by a tagpath
112 data1_node *data1_LookupNode(data1_node* node, char* pTagPath)
114 /* Node matching the pattern in the tagpath */
115 data1_node* matched_node = NULL;
117 /* Current Child node as we search for nodes matching the pattern in the tagpath */
118 data1_node* current_child = node->child;
120 /* Current position in string */
121 char* pCurrCharInPath = pTagPath;
124 char Buffer[MAX_TAG_SIZE];
126 /* The tag type of this node */
129 /* for non string tags, the tag value */
132 /* for string tags, the tag value */
133 char StringTagVal[MAX_TAG_SIZE];
135 /* Which occurence of that tag under this node */
138 /* Character causing a break */
141 StringTagVal[0] = '\0';
143 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",[(."," ", Buffer);
147 /* Next component in node value is [ TagType, TagVal, TagOccurence ] */
148 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ","," ", Buffer);
149 iTagType = atoi(Buffer);
151 /* Occurence is optional... */
152 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",]."," ", Buffer);
155 strcpy(StringTagVal,Buffer);
157 iTagValue = atoi(Buffer);
159 /* If sepchar was a ',' there should be an instance */
162 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "]."," ", Buffer);
163 iOccurences = atoi(Buffer);
168 /* See if we can scan the . for the next component or the end of the line... */
169 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
173 yaz_log(YLOG_FATAL,"Node does not end with a ]");
180 /* We have a TagName so Read up to ( or . or EOL */
182 strcpy(StringTagVal,Buffer);
186 /* Read the occurence */
187 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ")"," ", Buffer);
188 iOccurences = atoi(Buffer);
190 /* See if we can find the . at the end of this clause */
191 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
196 yaz_log(YLOG_DEBUG,"search node for child like [%d,%d,%s,%d]",iTagType,iTagValue,StringTagVal,iOccurences);
199 /* OK.. We have extracted tagtype, Value and Occurence, see if we can find a node */
200 /* Under the current parent matching that description */
202 while ( ( current_child ) && ( matched_node == NULL ) )
204 if ( current_child->which == DATA1N_tag )
208 if ( ( current_child->u.tag.element == NULL ) &&
209 ( strcmp(current_child->u.tag.tag, StringTagVal) == 0 ) )
213 /* Everything matched, but not yet found the
214 right occurence of the given tag */
219 /* We have matched a string tag... Is there more to
221 matched_node = current_child;
225 else /* Attempt to match real element */
227 yaz_log(YLOG_WARN,"Non string tag matching not yet implemented");
230 current_child = current_child->next;
234 /* If there is more... Continue */
235 if ( ( sepchr == '.' ) && ( matched_node ) )
237 return data1_LookupNode(matched_node, pCurrCharInPath);
246 \brief Count the number of occurences of the last instance on a tagpath.
247 \param node : The root of the tree we wish to look for occurences in
248 \param pTagPath : The tagpath we want to count the occurences of...
250 int data1_CountOccurences(data1_node* node, char* pTagPath)
253 data1_node* n = NULL;
254 data1_node* pParent = NULL;
256 n = data1_LookupNode(node, pTagPath );
260 ( n->which == DATA1N_tag ) &&
263 data1_node* current_child;
266 for ( current_child = pParent->child;
268 current_child = current_child->next )
270 if ( current_child->which == DATA1N_tag )
272 if ( current_child->u.tag.element == NULL )
274 if ( ( n->u.tag.tag ) &&
275 ( current_child->u.tag.tag ) &&
276 ( strcmp(current_child->u.tag.tag, n->u.tag.tag) == 0 ) )
281 else if ( current_child->u.tag.element == n->u.tag.element )
283 /* Hmmm... Is the above right for non string tags???? */
295 * c-file-style: "Stroustrup"
296 * indent-tabs-mode: nil
298 * vim: shiftwidth=4 tabstop=8 expandtab