Blame Xml/ixml.h

Packit 857059
/* BEGIN_ICS_COPYRIGHT2 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015-2017, Intel Corporation
Packit 857059
Packit 857059
Redistribution and use in source and binary forms, with or without
Packit 857059
modification, are permitted provided that the following conditions are met:
Packit 857059
Packit 857059
    * Redistributions of source code must retain the above copyright notice,
Packit 857059
      this list of conditions and the following disclaimer.
Packit 857059
    * Redistributions in binary form must reproduce the above copyright
Packit 857059
      notice, this list of conditions and the following disclaimer in the
Packit 857059
      documentation and/or other materials provided with the distribution.
Packit 857059
    * Neither the name of Intel Corporation nor the names of its contributors
Packit 857059
      may be used to endorse or promote products derived from this software
Packit 857059
      without specific prior written permission.
Packit 857059
Packit 857059
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 857059
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 857059
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit 857059
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit 857059
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 857059
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 857059
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit 857059
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit 857059
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 857059
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 857059
Packit 857059
** END_ICS_COPYRIGHT2   ****************************************/
Packit 857059
Packit 857059
/* [ICS VERSION STRING: unknown] */
Packit 857059
Packit 857059
#ifndef _IBA_PUBLIC_IXML_H_
Packit 857059
#define _IBA_PUBLIC_IXML_H_
Packit 857059
Packit 857059
#include <iba/ipublic.h>
Packit 857059
#include <stdarg.h>
Packit 857059
#include <ctype.h>
Packit 857059
#if !defined(_GNU_SOURCE)
Packit 857059
#define _GNU_SOURCE
Packit 857059
#endif
Packit 857059
Packit 857059
#ifdef VXWORKS
Packit 857059
#include <XmlParser/expat.h>
Packit 857059
#else
Packit 857059
#include <expat.h>
Packit 857059
#endif
Packit 857059
Packit 857059
#ifdef __cplusplus
Packit 857059
extern "C" {
Packit 857059
#endif
Packit 857059
Packit 857059
#define DEBUG_IXML_PARSER 0	/* set to 1 to enable DbgOuts in Xml Parser */
Packit 857059
Packit 857059
/*****************************************************************************/
Packit 857059
/* XML declarations common to parser and output */
Packit 857059
struct IXmlOutputState;
Packit 857059
struct IXmlParserState;
Packit 857059
struct _IXML_FIELD;
Packit 857059
Packit 857059
typedef void (*IXML_FORMAT_FIELD_FUNC)(struct IXmlOutputState *state,
Packit 857059
				const char *tag, void *data);
Packit 857059
/* ATTR_FUNC should output a leading space before 1st attribute
Packit 857059
 * if there are no attributes to output it can simply do nothing
Packit 857059
 */
Packit 857059
typedef void (*IXML_FORMAT_ATTR_FUNC)(struct IXmlOutputState *state,
Packit 857059
				void *data);
Packit 857059
typedef void *(*IXML_START_TAG_FUNC)(struct IXmlParserState *state, 
Packit 857059
				void *parent, const char **attr);
Packit 857059
typedef void (*IXML_END_TAG_FUNC)(struct IXmlParserState *state, 
Packit 857059
				const struct _IXML_FIELD *field,
Packit 857059
				void *object, void *parent, XML_Char *content, unsigned len,
Packit 857059
				boolean valid);
Packit 857059
Packit 857059
typedef struct _IXML_FIELD {
Packit 857059
	const char *tag;		/* tag name in XML file or "*" */
Packit 857059
	char format;			/* format for tag, see below for choices */
Packit 857059
	int offset;				/* offset in C structure for tag's value */
Packit 857059
	int size;				/* size of field in C structure */
Packit 857059
	IXML_FORMAT_FIELD_FUNC format_func;	/* custom function to format output */
Packit 857059
	struct _IXML_FIELD *subfields;	/* fields within a container tag */
Packit 857059
	IXML_START_TAG_FUNC start_func;	/* function when input <tag> */
Packit 857059
	IXML_END_TAG_FUNC end_func;	/* function when input </tag> */
Packit 857059
} IXML_FIELD;
Packit 857059
Packit 857059
// helper macro, given a structure datatype and a member in structure
Packit 857059
// this provides initializers for IXML_FIELD offset and size
Packit 857059
#define IXML_FIELD_INFO(TYPE, MEMBER) offset:offsetof(TYPE, MEMBER), size:sizeof(((TYPE*)0)->MEMBER)
Packit 857059
// similar helper for 'p' formats, here the size can be specified as upper bound
Packit 857059
// for the string.  Use IB_INT32_MAX if there is no practical limit
Packit 857059
#define IXML_P_FIELD_INFO(TYPE, MEMBER, SIZE) offset:offsetof(TYPE, MEMBER), size:SIZE
Packit 857059
Packit 857059
/* formats:
Packit 857059
 * d - %d format for given field size (1, 2, 4, 8)
Packit 857059
 * 		Leading and trailing whitespace ignored.
Packit 857059
 * 		Undefined if also specify subfields
Packit 857059
 * u - %u format for given field size (1, 2, 4, 8)
Packit 857059
 * 		Leading and trailing whitespace ignored.
Packit 857059
 * 		Undefined if also specify subfields
Packit 857059
 * x - 0x%x format for given field size (1, 2, 4, 8) w/o 0 pad
Packit 857059
 * 		Leading and trailing whitespace ignored.
Packit 857059
 * 		Undefined if also specify subfields
Packit 857059
 * h - 0x%x format for given field size (1, 2, 4, 8) with 0 pad
Packit 857059
 * 		Leading and trailing whitespace ignored.
Packit 857059
 * 		Undefined if also specify subfields
Packit 857059
 * s - '\0' terminated array of chars, %s format, output until '\0' encountered
Packit 857059
 * 		use this for arrays of characters directly in the parent structure
Packit 857059
 * 		which are to be '\0' terminated.  size indicates size of array
Packit 857059
 * 		including space for the '\0' terminator (eg. string is limited to
Packit 857059
 * 		size-1 characters).
Packit 857059
 * 		Leading and trailing whitespace not trimmed.
Packit 857059
 * 		Undefined if also specify subfields
Packit 857059
 * p - pointer to string, %s format, output until '\0' encountered
Packit 857059
 * 		use this for pointers to strings in the parent structure.  On input
Packit 857059
 * 		the pointer will be allocated.  Caller must use MemoryDeallocate
Packit 857059
 * 		to free the string when done with it. size indicates upper bound for
Packit 857059
 * 		string (not including '\0').  strings longer than this will be truncated
Packit 857059
 * 		on input and output, but still '\0' terminated.  NULL pointers will
Packit 857059
 * 		be skipped on output and not output the tag at all.  For optional input
Packit 857059
 * 		fields when field is not found will default to value set in structure
Packit 857059
 * 		StartTag function, typically NULL.
Packit 857059
 * 		Leading and trailing whitespace not trimmed.
Packit 857059
 * 		Undefined if also specify subfields
Packit 857059
 * c - fixed length string input/output until size characters or '\0'
Packit 857059
 * 		use this for arrays of characters directly in the parent structure
Packit 857059
 * 		which need not be '\0' terminated (such as in IB SA Records).
Packit 857059
 * 		size indicates size of array.  A '\0' terminator is added only if the
Packit 857059
 * 		input string is less than size.
Packit 857059
 * 		Leading and trailing whitespace not trimmed.
Packit 857059
 * 		Undefined if also specify subfields
Packit 857059
 * k - invoke 'kustom' format_func for output, can use subfields for input
Packit 857059
 * 		Leading and trailing whitespace trimmed.
Packit 857059
 * 		Enforces that if subfields are specified, no content is	allowed
Packit 857059
 *		It is expected that fields without subfields will have explicit
Packit 857059
 *		end_func to process them.
Packit 857059
 * t - invoke 'kustom' format_func for output, can use subfields for input
Packit 857059
 * 		Leading and trailing whitespace not trimmed.
Packit 857059
 * 		Enforces that if subfields are specified, no content is	allowed
Packit 857059
 *		It is expected that fields without subfields will have explicit
Packit 857059
 *		end_func to process them.
Packit 857059
 * w - wildcarded tag format.
Packit 857059
 * 		Leading and trailing whitespace not trimmed.
Packit 857059
 * 		Enforces that if subfields are encountered, no content is allowed
Packit 857059
 * 		An end_func should be supplied to handle input, especially when
Packit 857059
 * 		no subfields.
Packit 857059
 *		Typically used in conjunction with tag name of '*' to permit IXml
Packit 857059
 *		parser to implement a stack but manually do tag processing in Start
Packit 857059
 *		and End functions.
Packit 857059
 * y - trimmed wildcarded tag format.
Packit 857059
 * 		Leading and trailing whitespace trimmed.
Packit 857059
 * 		Enforces that if subfields are encountered, no content is allowed
Packit 857059
 * 		An end_func should be supplied to handle input, especially when
Packit 857059
 * 		no subfields.
Packit 857059
 *		Typically used in conjunction with tag name of '*' to permit IXml
Packit 857059
 *		parser to implement a stack but manually do tag processing in Start
Packit 857059
 *		and End functions.
Packit 857059
 *
Packit 857059
 * The IXmlParserState and IXmlOutputState structures should be treated
Packit 857059
 * as opaque structures.  format_func, end_func and start_func should not
Packit 857059
 * use fields in these structures.  The necessary information from the state
Packit 857059
 * is supplied as explicit arguments.
Packit 857059
 *
Packit 857059
 * Output:
Packit 857059
 * each field is processed in order.
Packit 857059
 * If format_func is specified it will be called (regardless of format)
Packit 857059
 * with data pointer pointing to present object + offset.
Packit 857059
 * If no format_func is specified, the offset and size will be used along
Packit 857059
 * with the format to automatically fetch the field and generate output
Packit 857059
 * 'k', 't', 'w' and 'y' formats must supply a format_func.
Packit 857059
 *
Packit 857059
 * Input Parsing:
Packit 857059
 * On input parsing, capital letters for format indicate manditory fields
Packit 857059
 * Present implementation is limited to no more than 64 manditory fields
Packit 857059
 * per object
Packit 857059
 *
Packit 857059
 * On input parsing, if a start_func is supplied an end_func must also
Packit 857059
 * be supplied.  If a end_func is supplied, format is not used to parse
Packit 857059
 * data but affects whitespace and subfield processing.
Packit 857059
 * An end_func should be supplied for 'k'/'t'/'w'/'y' formats, otherwise
Packit 857059
 * the input field will be ignored (recommend use of IXmlParserEndNoop
Packit 857059
 * rather than NULL for future compatibility).
Packit 857059
 *
Packit 857059
 * On output processing, capital letters for format indicate manditory fields
Packit 857059
 * which are always output regardless of value.  lower case leters for format
Packit 857059
 * are optional fields which will only be output if non-zero/non-NULL.
Packit 857059
 * For 'k', 't', 'w' and 'y' fields, its up to the supplied format_func to
Packit 857059
 * decide.
Packit 857059
 * There are "Optional" variations of most generic format functions which may
Packit 857059
 * be used by format_func if desired.
Packit 857059
 *
Packit 857059
 * For an output only field:
Packit 857059
 * 	type/format_func define output
Packit 857059
 * 	start_func=NULL, end_func=IXmlParserEndNoop
Packit 857059
 * For an input only field:
Packit 857059
 * 	type/start_func/end_func define input
Packit 857059
 * 	format_func=IXmlOutputNoop
Packit 857059
 * For an input/output field:
Packit 857059
 * 	type/start_func/end_func define input
Packit 857059
 * 	type/format_func define output
Packit 857059
 *
Packit 857059
 * Error handling:
Packit 857059
 * Failures in XML syntax or calls to IXmlParserPrintError will stop
Packit 857059
 * the parser with an error.  For such parsing failures, the parser
Packit 857059
 * will unwind and invoke the end_func's for all objects whose start_func
Packit 857059
 * had been called.  Such calls will have valid=FALSE.  In this case
Packit 857059
 * the end_func should undo any operations which the start_func did
Packit 857059
 * (free object, remove object from lists in parent to which start func added it
Packit 857059
 * etc).
Packit 857059
 *
Packit 857059
 * If a start_func or end_func encounters a fatal error, it should call
Packit 857059
 * IXmlParserPrintError with an appropriate message.  This will output
Packit 857059
 * a message including input file line, present tag and the message
Packit 857059
 * provided by the caller.  It will also start the parser error and unwind
Packit 857059
 * sequence.
Packit 857059
 *
Packit 857059
 * Once a parser error is detected, no further start_func's will be called.
Packit 857059
 *
Packit 857059
 * Object handling:
Packit 857059
 * The parser assists in tracking object heirachies and provides objects
Packit 857059
 * to the start_func and end_func.  The start_func is expected to return an
Packit 857059
 * object pointer.  This pointer is typically an object/structure allocated
Packit 857059
 * by the start function to hold the subsequent tags.  The pointer returned by
Packit 857059
 * the start_func will be provided to the end_func as the "object" argument.
Packit 857059
 * Also if there are nested tags (eg. subfields), the object returned by
Packit 857059
 * the start_func will also be provided to the nested tags' start_func and
Packit 857059
 * end_func as the "parent".
Packit 857059
 *
Packit 857059
 * Typical operation would be for the start_func to allocate and initialize
Packit 857059
 * the empty object.  For simple structures which simply need to be
Packit 857059
 * allocated and zeroed, the IXmlParserStartStruct function is provided.
Packit 857059
 * Then the end_func would verify the consistency of the fields and link the
Packit 857059
 * object into its parent (add to a list or pointer).  If the end_func discovers
Packit 857059
 * an error it should call IXmlParserPrintError (or Warning if its non-fatal)
Packit 857059
 * and free the object.
Packit 857059
 *
Packit 857059
 * For simple fields (bitfields, needing special handling, etc).  The
Packit 857059
 * start_func can be NULL and the end_func will be given the object and
Packit 857059
 * parent applicable to the preceeding tag.
Packit 857059
 *
Packit 857059
 * The code in ixml_ib.c is a good example of use of the parser.
Packit 857059
 *
Packit 857059
 * xml_sample provides a simple example of a parser which uses the
Packit 857059
 * wildcards to parse and dump any XML file given.
Packit 857059
 *
Packit 857059
 * opaxmlindent expands on xml_sample by dumping the XML with nice indentation
Packit 857059
 */
Packit 857059
Packit 857059
/*****************************************************************************/
Packit 857059
/* XML Output Declarations */
Packit 857059
typedef enum {
Packit 857059
	/* flags which can be passed to IXmlInit and IXmlOutputInit */
Packit 857059
	IXML_OUTPUT_FLAG_NONE = 0,
Packit 857059
	IXML_OUTPUT_FLAG_SERIALIZE = 1,	/* compact serialized format */
Packit 857059
	/* these flags are for internal use only */
Packit 857059
	IXML_OUTPUT_FLAG_START_NEED_NL = 0x10000,	/* start tag output without newline */
Packit 857059
	IXML_OUTPUT_FLAG_HAD_CONTENT = 0x20000,	/* tag had content output */
Packit 857059
	IXML_OUTPUT_FLAG_IN_START_TAG = 0x40000, /* For printing multiple attrs */
Packit 857059
} IXmlOutputFlags_t;
Packit 857059
Packit 857059
/* these structures should not be directly used by callers */
Packit 857059
typedef struct IXmlOutputState {
Packit 857059
// TBD - later support output to a memory buffer
Packit 857059
	FILE *file;		/* output file */
Packit 857059
	unsigned indent;	/* level of indent */
Packit 857059
	unsigned cur_indent;	/* level of indent */
Packit 857059
	int flags;
Packit 857059
	void *context;	/* caller supplied context */
Packit 857059
} IXmlOutputState_t;
Packit 857059
Packit 857059
/* for use in output calls so can early exit */
Packit 857059
/* note that IXmlOutputStruct tests this, so in general it does not need to
Packit 857059
 * be called in other functions
Packit 857059
 */
Packit 857059
static _inline boolean IXmlOutputFailed(IXmlOutputState_t *state)
Packit 857059
{
Packit 857059
	return (ferror(state->file) != 0);
Packit 857059
}
Packit 857059
Packit 857059
/* get access to caller supplied context for output */
Packit 857059
static _inline void* IXmlOutputGetContext(IXmlOutputState_t *state)
Packit 857059
{
Packit 857059
	return state->context;
Packit 857059
}
Packit 857059
Packit 857059
/* indent is additional indent per level */
Packit 857059
extern void IXmlInit(IXmlOutputState_t *state, FILE *file,
Packit 857059
				unsigned indent, IXmlOutputFlags_t flags, void *context);
Packit 857059
extern FSTATUS IXmlOutputInit(IXmlOutputState_t *state, FILE *file,
Packit 857059
				unsigned indent, IXmlOutputFlags_t flags, void *context);
Packit 857059
extern void IXmlOutputDestroy(IXmlOutputState_t *state);
Packit 857059
extern void IXmlOutputPrint(IXmlOutputState_t *state, const char *format, ...);
Packit 857059
extern void IXmlOutputPrintIndent(IXmlOutputState_t *state, const char *format, ...);
Packit 857059
extern void IXmlOutputNoop(IXmlOutputState_t *state, const char *tag, void *data);
Packit 857059
extern void IXmlOutputStartTag(IXmlOutputState_t *state, const char *tag);
Packit 857059
Packit 857059
/*
Packit 857059
 * Print start tag with single attribute and value. Use
Packit 857059
 * IXmlOutputStartTag() and IXmlOutputAttr*() if you need to print
Packit 857059
 * multiple attributes.
Packit 857059
 */
Packit 857059
extern void IXmlOutputStartAttrTag(IXmlOutputState_t *state, const char *tag, void *data, IXML_FORMAT_ATTR_FUNC attr_func);
Packit 857059
Packit 857059
/*
Packit 857059
 * Add @attr with @val to current element tag definition.
Packit 857059
 * This doesn't do any sanitizing on @attr or @val so be careful
Packit 857059
 * what you put in. Should be called after a call to IXmlOutputStartTag().
Packit 857059
 * Any call (direct or indirect) to IXmlOutputPrint() or
Packit 857059
 * IXmlOutputPrintIndent() closes the start tag.
Packit 857059
 *
Packit 857059
 * @return FSUCCESS on success, FERROR if not in the start of a tag
Packit 857059
 */
Packit 857059
extern FSTATUS IXmlOutputAttr(IXmlOutputState_t *state, const char *attr, const char *val);
Packit 857059
Packit 857059
/*
Packit 857059
 * Like IXmlOutputAttr() but takes a format string and variable args.
Packit 857059
 * As with IXmlOutputAttr(), does not sanitize inputs.
Packit 857059
 *
Packit 857059
 * @return FSUCCESS on success, FERROR if not in the start of a tag
Packit 857059
 */
Packit 857059
extern FSTATUS IXmlOutputAttrFmt(IXmlOutputState_t *state, const char *attr, const char *format, ...);
Packit 857059
extern void IXmlOutputEndTag(IXmlOutputState_t *state, const char *tag);
Packit 857059
extern void IXmlOutputEndTagWithLineno(IXmlOutputState_t *state, const char *tag, unsigned long lineno);
Packit 857059
extern void IXmlOutputHexPad8(IXmlOutputState_t *state, const char *tag, uint8 value);
Packit 857059
extern void IXmlOutputOptionalHexPad8(IXmlOutputState_t *state, const char *tag, uint8 value);
Packit 857059
extern void IXmlOutputHexPad16(IXmlOutputState_t *state, const char *tag, uint16 value);
Packit 857059
extern void IXmlOutputOptionalHexPad16(IXmlOutputState_t *state, const char *tag, uint16 value);
Packit 857059
extern void IXmlOutputHexPad32(IXmlOutputState_t *state, const char *tag, uint32 value);
Packit 857059
extern void IXmlOutputOptionalHexPad32(IXmlOutputState_t *state, const char *tag, uint32 value);
Packit 857059
extern void IXmlOutputHexPad64(IXmlOutputState_t *state, const char *tag, uint64 value);
Packit 857059
extern void IXmlOutputOptionalHexPad64(IXmlOutputState_t *state, const char *tag, uint64 value);
Packit 857059
extern void IXmlOutputInt(IXmlOutputState_t *state, const char *tag, int value);
Packit 857059
extern void IXmlOutputOptionalInt(IXmlOutputState_t *state, const char *tag, int value);
Packit 857059
extern void IXmlOutputInt64(IXmlOutputState_t *state, const char *tag, int64 value);
Packit 857059
extern void IXmlOutputOptionalInt64(IXmlOutputState_t *state, const char *tag, int64 value);
Packit 857059
extern void IXmlOutputUint(IXmlOutputState_t *state, const char *tag, unsigned value);
Packit 857059
extern void IXmlOutputOptionalUint(IXmlOutputState_t *state, const char *tag, unsigned value);
Packit 857059
extern void IXmlOutputUint64(IXmlOutputState_t *state, const char *tag, uint64 value);
Packit 857059
extern void IXmlOutputOptionalUint64(IXmlOutputState_t *state, const char *tag, uint64 value);
Packit 857059
extern void IXmlOutputHex(IXmlOutputState_t *state, const char *tag, unsigned value);
Packit 857059
extern void IXmlOutputOptionalHex(IXmlOutputState_t *state, const char *tag, unsigned value);
Packit 857059
extern void IXmlOutputHex64(IXmlOutputState_t *state, const char *tag, uint64 value);
Packit 857059
extern void IXmlOutputOptionalHex64(IXmlOutputState_t *state, const char *tag, uint64 value);
Packit 857059
extern void IXmlOutputPrintStrLen(IXmlOutputState_t *state, const char* value, int len);
Packit 857059
extern void IXmlOutputPrintStr(IXmlOutputState_t *state, const char* value);
Packit 857059
extern void IXmlOutputStrLen(IXmlOutputState_t *state, const char *tag, const char* value, int len);
Packit 857059
extern void IXmlOutputOptionalStrLen(IXmlOutputState_t *state, const char *tag, const char* value, int len);
Packit 857059
extern void IXmlOutputStr(IXmlOutputState_t *state, const char *tag, const char* value);
Packit 857059
extern void IXmlOutputOptionalStr(IXmlOutputState_t *state, const char *tag, const char* value);
Packit 857059
extern void IXmlOutputStrUint(IXmlOutputState_t *state, const char *tag, const char* str, unsigned value);
Packit 857059
extern void IXmlOutputOptionalStrUint(IXmlOutputState_t *state, const char *tag, const char* str, unsigned value);
Packit 857059
extern void IXmlOutputStrUint64(IXmlOutputState_t *state, const char *tag, const char* str, uint64 value);
Packit 857059
extern void IXmlOutputOptionalStrUint64(IXmlOutputState_t *state, const char *tag, const char* str, uint64 value);
Packit 857059
extern void IXmlOutputStrInt(IXmlOutputState_t *state, const char *tag, const char* str, int value);
Packit 857059
extern void IXmlOutputOptionalStrInt(IXmlOutputState_t *state, const char *tag, const char* str, int value);
Packit 857059
extern void IXmlOutputStruct(IXmlOutputState_t *state, const char *tag, void *data,
Packit 857059
				IXML_FORMAT_ATTR_FUNC attr_func, const IXML_FIELD *fields);
Packit 857059
extern void IXmlOutputOptionalStruct(IXmlOutputState_t *state, const char *tag, void *data, IXML_FORMAT_ATTR_FUNC attr_func, IXML_FIELD *fields);
Packit 857059
Packit 857059
/*****************************************************************************/
Packit 857059
/* XML Parser declarations */
Packit 857059
/* these structures should not be directly used by callers */
Packit 857059
typedef struct IXmlParserStackEntry {
Packit 857059
	char *tag;				// locally allocated copy
Packit 857059
	const IXML_FIELD *field;
Packit 857059
	const IXML_FIELD *subfields;
Packit 857059
	void *object;
Packit 857059
	unsigned tags_found;	// total subfield tags encountered including dups
Packit 857059
	uint64 fields_found;	// bit mask of indexes into subfields
Packit 857059
} IXmlParserStackEntry_t;
Packit 857059
Packit 857059
#define STACK_DEPTH 100
Packit 857059
Packit 857059
typedef struct IXmlParserStack {
Packit 857059
	/* TOS is kept in state->current instead */
Packit 857059
	unsigned sp;	/* if 0, stack is empty */
Packit 857059
	IXmlParserStackEntry_t entries[STACK_DEPTH];	/* entry 0 is unused */
Packit 857059
} IXmlParserStack_t;
Packit 857059
Packit 857059
/* callbacks by the parser to output errors and warnings */
Packit 857059
typedef void (*IXmlParserPrintMessage)(const char *message);
Packit 857059
Packit 857059
typedef struct IXmlParserState {
Packit 857059
// TBD - later support input from a memory buffer
Packit 857059
	XML_Parser parser;
Packit 857059
	int			flags;	/* parser option flags */
Packit 857059
	unsigned	depth;	/* how many nested elements deep >= 1 */
Packit 857059
	unsigned 	skip;	/* skip all elements until we return to this depth */
Packit 857059
	IXmlParserStackEntry_t current; /* state of current element being parsed */
Packit 857059
	XML_Char *content;	/* text contents of current element */
Packit 857059
	unsigned len;		/* number of characters in content */
Packit 857059
	IXmlParserStack_t stack;	/* stack of parent elements' states */
Packit 857059
	unsigned error_cnt;
Packit 857059
	unsigned warning_cnt;
Packit 857059
	void *context;	/* caller supplied context */
Packit 857059
	IXmlParserPrintMessage printError;
Packit 857059
	IXmlParserPrintMessage printWarning;
Packit 857059
} IXmlParserState_t;
Packit 857059
Packit 857059
/* get access to caller supplied context for input */
Packit 857059
static _inline void* IXmlParserGetContext(IXmlParserState_t *state)
Packit 857059
{
Packit 857059
	return state->context;
Packit 857059
}
Packit 857059
Packit 857059
typedef enum {
Packit 857059
	/* flags which can be passed to IXmlInit and IXmlOutputInit */
Packit 857059
	IXML_PARSER_FLAG_NONE = 0,
Packit 857059
	IXML_PARSER_FLAG_STRICT = 1,	/* provide warnings for unknown tags, etc */
Packit 857059
} IXmlParserFlags_t;
Packit 857059
Packit 857059
/* get parser option flags */
Packit 857059
extern int IXmlParserGetFlags(IXmlParserState_t *state);
Packit 857059
Packit 857059
/* get current tag name, returns NULL if no current tag */
Packit 857059
extern const char* IXmlParserGetCurrentTag(IXmlParserState_t *state);
Packit 857059
Packit 857059
/* get parent tag name, returns NULL if no parent tag */
Packit 857059
extern const char* IXmlParserGetParentTag(IXmlParserState_t *state);
Packit 857059
Packit 857059
/* get current Full dotted tag name, returns NULL if no current tag,
Packit 857059
 * returns pointer to a static buffer which is invalid after next call
Packit 857059
 * to this function
Packit 857059
 * In the event of overflow, the string "overflow" is returned
Packit 857059
 */
Packit 857059
extern const char* IXmlParserGetCurrentFullTag(IXmlParserState_t *state);
Packit 857059
Packit 857059
/* get count of child tags to current tag, typically called in ParserEnd */
Packit 857059
extern unsigned  IXmlParserGetChildTagCount(IXmlParserState_t *state);
Packit 857059
Packit 857059
// set subfields for present tag, only valid to call within ParserStart
Packit 857059
// callback.  This will override the subfields which were specified for
Packit 857059
// the current IXML_FIELD structure
Packit 857059
extern void IXmlParserSetSubfields(IXmlParserState_t *state, const IXML_FIELD *subfields);
Packit 857059
Packit 857059
// set field for present tag, only valid to call within ParserStart
Packit 857059
// callback.  This will override the field which was specified for
Packit 857059
// the matching IXML_FIELD structure
Packit 857059
// Beware the ParserEndFunc in field will be called instead of the one in
Packit 857059
// the original subfields list which matched this tag
Packit 857059
// The current subfields are also set to field->subfields
Packit 857059
extern void IXmlParserSetField(IXmlParserState_t *state, const IXML_FIELD *field);
Packit 857059
Packit 857059
// output an error message and increment error_cnt
Packit 857059
extern void IXmlParserPrintError(IXmlParserState_t *state, const char *format, ...);
Packit 857059
Packit 857059
// output a warning message and increment warning_cnt
Packit 857059
extern void IXmlParserPrintWarning(IXmlParserState_t *state, const char *format, ...);
Packit 857059
Packit 857059
/* helper functions to aid getting field pointer in end_func callbacks */
Packit 857059
/* this is useful when implementing reusable end_func's which don't know exact
Packit 857059
 * datatype of object
Packit 857059
 */
Packit 857059
static _inline void* IXmlParserGetField(const IXML_FIELD* field, void *object)
Packit 857059
{
Packit 857059
	return (void*)((uintn)object + field->offset);
Packit 857059
}
Packit 857059
Packit 857059
/* helper functions to aid parsing of unsigned hex or decimal fields */
Packit 857059
/* return TRUE on success, FALSE on failure
Packit 857059
 * on failure IXmlParserPrintError called to describe error and move
Packit 857059
 * parser to Failed state
Packit 857059
 */
Packit 857059
extern boolean IXmlParseUint8(IXmlParserState_t *state,
Packit 857059
							XML_Char *content, unsigned len, uint8 *value);
Packit 857059
extern boolean IXmlParseUint16(IXmlParserState_t *state,
Packit 857059
							XML_Char *content, unsigned len, uint16 *value);
Packit 857059
extern boolean IXmlParseUint32(IXmlParserState_t *state,
Packit 857059
							XML_Char *content, unsigned len, uint32 *value);
Packit 857059
extern boolean IXmlParseUint64(IXmlParserState_t *state,
Packit 857059
							XML_Char *content, unsigned len, uint64 *value);
Packit 857059
Packit 857059
/* helper functions to aid parsing of signed decimal fields */
Packit 857059
extern boolean IXmlParseInt8(IXmlParserState_t *state,
Packit 857059
							XML_Char *content, unsigned len, int8 *value);
Packit 857059
extern boolean IXmlParseInt16(IXmlParserState_t *state,
Packit 857059
							XML_Char *content, unsigned len, int16 *value);
Packit 857059
extern boolean IXmlParseInt32(IXmlParserState_t *state,
Packit 857059
							XML_Char *content, unsigned len, int32 *value);
Packit 857059
extern boolean IXmlParseInt64(IXmlParserState_t *state,
Packit 857059
							XML_Char *content, unsigned len, int64 *value);
Packit 857059
Packit 857059
/* start_func for a simple structure.  Allocates and zeros the structure using
Packit 857059
 * size specified in XML_FIELD
Packit 857059
 */
Packit 857059
extern void *IXmlParserStartStruct(IXmlParserState_t *state, void *parent, const char **attr);
Packit 857059
Packit 857059
/* end tag function which is a noop.  Use this with start_func=NULL
Packit 857059
 * to define XML_FIELDs which are output only
Packit 857059
 */
Packit 857059
extern void IXmlParserEndNoop(struct IXmlParserState *state, 
Packit 857059
				const IXML_FIELD *field,
Packit 857059
				void *object, void *parent, XML_Char *content, unsigned len,
Packit 857059
				boolean valid);
Packit 857059
Packit 857059
/* return TRUE if current field's contents are empty or all whitespace */
Packit 857059
boolean IXmlIsWhitespace(const XML_Char *str, boolean *hasNewline);
Packit 857059
Packit 857059
/* discard leading and trailing whitespace in str, return new length
Packit 857059
 * str modified in place
Packit 857059
 */
Packit 857059
unsigned IXmlTrimWhitespace(XML_Char *str, unsigned len);
Packit 857059
Packit 857059
extern FSTATUS IXmlParserInit(IXmlParserState_t *state, IXmlParserFlags_t flags,
Packit 857059
				const IXML_FIELD *subfields, void *object, void *context,
Packit 857059
				IXmlParserPrintMessage printError,
Packit 857059
			   	IXmlParserPrintMessage printWarning,
Packit 857059
				XML_Memory_Handling_Suite* memsuite);
Packit 857059
Packit 857059
extern FSTATUS IXmlParserReadFile(IXmlParserState_t *state, FILE *file);
Packit 857059
extern void IXmlParserDestroy(IXmlParserState_t *state);
Packit 857059
Packit 857059
#ifndef VXWORKS
Packit 857059
// parse supplied file.  filename is only used in error messages
Packit 857059
extern FSTATUS IXmlParseFile(FILE *file, const char* filename,
Packit 857059
			   	IXmlParserFlags_t flags,
Packit 857059
				const IXML_FIELD *subfields, void *object, void *context,
Packit 857059
				IXmlParserPrintMessage printError,
Packit 857059
			   	IXmlParserPrintMessage printWarning,
Packit 857059
				unsigned* tags_found, unsigned *fields_found);
Packit 857059
// open and parse input_file
Packit 857059
extern FSTATUS IXmlParseInputFile(const char *input_file,
Packit 857059
			   	IXmlParserFlags_t flags,
Packit 857059
				const IXML_FIELD *subfields, void *object, void *context,
Packit 857059
				IXmlParserPrintMessage printError,
Packit 857059
			   	IXmlParserPrintMessage printWarning,
Packit 857059
				unsigned* tags_found, unsigned *fields_found);
Packit 857059
#else
Packit 857059
// parse supplied file.  filename is only used in error messages
Packit 857059
extern FSTATUS IXmlParseFile(FILE *file, const char* filename,
Packit 857059
			   	IXmlParserFlags_t flags,
Packit 857059
				const IXML_FIELD *subfields, void *object, void *context,
Packit 857059
				IXmlParserPrintMessage printError,
Packit 857059
			   	IXmlParserPrintMessage printWarning,
Packit 857059
				unsigned* tags_found, unsigned *fields_found,
Packit 857059
				XML_Memory_Handling_Suite* memsuite);
Packit 857059
// open and parse input_file
Packit 857059
extern FSTATUS IXmlParseInputFile(const char *input_file,
Packit 857059
			   	IXmlParserFlags_t flags,
Packit 857059
				const IXML_FIELD *subfields, void *object, void *context,
Packit 857059
				IXmlParserPrintMessage printError,
Packit 857059
			   	IXmlParserPrintMessage printWarning,
Packit 857059
				unsigned* tags_found, unsigned *fields_found,
Packit 857059
				XML_Memory_Handling_Suite* memsuite);
Packit 857059
#endif
Packit 857059
Packit 857059
#ifdef __cplusplus
Packit 857059
};
Packit 857059
#endif
Packit 857059
Packit 857059
#endif /* _IBA_PUBLIC_IXML_H_ */