// file: $isip/class/mmedia/XMLParser/xp_07.cc
// version: $Id: xp_07.cc 10284 2005-10-27 20:52:14Z wholland $

#if defined(HAVE_EXPAT)

// ISIP include files
//
#include "XMLParser.h"
#include "Error.h"

// method: Create
//
// arguments:
//   const XML_Char* encoding_a,
//   const XML_Char* separator_a
//
// return: a boolean indicating status
//
// Creates the expat XML parser
// 
bool XMLParser::Create(const XML_Char* encoding_a,
		       const XML_Char* separator_a) {
  Destroy();

  if (encoding_a!=NULL && encoding_a[0]==0) {
      encoding_a=NULL;
  }
  if (separator_a!=NULL && separator_a[0]==0) {
      separator_a=NULL;
  }

  parser_d= XML_ParserCreate_MM(encoding_a, NULL, separator_a);
  if (parser_d==NULL) {
    return false;
  }

  OnPostCreate();

  XML_SetUserData(parser_d, (void*) this);
  return true;
}

// method: Destroy
//
// arguments:
//   
//
// return: void
//
// Clears the expat xml parser
// 
void XMLParser::Destroy() {
  if (parser_d != NULL) {
      XML_ParserFree (parser_d);
  }
}

// method: Parse
//
// arguments:
//   const char* buffer_a
//   int length_a
//   bool is_final_a
//
// return: a boolean indicating status
//
// Parses the string in buffer_a.
// 
bool XMLParser::Parse (const char* buffer_a, int length_a, bool is_final_a) {
  if (parser_d==NULL) {
      Error::handle(name(),L"general error",
		    Error::NOT_IMPLEM, __FILE__, __LINE__);
  }

  SysString temp_string((byte *)buffer_a);
  
  if (length_a<0) {
      length_a=temp_string.length();
  }

  return (XML_Parse(parser_d, buffer_a, length_a, is_final_a) != 0);
}

// method: ParseBuffer
//
// arguments:
//   int length_a
//   bool is_final_a
//
// return: a boolean indicating status
//
// sets expat's parse buffer
// 
bool XMLParser::ParseBuffer (int length_a, bool is_final_a) {
  if (parser_d==NULL) {
      Error::handle(name(),L"general error",
		    Error::NOT_IMPLEM, __FILE__, __LINE__);
  }

  return (XML_ParseBuffer(parser_d, length_a, is_final_a) != 0);
}

// method: GetBuffer
//
// arguments:
//   int length_a
//
// return: void*
//
// retrieve's expat's parse buffer
// 
void* XMLParser::GetBuffer (int length_a) {
  if (parser_d==NULL) {
      Error::handle(name(),L"general error",
		    Error::NOT_IMPLEM, __FILE__, __LINE__);
  }

  return XML_GetBuffer (parser_d, length_a);
}

// method: EnableStartElementHandler
//
// arguments:
//   bool enable_a
//
// return: void
//
// Enables/disables the start element handler.
// 
void XMLParser::EnableStartElementHandler (bool enable_a) {
  if (parser_d==NULL) {
    Error::handle(name(), L"general error",
		  Error::NOT_IMPLEM, __FILE__, __LINE__);
  }
  if (enable_a) {
    XML_SetStartElementHandler (parser_d, StartElementHandler);
  }
  else {
    XML_SetStartElementHandler (parser_d, NULL);
  }
}

// method: EnableEndElementHandler
//
// arguments:
//   bool enable_a
//
// return: void
//
// enables/disables the end element handler
// 
void XMLParser::EnableEndElementHandler (bool enable_a) {
  if (parser_d==NULL) {
      Error::handle(name(),L"general error",
		    Error::NOT_IMPLEM, __FILE__, __LINE__);
  }

  if (enable_a) {
    XML_SetEndElementHandler (parser_d, EndElementHandler);
  }
  else {
    XML_SetEndElementHandler (parser_d, NULL);
  }
}

// method: EnableElementHandler
//
// arguments:
//   bool enable_a
//
// return: void
//
// Enables/Disables both start and end element handlers
// 
void XMLParser::EnableElementHandler (bool enable_a) {
  if (parser_d==NULL) {
      Error::handle(name(),L"general error",
		    Error::NOT_IMPLEM, __FILE__, __LINE__);
  }

  EnableStartElementHandler (enable_a);
  EnableEndElementHandler (enable_a);
}

// method: EnableCharacterDataHandler
//
// arguments:
//   bool enable_a
//
// return: void
//
// enables/disables character data handler
// 
void XMLParser::EnableCharacterDataHandler (bool enable_a) {
  if (parser_d==NULL) {
      Error::handle(name(),L"general error",
		    Error::NOT_IMPLEM, __FILE__, __LINE__);
  }

  if (enable_a) {
    XML_SetCharacterDataHandler (parser_d, CharacterDataHandler);
  }
  else {
    XML_SetCharacterDataHandler (parser_d, NULL);
  }
    
}

// method: StartElementHandler
//
// arguments:
//   void* user_data_a
//   const XML_Char* name_a
//   const XML_Char** attributes_a
//
// return: a boolean indicating status
//
// Handles start elements
// 
void XMLParser::StartElementHandler (void *user_data_a,
					    const XML_Char* name_a,
					    const XML_Char** attributes_a) {
  ((XMLParser *)user_data_a)->OnStartElement(name_a, attributes_a);
}

// method: EndElementHandler
//
// arguments:
//   void* user_data_a
//   const XML_Char* name_a
//
// return: a boolean indicating status
//
// Handles end elements
// 
void XMLParser::EndElementHandler (void *user_data_a,
					    const XML_Char* name_a) {
  ((XMLParser *)user_data_a)->OnEndElement(name_a);
}

// method: CharacterDataHandler
//
// arguments:
//   void* user_data_a
//   const XML_Char* data_a
//   int length_a
//
// return: a boolean indicating status
//
// Handles cdata
// 
void XMLParser::CharacterDataHandler (void *user_data_a,
					    const XML_Char* data_a,
					     int length_a) {
  ((XMLParser *)user_data_a)->OnCharacterData(data_a, length_a);
}

#endif
