⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gameswf_xml.cpp

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// gameswf_xml.h      -- Rob Savoye <rob@welcomehome.org> 2005// This source code has been donated to the Public Domain.  Do// whatever you want with it.#include <sys/types.h>#include <sys/stat.h>#include "gameswf_log.h"#include "gameswf_action.h"#include "gameswf_impl.h"#include "gameswf_log.h"#include "base/smart_ptr.h"#include "gameswf_string.h"#include "base/tu_config.h"#ifdef HAVE_LIBXML#include <unistd.h>#include "gameswf_xml.h"#include <libxml/xmlmemory.h>#include <libxml/parser.h>#include <libxml/xmlreader.h>namespace gameswf{    //#define DEBUG_MEMORY_ALLOCATION 1  array<as_object *> _xmlobjs;    // FIXME: hack alertXMLAttr::XMLAttr(){#ifdef DEBUG_MEMORY_ALLOCATION  log_msg("\t\tCreating XMLAttr data at %p \n", this);#endif  _name = 0;  _value = 0;}XMLAttr::~XMLAttr(){#ifdef DEBUG_MEMORY_ALLOCATION  log_msg("\t\tDeleting XMLAttr data %s at %p \n", this->_name, this);#endif  //log_msg("%s: %p \n", __FUNCTION__, this);  if (_name) {    delete _name;  }  if (_value) {    delete _value;  }  }  XMLNode::XMLNode(){  //log_msg("%s: %p \n", __FUNCTION__, this);#ifdef DEBUG_MEMORY_ALLOCATION  log_msg("\tCreating XMLNode data at %p \n", this);#endif  _name = 0;  _value = 0;}XMLNode::~XMLNode(){  int i;  //log_msg("%s: %p \n", __FUNCTION__, this);#ifdef DEBUG_MEMORY_ALLOCATION  log_msg("\tDeleting XMLNode data %s at %p\n", this->_name, this);#endif    for (i=0; i<_children.size(); i++) {//     if (_children[i]->_name) {//       delete _children[i]->_name;//     }//     if (_children[i]->_value) {//       delete _children[i]->_value;//     }    delete _children[i];  }  for (i=0; i<_attributes.size(); i++) {    //     if (_attributes[i]->_name) {//       delete _attributes[i]->_name;//     }//     if (_attributes[i]->_value) {//       delete _attributes[i]->_value;//     }    delete _attributes[i];  }  _children.clear();  _attributes.clear();  if (_name) {    delete _name;  }  if (_value) {    delete _value;  }  //  _value.set_undefined();}XML::XML(){#ifdef DEBUG_MEMORY_ALLOCATION  log_msg("Creating XML data at %p \n", this);#endif  //log_msg("%s: %p \n", __FUNCTION__, this);  _loaded = false;  _nodename = 0;}// Parse the ASCII XML string into memoryXML::XML(tu_string xml_in){#ifdef DEBUG_MEMORY_ALLOCATION  log_msg("Creating XML data at %p \n", this);#endif  //log_msg("%s: %p \n", __FUNCTION__, this);  //memset(&_nodes, 0, sizeof(XMLNode));  parseXML(xml_in);}XML::XML(struct node *childNode){#ifdef DEBUG_MEMORY_ALLOCATION  log_msg("\tCreating XML data at %p \n", this);#endif  //log_msg("%s: %p \n", __FUNCTION__, this);}XML::~XML(){#ifdef DEBUG_MEMORY_ALLOCATION  if (this->_nodes) {    log_msg("\tDeleting XML top level node %s at %p \n", this->_nodes->_name, this);  } else {    log_msg("\tDeleting XML top level node at %p \n", this);  }#endif    //log_msg("%s: %p \n", __FUNCTION__, this);  delete _nodes;}// Dispatch event handler(s), if any.boolXML::on_event(event_id id){  // Keep m_as_environment alive during any method calls!  //  smart_ptr<as_object_interface>	this_ptr(this);  #if 0  // First, check for built-in event handler.  as_value	method;  if (get_event_handler(event_id(id), &method))    {/      // Dispatch.      call_method0(method, &m_as_environment, this);          return true;    }    // Check for member function.  // In ActionScript 2.0, event method names are CASE SENSITIVE.  // In ActionScript 1.0, event method names are CASE INSENSITIVE.  const tu_string&	method_name = id.get_function_name();  if (method_name.length() > 0)hostByNameGet    {      as_value	method;      if (get_member(method_name, &method))        {          call_method0(method, &m_as_environment, this);          return true;        }    }#endif  return false;}voidXML::on_event_load(){  // Do the events that (appear to) happen as the movie  // loads.  frame1 tags and actions are executed (even  // before advance() is called).  Then the onLoad event  // is triggered.  {    on_event(event_id::LOAD);  }}XMLNode*XML::extractNode(xmlNodePtr node, bool mem){  xmlAttrPtr attr;  xmlNodePtr childnode;  xmlChar *ptr = NULL;  XMLNode *element, *child;  int len;  element = new XMLNode;              //log_msg("Created new element for %s at %p\n", node->name, element);  memset(element, 0, sizeof (XMLNode));  //log_msg("%s: extracting node %s\n", __FUNCTION__, node->name);  // See if we have any Attributes (properties)  attr = node->properties;  while (attr != NULL) {    //log_msg("extractNode %s has property %s, value is %s\n",    //          node->name, attr->name, attr->children->content);    XMLAttr *attrib = new XMLAttr;    len = memadjust(strlen(reinterpret_cast<const char *>(attr->name))+1);    attrib->_name = (char *)new char[len];    memset(attrib->_name, 0, len);    strcpy(attrib->_name, reinterpret_cast<const char *>(attr->name));    len = memadjust(strlen(reinterpret_cast<const char *>(attr->children->content))+1);    attrib->_value = (char *)new char[len];    memset(attrib->_value, 0, len);    strcpy(attrib->_value, reinterpret_cast<const char *>(attr->children->content));    //log_msg("\tPushing attribute %s for element %s has value %s\n",    //        attr->name, node->name, attr->children->content);    element->_attributes.push_back(attrib);    attr = attr->next;  }  len = memadjust(strlen(reinterpret_cast<const char *>(node->name))+1);  element->_name = (char *)new char[len];  memset(element->_name, 0, len);  strcpy(element->_name, reinterpret_cast<const char *>(node->name));  //element->_name = reinterpret_cast<const char *>(node->name);  if (node->children) {    //ptr = node->children->content;    ptr = xmlNodeGetContent(node->children);    if (ptr != NULL) {      if ((strchr((const char *)ptr, '\n') == 0) && (ptr[0] != 0))      {        if (node->children->content == NULL) {          //log_msg("Node %s has no contents\n", node->name);        } else {          //log_msg("extractChildNode from text for %s has contents %s\n", node->name, ptr);          len = memadjust(strlen(reinterpret_cast<const char *>(ptr))+1);          element->_value = (char *)new char[len];          memset(element->_value, 0, len);          strcpy(element->_value, reinterpret_cast<const char *>(ptr));          //element->_value = reinterpret_cast<const char *>(ptr);        }      }      xmlFree(ptr);    }  }  // See if we have any data (content)  childnode = node->children;  while (childnode != NULL) {    if (childnode->type == XML_ELEMENT_NODE) {      //log_msg("\t\t extracting node %s\n", childnode->name);      child = extractNode(childnode, mem);      //if (child->_value.get_type() != as_value::UNDEFINED) {      if (child->_value != 0) {        //log_msg("\tPushing childNode %s, value %s on element %p\n", child->_name.c_str(), child->_value.to_string(), element);      } else {        //log_msg("\tPushing childNode %s on element %p\n", child->_name.c_str(), element);      }      element->_children.push_back(child);    }    childnode = childnode->next;  }  return element;}// Read in an XML document from the specified sourceboolXML::parseDoc(xmlDocPtr document, bool mem){  XMLNode *top;  xmlNodePtr cur;  if (document == 0) {    log_error("Can't load XML file!\n");    return false;  }  cur = xmlDocGetRootElement(document);    if (cur != NULL) {    top = extractNode(cur, mem);    //_nodes->_name = reinterpret_cast<const char *>(cur->name);    _nodes = top;    //_node_data.push_back(top);    //cur = cur->next;  }    _loaded = true;  return true;}// This reads in an XML file from disk and parses into into a memory resident// tree which can be walked through later.boolXML::parseXML(tu_string xml_in){  bool ret = true;  //log_msg("Parse XML from memory: %s\n", xml_in.c_str());  if (xml_in.size() == 0) {    log_error("XML data is empty!\n");    return false;  }#ifndef USE_DMALLOC  //dump_memory_stats(__FUNCTION__, __LINE__, "before xmlParseMemory");#endif#ifdef USE_XMLREADER  XMLNode *node = 0;  xmlTextReaderPtr reader;  reader = xmlReaderForMemory(xml_in.c_str(), xml_in.size(), NULL, NULL, 0);  if (reader != NULL) {    ret = true;    while (ret) {      ret = xmlTextReaderRead(reader);      node = processNode(reader, node);    }    xmlFreeTextReader(reader);    if (ret != false) {      log_error("%s : couldn't parse\n", xml_in.c_str());      return false;    }  } else {    log_error("Unable to open %s\n", xml_in.c_str());      return false;  }  xmlCleanupParser();  return true;#else#ifdef USE_DOM  xmlInitParser();    _doc = xmlParseMemory(xml_in.c_str(), xml_in.size());  if (_doc == 0) {    log_error("Can't parse XML data!\n");    return false;  }  ret = parseDoc(_doc, true);  xmlCleanupParser();  xmlFreeDoc(_doc);  xmlMemoryDump();#endif#ifndef USE_DMALLOC  //dump_memory_stats(__FUNCTION__, __LINE__, "after xmlParseMemory");#endif  return ret;#endif  }//     XML_READER_TYPE_NONE = 0//     XML_READER_TYPE_ELEMENT = 1,//     XML_READER_TYPE_ATTRIBUTE = 2,//     XML_READER_TYPE_TEXT = 3,//     XML_READER_TYPE_COMMENT = 8,//     XML_READER_TYPE_SIGNIFICANT_WHITESPACE = 14,//     XML_READER_TYPE_END_ELEMENT = 15,//// processNode:// 2 1 IP 0// processNode:// 3 3 #text 0 192.168.2.50// processNode:// 2 15 IP 0// processNode:// 2 14 #text 0const char *tabs[] = {  "",  "\t",  "\t\t",  "\t\t\t",  "\t\t\t",  "\t\t\t\t",};#ifdef USE_XMLREADER// This is an xmlReader (SAX) based parser. For some reason it core dumps// when compiled with GCC 3.x, but works just fine with GCC 4.x.XMLNode*XML::processNode(xmlTextReaderPtr reader, XMLNode *node){  //log_msg("%s: node is %p\n", __FUNCTION__, node);  static XMLNode *parent[10];  xmlChar *name, *value;  int   depth;  XMLNode *element;  //static int previous_depth = 0;  xmlReaderTypes type;  if (node == 0) {    memset(parent, 0, sizeof(XMLNode *));  }  type = (xmlReaderTypes)xmlTextReaderNodeType(reader);  depth = xmlTextReaderDepth(reader);  value = xmlTextReaderValue(reader);  name = xmlTextReaderName(reader);    if (name == NULL)    name = xmlStrdup(BAD_CAST "--");#if 0  printf("%d %d %s %d\n",         depth,         (int)type,         name,         xmlTextReaderIsEmptyElement(reader));  #endif    //child = node->_children[0];  switch(xmlTextReaderNodeType(reader)) {  case XML_READER_TYPE_NONE:    break;  case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: // This is an empty text node    //log_msg("\tWhitespace at depth %d\n", depth);    break;  case XML_READER_TYPE_END_ELEMENT:     if (depth == 0) {          // This is the last node in the file       element = node;       break;     }     parent[depth]->_children.push_back(element);//       log_msg("Pushing element %s on node %s\n", node->_name, parent[depth]->_name);//       log_msg("End element at depth %d is %s for parent %s %p\n", depth, name,//               parent[depth]->_name, parent[depth]);     element = parent[depth];    break;  case XML_READER_TYPE_ELEMENT:    element = new XMLNode;//      log_msg("%sElement at depth %d is %s for node at %p\n", tabs[depth], depth, name, element);    element->_name = (char *)new char[strlen(reinterpret_cast<const char *>(name))+1];    memset(element->_name, 0, strlen(reinterpret_cast<const char *>(name))+1);    strcpy(element->_name, reinterpret_cast<const char *>(name));    if (node == 0) {      _nodes = element;      parent[0] = element;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -