/* $Id: d1_if.c,v 1.2 2002/10/22 13:19:50 adam Exp $
Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
Index Data Aps
This file is part of the Zebra server.
Zebra is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with Zebra; see the file LICENSE.zebra. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <data1.h>
#include <yaz/log.h>
#include <string.h>
/*
* Search for a token in the supplied string up to the supplied list of stop characters or EOL
* At the end, return the character causing the break and fill pTokenBuffer with the token string so far
* After the scan, *pPosInBuffer will point to the next character after the one causing the break and
* pTokenBuffer will contain the actual token
*/
char data1_ScanNextToken(char* pBuffer,
char** pPosInBuffer,
char* pBreakChars,
char* pWhitespaceChars,
char* pTokenBuffer)
{
char* pBuff = pTokenBuffer;
*pBuff = '\0';
while ( **pPosInBuffer )
{
if ( strchr(pBreakChars,**pPosInBuffer) != NULL )
{
/* Current character is a break character */
*pBuff++ = '\0';
return *((*pPosInBuffer)++);
}
else
{
if ( strchr(pWhitespaceChars, **pPosInBuffer) != NULL )
(*pPosInBuffer)++;
else
*pBuff++ = *((*pPosInBuffer)++);
}
}
*pBuff++ = *((*pPosInBuffer)++);
return(**pPosInBuffer);
}
/*
* Attempt to find a string value given the specified tagpath
*
* Need to make this safe by passing in a buffer.....
*
*/
char *data1_getNodeValue(data1_node* node, char* pTagPath)
{
data1_node* n = NULL;
n = data1_LookupNode(node, pTagPath );
if ( n )
{
/* n should be a tag node with some data under it.... */
if ( n->child )
{
if ( n->child->which == DATA1N_data )
{
return n->child->u.data.data;
}
else
{
yaz_log(LOG_WARN,"Attempting to lookup data for tagpath: Child node is not a data node");
}
}
else
{
yaz_log(LOG_WARN,"Found a node matching the tagpath, but it has no child data nodes");
}
}
else
{
yaz_log(LOG_WARN,"Unable to lookup a node on the specified tag path");
}
return "";
}
/* Max length of a tag */
#define MAX_TAG_SIZE 50
/*
* data1_LookupNode : Try and find a node as specified by a tagpath
*/
data1_node *data1_LookupNode(data1_node* node, char* pTagPath)
{
/* Node matching the pattern in the tagpath */
data1_node* matched_node = NULL;
/* Current Child node as we search for nodes matching the pattern in the tagpath */
data1_node* current_child = node->child;
/* Current position in string */
char* pCurrCharInPath = pTagPath;
/* Work buffer */
char Buffer[MAX_TAG_SIZE];
/* The tag type of this node */
int iTagType = 0;
/* for non string tags, the tag value */
int iTagValue = 0;
/* for string tags, the tag value */
char StringTagVal[MAX_TAG_SIZE];
/* Which occurence of that tag under this node */
int iOccurences=0;
/* Character causing a break */
char sepchr = '\0';
Buffer[0] = '\0';
StringTagVal[0] = '\0';
sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",[(."," ", Buffer);
if ( sepchr == '[' )
{
/* Next component in node value is [ TagType, TagVal, TagOccurence ] */
sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ","," ", Buffer);
iTagType = atoi(Buffer);
/* Occurence is optional... */
sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",]."," ", Buffer);
if ( iTagType == 3 )
strcpy(StringTagVal,Buffer);
else
iTagValue = atoi(Buffer);
/* If sepchar was a ',' there should be an instance */
if ( sepchr == ',' )
{
sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "]."," ", Buffer);
iOccurences = atoi(Buffer);
}
if ( sepchr == ']' )
{
/* See if we can scan the . for the next component or the end of the line... */
sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
}
else
{
yaz_log(LOG_FATAL,"Node does not end with a ]");
/* Fatal Error */
return(NULL);
}
}
else
{
/* We have a TagName so Read up to ( or . or EOL */
iTagType = 3;
strcpy(StringTagVal,Buffer);
if ( sepchr == '(' )
{
/* Read the occurence */
sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ")"," ", Buffer);
iOccurences = atoi(Buffer);
/* See if we can find the . at the end of this clause */
sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
}
}
yaz_log(LOG_DEBUG,"search node for child like [%d,%d,%s,%d]",iTagType,iTagValue,StringTagVal,iOccurences);
/* OK.. We have extracted tagtype, Value and Occurence, see if we can find a node */
/* Under the current parent matching that description */
while ( ( current_child ) && ( matched_node == NULL ) )
{
if ( current_child->which == DATA1N_tag )
{
if ( iTagType == 3 )
{
if ( ( current_child->u.tag.element == NULL ) &&
( strcmp(current_child->u.tag.tag, StringTagVal) == 0 ) )
{
if ( iOccurences )
{
/* Everything matched, but not yet found the
right occurence of the given tag */
iOccurences--;
}
else
{
/* We have matched a string tag... Is there more to
process? */
matched_node = current_child;
}
}
}
else /* Attempt to match real element */
{
yaz_log(LOG_WARN,"Non string tag matching not yet implemented");
}
}
current_child = current_child->next;
}
/* If there is more... Continue */
if ( ( sepchr == '.' ) && ( matched_node ) )
{
return data1_LookupNode(matched_node, pCurrCharInPath);
}
else
{
return matched_node;
}
}
/**
data1_CountOccurences
Count the number of occurences of the last instance on a tagpath.
@param data1_node* node : The root of the tree we wish to look for occurences in
@param const char* pTagPath : The tagpath we want to count the occurences of...
*/
int data1_CountOccurences(data1_node* node, char* pTagPath)
{
int iRetVal = 0;
data1_node* n = NULL;
data1_node* pParent = NULL;
n = data1_LookupNode(node, pTagPath );
if ( ( n ) &&
( n->which == DATA1N_tag ) &&
( n->parent ) )
{
data1_node* current_child;
pParent = n->parent;
for ( current_child = pParent->child;
current_child;
current_child = current_child->next )
{
if ( current_child->which == DATA1N_tag )
{
if ( current_child->u.tag.element == NULL )
{
if ( ( n->u.tag.tag ) &&
( current_child->u.tag.tag ) &&
( strcmp(current_child->u.tag.tag, n->u.tag.tag) == 0 ) )
{
iRetVal++;
}
}
else if ( current_child->u.tag.element == n->u.tag.element )
{
/* Hmmm... Is the above right for non string tags???? */
iRetVal++;
}
}
}
}
return iRetVal;
}
syntax highlighted by Code2HTML, v. 0.9.1