liblogging: namevaluetree.c File Reference

Main Page | Compound List | File List | Compound Members | File Members | Related Pages

# namevaluetree.c File Reference

Implemetation of the NameValueTree helper object (includes XML parser). More...

`#include <assert.h>`
`#include <ctype.h>`
`#include "config.h"`
`#include "liblogging.h"`
`#include "namevaluetree.h"`
`#include "stringbuf.h"`

## Functions
void | sbNVTRDestroy (sbNVTRObj *pThis)
| Destructor for root elements - destroys a complete list.
void | sbNVTEDestroy (sbNVTEObj *pThis)
| Destructor for entry elements.
srRetVal | sbNVTXMLEscapePCDATAintoStrB (char *pszToEscape, sbStrBObj *pStr)
char * | sbNVTXMLEscapePCDATA (char *pszToEscape)
| XML-Escape a string.
sbNVTRObj * | sbNVTRConstruct (void)
| Construct a NameValueTree Root Object.
sbNVTEObj * | sbNVTEConstruct (void)
| Construct a NameValueTree Entry Object.
srRetVal | sbNVTESetChild (sbNVTEObj *pEntry, sbNVTRObj *pChildRoot)
| Link a child list to the current entry.
sbNVTEObj * | sbNVTAddEntry (sbNVTRObj *pRoot)
| Add an entry to the end of a NameValueTree List.
srRetVal | sbNVTRRemoveFirst (sbNVTRObj *pRoot)
| Removes the first entry from a list.
sbNVTEObj * | sbNVTUnlinkElement (sbNVTRObj *pRoot)
| Unlink the first element from a name value tree.
sbNVTEObj * | sbNVTSearchKeySZ (sbNVTRObj *pRoot, sbNVTEObj *pStart, char *pszSearch)
| Find the next element with a given string key inside the list.
sbNVTEObj * | sbNVTSearchKeyU (sbNVTRObj *pRoot, sbNVTEObj *pStart, unsigned uSearch)
| Find the next element with a given integer key inside the list.
sbNVTEObj * | sbNVTSearchKeyUAndPrev (sbNVTRObj *pRoot, sbNVTEObj *pStart, unsigned uSearch, sbNVTEObj **ppPrevEntry)
| This is more or less a duplicate of the sbNVTSearchKeyU.
sbNVTEObj * | sbNVTSearchpUsrAndPrev (sbNVTRObj *pRoot, sbNVTEObj *pStart, void *pUsr, sbNVTEObj **ppPrevEntry)
| This method searches for a specific pUsr and returns the entry in question PLUS the previous element.
char * | sbNVTEUtilStrDup (char *pszStrToDup)
| Duplicate a string and return it.
srRetVal | sbNVTESetKeySZ (sbNVTEObj *pThis, char *pszKey, int bCopy)
| Set the string key for a given entry.
srRetVal | sbNVTESetValueSZ (sbNVTEObj *pThis, char *pszVal, int bCopy)
| Set the string value for a given entry.
srRetVal | sbNVTESetKeyU (sbNVTEObj *pThis, unsigned uKey)
| Set the integer key for a given entry.
srRetVal | sbNVTEUnsetKeyU (sbNVTEObj *pThis)
| Remove the integer key for a given entry.
srRetVal | sbNVTESetUsrPtr (sbNVTEObj *pThis, void *pPtr, void(pPtrDestroy)(void *))
| Set the user pointer for a given entry.
srRetVal | sbNVTESetValueU (sbNVTEObj *pThis, unsigned uVal)
| Set the integer value for a given entry.
srRetVal | sbNVTEGetValueU (sbNVTEObj *pThis, unsigned *puValue)
| Return the uValue for this object.
void | sbNVTEUnsetUsrPtr (sbNVTEObj *pEntry)
| Remove the user point from an element.
void | sbNVTRUnlinkFromParent (sbNVTRObj *pRoot)
| Unlinks a root element (complete list) from its parent.
void | sbNVTEUnlinkFromList (sbNVTRObj *pRoot, sbNVTEObj *pEntry, sbNVTEObj *pPrev)
| Unlink an entry from the current list.
srRetVal | sbNVTRRemoveKeyU (sbNVTRObj *pRoot, unsigned uKey)
| Remove a keyed entry from a root element.
srRetVal | sbNVTRRemovEntryWithpUsr (sbNVTRObj *pRoot, void *pUsr)
| Remove an entry with a specific pUsr from a root element.
srRetVal | sbNVTRParseXML (sbNVTRObj *pRoot, char *pszXML)
| Populate a NameValueTree based on a BEEP XML stream.
void | sbNVTDebugPrintTree (sbNVTRObj *pRoot, int iLevel)
| Print out a whole tree structure.
sbNVTEObj * | sbNVTRHasElement (sbNVTRObj *pRoot, char *pEltname, int bMustBeOnly)
| Checks if a list has the named element.

## Detailed Description

Implemetation of the NameValueTree helper object (includes XML parser).

Author:
  Rainer Gerhards <rgerhards@adiscon.com>

Date:
  2003-08-04 Initial version as part of liblogging 0.2 begun.

Copyright 2002-2003 Rainer Gerhards and Adiscon GmbH. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

* Neither the name of Adiscon GmbH or Rainer Gerhards nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

## Function Documentation

sbNVTEObj* sbNVTAddEntry | ( | sbNVTRObj * | pRoot | ) |

  | Add an entry to the end of a NameValueTree List. A new entry element is constructed and added onto the end of the list. Parameters:
  pRoot | Root of the list the element is to be added to.
  Return values:
  pointer | to newly created list element or NULL if error occured.

void sbNVTDebugPrintTree | ( | sbNVTRObj * | pRoot,
|  | int | iLevel
| ) |

  | Print out a whole tree structure. This is a debug aid and ONLY AVAILABLE IN DEBUG BUILDS! We walk the tree and call ourselfs recursively. Parameters:
  iLevel | - the current level (tree-depth) we are in.

sbNVTEObj* sbNVTEConstruct | ( | void |  | ) |

  | Construct a NameValueTree Entry Object. Use this constructor whenever a new object is created! Return values:
  pointer | to the new object or NULL, if an error occured.

void sbNVTEDestroy | ( | sbNVTEObj * | pThis | ) |

| Destructor for entry elements. This destructor destroys all elements directly associated with this entry element. As such, XML Properties and Childs are destroyed, but not the parent or sibling, as they may remain valid in another context. If there is a user pointer, the supplied free() function is called on it.

srRetVal sbNVTEGetValueU | ( | sbNVTEObj * | pThis,
|  | unsigned * | puValue
| ) |

  | Return the uValue for this object. If the uValue is already set, it is returned. If it is not yet set, we look at the szValue and see if we can convert it to an uValue. If that succeeds, we return the converted value. If that does not succeed, -1 is returned and an error is flagged. Parameters:
  puValue | [out] pointer to an unsinged that should receive the uValue. Please note that we can not directly return this as a return value because we need to convey an error state which may happen at any time.

srRetVal sbNVTESetChild | ( | sbNVTEObj * | pEntry,
|  | sbNVTRObj * | pChildRoot
| ) |

  | Link a child list to the current entry. Parameters:
  pEntry | Pointer to the entry where the child is to be added.
  pChildRoot | Pointer to the to-be-added list.

srRetVal sbNVTESetKeySZ | ( | sbNVTEObj * | pThis,
|  | char * | pszKey,
|  | int | bCopy
| ) |

  | Set the string key for a given entry. The string key is copied to a new buffer if so requested. Parameters:
  pszKey | Pointer to string making up the key.
  bCopy | TRUE duplicate string, FALSE = use supplied buffer. In case of FALSE, the caller should no longer work with the supplied buffer as ownership moves to the name value tree. Results would be unpredictable at best...

srRetVal sbNVTESetKeyU | ( | sbNVTEObj * | pThis,
|  | unsigned | uKey
| ) |

  | Set the integer key for a given entry. Parameters:
  uKey | new key

srRetVal sbNVTESetUsrPtr | ( | sbNVTEObj * | pThis,
|  | void * | pPtr,
|  | void(pPtrDestroy | )(void *)
| ) |

  | Set the user pointer for a given entry. Parameters:
  pPtr | ponter to user supplied buffer
  pPtrDestroy | pointer to user-supplied method to destroy the buffer. This is necessary as the NameValueTree module may destroy the buffer at any time without the user actually knowing. As such, it must have a destructor. To avaoid coding errors and "too quick" hacks, this pointer is not allowed to be NULL. If you do not need any destructor, provide a pointer to an empty function in this case. The prototype is void Destruct(void* ptr) with ptr being the pinter supplied in pPtr.

srRetVal sbNVTESetValueSZ | ( | sbNVTEObj * | pThis,
|  | char * | pszVal,
|  | int | bCopy
| ) |

  | Set the string value for a given entry. The string key is copied to a new buffer if so requested. Parameters:
  pszVal | New string to be set.
  bCopy | TRUE duplicate string, FALSE = use supplied buffer. In case of FALSE, the caller should no longer work with the supplied buffer as ownership moves to the name value tree. Results would be unpredictable at best...

srRetVal sbNVTESetValueU | ( | sbNVTEObj * | pThis,
|  | unsigned | uVal
| ) |

  | Set the integer value for a given entry. Parameters:
  uKey | new value

void sbNVTEUnlinkFromList | ( | sbNVTRObj * | pRoot,
|  | sbNVTEObj * | pEntry,
|  | sbNVTEObj * | pPrev
| ) |

  | Unlink an entry from the current list. Parameters:
  pRoot | pointer to the root of this list
  pEntry | pointer to the entry to be unlinked
  pointer | to the element immediately before the to be unlinked entry in the list. May be NULL, in which case the to be unlinked element is the first element of the list.

void sbNVTEUnsetUsrPtr | ( | sbNVTEObj * | pEntry | ) |

| Remove the user point from an element. This is needed if the element got deleted by the user itself. If not done, the list destructor would try to delete the object, thus resulting in a double-free. If the user pointer is not set, nothing happens.

char* sbNVTEUtilStrDup | ( | char * | pszStrToDup | ) |

  | Duplicate a string and return it. This is a general utility, it was just defined first in the context of NVTE. Parameters:
  pszStrToDup | String to be duplicated. MUST not be NULL.
  Return values:
  duplicated | string. Must be free()ed if no longer needed.

sbNVTRObj* sbNVTRConstruct | ( | void |  | ) |

  | Construct a NameValueTree Root Object. Use this constructor whenever a new object is created! Return values:
  pointer | to the new object or NULL, if an error occured.

void sbNVTRDestroy | ( | sbNVTRObj * | pThis | ) |

| Destructor for root elements - destroys a complete list. So we need to walk it by using the raw pointers.

sbNVTEObj* sbNVTRHasElement | ( | sbNVTRObj * | pRoot,
|  | char * | pEltname,
|  | int | bMustBeOnly
| ) |

  | Checks if a list has the named element. Can also check if it is the only element in the list. Parameters:
  pEltname | Name of the element to look for (e.g. "ok")
  bMustBeOnly | TRUE = must be the only element, FALSE, can be one of many elements. Please note that the only element acutally means the only in this whole list (not the only of this name).
  Return values:
  if | the element could be found, a pointer to it is returned. NULL is returned if it is not found OR it is not the only entry and bMustBeOnly is TRUE.

srRetVal sbNVTRParseXML | ( | sbNVTRObj * | pRoot,
|  | char * | pszXML
| ) |

  | Populate a NameValueTree based on a BEEP XML stream. This is a mini BEEP XML parser. It parses those constructs supported by BEEP XML. It does NOT check the DTD, this needs to be done by the caller. This is a "one stop" method, which means that it will do anything needed to do the job. The method detects syntax errors, only. If one is detected, an error state is returned. In this case, the status of the provided NameValueTree structure is undefined - probably some elements have been added, others not. It is highly recommended that the caller discards the NameValueTree structure if this method does not return error-free. If a pre-populated NameValueTree is provided, the elements found in the XML stream are ADDED to it. This is a single-pass parser. ABNF for our Mini XML Parser: Note: This is Pseudo-ABNF, mostly following http://www.ietf.org/rfc/rfc2234.txt. BEEPXML = XMLSTREAM XMLSTREAM = *WHITESPACE *XMLELEMENT XMLELEMENT = (XMLNODE / XMLCONTAINER / CDATA) *WHITESPACE CDATA = "<![CDATA[" CDATAVALUE "]]>" ; "CDATA" must be upper case, only. ; Been to lazy to write it down in "right" ABNF ;) XMLNODE = "<" TAGwPARAMS 1*WHITESPACE "/>" ; is it really 1*WHITESPACE or just ; *WHITESPACE? In the implementation, we use *WHITESPACE when reading XMLCONTAINER = "<" TAGwPARAMS ">" (XMLVALUE / XMLSTREAM) "</" *WHITESPACE TAG ">" ; begin and end tag must be exactly the same. TAGwPARAMS = TAG *(1*WHITESPACE PARAM) *WHITESPACE TAG = XMLNAME PARAM = XMLNAME ["='" XMLVALUE "'"] XMLNAME = NON-WHITESPACE NO "/" / "<" / ">" / "=" / ";" XMLVALUE = *(PRINTABLECHAR / ESCSEQ) CDATAVALUE = all printable chars except "]" WHITESPACE = d09 / d10 / d13 / d32 ; C isspace() PRINTABLECHAR = all printable chars ESCSEQ = "&" XMLNAME ";" Parameters:
  pszXML | Pointer to a string containing the XML stream. May be NULL, in which case no processing takes place.

srRetVal sbNVTRRemoveFirst | ( | sbNVTRObj * | pRoot | ) |

| Removes the first entry from a list. The entry will be unlinked and then destroyed. It is valid to call this function on an empty list. In this case, nothing will happen.

srRetVal sbNVTRRemoveKeyU | ( | sbNVTRObj * | pRoot,
|  | unsigned | uKey
| ) |

| Remove a keyed entry from a root element. The key search is done on the unsigned key. The first entry with a matching key value is removed. Do not use this method on a list with potentially multiple keys of the same value - or be sure to know EXACTLY what you are doing and why... The entry shall not only be unlinked from the tree but also destroyed.

srRetVal sbNVTRRemovEntryWithpUsr | ( | sbNVTRObj * | pRoot,
|  | void * | pUsr
| ) |

  | Remove an entry with a specific pUsr from a root element. The first entry with a matching pUsr is removed. Do not use this method on a list with potentially multiple identical pUsrs - or be sure to know EXACTLY what you are doing and why... Parameters:
  pUsr | The pUsr to find and delete. This may be NULL but keep the above warning about multiple values in mind!
The entry shall not only be unlinked from the tree but also be destroyed.

void sbNVTRUnlinkFromParent | ( | sbNVTRObj * | pRoot | ) |

| Unlinks a root element (complete list) from its parent. If the root element has no parent, nothing happens. This is no error.

sbNVTEObj* sbNVTSearchKeySZ | ( | sbNVTRObj * | pRoot,
|  | sbNVTEObj * | pStart,
|  | char * | pszSearch
| ) |

  | Find the next element with a given string key inside the list. Note: A list may contain multiple entries with the same key. As such, this method receives a pointer to the last entry found and continues search from there. Call the method until NULL is returned, in which case no further match is found. Parameters:
  pRoot | Root of the list to be searched.
  pStart | Starting entry for the search. If NULL, search will begin at the first entry. Please note that pStart MUST belong to pRoot, otherwise results are unpredictable.
  pszSearch | String to search for. If this pointer is NULL, the next element is returned without any comparision. In short, with this parameter being NULL, the method can be used to walk the list.
  Return values:
  pointer | to found element or NULL, if no (more) element is found.

sbNVTEObj* sbNVTSearchKeyU | ( | sbNVTRObj * | pRoot,
|  | sbNVTEObj * | pStart,
|  | unsigned | uSearch
| ) |

  | Find the next element with a given integer key inside the list. Note: A list may contain multiple entries with the same key. As such, this method receives a pointer to the last entry found and continues search from there. Call the method until NULL is returned, in which case no further match is found. Parameters:
  pRoot | Root of the list to be searched.
  pStart | Starting entry for the search. If NULL, search will begin at the first entry. Please note that pStart MUST belong to pRoot, otherwise results are unpredictable.
  uSearch | Unsinged Integer to search for.
  Return values:
  pointer | to found element or NULL, if no (more) element is found.

sbNVTEObj* sbNVTSearchKeyUAndPrev | ( | sbNVTRObj * | pRoot,
|  | sbNVTEObj * | pStart,
|  | unsigned | uSearch,
|  | sbNVTEObj ** | ppPrevEntry
| ) |

  | This is more or less a duplicate of the sbNVTSearchKeyU. The difference is that this method also delivers back the previous entry. This is done for performance reasons - it saves us from doubly-linking the list, which would otherwise be required and for sure be overdone in the current state of affairs. AllParams are like sbNVTSearchKeyU plus Parameters:
  ppPrevEntry | Pointer to a pointer to the previous element. This is needed so that that element can be updated during unlink operations. Is NULL if there is no previous element.

sbNVTEObj* sbNVTSearchpUsrAndPrev | ( | sbNVTRObj * | pRoot,
|  | sbNVTEObj * | pStart,
|  | void * | pUsr,
|  | sbNVTEObj ** | ppPrevEntry
| ) |

  | This method searches for a specific pUsr and returns the entry in question PLUS the previous element. This is done for performance reasons - it saves us from doubly-linking the list, which would otherwise be required and for sure be overdone in the current state of affairs. Note: A list may contain multiple entries with the same key. As such, this method receives a pointer to the last entry found and continues search from there. Call the method until NULL is returned, in which case no further match is found. Parameters:
  pRoot | Root of the list to be searched.
  pStart | Starting entry for the search. If NULL, search will begin at the first entry. Please note that pStart MUST belong to pRoot, otherwise results are unpredictable.
  pUsr | pUsr to search for.
  ppPrevEntry | Pointer to a pointer to the previous element. This is needed so that that element can be updated during unlink operations. Is NULL if there is no previous element.
  Return values:
  pointer | to found element or NULL, if no (more) element is found.

sbNVTEObj* sbNVTUnlinkElement | ( | sbNVTRObj * | pRoot | ) |

  | Unlink the first element from a name value tree. The element is not destroyed, but simply unlinked. Note: It is the caller's responsibility to unlink the element when he is done! It is valid to call this mothod on a linked list WITHOUT any elements. In this case, NULL is returned. Return values:
  pointer | to unlinked element or NULL if list was empty.

char* sbNVTXMLEscapePCDATA | ( | char * | pszToEscape | ) |

  | XML-Escape a string. The resulting string is suitable for use in #pcdata, that is as a string BETWEEN XML tags (e.g. string. It is NOT suitable to be used inside a tag parameter (e.g. ). Parameters:
  pszToEscape | The string to be escaped. Should not be NULL. If it is NULL, the return value will also be NULL.
  Return values:
  Pointer | to an XML-escaped string or NULL, if no memory for that string could be allocated. IMPORTANT: the caller MUST free() that buffer once he is done with the string, otherwise a memory leak will be left.