예제 #1
0
파일: plist.c 프로젝트: daiwx/libplist
static void plist_copy_node(node_t *node, void *parent_node_ptr)
{
    plist_type node_type = PLIST_NONE;
    plist_t newnode = NULL;
    plist_data_t data = plist_get_data(node);
    plist_data_t newdata = plist_new_plist_data();

    assert(data);				// plist should always have data

    memcpy(newdata, data, sizeof(struct plist_data_s));

    node_type = plist_get_node_type(node);
    if (node_type == PLIST_DATA || node_type == PLIST_STRING || node_type == PLIST_KEY)
    {
        switch (node_type)
        {
        case PLIST_DATA:
            newdata->buff = (uint8_t *) malloc(data->length);
            memcpy(newdata->buff, data->buff, data->length);
            break;
        case PLIST_KEY:
        case PLIST_STRING:
            newdata->strval = strdup((char *) data->strval);
            break;
        default:
            break;
        }
    }
    newnode = plist_new_node(newdata);

    if (*(plist_t*)parent_node_ptr)
    {
        node_attach(*(plist_t*)parent_node_ptr, newnode);
    }
    else
    {
        *(plist_t*)parent_node_ptr = newnode;
    }

    node_iterator_t *ni = node_iterator_create(node->children);
    node_t *ch;
    while ((ch = node_iterator_next(ni))) {
        plist_copy_node(ch, &newnode);
    }
    node_iterator_destroy(ni);
}
예제 #2
0
/**
 * Set the length of each leaf to e recursively
 * @param v the node in question
 * @param log the log to record errors in
 */
static void set_e( suffixtree *st, node *v, plugin_log *log )
{
    if ( node_is_leaf(v) )
    {
        node_set_len( v, st->e-node_start(v)+1 );
    }
    node_iterator *iter = node_children( v, log );
    if ( iter != NULL )
    {
        while ( node_iterator_has_next(iter) )
        {
            node *u = node_iterator_next( iter );
            set_e( st, u, log );
        }
        node_iterator_dispose( iter );
    }
}
예제 #3
0
파일: plist.c 프로젝트: daiwx/libplist
static int plist_free_node(node_t* node)
{
    plist_data_t data = NULL;
    int index = node_detach(node->parent, node);
    data = plist_get_data(node);
    plist_free_data(data);
    node->data = NULL;

    node_iterator_t *ni = node_iterator_create(node->children);
    node_t *ch;
    while ((ch = node_iterator_next(ni))) {
        plist_free_node(ch);
    }
    node_iterator_destroy(ni);

    node_destroy(node);

    return index;
}
예제 #4
0
/**
 * Create a hashtable by conversion from a list of child-nodes
 * @param children add these nodes to the hashtable for starters
 * @return an initialised hashtable
 */
hashtable *hashtable_create( node *parent )
{
    hashtable *ht = calloc( 1, sizeof(hashtable) );
    if ( ht != NULL )
    {
        int nnodes = node_num_children( parent );
        mem_usage += sizeof(hashtable);
        ht->nbuckets = nnodes*2;
        ht->items = calloc( ht->nbuckets, sizeof(struct bucket*) );
        if ( ht->items != NULL )
        {
            int res = 1;
            mem_usage += ht->nbuckets*sizeof(struct bucket*);
            node_iterator *iter = node_children( parent );
            if ( iter != NULL )
            {
                while ( res && node_iterator_has_next(iter) )
                {
                    node *temp = node_iterator_next( iter );
                    node_clear_next( temp );
                    res = hashtable_add( ht, temp );
                }
                node_iterator_dispose( iter );
            }
            else
                res = 0;
            if ( !res )
            {
                hashtable_dispose( ht );
                ht = NULL;
            }
        }
        else
            fprintf(stderr,"failed to allocate %d buckets\n",ht->nbuckets);
    }
    else
        fprintf(stderr,"hashtable: failed to allocate\n");
    return ht;
}
예제 #5
0
파일: xplist.c 프로젝트: EchoLiao/libplist
static void node_to_xml(node_t* node, void *xml_struct)
{
    struct xml_node *xstruct = NULL;
    plist_data_t node_data = NULL;

    xmlNodePtr child_node = NULL;
    char isStruct = FALSE;
    char isUIDNode = FALSE;

    const xmlChar *tag = NULL;
    char *val = NULL;

    //for base64
    char *valtmp = NULL;

    uint32_t i = 0;

    if (!node)
        return;

    xstruct = (struct xml_node *) xml_struct;
    node_data = plist_get_data(node);

    switch (node_data->type)
    {
    case PLIST_BOOLEAN:
    {
        if (node_data->boolval)
            tag = XPLIST_TRUE;
        else
            tag = XPLIST_FALSE;
    }
    break;

    case PLIST_UINT:
        tag = XPLIST_INT;
        val = (char*)malloc(64);
        if (node_data->length == 16) {
	        (void)snprintf(val, 64, "%"PRIu64, node_data->intval);
	} else {
	        (void)snprintf(val, 64, "%"PRIi64, node_data->intval);
	}
        break;

    case PLIST_REAL:
        tag = XPLIST_REAL;
        val = (char*)malloc(64);
        (void)snprintf(val, 64, "%f", node_data->realval);
        break;

    case PLIST_STRING:
        tag = XPLIST_STRING;
        val = strdup((char*) node_data->strval);
        break;

    case PLIST_KEY:
        tag = XPLIST_KEY;
        val = strdup((char*) node_data->strval);
        break;

    case PLIST_DATA:
        tag = XPLIST_DATA;
        if (node_data->length)
        {
            size_t len = node_data->length;
            valtmp = base64encode(node_data->buff, &len);
            val = format_string(valtmp, len, 68, xstruct->depth);
            free(valtmp);
        }
        break;
    case PLIST_ARRAY:
        tag = XPLIST_ARRAY;
        isStruct = TRUE;
        break;
    case PLIST_DICT:
        tag = XPLIST_DICT;
        isStruct = TRUE;
        break;
    case PLIST_DATE:
        tag = XPLIST_DATE;
        {
            time_t timev = (time_t)node_data->timeval.tv_sec + MAC_EPOCH;
            struct tm *btime = gmtime(&timev);
            if (btime) {
                val = (char*)malloc(24);
                memset(val, 0, 24);
                if (strftime(val, 24, "%Y-%m-%dT%H:%M:%SZ", btime) <= 0) {
                    free (val);
                    val = NULL;
                }
            }
        }
        break;
    case PLIST_UID:
        // special case for keyed encoding
        tag = XPLIST_DICT;
        isStruct = TRUE;
        isUIDNode = TRUE;
        node_data->type = PLIST_DICT;
        node_attach(node, new_key_node("CF$UID"));
        node_attach(node, new_uint_node(node_data->intval));
        break;
    default:
        break;
    }

    for (i = 0; i < xstruct->depth; i++)
    {
        xmlNodeAddContent(xstruct->xml, BAD_CAST("\t"));
    }
    if (node_data->type == PLIST_STRING || node_data->type == PLIST_KEY) {
        /* make sure we convert the following predefined xml entities */
        /* < = &lt; > = &gt; ' = &apos; " = &quot; & = &amp; */
        child_node = xmlNewTextChild(xstruct->xml, NULL, tag, BAD_CAST(val));
    } else
        child_node = xmlNewChild(xstruct->xml, NULL, tag, BAD_CAST(val));
    xmlNodeAddContent(xstruct->xml, BAD_CAST("\n"));
    if (val) {
        free(val);
    }

    //add return for structured types
    if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT)
        xmlNodeAddContent(child_node, BAD_CAST("\n"));

    //make sure we don't produce <data/> if it's empty
    if ((node_data->type == PLIST_DATA) && !val) {
        xmlNodeAddContent(child_node, BAD_CAST("\n"));
        for (i = 0; i < xstruct->depth; i++)
        {
            xmlNodeAddContent(child_node, BAD_CAST("\t"));
        }
    }

    if (isStruct)
    {
        struct xml_node child = { child_node, xstruct->depth + 1 };
        node_iterator_t *ni = node_iterator_create(node->children);
        node_t *ch;
        while ((ch = node_iterator_next(ni))) {
            node_to_xml(ch, &child);
        }
        node_iterator_destroy(ni);
    }
    //fix indent for structured types
    if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT)
    {

        for (i = 0; i < xstruct->depth; i++)
        {
            xmlNodeAddContent(child_node, BAD_CAST("\t"));
        }
    }
    if (isUIDNode)
    {
        unsigned int num = node_n_children(node);
        unsigned int j;
        for (j = num; j > 0; j--) {
            node_t* ch = node_nth_child(node, j-1);
            node_detach(node, ch);
            node_destroy(ch);
        }
        node_data->type = PLIST_UID;
    }

    return;
}
예제 #6
0
static void receiver_receive(receiver_t *self, bytecode_stream_t *message,
                             context_t *context)
{
    atom_t selector;
    message_fifo_t *fifo;
    message_node_t *node;
    node_iterator_t it;

    if (!message || !message->end) {
        WARNING1("message === NULL");
        return;
    }

    selector = message->end->code.verb;
    fifo = get_fifo(self, selector);
    node = calloc(sizeof(message_node_t), 1);

    if (!fifo)
        fifo = add_fifo(self, selector);

    if (fifo->closed_p) {
        /* destroy the message and the context objects */
        bytecode_stream_retire(message);
        context_retire(context);

        return;
    }

    /*
       insert message in the right position

       messages are ordered by decreasing context from beginning to end.
    */
    if (get_node_iterator(fifo, &it)) {
        message_node_t *current = NULL;
        message_node_t *last = NULL;

        TRACE3("adding at: %f in fifo: %s", context->ms,
               atom_get_cstring_value(fifo->atom));

        while ((current = node_iterator_next(&it)) &&
               context->is_in(context, current->context)) {
            /* advance until context is not anymore in current context */
            TRACE2("current at: %f", current->context->ms);
            last = current;
        }

        if (last == NULL) {
            if (fifo->end == NULL) {
                TRACE1("append to empty fifo");
                node->next = node;
                node->prev = node;
                fifo->end = node;
            } else {
                if (context->is_in(context, current->context)) {
                    TRACE2("insert after current at %f", current->context->ms);
                    node->prev = current;
                    node->next = current->next;
                    current->next = node;
                    node->next->prev = node;
                } else {
                    TRACE2("insert before current at %f", current->context->ms);
                    node->next = current;
                    node->prev = current->prev;
                    current->prev = node;
                    node->prev->next = node;
                }
                if (current == fifo->end)
                    fifo->end = node;
            }
        } else {
            if (context->is_in(context, last->context)) {
                TRACE2("insert after last at %f", last->context->ms);
                node->prev = last;
                node->next = last->next;
                last->next = node;
                node->next->prev = node;
            } else {
                TRACE2("insert before last at %f", last->context->ms);
                node->next = last;
                node->prev = last->prev;
                last->prev = node;
                node->prev->next = node;
            }
            if (last == fifo->end)
                fifo->end = node;
        }
    }
    node->bytecodes = message;
    node->context = context;
    node->dispatched_p = 0;

    if (node->context->dispatch_now_p) {
        self->eval(self, node->bytecodes, node->context);
        node->dispatched_p = 1;
    }
}