void igraph_i_graphml_add_attribute_key(const xmlChar** attrs, struct igraph_i_graphml_parser_state *state) { xmlChar **it; igraph_trie_t *trie=0; igraph_vector_ptr_t *ptrvector=0; long int id; int ret; igraph_i_graphml_attribute_record_t *rec= igraph_Calloc(1, igraph_i_graphml_attribute_record_t); if (!state->successful) return; if (rec==0) { igraph_error("Cannot parse GraphML file", __FILE__, __LINE__, IGRAPH_ENOMEM); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file"); return; } IGRAPH_FINALLY(igraph_free, rec); for (it=(xmlChar**)attrs; *it; it+=2) { if (xmlStrEqual(*it, toXmlChar("id"))) { const char *id=(const char*)(*(it+1)); rec->id=strdup(id); } else if (xmlStrEqual(*it, toXmlChar("attr.name"))) { const char *name=fromXmlChar(*(it+1)); rec->record.name=strdup(name); } else if (xmlStrEqual(*it, toXmlChar("attr.type"))) { if (xmlStrEqual(*(it+1), (xmlChar*)"boolean")) { rec->type=I_GRAPHML_BOOLEAN; rec->record.type=IGRAPH_ATTRIBUTE_NUMERIC; } else if (xmlStrEqual(*(it+1), toXmlChar("string"))) { rec->type=I_GRAPHML_STRING; rec->record.type=IGRAPH_ATTRIBUTE_STRING; } else if (xmlStrEqual(*(it+1), toXmlChar("float"))) { rec->type=I_GRAPHML_FLOAT; rec->record.type=IGRAPH_ATTRIBUTE_NUMERIC; } else if (xmlStrEqual(*(it+1), toXmlChar("double"))) { rec->type=I_GRAPHML_DOUBLE; rec->record.type=IGRAPH_ATTRIBUTE_NUMERIC; } else if (xmlStrEqual(*(it+1), toXmlChar("int"))) { rec->type=I_GRAPHML_INTEGER; rec->record.type=IGRAPH_ATTRIBUTE_NUMERIC; } else if (xmlStrEqual(*(it+1), toXmlChar("long"))) { rec->type=I_GRAPHML_LONG; rec->record.type=IGRAPH_ATTRIBUTE_NUMERIC; } else { igraph_error("Cannot parse GraphML file, unknown attribute type", __FILE__, __LINE__, IGRAPH_PARSEERROR); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file, unknown attribute type"); return; } } else if (xmlStrEqual(*it, toXmlChar("for"))) { /* graph, vertex or edge attribute? */ if (xmlStrEqual(*(it+1), toXmlChar("graph"))) { trie=&state->g_names; ptrvector=&state->g_attrs; } else if (xmlStrEqual(*(it+1), toXmlChar("node"))) { trie=&state->v_names; ptrvector=&state->v_attrs; } else if (xmlStrEqual(*(it+1), toXmlChar("edge"))) { trie=&state->e_names; ptrvector=&state->e_attrs; } else { igraph_error("Cannot parse GraphML file, unknown attribute type", __FILE__, __LINE__, IGRAPH_PARSEERROR); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file, unknown attribute type"); return; } } } if (trie == 0 && state->successful) { igraph_error("Cannot parse GraphML file, missing 'for' attribute", __FILE__, __LINE__, IGRAPH_PARSEERROR); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file, missing 'for' attribute"); return; } /* add to trie, attribues */ igraph_trie_get(trie, rec->id, &id); if (id != igraph_trie_size(trie)-1) { igraph_error("Cannot parse GraphML file, duplicate attribute", __FILE__, __LINE__, IGRAPH_PARSEERROR); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file, duplicate attribute"); return; } ret=igraph_vector_ptr_push_back(ptrvector, rec); if (ret) { igraph_error("Cannot read GraphML file", __FILE__, __LINE__, ret); igraph_i_graphml_sax_handler_error(state, "Cannot read GraphML file"); return; } /* create the attribute values */ switch (rec->record.type) { igraph_vector_t *vec; igraph_strvector_t *strvec; case IGRAPH_ATTRIBUTE_NUMERIC: vec=igraph_Calloc(1, igraph_vector_t); if (vec==0) { igraph_error("Cannot parse GraphML file", __FILE__, __LINE__, IGRAPH_ENOMEM); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file"); return; } rec->record.value=vec; igraph_vector_init(vec, 0); break; case IGRAPH_ATTRIBUTE_STRING: strvec=igraph_Calloc(1, igraph_strvector_t); if (strvec==0) { igraph_error("Cannot parse GraphML file", __FILE__, __LINE__, IGRAPH_ENOMEM); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file"); return; } rec->record.value=strvec; igraph_strvector_init(strvec, 0); break; default: break; } IGRAPH_FINALLY_CLEAN(1); /* rec */ }
int main() { igraph_trie_t trie; long int id; int i; char *str; /* init */ igraph_trie_init(&trie, 0); /* add and get values */ igraph_trie_get(&trie, "hello", &id); printf("hello: %li\n", id); igraph_trie_get(&trie, "hepp", &id); printf("hepp: %li\n", id); igraph_trie_get(&trie, "alma", &id); printf("alma: %li\n", id); igraph_trie_get(&trie, "also", &id); printf("also: %li\n", id); igraph_trie_get(&trie, "hello", &id); printf("hello: %li\n", id); igraph_trie_get(&trie, "hepp", &id); printf("hepp: %li\n", id); igraph_trie_get(&trie, "alma", &id); printf("alma: %li\n", id); igraph_trie_get(&trie, "also", &id); printf("also: %li\n", id); igraph_trie_get(&trie, "a", &id); printf("a: %li\n", id); igraph_trie_get(&trie, "axon", &id); printf("axon: %li\n", id); igraph_trie_get(&trie, "hello", &id); printf("hello: %li\n", id); igraph_trie_get(&trie, "hepp", &id); printf("hepp: %li\n", id); igraph_trie_get(&trie, "alma", &id); printf("alma: %li\n", id); igraph_trie_get(&trie, "also", &id); printf("also: %li\n", id); /* check for existence */ igraph_trie_check(&trie, "head", &id); printf("head: %li\n", id); igraph_trie_check(&trie, "alma", &id); printf("alma: %li\n", id); /* destroy */ igraph_trie_destroy(&trie); /* the same with index */ igraph_trie_init(&trie, 1); igraph_trie_get(&trie, "hello", &id); printf("hello: %li\n", id); igraph_trie_get(&trie, "hepp", &id); printf("hepp: %li\n", id); igraph_trie_get(&trie, "alma", &id); printf("alma: %li\n", id); igraph_trie_get(&trie, "also", &id); printf("also: %li\n", id); igraph_trie_get(&trie, "hello", &id); printf("hello: %li\n", id); igraph_trie_get(&trie, "hepp", &id); printf("hepp: %li\n", id); igraph_trie_get(&trie, "alma", &id); printf("alma: %li\n", id); igraph_trie_get(&trie, "also", &id); printf("also: %li\n", id); igraph_trie_get(&trie, "a", &id); printf("a: %li\n", id); igraph_trie_get(&trie, "axon", &id); printf("axon: %li\n", id); igraph_trie_get(&trie, "hello", &id); printf("hello: %li\n", id); igraph_trie_get(&trie, "hepp", &id); printf("hepp: %li\n", id); igraph_trie_get(&trie, "alma", &id); printf("alma: %li\n", id); igraph_trie_get(&trie, "also", &id); printf("also: %li\n", id); /* check for existence */ igraph_trie_check(&trie, "head", &id); printf("head: %li\n", id); igraph_trie_check(&trie, "alma", &id); printf("alma: %li\n", id); for (i=0; i<igraph_trie_size(&trie); i++) { igraph_trie_idx(&trie, i, &str); printf("%d: %s\n", i, str); } igraph_trie_destroy(&trie); if (!IGRAPH_FINALLY_STACK_EMPTY) return 1; return 0; }
void igraph_i_graphml_sax_handler_end_document(void *state0) { struct igraph_i_graphml_parser_state *state= (struct igraph_i_graphml_parser_state*)state0; long i, l; int r; igraph_i_attribute_record_t idrec, eidrec; const char *idstr="id"; igraph_bool_t already_has_vertex_id=0, already_has_edge_id=0; if (!state->successful) return; if (state->index<0) { igraph_vector_ptr_t vattr, eattr, gattr; long int esize=igraph_vector_ptr_size(&state->e_attrs); const void **tmp; r=igraph_vector_ptr_init(&vattr, igraph_vector_ptr_size(&state->v_attrs)+1); if (r) { igraph_error("Cannot parse GraphML file", __FILE__, __LINE__, r); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file"); return; } IGRAPH_FINALLY(igraph_vector_ptr_destroy, &vattr); if (igraph_strvector_size(&state->edgeids) != 0) { esize++; } r=igraph_vector_ptr_init(&eattr, esize); if (r) { igraph_error("Cannot parse GraphML file", __FILE__, __LINE__, r); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file"); return; } IGRAPH_FINALLY(igraph_vector_ptr_destroy, &eattr); r=igraph_vector_ptr_init(&gattr, igraph_vector_ptr_size(&state->g_attrs)); if (r) { igraph_error("Cannot parse GraphML file", __FILE__, __LINE__, r); igraph_i_graphml_sax_handler_error(state, "Cannot parse GraphML file"); return; } IGRAPH_FINALLY(igraph_vector_ptr_destroy, &gattr); for (i=0; i<igraph_vector_ptr_size(&state->v_attrs); i++) { igraph_i_graphml_attribute_record_t *graphmlrec= VECTOR(state->v_attrs)[i]; igraph_i_attribute_record_t *rec=&graphmlrec->record; /* Check that the name of the vertex attribute is not 'id'. If it is then we cannot the complimentary 'id' attribute. */ if (! strcmp(rec->name, idstr)) { already_has_vertex_id=1; } if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *vec=(igraph_vector_t*)rec->value; long int origsize=igraph_vector_size(vec); long int nodes=igraph_trie_size(&state->node_trie); igraph_vector_resize(vec, nodes); for (l=origsize; l<nodes; l++) { VECTOR(*vec)[l]=IGRAPH_NAN; } } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strvec=(igraph_strvector_t*)rec->value; long int origsize=igraph_strvector_size(strvec); long int nodes=igraph_trie_size(&state->node_trie); igraph_strvector_resize(strvec, nodes); for (l=origsize; l<nodes; l++) { igraph_strvector_set(strvec, l, ""); } } VECTOR(vattr)[i]=rec; } if (!already_has_vertex_id) { idrec.name=idstr; idrec.type=IGRAPH_ATTRIBUTE_STRING; tmp=&idrec.value; igraph_trie_getkeys(&state->node_trie, (const igraph_strvector_t **)tmp); VECTOR(vattr)[i]=&idrec; } else { igraph_vector_ptr_pop_back(&vattr); IGRAPH_WARNING("Could not add vertex ids, " "there is already an 'id' vertex attribute"); } for (i=0; i<igraph_vector_ptr_size(&state->e_attrs); i++) { igraph_i_graphml_attribute_record_t *graphmlrec= VECTOR(state->e_attrs)[i]; igraph_i_attribute_record_t *rec=&graphmlrec->record; if (! strcmp(rec->name, idstr)) { already_has_edge_id=1; } if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *vec=(igraph_vector_t*)rec->value; long int origsize=igraph_vector_size(vec); long int edges=igraph_vector_size(&state->edgelist)/2; igraph_vector_resize(vec, edges); for (l=origsize; l<edges; l++) { VECTOR(*vec)[l]=IGRAPH_NAN; } } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strvec=(igraph_strvector_t*)rec->value; long int origsize=igraph_strvector_size(strvec); long int edges=igraph_vector_size(&state->edgelist)/2; igraph_strvector_resize(strvec, edges); for (l=origsize; l<edges; l++) { igraph_strvector_set(strvec, l, ""); } } VECTOR(eattr)[i]=rec; } if (igraph_strvector_size(&state->edgeids) != 0) { if (!already_has_edge_id) { long int origsize=igraph_strvector_size(&state->edgeids); eidrec.name=idstr; eidrec.type=IGRAPH_ATTRIBUTE_STRING; igraph_strvector_resize(&state->edgeids, igraph_vector_size(&state->edgelist)/2); for (; origsize < igraph_strvector_size(&state->edgeids); origsize++) { igraph_strvector_set(&state->edgeids, origsize, ""); } eidrec.value=&state->edgeids; VECTOR(eattr)[(long int)igraph_vector_ptr_size(&eattr)-1]=&eidrec; } else { igraph_vector_ptr_pop_back(&eattr); IGRAPH_WARNING("Could not add edge ids, " "there is already an 'id' edge attribute"); } } for (i=0; i<igraph_vector_ptr_size(&state->g_attrs); i++) { igraph_i_graphml_attribute_record_t *graphmlrec= VECTOR(state->g_attrs)[i]; igraph_i_attribute_record_t *rec=&graphmlrec->record; if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { igraph_vector_t *vec=(igraph_vector_t*)rec->value; long int origsize=igraph_vector_size(vec); igraph_vector_resize(vec, 1); for (l=origsize; l<1; l++) { VECTOR(*vec)[l]=IGRAPH_NAN; } } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { igraph_strvector_t *strvec=(igraph_strvector_t*)rec->value; long int origsize=igraph_strvector_size(strvec); igraph_strvector_resize(strvec, 1); for (l=origsize; l<1; l++) { igraph_strvector_set(strvec, l, ""); } } VECTOR(gattr)[i]=rec; } igraph_empty_attrs(state->g, 0, state->edges_directed, &gattr); igraph_add_vertices(state->g, igraph_trie_size(&state->node_trie), &vattr); igraph_add_edges(state->g, &state->edgelist, &eattr); igraph_vector_ptr_destroy(&vattr); igraph_vector_ptr_destroy(&eattr); igraph_vector_ptr_destroy(&gattr); IGRAPH_FINALLY_CLEAN(3); } igraph_i_graphml_destroy_state(state); }