Exemple #1
0
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;
}
Exemple #2
0
  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;
  }