/*******************************************************************************
 * Copyright (C) 2004-2006 Intel Corp. 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 Intel Corp. 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 Intel Corp. OR THE 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.
 *******************************************************************************/

/**
 * @author Eugene Yarmosh
 * @author Vadim Revyakin
 */

#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <ctype.h>
#include <assert.h>

#if defined (__SVR4) && defined (__sun)
#include <strings.h>
#endif

#include <u/libu.h>
#include <math.h>

#include "wsman-xml-api.h"
#include "wsman-soap.h"
#include "wsman-xml.h"

#include "wsman-dispatcher.h"
#include "wsman-xml-serializer.h"
#include "wsman-xml-serialize.h"
#include "wsman-soap-envelope.h"

struct __WsSerializerMemEntry {
	char buf[0];
};

typedef struct __WsSerializerMemEntry WsSerializerMemEntry;

struct __WsSerializerContext
{
	pthread_mutex_t lock;
	list_t *WsSerializerAllocList;
};

WsSerializerContextH ws_serializer_init()
{
	WsSerializerContextH serializercntx = NULL;
	serializercntx = u_malloc(sizeof(struct __WsSerializerContext));
	if(serializercntx == NULL) return NULL;
	serializercntx->WsSerializerAllocList = list_create(LISTCOUNT_T_MAX);
	if(serializercntx->WsSerializerAllocList == NULL) {
		u_free(serializercntx);
		return NULL;
	}
	u_init_lock(serializercntx);
	return serializercntx;
}

int ws_serializer_cleanup(WsSerializerContextH serctx)
{
	if(serctx && serctx->WsSerializerAllocList) {
		ws_serializer_free_all(serctx);
                u_destroy_lock(serctx);
		list_destroy(serctx->WsSerializerAllocList);
		u_free(serctx);
	}
	return 0;
}

void *xml_serializer_alloc(XmlSerializationData * data, int size,
			   int zeroInit)
{
	void *ptr = ws_serializer_alloc(data->serctx, size);
	TRACE_ENTER;
	if (ptr && zeroInit)
		memset(ptr, 0, size);
	TRACE_EXIT;
	return ptr;
}


int xml_serializer_free(XmlSerializationData * data, void *buf)
{
	return ws_serializer_free(data->serctx, buf);
}


WsXmlNodeH
xml_serializer_add_child(XmlSerializationData * data, char *value)
{
	const char *name = data->elementInfo->name;
	const char *ns = data->elementInfo->ns;
	WsXmlNodeH node;

	TRACE_ENTER;
	debug("name = %s; value(%p) = %s", name ? name : "NULL", value, value ? value : "NULL");
	node = ws_xml_add_child(data->xmlNode, ns, name, value);
	TRACE_EXIT;
	return node;
}



WsXmlNodeH xml_serializer_get_child(XmlSerializationData * data)
{
	WsXmlNodeH node;
	const char *name = data->elementInfo->name;
	const char *ns = data->elementInfo->ns;

	TRACE_ENTER;
	debug("name = %s:%s in %s [%d]", ns, name,
	      ws_xml_get_node_local_name(data->xmlNode), data->index);
	node = ws_xml_get_child(data->xmlNode, data->index, ns, name);
#if 0
	if (g_NameNameAliaseTable) {
		int index = 0;
		while (node == NULL &&
				g_NameNameAliaseTable[index].name != NULL) {
			if (!strcmp(g_NameNameAliaseTable[index].name, name))
			       	node = ws_xml_get_child(data->xmlNode,
						     data->index, ns,
						     g_NameNameAliaseTable
						     [index].aliase);
			index++;
		}
	}
#endif
	debug("returned %p; %s",
	      node, node ? ws_xml_get_node_local_name(node) : "");
	TRACE_EXIT;
	return node;
}

static int get_struct_align(void)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		struct {
			char x;
			void *y;
		} b;
	} dummy;
	return (char *) &(((dummy *) NULL)->b) - (char *) NULL;
}


static int
handle_attrs(struct __XmlSerializationData *data,
	     WsXmlNodeH node, size_t sz)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_NODE_ATTR *b;
	} dummy;

	int ret = 0;
	char *savedBufPtr = DATA_BUF(data);
	size_t al;
	size_t pad;
	int i;
	XML_NODE_ATTR **attrsp;
	XML_NODE_ATTR *attr;
	WsXmlAttrH xmlattr;
	char *src, *dstPtr;
	int dstSize;
	TRACE_ENTER;
	debug("node name = %s", ws_xml_get_node_local_name(node));
	if (!XML_IS_ATTRS(data->elementInfo)) {
		debug("No attrs");
		goto DONE;
	}


	DATA_BUF(data) = DATA_BUF(data) + sz;
	al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}
	debug("initial DATABUF = %p", DATA_BUF(data));
	DATA_BUF(data) = DATA_BUF(data) + pad;
	debug("alligned databuf = %p; pad = 0x%x", DATA_BUF(data), pad);

	if (data->mode == XML_SMODE_FREE_MEM) {
		// XXXXX   free memory
		goto DONE;
	}
	if (data->mode == XML_SMODE_SERIALIZE) {
		XML_NODE_ATTR *attrs =
		    *((XML_NODE_ATTR **) DATA_BUF(data));
		debug("attrs = %p", attrs);
		while (attrs) {
			debug("add attr. %s:%s = %s",
			      attrs->ns, attrs->name, attrs->value);
			if (ws_xml_add_node_attr(node,
						 attrs->ns, attrs->name,
						 attrs->value) == NULL) {
				error("could not add attr. %s:%s = %s",
				      attrs->ns, attrs->name,
				      attrs->value);
				ret = 1;
				goto DONE;
			}
			attrs = attrs->next;
		}
		goto DONE;
	}
	// XML_SMODE_DESERIALIZE
	attrsp = (XML_NODE_ATTR **) DATA_BUF(data);
	*attrsp = NULL;
	for (i = 0; i < ws_xml_get_node_attr_count(node); i++) {
		attr =
		    xml_serializer_alloc(data, sizeof(XML_NODE_ATTR), 1);
		if (attr == NULL) {
			error("no memory");
			ret = 1;
			goto DONE;
		}
		xmlattr = ws_xml_get_node_attr(node, i);
		if (xmlattr == NULL) {
			error("could not get attr %d", i);
			ret = 1;
			goto DONE;
		}
		src = ws_xml_get_attr_ns(xmlattr);
		if (!(src == NULL || *src == 0)) {
			dstSize = 1 + (int )strlen(src);
			dstPtr =
			    (char *) xml_serializer_alloc(data, dstSize,
							  1);
			if (dstPtr == NULL) {
				error("no memory");
				ret = 1;
				goto DONE;
			}
			strncpy(dstPtr, src, dstSize);
			attr->ns = dstPtr;
		}
		src = ws_xml_get_attr_name(xmlattr);
		if (!(src == NULL || *src == 0)) {
			dstSize = 1 + (int )strlen(src);
			dstPtr =
			    (char *) xml_serializer_alloc(data, dstSize,
							  1);
			if (dstPtr == NULL) {
				error("no memory");
				ret = 1;
				goto DONE;
			}
			strncpy(dstPtr, src, dstSize);
			attr->name = dstPtr;
		}
		src = ws_xml_get_attr_value(xmlattr);
		if (!(src == NULL || *src == 0)) {
			dstSize = 1 + (int )strlen(src);
			dstPtr =
			    (char *) xml_serializer_alloc(data, dstSize,
							  1);
			if (dstPtr == NULL) {
				error("no memory");
				ret = 1;
				goto DONE;
			}
			strncpy(dstPtr, src, dstSize);
			attr->value = dstPtr;
		}
		attr->next = *attrsp;
		*attrsp = attr;
	}
      DONE:
	DATA_BUF(data) = savedBufPtr;
	TRACE_EXIT;
	return ret;
}

static int do_serialize_int(XmlSerializationData * data, int valSize)
{
	WsXmlNodeH child = NULL;
	XML_TYPE_INT64 tmp;
	int retVal = DATA_ALL_SIZE(data);
	char *end;
	char *str;

	TRACE_ENTER;
	debug("handle %d INT%d %s;", DATA_COUNT(data),
	      8 * valSize, data->elementInfo->name);
	if (DATA_BUF(data) + retVal > data->stopper) {
		error("size of %d structures %s exceeds stopper (%p > %p)",
		      DATA_COUNT(data), DATA_ELNAME(data),
		      DATA_BUF(data) + retVal, data->stopper);
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}
	if (DATA_MUST_BE_SKIPPED(data) || data->mode == XML_SMODE_FREE_MEM) {
		DATA_BUF(data) = DATA_BUF(data) + retVal;
		goto DONE;
	}
	if ((data->mode != XML_SMODE_DESERIALIZE &&
	     data->mode != XML_SMODE_SERIALIZE)) {
		error("invalid mode %d", data->mode);
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}

	for (data->index = 0; data->index < DATA_COUNT(data);
	     data->index++) {
		debug("%s[%d] = %p", data->elementInfo->name, data->index,
		      data->elementBuf);

		if (data->mode == XML_SMODE_SERIALIZE) {
			debug("value size: %d", valSize);
			if (valSize == 1)
				tmp =
				    *((XML_TYPE_INT8 *) data->elementBuf);
			else if (valSize == 2)
				tmp = *((XML_TYPE_INT16 *) data->
				      elementBuf);
			else if (valSize == 4)
				tmp = *((XML_TYPE_INT32 *) data->
				      elementBuf);
			else if (valSize == 8)
				tmp = *((XML_TYPE_INT64 *) data->
				      elementBuf);
			else {
				error("unsupported uint size + %d",
						8 * valSize);
				retVal = WS_ERR_INVALID_PARAMETER;
				goto DONE;
			}

			if (((child = xml_serializer_add_child(data,
						       NULL)) == NULL)
			    || (ws_xml_set_node_long(child, tmp)) != 0) {
				debug("could not add child %s[%d]",
				      DATA_ELNAME(data), data->index);
				retVal = WS_ERR_INSUFFICIENT_RESOURCES;
				goto DONE;
			}
		}
		if (data->mode == XML_SMODE_DESERIALIZE) {
			if ((child = xml_serializer_get_child(data)) == NULL) {
				error ("not enough (%d < %d) instances of element %s",
				     data->index, DATA_COUNT(data),
				     DATA_ELNAME(data));
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			if ((str = ws_xml_get_node_text(child)) == NULL) {
				error("No text of node %s[%d]",
				      DATA_ELNAME(data), data->index);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			while (isspace(str[0]))
				str++;
			errno = 0;
			if (str[0] == 0) {
				if (ws_xml_find_attr_bool(child,
						     XML_NS_SCHEMA_INSTANCE,
						     XML_SCHEMA_NIL)) {
					goto ATTR;
				}
				error("absent value = %s", str);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			tmp = strtoll(str, &end, 10);
			if (errno) {
				error("strtoul(%s) failed; errno = %d",
				      str, errno);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			while (isspace(end[0]))
				end++;
			if (*end != 0) {
				error("wrong token = %s.", str);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			if (valSize == 1) {
				if (tmp > 127 || tmp < -128) {
					error("not int8 = %ld", tmp);
					retVal = WS_ERR_XML_PARSING;
					goto DONE;
				}
				*((XML_TYPE_INT8 *) data->elementBuf) =
				    (XML_TYPE_INT8) tmp;
			} else if (valSize == 2) {
				if (tmp > 32767 || tmp < -32768) {
					error("not int16 = %ld", tmp);
					retVal = WS_ERR_XML_PARSING;
					goto DONE;
				}
				*((XML_TYPE_INT16 *) data->elementBuf) =
				    (XML_TYPE_INT16) tmp;
			} else if (valSize == 4) {
				*((XML_TYPE_INT32 *) data->elementBuf) =
				    (XML_TYPE_INT32) tmp;
			} else if (valSize == 8) {
				*((XML_TYPE_INT64 *) data->elementBuf) =
				    (XML_TYPE_INT64) tmp;
			} else {
				error("unsupported int size + %d",
				      8 * valSize);
				retVal = WS_ERR_INVALID_PARAMETER;
				goto DONE;
			}
		}
ATTR:
		handle_attrs(data, child, valSize);
		DATA_BUF(data) = DATA_BUF(data) + DATA_SIZE(data);
	}
	if ((data->mode == XML_SMODE_DESERIALIZE) &&
	    xml_serializer_get_child(data)) {
		error("too many (%d > %d) instances of element %s",
		      data->index, DATA_COUNT(data), DATA_ELNAME(data));
		retVal = WS_ERR_XML_PARSING;
		goto DONE;
	}
DONE:
	TRACE_EXIT;
	return retVal;
}

static int do_serialize_uint(XmlSerializationData * data, int valSize)
{
	WsXmlNodeH child = NULL;
	XML_TYPE_UINT64 tmp;
	int retVal = DATA_ALL_SIZE(data);
	char *end;
	char *str;

	TRACE_ENTER;
	debug("handle %d UINT%d %s;", DATA_COUNT(data),
	      8 * valSize, data->elementInfo->name);
	if (DATA_BUF(data) + retVal > data->stopper) {
		error("size of %d structures %s exceeds stopper (%p > %p)",
		      DATA_COUNT(data), DATA_ELNAME(data),
		      DATA_BUF(data) + retVal, data->stopper);
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}
	if (DATA_MUST_BE_SKIPPED(data) || data->mode == XML_SMODE_FREE_MEM) {
		DATA_BUF(data) = DATA_BUF(data) + retVal;
		goto DONE;
	}
	if ((data->mode != XML_SMODE_DESERIALIZE &&
	     data->mode != XML_SMODE_SERIALIZE)) {
		error("invalid mode %d", data->mode);
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}

	for (data->index = 0; data->index < DATA_COUNT(data);
	     data->index++) {
		debug("%s[%d] = %p", data->elementInfo->name, data->index,
		      data->elementBuf);

		if (data->mode == XML_SMODE_SERIALIZE) {
			debug("value size: %d", valSize);
			if (valSize == 1)
				tmp =
				    *((XML_TYPE_UINT8 *) data->elementBuf);
			else if (valSize == 2)
				tmp = *((XML_TYPE_UINT16 *) data->
				      elementBuf);
			else if (valSize == 4)
				tmp = *((XML_TYPE_UINT32 *) data->
				      elementBuf);
			else if (valSize == 8)
				tmp = *((XML_TYPE_UINT64 *) data->
				      elementBuf);
			else {
				error("unsupported uint size + %d",
						8 * valSize);
				retVal = WS_ERR_INVALID_PARAMETER;
				goto DONE;
			}

			if (((child = xml_serializer_add_child(data,
						       NULL)) == NULL)
			    || (ws_xml_set_node_ulong(child, tmp)) != 0) {
				debug("could not add child %s[%d]",
				      DATA_ELNAME(data), data->index);
				retVal = WS_ERR_INSUFFICIENT_RESOURCES;
				goto DONE;
			}
		}
		if (data->mode == XML_SMODE_DESERIALIZE) {
			if ((child = xml_serializer_get_child(data)) == NULL) {
				error ("not enough (%d < %d) instances of element %s",
				     data->index, DATA_COUNT(data),
				     DATA_ELNAME(data));
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			if ((str = ws_xml_get_node_text(child)) == NULL) {
				error("No text of node %s[%d]",
				      DATA_ELNAME(data), data->index);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			while (isspace(str[0]))
				str++;
			errno = 0;
			if (str[0] == '-' || str[0] == 0) {
				if (ws_xml_find_attr_bool(child,
						     XML_NS_SCHEMA_INSTANCE,
						     XML_SCHEMA_NIL)) {
					goto ATTR;
				}
				error("absent value = %s", str);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			tmp = strtoull(str, &end, 10);
			if (errno) {
				error("strtoul(%s) failed; errno = %d",
				      str, errno);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			while (isspace(end[0]))
				end++;
			if (*end != 0) {
				error("wrong token = %s.", str);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			if (valSize == 1) {
				if (tmp > 255) {
					error("not uint8 = %ld", tmp);
					retVal = WS_ERR_XML_PARSING;
					goto DONE;
				}
				*((XML_TYPE_UINT8 *) data->elementBuf) =
				    (XML_TYPE_UINT8) tmp;
			} else if (valSize == 2) {
				if (tmp > 65535) {
					error("not uint16 = %ld", tmp);
					retVal = WS_ERR_XML_PARSING;
					goto DONE;
				}
				*((XML_TYPE_UINT16 *) data->elementBuf) =
				    (XML_TYPE_UINT16) tmp;
			} else if (valSize == 4) {
				*((XML_TYPE_UINT32 *) data->elementBuf) =
				    (XML_TYPE_UINT32) tmp;
			} else if (valSize == 8) {
				*((XML_TYPE_UINT64 *) data->elementBuf) =
				    (XML_TYPE_UINT64) tmp;
			} else {
				error("unsupported uint size + %d",
				      8 * valSize);
				retVal = WS_ERR_INVALID_PARAMETER;
				goto DONE;
			}
		}
ATTR:
		handle_attrs(data, child, valSize);
		DATA_BUF(data) = DATA_BUF(data) + DATA_SIZE(data);
	}
	if ((data->mode == XML_SMODE_DESERIALIZE) &&
	    xml_serializer_get_child(data)) {
		error("too many (%d > %d) instances of element %s",
		      data->index, DATA_COUNT(data), DATA_ELNAME(data));
		retVal = WS_ERR_XML_PARSING;
		goto DONE;
	}
DONE:
	TRACE_EXIT;
	return retVal;
}



int do_serialize_uint8(XmlSerializationData * data)
{
	if (XML_IS_ATTRS(data->elementInfo)) {
		size_t al = get_struct_align();
		size_t pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
		if (pad) {
			pad = al - pad;
		}
		DATA_BUF(data) = DATA_BUF(data) + pad;
	}

	return do_serialize_uint(data, sizeof(XML_TYPE_UINT8));
}


int do_serialize_uint16(XmlSerializationData * data)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_UINT16 b;
	} dummy;
	size_t al;
	size_t pad;
	int retVal;
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
	pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);

	if (pad) {
		pad = al - pad;
	}

	DATA_BUF(data) = DATA_BUF(data) + pad;
	retVal = do_serialize_uint(data, sizeof(XML_TYPE_UINT16));
	if (retVal >= 0) {
		retVal += pad;
	}
	return retVal;
}

int do_serialize_uint32(XmlSerializationData * data)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_UINT32 b;
	} dummy;
	size_t al;
	size_t pad;
	int retVal;
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
	pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}

	DATA_BUF(data) = DATA_BUF(data) + pad;
	retVal = do_serialize_uint(data, sizeof(XML_TYPE_UINT32));
	if (retVal >= 0) {
		retVal += pad;
	}
	return retVal;
}

int do_serialize_uint64(XmlSerializationData * data)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_UINT64 b;
	} dummy;
	size_t al;
	size_t pad;
	int retVal;
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
        pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}

	DATA_BUF(data) = DATA_BUF(data) + pad;
	retVal = do_serialize_uint(data, sizeof(XML_TYPE_UINT64));
	if (retVal >= 0) {
		retVal += pad;
	}
	return retVal;
}

int do_serialize_int8(struct __XmlSerializationData* data)
{
	if (XML_IS_ATTRS(data->elementInfo)) {
		size_t al = get_struct_align();
		size_t pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
		if (pad) {
			pad = al - pad;
		}
		DATA_BUF(data) = DATA_BUF(data) + pad;
	}

	return do_serialize_int(data, sizeof(XML_TYPE_INT8));
}
int do_serialize_int16(struct __XmlSerializationData* data)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_UINT16 b;
	} dummy;
	size_t al;
	size_t pad;
	int retVal;
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
	pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);

	if (pad) {
		pad = al - pad;
	}

	DATA_BUF(data) = DATA_BUF(data) + pad;
	retVal = do_serialize_int(data, sizeof(XML_TYPE_INT16));
	if (retVal >= 0) {
		retVal += pad;
	}
	return retVal;
}
int do_serialize_int32(struct __XmlSerializationData* data)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_UINT32 b;
	} dummy;
	size_t al;
	size_t pad;
	int retVal;
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
	pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}

	DATA_BUF(data) = DATA_BUF(data) + pad;
	retVal = do_serialize_int(data, sizeof(XML_TYPE_INT32));
	if (retVal >= 0) {
		retVal += pad;
	}
	return retVal;
}
int do_serialize_int64(struct __XmlSerializationData* data)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_UINT64 b;
	} dummy;
	size_t al;
	size_t pad;
	int retVal;
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
        pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}

	DATA_BUF(data) = DATA_BUF(data) + pad;
	retVal = do_serialize_int(data, sizeof(XML_TYPE_INT64));
	if (retVal >= 0) {
		retVal += pad;
	}
	return retVal;
}

static int do_serialize_real(XmlSerializationData * data, int valSize)
{
	WsXmlNodeH child = NULL;
	XML_TYPE_REAL64 tmp;
	int retVal = DATA_ALL_SIZE(data);
	char *end;
	char *str;

	TRACE_ENTER;
	debug("handle %d REAL%d %s;", DATA_COUNT(data),
	      8 * valSize, data->elementInfo->name);
	if (DATA_BUF(data) + retVal > data->stopper) {
		error("size of %d structures %s exceeds stopper (%p > %p)",
		      DATA_COUNT(data), DATA_ELNAME(data),
		      DATA_BUF(data) + retVal, data->stopper);
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}
	if (DATA_MUST_BE_SKIPPED(data) || data->mode == XML_SMODE_FREE_MEM) {
		DATA_BUF(data) = DATA_BUF(data) + retVal;
		goto DONE;
	}
	if ((data->mode != XML_SMODE_DESERIALIZE &&
	     data->mode != XML_SMODE_SERIALIZE)) {
		error("invalid mode %d", data->mode);
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}

	for (data->index = 0; data->index < DATA_COUNT(data);
	     data->index++) {
		debug("%s[%d] = %p", data->elementInfo->name, data->index,
		      data->elementBuf);

		if (data->mode == XML_SMODE_SERIALIZE) {
			debug("value size: %d", valSize);
			if (valSize == 4)
				tmp = *((XML_TYPE_REAL32 *) data->
				      elementBuf);
			else if (valSize == 8)
				tmp = *((XML_TYPE_REAL64 *) data->
				      elementBuf);
			else {
				error("unsupported real size + %d",
						8 * valSize);
				retVal = WS_ERR_INVALID_PARAMETER;
				goto DONE;
			}

			if (((child = xml_serializer_add_child(data,
						       NULL)) == NULL)
			    || (ws_xml_set_node_real(child, tmp)) != 0) {
				debug("could not add child %s[%d]",
				      DATA_ELNAME(data), data->index);
				retVal = WS_ERR_INSUFFICIENT_RESOURCES;
				goto DONE;
			}
		}
		if (data->mode == XML_SMODE_DESERIALIZE) {
			if ((child = xml_serializer_get_child(data)) == NULL) {
				error ("not enough (%d < %d) instances of element %s",
				     data->index, DATA_COUNT(data),
				     DATA_ELNAME(data));
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			if ((str = ws_xml_get_node_text(child)) == NULL) {
				error("No text of node %s[%d]",
				      DATA_ELNAME(data), data->index);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			while (isspace(str[0]))
				str++;
			errno = 0;
			if (str[0] == 0) {
				if (ws_xml_find_attr_bool(child,
						     XML_NS_SCHEMA_INSTANCE,
						     XML_SCHEMA_NIL)) {
					goto ATTR;
				}
				error("absent value = %s", str);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			tmp = strtod(str, &end);
			if (errno) {
				error("strtod(%s) failed; errno = %d",
				      str, errno);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			while (isspace(end[0]))
				end++;
			if (*end != 0) {
				error("wrong token = %s.", str);
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			if (valSize == 4) {
				*((XML_TYPE_REAL32 *) data->elementBuf) =
				    (XML_TYPE_REAL32) tmp;
			} else if (valSize == 8) {
				*((XML_TYPE_REAL64 *) data->elementBuf) =
				    (XML_TYPE_REAL64) tmp;
			} else {
				error("unsupported REAL size + %d",
				      8 * valSize);
				retVal = WS_ERR_INVALID_PARAMETER;
				goto DONE;
			}
		}
ATTR:
		handle_attrs(data, child, valSize);
		DATA_BUF(data) = DATA_BUF(data) + DATA_SIZE(data);
	}
	if ((data->mode == XML_SMODE_DESERIALIZE) &&
	    xml_serializer_get_child(data)) {
		error("too many (%d > %d) instances of element %s",
		      data->index, DATA_COUNT(data), DATA_ELNAME(data));
		retVal = WS_ERR_XML_PARSING;
		goto DONE;
	}
DONE:
	TRACE_EXIT;
	return retVal;
}

int do_serialize_real32(struct __XmlSerializationData* data)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_REAL32 b;
	} dummy;
	size_t al;
	size_t pad;
	int retVal;
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
	pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}

	DATA_BUF(data) = DATA_BUF(data) + pad;
	retVal = do_serialize_real(data, sizeof(XML_TYPE_REAL32));
	if (retVal >= 0) {
		retVal += pad;
	}
	return retVal;
}
int do_serialize_real64(struct __XmlSerializationData* data)
{
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_REAL64 b;
	} dummy;
	size_t al;
	size_t pad;
	int retVal;
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
        pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}
	DATA_BUF(data) = DATA_BUF(data) + pad;
	retVal = do_serialize_real(data, sizeof(XML_TYPE_REAL64));
	if (retVal >= 0) {
		retVal += pad;
	}
	return retVal;
}

int do_serialize_string(XmlSerializationData * data)
{
	WsXmlNodeH child = NULL;
	int retVal = DATA_ALL_SIZE(data);
	size_t al;
	size_t pad;
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_STR b;
	} dummy;

	TRACE_ENTER;
	debug("handle %d strings %s = %p", DATA_COUNT(data),
	      data->elementInfo->name, data->elementBuf);
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
	pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}
	retVal += pad;
	if (DATA_BUF(data) + retVal > data->stopper) {
		error("stopper: %p > %p",
		      DATA_BUF(data) + retVal, data->stopper);
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}
	if (DATA_MUST_BE_SKIPPED(data)) {
		data->elementBuf = DATA_BUF(data) + retVal;
		goto DONE;
	}
	DATA_BUF(data) = DATA_BUF(data) + pad;
	debug("adjusted elementBuf = %p", data->elementBuf);

	for (data->index = 0; data->index < DATA_COUNT(data);
	     data->index++) {
		if (data->mode == XML_SMODE_FREE_MEM) {
			xml_serializer_free(data, *(XML_TYPE_STR *) DATA_BUF(data));
			*(XML_TYPE_STR *) DATA_BUF(data) = NULL;
		} else if (data->mode == XML_SMODE_SERIALIZE) {
			char *valPtr = *((char **) DATA_BUF(data));
			child = xml_serializer_add_child(data, valPtr);
			if (child == NULL) {
				error("xml_serializer_add_child failed.");
				retVal = WS_ERR_INSUFFICIENT_RESOURCES;
				goto DONE;
			}
			if (ws_xml_get_node_text(child) == NULL) {
				ws_xml_add_node_attr(child,
						     XML_NS_SCHEMA_INSTANCE,
						     XML_SCHEMA_NIL,
						     "true");
			}
		} else if (data->mode == XML_SMODE_DESERIALIZE) {
			char *src;
			if ((child =
			     xml_serializer_get_child(data)) == NULL) {
				error
				    ("not enough (%d < %d) instances of element %s",
				     data->index, DATA_COUNT(data),
				     DATA_ELNAME(data));
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}

			src = ws_xml_get_node_text(child);
			if (src != NULL && *src != 0) {
				char *dstPtr;
				int dstSize = 1 + strlen(src);
				dstPtr =
				    (char *) xml_serializer_alloc(data,
								  dstSize,
								  1);
				if (dstPtr == NULL) {
					error("no memory");
					retVal =
					    WS_ERR_INSUFFICIENT_RESOURCES;
					goto DONE;
				}
				strncpy(dstPtr, src, dstSize);
				*((XML_TYPE_PTR *) DATA_BUF(data)) =
				    dstPtr;
			}
		} else {
			error("invalid mode");
			retVal = WS_ERR_INVALID_PARAMETER;
			goto DONE;
		}
		handle_attrs(data, child, sizeof(XML_TYPE_STR));
		DATA_BUF(data) = DATA_BUF(data) + DATA_SIZE(data);
	}
	if ((data->mode == XML_SMODE_DESERIALIZE) &&
	    xml_serializer_get_child(data)) {
		error("too many (%d > %d) instances of element %s",
		      data->index, DATA_COUNT(data), DATA_ELNAME(data));
		retVal = WS_ERR_XML_PARSING;
		goto DONE;
	}
      DONE:
	TRACE_EXIT;
	return retVal;
}



int do_serialize_bool(XmlSerializationData * data)
{
	int retVal = DATA_ALL_SIZE(data);
	typedef struct {
		XML_TYPE_UINT8 a;
		XML_TYPE_BOOL b;
	} dummy;
	size_t al;
	size_t pad;
	WsXmlNodeH child = NULL;

	TRACE_ENTER;
	debug("handle %d booleans %s; ptr = %p", DATA_COUNT(data),
	      DATA_ELNAME(data), DATA_BUF(data));
	if (XML_IS_ATTRS(data->elementInfo)) {
		al = get_struct_align();
	} else {
		al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	}
	pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}
	retVal += pad;
	if (DATA_BUF(data) + retVal > data->stopper) {
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}
	if (DATA_MUST_BE_SKIPPED(data) || data->mode == XML_SMODE_FREE_MEM) {
		data->elementBuf = DATA_BUF(data) + retVal;
		goto DONE;
	}
	DATA_BUF(data) = DATA_BUF(data) + pad;
	debug("adjusted elementBuf = %p", data->elementBuf);

	for (data->index = 0; data->index < DATA_COUNT(data);
	     data->index++) {
		debug("%s[%d] = %p", DATA_ELNAME(data), data->index,
		      DATA_BUF(data));
		if (data->mode == XML_SMODE_SERIALIZE) {
			XML_TYPE_BOOL tmp;
			tmp = *((XML_TYPE_BOOL *) DATA_BUF(data));
			if ((child = xml_serializer_add_child(data,
			      (tmp == 0) ? "false" : "true")) == NULL) {
				retVal = WS_ERR_INSUFFICIENT_RESOURCES;
				goto DONE;
			}
		} else if (data->mode == XML_SMODE_DESERIALIZE) {
			XML_TYPE_PTR dataPtr =
			    (XML_TYPE_PTR) DATA_BUF(data);
			XML_TYPE_BOOL tmp = -1;
			char *src;
			if ((child =
			     xml_serializer_get_child(data)) == NULL) {
				error("not enough (%d < %d) instances of element %s",
				     data->index, DATA_COUNT(data), DATA_ELNAME(data));
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			src = ws_xml_get_node_text(child);
			if (src == NULL || *src == 0) {
				tmp = 1;
			} else {
				if (isdigit(*src)) {
					tmp = atoi(src);
				} else {
					if (strcmp(src, "yes") == 0 ||
						strcmp(src, "true") == 0) {
						tmp = 1;
					} else if (strcmp(src, "no") == 0 ||
							strcmp(src, "false") == 0) {
						tmp = 0;
					}
				}
			}

			if (tmp == 0 || tmp == 1) {
				*((XML_TYPE_BOOL *) dataPtr) = tmp;
			} else {
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
		} else {
			retVal = WS_ERR_INVALID_PARAMETER;
			goto DONE;
		}
		handle_attrs(data, child, sizeof(XML_TYPE_BOOL));
		DATA_BUF(data) = DATA_BUF(data) + DATA_SIZE(data);
	}
	if ((data->mode == XML_SMODE_DESERIALIZE) &&
	    xml_serializer_get_child(data)) {
		error("too many (%d > %d) instances of element %s",
		      data->index, DATA_COUNT(data), DATA_ELNAME(data));
		retVal = WS_ERR_XML_PARSING;
		goto DONE;
	}
      DONE:
	TRACE_EXIT;
	return retVal;
}



static XmlSerialiseDynamicSizeData *make_dyn_size_data(XmlSerializationData
						       * data,
						       int * retValp)
{
	XmlSerialiseDynamicSizeData *dyn =
	    (XmlSerialiseDynamicSizeData *) data->elementBuf;
	int savedIndex = data->index;
	int size;

	TRACE_ENTER;
	data->index = 0;
	while (xml_serializer_get_child(data) != NULL) {
		data->index++;
	}
	dyn->count = data->index;
	data->index = savedIndex;
	if (dyn->count < DATA_MIN_COUNT(data)) {
		error("not enough (%d < %d) elements %s", dyn->count,
		      DATA_MIN_COUNT(data), DATA_ELNAME(data));
		*retValp = WS_ERR_XML_PARSING;
		dyn = NULL;
		goto DONE;
	}
	if ((DATA_MAX_COUNT(data) > 0)
	    && dyn->count > DATA_MAX_COUNT(data)) {
		error("too many (%d > %d) elements %s", dyn->count,
		      DATA_MAX_COUNT(data), DATA_ELNAME(data));
		*retValp = WS_ERR_XML_PARSING;
		dyn = NULL;
		goto DONE;
	}
	debug("count = %d of %d sizes", dyn->count, DATA_SIZE(data));
	if (dyn->count == 0) {
		goto DONE;
	}

	size = DATA_SIZE(data) * dyn->count;
	dyn->data = xml_serializer_alloc(data, size, 1);
	if (dyn->data == NULL) {
		error("no memory");
		*retValp = WS_ERR_INSUFFICIENT_RESOURCES;
		dyn = NULL;
	}

      DONE:
	TRACE_EXIT;
	return dyn;
}


int do_serialize_dyn_size_array(XmlSerializationData * data)
{
	typedef struct {
		char a;
		XmlSerialiseDynamicSizeData b;
	} dummy;
	size_t al = (char *) &(((dummy *) NULL)->b) - (char *) NULL;
	size_t pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	int retVal;
	char *savedBufPtr;
	XmlSerializerInfo *savedElementInfo;
	XmlSerialiseDynamicSizeData *dyn = NULL;
	int tmp;
	XmlSerializerInfo myinfo;
	int savedIndex;
	char *savedStopper;
	TRACE_ENTER;
	debug("Dyn size array %s; ptr = %p", data->elementInfo->name,
	      data->elementBuf);

	if (pad)
		pad = al - pad;

	retVal = DATA_SIZE(data) + pad;
	if (DATA_BUF(data) + retVal > data->stopper) {
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}
	if (DATA_MUST_BE_SKIPPED(data)) {
		DATA_BUF(data) = DATA_BUF(data) + retVal;
		goto DONE;
	}
	DATA_BUF(data) = DATA_BUF(data) + pad;
	debug("adjusted elementBuf = %p", data->elementBuf);

	savedBufPtr = DATA_BUF(data);
	savedElementInfo = data->elementInfo;

	if (data->mode != XML_SMODE_SERIALIZE &&
	    data->mode != XML_SMODE_DESERIALIZE &&
	    data->mode != XML_SMODE_FREE_MEM) {
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}

	if (data->mode == XML_SMODE_DESERIALIZE) {
		if ((dyn = make_dyn_size_data(data, &retVal)) == NULL) {
			goto DONE;
		}
	} else {
		dyn = (XmlSerialiseDynamicSizeData *) data->elementBuf;
		if (data->mode == XML_SMODE_SERIALIZE) {
			if (dyn->count < DATA_MIN_COUNT(data)) {
				error("not enough (%d < %d) elements %s",
				      dyn->count, DATA_MIN_COUNT(data),
				      DATA_ELNAME(data));
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			if ((DATA_MAX_COUNT(data) > 0)
			    && dyn->count > DATA_MAX_COUNT(data)) {
				error("too many (%d > %d) elements %s",
				      dyn->count, DATA_MAX_COUNT(data),
				      DATA_ELNAME(data));
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
		}
	}

	if (dyn->count == 0) {
		// no dynamic data. nothing to do
		goto DONE;
	}

	savedIndex = data->index;
	savedStopper = data->stopper;
	memcpy(&myinfo, savedElementInfo->extData,
	       sizeof(XmlSerializerInfo));
	myinfo.count = dyn->count;
	myinfo.name = data->elementInfo->name;
	myinfo.ns = data->elementInfo->ns;

	data->stopper = (char *) dyn->data + DATA_SIZE(data) * dyn->count;
	data->elementInfo = &myinfo;
	DATA_BUF(data) = dyn->data;
	data->index = 0;

	debug("dyn = %p, dyn->data = %p + 0x%x",
	      dyn, dyn->data, DATA_SIZE(data) * dyn->count);
	tmp = data->elementInfo->proc(data);

	data->index = savedIndex;
	DATA_BUF(data) = savedBufPtr;
	data->elementInfo = savedElementInfo;
	data->stopper = savedStopper;
	if (tmp < 0 && data->mode != XML_SMODE_FREE_MEM) {
		retVal = tmp;
		goto DONE;
	}
	if ((data->mode == XML_SMODE_FREE_MEM) && dyn->data) {
		xml_serializer_free(data, dyn->data);
		goto DONE;
	}
      DONE:
	DATA_BUF(data) = DATA_BUF(data) + DATA_SIZE(data);
	TRACE_EXIT;
	return retVal;
}




int do_serialize_struct(XmlSerializationData * data)
{
	int retVal = 0;
	int i;
	int elementCount = 0;
	XmlSerializerInfo *elements =
	    (XmlSerializerInfo *) data->elementInfo->extData;
	WsXmlNodeH savedXmlNode = data->xmlNode;
	XmlSerializerInfo *savedElement = data->elementInfo;
	int savedMode = data->mode;
	int savedIndex = data->index;
	void *savedStopper = data->stopper;
	size_t al = get_struct_align();
	size_t pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	size_t count;
	size_t struct_size;
	int savedLocalIndex;
	char *savedLocalElementBuf;
	WsXmlNodeH child;

	TRACE_ENTER;

	debug("handle %d structure \"%s\" ptr = %p", DATA_COUNT(data),
	      data->elementInfo->name ? data->elementInfo->name : "NULL",
	      data->elementBuf);
	if (data->mode != XML_SMODE_SERIALIZE &&
	    data->mode != XML_SMODE_DESERIALIZE &&
	    data->mode != XML_SMODE_FREE_MEM) {
		retVal = WS_ERR_INVALID_PARAMETER;
		debug("Incorrect data->mode = %d", data->mode);
		goto DONE;
	}
	al = get_struct_align();
	pad = (size_t) ((PTRTOINT) DATA_BUF(data) % al);
	if (pad) {
		pad = al - pad;
	}
	retVal = pad + XML_IS_HEAD(savedElement) ?
	    DATA_SIZE(data) : DATA_ALL_SIZE(data);
	if ((char *) DATA_BUF(data) + retVal > data->stopper) {
		error("size of %d structures \"%s\" exceeds stopper (%p > %p)",
		      DATA_COUNT(data), DATA_ELNAME(data) ? DATA_ELNAME(data) : "NULL",
		      (char *) DATA_BUF(data) + retVal, data->stopper);
		retVal = WS_ERR_INVALID_PARAMETER;
		goto DONE;
	}
	if (DATA_MUST_BE_SKIPPED(data)) {
		debug(" %d elements %s skipped", DATA_COUNT(data),
		      DATA_ELNAME(data) ? DATA_ELNAME(data) : "NULL");
		DATA_BUF(data) = DATA_BUF(data) + retVal;
		goto DONE;
	}
	DATA_BUF(data) = DATA_BUF(data) + pad;
	debug("adjusted ptr= %p", data->elementBuf);

	while (elements[elementCount].proc != NULL) {
		elementCount++;
	}

	count = DATA_COUNT(data);
	struct_size = DATA_SIZE(data);
	if (XML_IS_HEAD(savedElement)) {
		count = data->index + 1;
	} else {
		data->index = 0;
	}

	for (; data->index < count; data->index++) {
		int tmp;
		child = NULL;
		savedLocalIndex = data->index;
		savedLocalElementBuf = DATA_BUF(data);
		data->stopper = savedLocalElementBuf + DATA_SIZE(data);
		debug("%s[%d] = %p", DATA_ELNAME(data) ? DATA_ELNAME(data) : "NULL",
		      data->index,
		      DATA_BUF(data));
		if (data->mode == XML_SMODE_SERIALIZE) {
			child = xml_serializer_add_child(data, NULL);
			data->xmlNode = child;
			if (data->xmlNode == NULL) {
				error("cant add child");
				retVal = WS_ERR_INSUFFICIENT_RESOURCES;
				goto DONE;
			}
		} else if (data->mode == XML_SMODE_DESERIALIZE) {
			child = xml_serializer_get_child(data);
			if (child == NULL) {
				error
				    ("not enough (%d < %d) instances of element %s",
				     data->index, DATA_COUNT(data),
				     DATA_ELNAME(data) ? DATA_ELNAME(data) : "NULL");
				retVal = WS_ERR_XML_PARSING;
				goto DONE;
			}
			data->xmlNode = child;
		}

		debug("before for loop. Struct %s = %p",
		      savedElement->name ? savedElement->name : "NULL", DATA_BUF(data));

		for (i = 0; retVal > 0 && i < elementCount; i++) {
			data->elementInfo = &elements[i];
			debug
			    ("handle %d elements %s of struct %s. dstPtr = %p",
			     DATA_COUNT(data), DATA_ELNAME(data) ? DATA_ELNAME(data) : "NULL",
			     savedElement->name ? savedElement->name : "NULL", DATA_BUF(data));
			if (XML_IS_SKIP(data->elementInfo)) {
				data->mode = XML_SMODE_SKIP;
			}

			tmp = data->elementInfo->proc(data);
			debug("retval: %d", tmp);

			if (tmp < 0) {
				error("handling of element \"%s\" failed = %d",
				      DATA_ELNAME(data) ? DATA_ELNAME(data) : "NULL", tmp);
				retVal = tmp;
				goto DONE;
			}
		}
		data->elementInfo = savedElement;
		data->index = savedLocalIndex;
		data->mode = savedMode;
		data->xmlNode = savedXmlNode;
		data->elementInfo = savedElement;
		handle_attrs(data, child, 0);
		data->elementBuf = savedLocalElementBuf + struct_size;
	}
      DONE:
	data->stopper = savedStopper;
	data->elementInfo = savedElement;
	data->index = savedIndex;
	data->mode = savedMode;
	data->xmlNode = savedXmlNode;
	TRACE_EXIT;
	return retVal;
}



static void
initialize_xml_serialization_data(XmlSerializationData * data,
				  WsSerializerContextH serctx,
				  XmlSerializerInfo * elementInfo,
				  XML_TYPE_PTR dataBuf,
				  int mode,
				  XML_NODE_ATTR * attrs,
				  WsXmlNodeH xmlNode)
{
	debug("Initialize XML Serialization...");
	TRACE_ENTER;
	memset(data, 0, sizeof(XmlSerializationData));
	data->serctx = serctx;
	data->elementInfo = elementInfo;
	data->elementBuf = dataBuf;
	data->mode = mode;
	data->attrs = attrs;
	data->xmlNode = xmlNode;

	debug("Finished initializing XML Serialization...");
	TRACE_EXIT;
	return;
}



int ws_serialize(WsSerializerContextH serctx,
		    WsXmlNodeH xmlNode,
		    XML_TYPE_PTR dataPtr,
		    XmlSerializerInfo * info,
		    const char *name,
		    const char *ns, XML_NODE_ATTR * attrs, int output)
{
	int retVal = WS_ERR_INSUFFICIENT_RESOURCES;
	XmlSerializerInfo myinfo;
	XmlSerializationData data;

	TRACE_ENTER;
	if (info->proc == NULL) {
		error("info->proc == NULL");
		goto DONE;
	}
	memcpy(&myinfo, info, sizeof(XmlSerializerInfo));
	if (name == NULL) {
		error("name == NULL");
		goto DONE;
	}
	myinfo.name = name;
	myinfo.ns = ns;
	myinfo.flags |= SER_HEAD;
	initialize_xml_serialization_data(&data,
					  serctx,
					  &myinfo,
					  dataPtr,
					  XML_SMODE_SERIALIZE,
					  attrs, xmlNode);

	data.stopper = (char *) dataPtr + myinfo.size;
	if (output) {
		data.skipFlag = SER_IN;
	} else {
		data.skipFlag = SER_OUT;
	}
	retVal = myinfo.proc(&data);

      DONE:
	TRACE_EXIT;
	return retVal;
}


int ws_serializer_free_mem(WsSerializerContextH serctx, XML_TYPE_PTR buf,
			      XmlSerializerInfo * info)
{
	int retVal;
	XmlSerializationData data;
	XmlSerializerInfo myinfo;

	TRACE_ENTER;
	memcpy(&myinfo, info, sizeof(XmlSerializerInfo));
	myinfo.flags |= SER_HEAD;
	initialize_xml_serialization_data(&data,
					  serctx,
					  &myinfo,
					  buf,
					  XML_SMODE_FREE_MEM, NULL, NULL);

	data.stopper = (char *) buf + myinfo.size;
	if ((retVal = info->proc(&data)) >= 0) {
		xml_serializer_free(&data, buf);
	}
	TRACE_EXIT;
	return retVal;
}


void *ws_deserialize(WsSerializerContextH serctx,
		     WsXmlNodeH xmlParent,
		     XmlSerializerInfo * info,
		     const char *name,
		     const char *ns,
		     XML_NODE_ATTR ** attrs, int index, int output)
{
	int size;
	void *retPtr = NULL;
	XmlSerializationData data;
	XmlSerializerInfo myinfo;

	TRACE_ENTER;
	memcpy(&myinfo, info, sizeof(XmlSerializerInfo));
	if (name == NULL) {
		error("name == NULL");
	}
	myinfo.name = name;
	myinfo.ns = ns;
	myinfo.flags |= SER_HEAD;
	initialize_xml_serialization_data(&data, serctx, &myinfo, NULL,
					  XML_SMODE_DESERIALIZE,
					  NULL, xmlParent);

	data.index = index;

	if (output) {
		data.skipFlag = SER_IN;
	} else {
		data.skipFlag = SER_OUT;
	}

	size = myinfo.size;
	if ((data.elementBuf = xml_serializer_alloc(&data, size, 1)) != NULL) {
		retPtr = data.elementBuf;
		data.stopper = (char *) retPtr + size;
		if (myinfo.proc && myinfo.proc(&data) <= 0) {
			data.elementBuf = retPtr;
			retPtr = NULL;
			ws_serializer_free_mem(serctx, data.elementBuf,
					       &myinfo);
			error("Error during serialization");
		}
	}
	TRACE_EXIT;
	return retPtr;
}

static void enforce_mustunderstand(WsXmlNodeH node)
{
	WsXmlDocH doc = ws_xml_get_node_doc(node);
	char *ns = ws_xml_get_node_name_ns(ws_xml_get_doc_root(doc));
	ws_xml_add_node_attr(node, ns, SOAP_MUST_UNDERSTAND, "true");
}

int
ws_serialize_str(WsSerializerContextH serctx, WsXmlNodeH parent, const char *str,
		 const char *nameNs, const char *name, int mustunderstand)
{
	WsXmlNodeH node;
	TRACE_ENTER;
	//printf("mustunderstand flag for %s: %d\n", name, mustunderstand );
	node = ws_xml_add_child(parent, nameNs, name, str);
	if (node && mustunderstand) {
		enforce_mustunderstand(node);
	}
	TRACE_EXIT;
	return (node == NULL);
}


int ws_serialize_uint32(WsSerializerContextH serctx, WsXmlNodeH parent,
			unsigned long val, const char *nameNs,
			const char *name, int mustunderstand)
{
	WsXmlNodeH node = ws_xml_add_child(parent, nameNs, name, NULL);
	TRACE_ENTER;
	if (node) {
		ws_xml_set_node_ulong(node, val);
		if (mustunderstand) {
			enforce_mustunderstand(node);
		}
	}
	TRACE_EXIT;
	return (node == NULL);
}


char *ws_deserialize_str(WsSerializerContextH serctx, WsXmlNodeH parent, int index,
			 const char *nameNs, const char *name)
{
	char *str = NULL;
	WsXmlNodeH node = ws_xml_get_child(parent, index, nameNs, name);
	TRACE_ENTER;
	if (node) {
		str = ws_xml_get_node_text(node);
		if (serctx && str) {
			int len = (int )strlen(str) + 1;
			char *tmp = str;
			if ((str = ws_serializer_alloc(serctx,
						 len * sizeof(char))))
				strcpy(str, tmp);
		}
	}
	TRACE_EXIT;
	return str;
}

unsigned long ws_deserialize_uint32(WsSerializerContextH serctx,
				    WsXmlNodeH parent, int index,
				    const char *nameNs, const char *name)
{
	unsigned long val = 0;
	WsXmlNodeH node = ws_xml_get_child(parent, index, nameNs, name);
	TRACE_ENTER;
	if (node) {
		val = ws_xml_get_node_ulong(node);
	}
	TRACE_EXIT;
	return val;
}

/*
 * Returns duration in seconds in <value> argument
 *
 *  the format of OperationTimeout is defined by the
 *  XML Schema Datatypes Section 3.2.6.1 http://www.w3.org/TR/xmlschema-2/
 * 
 * Sample: P0Y0M0DT0H0M60.00S
 * 
 * (must start with 'P', 'T' separated date from time, seconds may have fraction)
 * 
 * FIXME: handle fractions of seconds (don't return a time_t but a struct timeval)
 * 
 */
int ws_deserialize_duration(const char *t, time_t * value)
{
	long years = 0;
	long months = 0;
	long days = 0;
	long hours = 0;
	long mins = 0;
	long secs = 0;
	time_t vs;
	int v;
	double f;               /* float for fractional second */
	char *e;                /* end pointer for strtol */
        int got = 64;           /* bitmask of parsing position, 64==year */
	int res = 1;            /* final result, 1 == error */
	int time_handeled = 0;  /* seen 'T' */
	int negative = 0;

	TRACE_ENTER;
	if (t == NULL) {
		debug("node text == NULL");
		goto DONE;
	}

	if (*t == '-') {
		negative = 1;
		t++;
	}
	if (*t != 'P') {
		debug("Wrong begining of duration");
		goto DONE;
	}
	while (*++t) {
		if (*t == 'T') {
			time_handeled = 1;
			continue;
		}
		v = strtol(t, &e, 10);
		if (t == e) {
			debug("wrong format, missing numeric value");
			goto DONE;
		}
		if (time_handeled && (*e == '.')) {
			f = strtod(t, &e);
			if (*e != 'S') {
				debug("float but not secs");
				goto DONE;
			}
			if (((int)floor(f+0.5)) > v) {
				v++;  /* round value up */
			}
		}
		switch (*e) {
		case 'Y':
			if (got <= 32 || time_handeled) {
				debug("wrong order Y");
				goto DONE;
			}
			years = v;
			got = 32;
			break;
		case 'M':
			if (!time_handeled) {	// months
				if (got <= 16) {
					debug("wrong order M");
					goto DONE;
				}
				months = v;
				got = 16;
				break;
			}
			// minutes
			if (got <= 2 || !time_handeled) {
				debug("wrong order M");
				goto DONE;
			}
			mins = v;
			got = 2;
			break;
		case 'D':
			if (got <= 8 || time_handeled) {
				debug("wrong order D");
				goto DONE;
			}
			days = v;
			got = 8;
			break;
		case 'H':
			if (got <= 4 || !time_handeled) {
				debug("wrong order H");
				goto DONE;
			}
			hours = v;
			got = 4;
			break;
		case 'S':
			if (got <= 1 || !time_handeled) {
				debug("wrong order S");
				goto DONE;
			}
			secs = v;
			got = 1;
			break;
		default:
			debug("wrong format %c", *e);
			goto DONE;
		}
		t = e;
	}

	// invalid if T found and no HMS, or no time value detected
	if ((time_handeled && (got > 4)) || (64 == got)){
		debug("wrong format: floating T or no time value detected");
		goto DONE;
	}

	// We don't know exact date and time of the sender.
	// For simplicity comsider 1 month = 30days;

	vs = secs + 60 * mins + 60 * 60 * hours + 60 * 60 * 24 * days +
	    60 * 60 * 24 * 30 * months + 60 * 60 * 24 * 30 * 12 * years;
	if (negative) {
		vs = 0 - vs;
	}
	*value = vs;
	res = 0; // good at this point

      DONE:
	TRACE_EXIT;
	return res;
}


int ws_deserialize_datetime(const char *text, XML_DATETIME * tmx)
{
	int res = 0;
	int r;
	int hours;
	int mins;
	struct tm tm;
	time_t t;

	TRACE_ENTER;
	if (text == NULL) {
		debug("node text == NULL");
		res = 1;
		goto DONE;
	}
	bzero(tmx, sizeof(XML_DATETIME));

	r = sscanf(text, "%u-%u-%uT%u:%u:%u%d:%u", &tmx->tm.tm_year,
		   &tmx->tm.tm_mon, &tmx->tm.tm_mday,
		   &tmx->tm.tm_hour, &tmx->tm.tm_min, &tmx->tm.tm_sec,
		   &hours, &mins);
	if (r != 8) {
		debug("wrong body of datetime(%d): %s", r, text);
		res = 1;
		goto DONE;
	}
	tmx->tm.tm_year -= 1900;
	tmx->tm.tm_mon -= 1;

	t = time(NULL);
#ifdef _WIN32
	localtime_s(&tm, &t);
#else
	localtime_r(&t, &tm);
#endif
	tmx->tm.tm_isdst = tm.tm_isdst;

	if (hours < 0) {
		tmx->tz_min = 60 * hours - mins;
	} else {
		tmx->tz_min = 60 * hours + mins;
	}
      DONE:
	return res;
}



void *ws_serializer_alloc(WsSerializerContextH serctx, int size)
{
	WsSerializerMemEntry *ptr = NULL;
	TRACE_ENTER;
	if ((ptr = (WsSerializerMemEntry *) u_malloc(sizeof(WsSerializerMemEntry) + size)) != NULL) {
		lnode_t *node;
		u_lock(serctx);
		if ((node = lnode_create(ptr)) == NULL) {
			u_free(ptr);
			ptr = NULL;
		} else {
			list_append(serctx->WsSerializerAllocList, node);
		}
		u_unlock(serctx);
	}
	TRACE_EXIT;
	return ptr ? ptr->buf : NULL;
}


static int do_serializer_free(WsSerializerContextH serctx, void *ptr)
{
	lnode_t *node = NULL;
	lnode_t *node2 = NULL;
	TRACE_ENTER;
	if (serctx) {
		u_lock(serctx);
		node = list_first(serctx->WsSerializerAllocList);
		while (node != NULL) {
			WsSerializerMemEntry *entry =
			    (WsSerializerMemEntry *) node->list_data;

			if (entry && (!ptr || ptr == entry->buf)) {
				u_free(entry);
				node2 = node;
				node = list_delete2(serctx->WsSerializerAllocList, node);
				lnode_destroy (node2);
				if (ptr != NULL) {
					break;
				}
			}
			else
				node = list_next(serctx->WsSerializerAllocList, node);
		}
		u_unlock(serctx);
	}
	TRACE_EXIT;
	return (node != NULL);
}

int ws_serializer_free(WsSerializerContextH serctx, void *ptr)
{
	int retVal = 0;
	TRACE_ENTER;
	if (ptr != NULL)
		retVal = do_serializer_free(serctx, ptr);
	TRACE_EXIT;
	return retVal;
}

void ws_serializer_free_all(WsSerializerContextH serctx)
{
	TRACE_ENTER;
	do_serializer_free(serctx, NULL);
	TRACE_EXIT;
}

int ws_havenilvalue(XML_NODE_ATTR *attrs) 
{
	while(attrs) { 
		if(attrs->ns && attrs->name && attrs->value && 
			strcmp(attrs->ns, XML_NS_SCHEMA_INSTANCE) == 0 && 
			strcmp(attrs->name, XML_SCHEMA_NIL) == 0 && 
			strcasecmp(attrs->value, "true") == 0) 
			return 1; 
		attrs = attrs->next; 
	} 
	return 0; 
} 

