예제 #1
0
void
xml_element_free(xml_element * const elemP) {
/*----------------------------------------------------------------------------
  Blow away an existing element & all of its child elements.
-----------------------------------------------------------------------------*/
    xmlrpc_mem_block * children;
    unsigned int size;
    unsigned int i;
    xml_element ** contents;

    XMLRPC_ASSERT_ELEM_OK(elemP);

    xmlrpc_strfree(elemP->name);
    elemP->name = XMLRPC_BAD_POINTER;
    xmlrpc_mem_block_clean(&elemP->cdata);

    /* Deallocate all of our children recursively. */
    children = &elemP->children;
    contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element *, children);
    size = XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, children);
    for (i = 0; i < size; ++i)
        xml_element_free(contents[i]);

    xmlrpc_mem_block_clean(&elemP->children);

    free(elemP);
}
예제 #2
0
static xml_element *
xmlElementNew(xmlrpc_env * const envP,
              const char * const name) {
/*----------------------------------------------------------------------------
  Create a new xml_element. This routine isn't exported, because the
  arguments are implementation-dependent.
-----------------------------------------------------------------------------*/

    xml_element * retval;
    bool nameIsValid;
    bool cdataIsValid;
    bool childrenAreValid;

    XMLRPC_ASSERT_ENV_OK(envP);
    assert(name != NULL);

    /* Set up our error-handling preconditions. */
    retval = NULL;
    nameIsValid = cdataIsValid = childrenAreValid = false;

    MALLOCVAR(retval);
    XMLRPC_FAIL_IF_NULL(retval, envP, XMLRPC_INTERNAL_ERROR,
                        "Couldn't allocate memory for XML element");

    retval->parentP = NULL;
    
    /* Copy over the element name. */
    retval->name = strdup(name);
    XMLRPC_FAIL_IF_NULL(retval->name, envP, XMLRPC_INTERNAL_ERROR,
                        "Couldn't allocate memory for XML element");
    nameIsValid = true;

    /* Initialize a block to hold our CDATA. */
    XMLRPC_TYPED_MEM_BLOCK_INIT(char, envP, &retval->cdata, 0);
    XMLRPC_FAIL_IF_FAULT(envP);
    cdataIsValid = true;

    /* Initialize a block to hold our child elements. */
    XMLRPC_TYPED_MEM_BLOCK_INIT(xml_element *, envP, &retval->children, 0);
    XMLRPC_FAIL_IF_FAULT(envP);
    childrenAreValid = true;

cleanup:
    if (envP->fault_occurred) {
        if (retval) {
            if (nameIsValid)
                xmlrpc_strfree(retval->name);
            if (cdataIsValid)
                xmlrpc_mem_block_clean(&retval->cdata);
            if (childrenAreValid)
                xmlrpc_mem_block_clean(&retval->children);
            free(retval);
        }
        retval = NULL;
    }
    return retval;
}
예제 #3
0
static void
destroyValue(xmlrpc_value * const valueP) {

    /* First, we need to destroy this value's contents, if any. */
    switch (valueP->_type) {
    case XMLRPC_TYPE_INT:
        break;
        
    case XMLRPC_TYPE_BOOL:
        break;

    case XMLRPC_TYPE_DOUBLE:
        break;

    case XMLRPC_TYPE_DATETIME:
        xmlrpc_mem_block_clean(&valueP->_block);
        break;

    case XMLRPC_TYPE_STRING:
        xmlrpc_destroyString(valueP);
        break;
        
    case XMLRPC_TYPE_BASE64:
        xmlrpc_mem_block_clean(&valueP->_block);
        break;

    case XMLRPC_TYPE_ARRAY:
        xmlrpc_destroyArrayContents(valueP);
        break;
        
    case XMLRPC_TYPE_STRUCT:
        xmlrpc_destroyStruct(valueP);
        break;

    case XMLRPC_TYPE_C_PTR:
        break;

    case XMLRPC_TYPE_NIL:
        break;

    case XMLRPC_TYPE_I8:
        break;

    case XMLRPC_TYPE_DEAD:
        XMLRPC_ASSERT(false); /* Can't happen, per entry conditions */

    default:
        XMLRPC_ASSERT(false); /* There are no other possible values */
    }

    /* Next, we mark this value as invalid, to help catch refcount
        ** errors. */
    valueP->_type = XMLRPC_TYPE_DEAD;

    /* Finally, we destroy the value itself. */
    free(valueP);
}
void
xmlrpc_destroyString(xmlrpc_value * const valueP) {

    if (valueP->_wcs_block)
        xmlrpc_mem_block_free(valueP->_wcs_block);

    xmlrpc_mem_block_clean(&valueP->_block);
}
예제 #5
0
/* Destroy an existing xmlrpc_mem_block, and everything it contains. */
void
xmlrpc_mem_block_free(xmlrpc_mem_block * const blockP) {

    XMLRPC_ASSERT(blockP != NULL);
    XMLRPC_ASSERT(blockP->_block != NULL);

    xmlrpc_mem_block_clean(blockP);
    free(blockP);
}