/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmXMLParser.h"

#include <cmsys/FStream.hxx>

#include <cm_expat.h>
#include <ctype.h>

cmXMLParser::cmXMLParser()
{
  this->Parser = 0;
  this->ParseError = 0;
  this->ReportCallback = 0;
  this->ReportCallbackData = 0;
}

cmXMLParser::~cmXMLParser()
{
  if (this->Parser) {
    this->CleanupParser();
  }
}

int cmXMLParser::Parse(const char* string)
{
  return (int)this->InitializeParser() &&
    this->ParseChunk(string, strlen(string)) && this->CleanupParser();
}

int cmXMLParser::ParseFile(const char* file)
{
  if (!file) {
    return 0;
  }

  cmsys::ifstream ifs(file);
  if (!ifs) {
    return 0;
  }

  std::ostringstream str;
  str << ifs.rdbuf();
  return this->Parse(str.str().c_str());
}

int cmXMLParser::InitializeParser()
{
  if (this->Parser) {
    std::cerr << "Parser already initialized" << std::endl;
    this->ParseError = 1;
    return 0;
  }

  // Create the expat XML parser.
  this->Parser = XML_ParserCreate(0);
  XML_SetElementHandler(static_cast<XML_Parser>(this->Parser),
                        &cmXMLParserStartElement, &cmXMLParserEndElement);
  XML_SetCharacterDataHandler(static_cast<XML_Parser>(this->Parser),
                              &cmXMLParserCharacterDataHandler);
  XML_SetUserData(static_cast<XML_Parser>(this->Parser), this);
  this->ParseError = 0;
  return 1;
}

int cmXMLParser::ParseChunk(const char* inputString,
                            std::string::size_type length)
{
  if (!this->Parser) {
    std::cerr << "Parser not initialized" << std::endl;
    this->ParseError = 1;
    return 0;
  }
  int res;
  res = this->ParseBuffer(inputString, length);
  if (res == 0) {
    this->ParseError = 1;
  }
  return res;
}

int cmXMLParser::CleanupParser()
{
  if (!this->Parser) {
    std::cerr << "Parser not initialized" << std::endl;
    this->ParseError = 1;
    return 0;
  }
  int result = !this->ParseError;
  if (result) {
    // Tell the expat XML parser about the end-of-input.
    if (!XML_Parse(static_cast<XML_Parser>(this->Parser), "", 0, 1)) {
      this->ReportXmlParseError();
      result = 0;
    }
  }

  // Clean up the parser.
  XML_ParserFree(static_cast<XML_Parser>(this->Parser));
  this->Parser = 0;

  return result;
}

int cmXMLParser::ParseBuffer(const char* buffer, std::string::size_type count)
{
  // Pass the buffer to the expat XML parser.
  if (!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer,
                 static_cast<int>(count), 0)) {
    this->ReportXmlParseError();
    return 0;
  }
  return 1;
}

int cmXMLParser::ParseBuffer(const char* buffer)
{
  return this->ParseBuffer(buffer, static_cast<int>(strlen(buffer)));
}

int cmXMLParser::ParsingComplete()
{
  // Default behavior is to parse to end of stream.
  return 0;
}

void cmXMLParser::StartElement(const std::string& name, const char** /*atts*/)
{
  std::cout << "Start element: " << name << std::endl;
}

void cmXMLParser::EndElement(const std::string& name)
{
  std::cout << "End element: " << name << std::endl;
}

void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
                                       int /*inLength*/)
{
}

int cmXMLParser::IsSpace(char c)
{
  return isspace(c);
}

const char* cmXMLParser::FindAttribute(const char** atts,
                                       const char* attribute)
{
  if (atts && attribute) {
    for (const char** a = atts; *a && *(a + 1); a += 2) {
      if (strcmp(*a, attribute) == 0) {
        return *(a + 1);
      }
    }
  }
  return 0;
}

void cmXMLParserStartElement(void* parser, const char* name, const char** atts)
{
  // Begin element handler that is registered with the XML_Parser.
  // This just casts the user data to a cmXMLParser and calls
  // StartElement.
  static_cast<cmXMLParser*>(parser)->StartElement(name, atts);
}

void cmXMLParserEndElement(void* parser, const char* name)
{
  // End element handler that is registered with the XML_Parser.  This
  // just casts the user data to a cmXMLParser and calls EndElement.
  static_cast<cmXMLParser*>(parser)->EndElement(name);
}

void cmXMLParserCharacterDataHandler(void* parser, const char* data,
                                     int length)
{
  // Character data handler that is registered with the XML_Parser.
  // This just casts the user data to a cmXMLParser and calls
  // CharacterDataHandler.
  static_cast<cmXMLParser*>(parser)->CharacterDataHandler(data, length);
}

void cmXMLParser::ReportXmlParseError()
{
  XML_Parser parser = static_cast<XML_Parser>(this->Parser);
  this->ReportError(XML_GetCurrentLineNumber(parser),
                    XML_GetCurrentColumnNumber(parser),
                    XML_ErrorString(XML_GetErrorCode(parser)));
}

void cmXMLParser::ReportError(int line, int, const char* msg)
{
  if (this->ReportCallback) {
    this->ReportCallback(line, msg, this->ReportCallbackData);
  } else {
    std::cerr << "Error parsing XML in stream at line " << line << ": " << msg
              << std::endl;
  }
}
