📄 gameswf_xml.cpp
字号:
} else { parent[depth] = node; parent[depth+1] = node; } // xmlTextReaderAttributeCount(reader); if (xmlTextReaderHasAttributes(reader)) { // log_msg("Has Attributes!\n"); xmlTextReaderMoveToFirstAttribute(reader); processNode(reader, element); while(xmlTextReaderMoveToNextAttribute(reader)) { processNode(reader, element); } } break; case XML_READER_TYPE_TEXT: element = node;// log_msg("%sValue at depth %d is \"%s\" for node at %p\n", tabs[depth], depth, value, element); element->_value = (char *)new char[strlen(reinterpret_cast<const char *>(value))+1]; memset(element->_value, 0, strlen(reinterpret_cast<const char *>(value))+1); strcpy(element->_value, reinterpret_cast<const char *>(value)); break; case XML_READER_TYPE_ATTRIBUTE: element = node; XMLAttr *attrib = new XMLAttr; attrib->_name = (char *)new char[strlen(reinterpret_cast<const char *>(name))+1]; memset(attrib->_name, 0, strlen(reinterpret_cast<const char *>(name))+1); strcpy(attrib->_name, reinterpret_cast<const char *>(name)); attrib->_value = (char *)new char[strlen(reinterpret_cast<const char *>(value))+1]; memset(attrib->_value, 0, strlen(reinterpret_cast<const char *>(value))+1); strcpy(attrib->_value, reinterpret_cast<const char *>(value));// log_msg("%sPushing attribute %s, value \"%s\" for node %s\n", tabs[depth], name, value, element->_name); element->_attributes.push_back(attrib); break; default: // FIXME: why does this break GCC 3.3.3 but not 3.4.3 ? log_error("Unsupported XML type %d\n!", type); break; }; xmlFree(name); if (value != NULL) { xmlFree(value); } //previous_depth = depth; return element;}#endif// This reads in an XML file from disk and parses into into a memory resident// tree which can be walked through later.boolXML::load(const char *filespec){ bool ret = true; log_msg("Load disk XML file: %s\n", filespec); //log_msg("%s: mem is %d\n", __FUNCTION__, mem);#ifdef USE_XMLREADER XMLNode *node = 0; xmlTextReaderPtr reader; reader = xmlNewTextReaderFilename(filespec); 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", filespec); return false; } } else { log_error("Unable to open %s\n", filespec); return false; } xmlCleanupParser(); return true;#else#ifdef USE_DOM xmlInitParser(); _doc = xmlParseFile(filespec); if (_doc == 0) { log_error("Can't load XML file: %s!\n", filespec); return false; } ret = parseDoc(_doc, false); xmlCleanupParser(); xmlFreeDoc(_doc); xmlMemoryDump(); return true;#else#error "You have to enable either a DOM or an xmlReader XML parser"#endif#endif}boolXML::onLoad(){ log_msg("%s: FIXME: onLoad Default event handler\n", __FUNCTION__); return(_loaded);}XMLNode *XML::operator [] (int x) { log_msg("%s:\n", __FUNCTION__); return _nodes->_children[x];}voidXML::cleanupStackFrames(XMLNode *xml){}as_object *XML::setupFrame(as_object *obj, XMLNode *xml, bool mem){ int child, i; const char *nodename; //const char *nodevalue; //AS_value nodevalue; int length; as_value inum; XMLNode *childnode; xmlnode_as_object *xmlchildnode_obj; xmlattr_as_object* attr_obj; //log_msg("\t%s: processing node %s for object %p, mem is %d\n", __FUNCTION__, xml->_name, obj, mem); // Get the data for this node nodename = xml->_name; //nodename = xml->_name.c_str(); //nodevalue = xml->_value; length = xml->length(); // Set these members in the top level object passed in. This are used // primarily by the disk based XML parser, where at least in all my current // test cases this is referenced with firstChild first, then nodeName and // childNodes. obj->set_member("nodeName", nodename); obj->set_member("length", length); if (xml->_value != 0) { obj->set_member("nodeValue", xml->_value); //log_msg("\tnodevalue for %s is: %s\n", nodename, xml->_value); } else { obj->set_member("nodeValue", as_value::UNDEFINED); }// if (nodevalue.get_type() != as_value::UNDEFINED) {// obj->set_member("nodeValue", nodevalue.to_string());// log_msg("\tnodevalue for %s is: %s\n", nodename, nodevalue.to_string());// } else {// // If there is no value, we want to define it as an empty// // string.// obj->set_member("nodeValue", "");// } // Process the attributes, if any if (xml->_attributes.size() == 0) { //log_msg("\t\tNo attributes for node %s, created empty object at %p\n", nodename, attr_obj);// log_msg("\t\tNo attributes for node %s\n", nodename); } else { attr_obj = new xmlattr_as_object; for (i=0; i<xml->_attributes.size(); i++) { attr_obj->set_member(xml->_attributes[i]->_name, xml->_attributes[i]->_value);// log_msg("\t\tAdding attribute as member %s, value is %s to node %s (%p)\n",// xml->_attributes[i]->_name,// xml->_attributes[i]->_value, nodename, obj); } obj->set_member("attributes", attr_obj); } //xml->_attributes.resize(0); //obj->set_member("attributes", attr_obj); // Process the children, if there are any if (length) { //log_msg("\tProcessing %d children nodes for %s\n", length, nodename); inum = 0; for (child=0; child<length; child++) { // Create a new AS object for this node's children xmlchildnode_obj = new xmlnode_as_object; // When parsing XML from memory, the test movies I have expect the firstChild // to be the first element of the array instead. if (mem) { childnode = xml; //obj->set_member(inum.to_string(), obj); //inum += 1; //childnode = xml->_children[child]; } else { childnode = xml->_children[child]; } setupFrame(xmlchildnode_obj, childnode, false); // setup child node obj->set_member(inum.to_string(), xmlchildnode_obj); inum += 1; } } else { //log_msg("\tNode %s has no children\n", nodename); } return obj;} //// Callbacks. These are the wrappers for the C++ functions so they'll work as// callbacks from within gameswf.//voidxml_load(const fn_call& fn){ as_value method; as_value val; bool ret; struct stat stats; //log_msg("%s:\n", __FUNCTION__); xml_as_object *xml_obj = (xml_as_object*)fn.this_ptr; assert(ptr); const tu_string filespec = fn.env->bottom(fn.first_arg_bottom_index).to_string(); // If the file doesn't exist, don't try to do anything. if (stat(filespec.c_str(), &stats) < 0) { fprintf(stderr, "ERROR: doesn't exist.%s\n", filespec.c_str()); fn.result->set(false); return; } // Set the argument to the function event handler based on whether the load // was successful or failed. ret = xml_obj->obj.load(filespec); fn.result->set(ret); if (ret == false) { return; } //env->bottom(first_arg) = ret; array<with_stack_entry> with_stack; array<with_stack_entry> dummy_stack; // struct node *first_node = ptr->obj.firstChildGet(); //const char *name = ptr->obj.nodeNameGet(); if (xml_obj->obj.hasChildNodes() == false) { log_error("%s: No child nodes!\n", __FUNCTION__); } xml_obj->obj.setupFrame(xml_obj, xml_obj->obj.firstChild(), false); #if 1 if (fn.this_ptr->get_member("onLoad", &method)) { // log_msg("FIXME: Found onLoad!\n"); fn.env->set_variable("success", true, 0); fn.env->bottom(fn.first_arg_bottom_index) = true; as_c_function_ptr func = method.to_c_function(); if (func) { // It's a C function. Call it. log_msg("Calling C function for onLoad\n"); (*func)(fn_call(&val, xml_obj, fn.env, fn.nargs, fn.first_arg_bottom_index)); // was this_ptr instead of node } else if (as_as_function* as_func = method.to_as_function()) { // It's an ActionScript function. Call it. log_msg("Calling ActionScript function for onLoad\n"); (*as_func)(fn_call(&val, xml_obj, fn.env, fn.nargs, fn.first_arg_bottom_index)); // was this_ptr instead of node } else { log_error("error in call_method(): method is not a function\n"); } } else { log_msg("Couldn't find onLoad event handler, setting up callback\n"); // ptr->set_event_handler(event_id::XML_LOAD, (as_c_function_ptr)&xml_onload); }#else xml_obj->set_event_handler(event_id::XML_LOAD, &xml_onload);#endif fn.result->set(true);}// This executes the event handler for XML::XML_LOAD if it's been defined,// and the XML file has loaded sucessfully.voidxml_onload(const fn_call& fn){ //log_msg("%s:\n", __FUNCTION__); as_value method; as_value val; static bool first = true; // This event handler should only be executed once. array<with_stack_entry> empty_with_stack; xml_as_object* ptr = (xml_as_object*) (as_object*) fn.this_ptr; assert(ptr); if ((ptr->obj.loaded()) && (first)) { // env->set_variable("success", true, 0); //as_value bo(true); //env->push_val(bo); first = false; log_msg("The XML file has been loaded successfully!\n"); // ptr->on_event(event_id::XML_LOAD); //env->set_variable("success", true, 0); //env->bottom(0) = true; if (fn.this_ptr->get_member("onLoad", &method)) { // log_msg("FIXME: Found onLoad!\n"); as_c_function_ptr func = method.to_c_function(); if (func) { // It's a C function. Call it. log_msg("Calling C function for onLoad\n"); (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0)); } else if (as_as_function* as_func = method.to_as_function()) { // It's an ActionScript function. Call it. log_msg("Calling ActionScript function for onLoad\n"); (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0)); } else { log_error("error in call_method(): method is not a function\n"); } } else { log_msg("FIXME: Couldn't find onLoad!\n"); } } fn.result->set(&val);}// This is the default event handler, and is usually redefined in the SWF scriptvoidxml_ondata(const fn_call& fn){ log_msg("%s:\n", __FUNCTION__); as_value method; as_value val; static bool first = true; // FIXME: ugly hack! xml_as_object* ptr = (xml_as_object*)fn.this_ptr; assert(ptr); if ((ptr->obj.loaded()) && (first)) { if (fn.this_ptr->get_member("onData", &method)) { log_msg("FIXME: Found onData!\n"); as_c_function_ptr func = method.to_c_function(); fn.env->set_variable("success", true, 0); if (func) { // It's a C function. Call it. log_msg("Calling C function for onData\n"); (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0)); } else if (as_as_function* as_func = method.to_as_function()) { // It's an ActionScript function. Call it. log_msg("Calling ActionScript function for onData\n"); (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0)); } else { log_error("error in call_method(): method is not a function\n"); } } else { log_msg("FIXME: Couldn't find onData!\n"); } } fn.result->set(&val);}voidxml_new(const fn_call& fn){ as_value inum; xml_as_object *xml_obj; //const char *data; //log_msg("%s: nargs=%d\n", __FUNCTION__, nargs); if (fn.nargs > 0) { if (fn.env->top(0).get_type() == as_value::STRING) { xml_obj = new xml_as_object; //log_msg("\tCreated New XML object at %p\n", xml_obj); tu_string datain = fn.env->top(0).to_tu_string(); xml_obj->obj.parseXML(datain); //log_msg("*** Start setting up the stack frames ***\n"); xml_obj->obj.setupFrame(xml_obj, xml_obj->obj.firstChild(), true); //xml_obj->obj.clear(); //delete xml_obj->obj.firstChild(); } else { xml_as_object* xml_obj = (xml_as_object*)fn.env->top(0).to_object(); //log_msg("\tCloned the XML object at %p\n", xml_obj); //result->set(xml_obj); fn.result->set_as_object_interface(xml_obj); return; } } else { xml_obj = new xml_as_object; //log_msg("\tCreated New XML object at %p\n", xml_obj); xml_obj->set_member("load", &xml_load); xml_obj->set_member("loaded", &xml_loaded); } fn.result->set_as_object_interface(xml_obj);}//// SWF Property of this class. These are "accessors" into the private data// of the class.//// determines whether the document-loading process initiated by the XML.load()// call has completed. If the process completes successfully, the method// returns true; otherwise, it returns false.voidxml_loaded(const fn_call& fn){ as_value method; as_value val; log_msg("%s:\n", __FUNCTION__); xml_as_object* ptr = (xml_as_object*) (as_object*) fn.this_ptr; assert(ptr); tu_string filespec = fn.env->bottom(fn.first_arg_bottom_index).to_string(); fn.result->set(ptr->obj.loaded());}intmemadjust(int x){ return (x + (4 - x % 4));}} // end of gameswf namespace// HAVE_LIBXML#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -