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); }
/** * 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 ); } }
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; }
/** * 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; }
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 */ /* < = < > = > ' = ' " = " & = & */ 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; }
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; } }