// $Id: CXmlLibs.cc,v 1.15 2003/05/30 05:27:12 ta_muto Exp $

#include <CXmlLibs.h>
#include <CConfig.h>

#include <time.h>

xmlDocPtr wax::CXmlLibs::read(IReader* reader, bool recordError)
{
	if(reader == NULL)	return NULL;
#if LE==1
	return xmlParseFile((const char*)reader->getPath());
#else
	if(reader->open() == true) {
		int size;
		char buffer[1024];
		xmlDocPtr doc = NULL;

		size = reader->read(buffer, 4);
		if(size > 0) {
			xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt(NULL, NULL, buffer, size, (const char*)reader->getPath());
			if(ctxt == NULL) {
				IError::message(ERR_OUTOFMEMORY, LOCATION);
			} else {
				while((size = reader->read(buffer, 1024)) > 0) {
					if(xmlParseChunk(ctxt, buffer, size, 0) != 0) {
						return NULL;
					}
				}
				if(xmlParseChunk(ctxt, buffer, 0, 1) != 0) {
					return NULL;
				}
				doc = ctxt->myDoc;
				xmlFreeParserCtxt(ctxt);
			}
		}
		reader->close();
		return doc;
	} else {
		if(recordError == true) {
			IError::message(ERR_EXISTFILE, reader->getPath());
		}
	}
	return NULL;
#endif
}

xmlChar* wax::CXmlLibs::getDateTime(const xmlChar* dateFormat)
{
	time_t t;
	tm *now;
	
	t = time(NULL);
	now = localtime(&t);
	
	char buffer[256];
	strftime(buffer, 256, (const char*)dateFormat, now);
	return xmlStrdup((const xmlChar*)buffer);
}

wax::CXPathMacro::CXPathMacro(xmlDocPtr doc)
{
	eval = NULL;
	xpctx = NULL;
	if(doc != NULL) {
		xpctx = xmlXPathNewContext(doc);
	}
}

wax::CXPathMacro::~CXPathMacro()
{
	if(xpctx != NULL)	xmlXPathFreeContext(xpctx);
	if(eval != NULL)	xmlXPathFreeObject(eval);
}

void wax::CXPathMacro::registerVariable(const xmlChar* name, const xmlChar* value)
{
	if(xpctx != NULL) {
		xmlXPathRegisterVariable(xpctx, name, xmlXPathNewString(value));
	}
}

void wax::CXPathMacro::registerNs(const xmlChar* prefix, const xmlChar* uri)
{
	if(xpctx != NULL) {
		xmlXPathRegisterNs(xpctx, prefix, uri);
	}
}

bool wax::CXPathMacro::evaluate(const xmlChar* xpath)
{
	if(xpctx == NULL)	return false;
	if(eval != NULL)	xmlXPathFreeObject(eval);

	eval = xmlXPathEval(xpath, xpctx);
	if(eval == NULL)	return false;
	return true;
}

xmlChar* wax::CXPathMacro::getString()
{
	if(eval != NULL) {
		return xmlXPathCastToString(eval);
	}
	return NULL;
}

int wax::CXPathMacro::getNodeCount()
{
	if(eval == NULL)	return 0;
	if(eval->type != XPATH_NODESET)	return 0;
	if(eval->nodesetval == NULL)	return 0;
	return eval->nodesetval->nodeNr;
}

xmlNodePtr wax::CXPathMacro::getNode(int index)
{
	if(eval == NULL)	return NULL;
	if(eval->type != XPATH_NODESET)	return NULL;
	if(eval->nodesetval == NULL)	return NULL;
	if(index < 0 || index >= eval->nodesetval->nodeNr) {
		return NULL;
	}
	return eval->nodesetval->nodeTab[index];
}
