static ExpatStatus builder_StartElement(void *userState, ExpatName *name, ExpatAttribute atts[], size_t natts) { ParserState *state = (ParserState *)userState; PyObject *attribute_factory=NULL; ElementObject *elem=NULL; Py_ssize_t i; PyObject *key, *value; #ifdef DEBUG_PARSER fprintf(stderr, "--- builder_StartElement(name="); PyObject_Print(name->qualifiedName, stderr, 0); fprintf(stderr, ", atts={"); for (i = 0; i < natts; i++) { if (i > 0) { fprintf(stderr, ", "); } PyObject_Print(atts[i].qualifiedName, stderr, 0); fprintf(stderr, ", "); PyObject_Print(atts[i].value, stderr, 0); } fprintf(stderr, "})\n"); #endif if (state->element_factory) { elem = (ElementObject *) PyObject_CallFunctionObjArgs(state->element_factory, name->namespaceURI, name->qualifiedName, NULL); if (elem == NULL) return EXPAT_STATUS_ERROR; if (!Element_Check(elem)) { PyErr_Format(PyExc_TypeError, "xml_element_factory should return element, not %s", elem->ob_type->tp_name); Py_DECREF(elem); return EXPAT_STATUS_ERROR; } } else { elem = Element_New(name->namespaceURI, name->qualifiedName, name->localName); if (elem == NULL) return EXPAT_STATUS_ERROR; } /** namespaces *******************************************************/ /* new_namespaces is a dictionary where key is the prefix and value * is the uri. */ if (((PyDictObject *)state->new_namespaces)->ma_used) { i = 0; while (PyDict_Next(state->new_namespaces, &i, &key, &value)) { NamespaceObject *nsnode = Element_AddNamespace(elem, key, value); if (nsnode == NULL) { Py_DECREF(elem); Py_XDECREF(attribute_factory); return EXPAT_STATUS_ERROR; } Py_DECREF(nsnode); } /* make sure children don't set these namespaces */ PyDict_Clear(state->new_namespaces); } /** attributes *******************************************************/ for (i = 0; i < (Py_ssize_t)natts; i++) { AttrObject *attr = Element_AddAttribute(elem, atts[i].namespaceURI, atts[i].qualifiedName, atts[i].localName, atts[i].value); if (attr == NULL) { Py_DECREF(elem); return EXPAT_STATUS_ERROR; } /* save the attribute type as well (for getElementById) */ Attr_SET_TYPE(attr, atts[i].type); Py_DECREF(attr); } /* Check for rule matching */ if (state->rule_matcher) { if (RuleMatch_StartElement(state->rule_matcher,(PyObject *) elem,name,atts,natts) < 0) { Py_DECREF(elem); return EXPAT_STATUS_ERROR; } } /* save states on the context */ if (ParserState_AddContext(state, (NodeObject *) elem) == NULL) { Py_DECREF(elem); return EXPAT_STATUS_ERROR; } return EXPAT_STATUS_OK; }
Cache_New( TCache* cache, void** new_object, void* parent_object ) { TT_Error error; PList_Element current; PConstructor build; PRefresher reset; void* object; LOCK(); current = cache->idle; if ( current ) { cache->idle = current->next; cache->idle_count--; } UNLOCK(); if ( current ) { object = current->data; reset = cache->clazz->reset; if ( reset ) { error = reset( object, parent_object ); if ( error ) { LOCK(); current->next = cache->idle; cache->idle = current; cache->idle_count++; UNLOCK(); goto Exit; } } } else { /* if no object was found in the cache, create a new one */ build = cache->clazz->init; if ( MEM_Alloc( object, cache->clazz->object_size ) ) goto Memory_Fail; current = Element_New( cache->engine ); if ( !current ) goto Memory_Fail; current->data = object; error = build( object, parent_object ); if ( error ) { Element_Done( cache->engine, current ); goto Fail; } } LOCK(); current->next = cache->active; cache->active = current; UNLOCK(); *new_object = current->data; return TT_Err_Ok; Exit: *new_object = NULL; return error; Memory_Fail: error = TT_Err_Out_Of_Memory; Fail: FREE( object ); goto Exit; }