int fs_metadata_flush(fs_metadata *m) { raptor_serializer *ser = raptor_new_serializer(m->rw, "turtle"); if (!ser) { fs_error(LOG_CRIT, "cannot create turtle serialiser for metadata"); return 1; } raptor_serializer_start_to_filename(ser, m->uri+7); raptor_statement st; for (int e=0; e < m->length; e++) { st.subject = raptor_new_term_from_uri_string(m->rw, (unsigned char *)m->uri); st.predicate = raptor_new_term_from_uri_string(m->rw, (unsigned char *)m->entries[e].key); st.object = raptor_new_term_from_literal(m->rw, (unsigned char *)m->entries[e].val, NULL, NULL); raptor_serializer_serialize_statement(ser, &st); raptor_free_term(st.subject); raptor_free_term(st.predicate); raptor_free_term(st.object); } raptor_serializer_serialize_end(ser); raptor_free_serializer(ser); return 0; }
/** * librdf_free_node: * @node: #librdf_node object * * Destructor - destroy an #librdf_node object. * **/ void librdf_free_node(librdf_node *node) { if(!node) return; raptor_free_term(node); }
void raptor_concepts_finish(raptor_world* world) { int i; for(i = 0; i < RDF_NS_LAST + 1; i++) { raptor_uri* concept_uri = world->concepts[i]; if(concept_uri) { raptor_free_uri(concept_uri); world->concepts[i] = NULL; } if(world->terms[i]) raptor_free_term(world->terms[i]); } }
void raptor_free_rss_item(raptor_rss_item* item) { int i; for(i = 0; i< RAPTOR_RSS_FIELDS_SIZE; i++) { if(item->fields[i]) raptor_rss_field_free(item->fields[i]); } if(item->blocks) raptor_free_rss_block(item->blocks); if(item->uri) raptor_free_uri(item->uri); if(item->term) raptor_free_term(item->term); if(item->triples) raptor_free_sequence(item->triples); RAPTOR_FREE(raptor_rss_item, item); }
void raptor_free_rss_block(raptor_rss_block *block) { int i; for(i = 0; i < RSS_BLOCK_MAX_URLS; i++) { if(block->urls[i]) raptor_free_uri(block->urls[i]); } for(i = 0; i < RSS_BLOCK_MAX_STRINGS; i++) { if(block->strings[i]) RAPTOR_FREE(char*, block->strings[i]); } if(block->next) raptor_free_rss_block(block->next); if(block->identifier) raptor_free_term(block->identifier); RAPTOR_FREE(raptor_rss_block, block); }
/** * rasqal_query_results_get_triple: * @query_results: #rasqal_query_results query_results * * Get the current triple in the result. * * The return value is a shared #raptor_statement. * * Return value: #raptor_statement or NULL if failed or results exhausted **/ raptor_statement* rasqal_query_results_get_triple(rasqal_query_results* query_results) { rasqal_query* query; int rc; rasqal_triple *t; rasqal_literal *s, *p, *o; raptor_statement *rs = NULL; unsigned char *nodeid; int skipped; RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query_results, rasqal_query_results, NULL); if(query_results->failed || query_results->finished) return NULL; if(!rasqal_query_results_is_graph(query_results)) return NULL; query = query_results->query; if(!query) return NULL; if(query->verb == RASQAL_QUERY_VERB_DESCRIBE) return NULL; /* ensure we have a row to work on */ if(rasqal_query_results_ensure_have_row_internal(query_results)) return NULL; skipped = 0; while(1) { if(skipped) { rc = rasqal_query_results_next(query_results); if(rc) { rs = NULL; break; } query_results->current_triple_result = -1; } if(query_results->current_triple_result < 0) query_results->current_triple_result = 0; t = (rasqal_triple*)raptor_sequence_get_at(query->constructs, query_results->current_triple_result); rs = &query_results->result_triple; s = rasqal_literal_as_node(t->subject); if(!s) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_WARN, &query->locator, "Triple with unbound subject skipped"); skipped = 1; continue; } /* raptor v2 terms are copied, not shared */ if(rs->subject) { raptor_free_term(rs->subject); rs->subject = NULL; } switch(s->type) { case RASQAL_LITERAL_URI: rs->subject = raptor_new_term_from_uri(query_results->world->raptor_world_ptr, s->value.uri); break; case RASQAL_LITERAL_BLANK: nodeid = rasqal_prefix_id(query_results->result_count, (unsigned char*)s->string); rasqal_free_literal(s); if(!nodeid) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_FATAL, &query->locator, "Could not prefix subject blank identifier"); return NULL; } s = rasqal_new_simple_literal(query_results->world, RASQAL_LITERAL_BLANK, nodeid); if(!s) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_FATAL, &query->locator, "Could not create a new subject blank literal"); return NULL; } rs->subject = raptor_new_term_from_blank(query_results->world->raptor_world_ptr, nodeid); break; case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_XSD_STRING: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UDT: case RASQAL_LITERAL_INTEGER_SUBTYPE: /* QNames should be gone by the time expression eval happens * Everything else is removed by rasqal_literal_as_node() above. */ case RASQAL_LITERAL_STRING: /* string [literal] subjects are not RDF */ case RASQAL_LITERAL_UNKNOWN: default: /* case RASQAL_LITERAL_STRING: */ rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_WARN, &query->locator, "Triple with non-URI/blank node subject skipped"); skipped = 1; break; } if(skipped) { if(s) rasqal_free_literal(s); continue; } p = rasqal_literal_as_node(t->predicate); if(!p) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_WARN, &query->locator, "Triple with unbound predicate skipped"); rasqal_free_literal(s); skipped = 1; continue; } switch(p->type) { case RASQAL_LITERAL_URI: /* raptor v2 terms are copied, not shared */ if(rs->predicate) { raptor_free_term(rs->predicate); rs->predicate = NULL; } rs->predicate = raptor_new_term_from_uri(query_results->world->raptor_world_ptr, p->value.uri); break; case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_XSD_STRING: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UDT: case RASQAL_LITERAL_INTEGER_SUBTYPE: /* QNames should be gone by the time expression eval happens * Everything else is removed by rasqal_literal_as_node() above. */ case RASQAL_LITERAL_BLANK: case RASQAL_LITERAL_STRING: /* blank node or string [literal] predicates are not RDF */ case RASQAL_LITERAL_UNKNOWN: default: rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_WARN, &query->locator, "Triple with non-URI predicate skipped"); skipped = 1; break; } if(skipped) { rasqal_free_literal(s); if(p) rasqal_free_literal(p); continue; } o = rasqal_literal_as_node(t->object); if(!o) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_WARN, &query->locator, "Triple with unbound object skipped"); rasqal_free_literal(s); rasqal_free_literal(p); skipped = 1; continue; } /* raptor v2 terms are copied, not shared */ if(rs->object) { raptor_free_term(rs->object); rs->object = NULL; } switch(o->type) { case RASQAL_LITERAL_URI: rs->object = raptor_new_term_from_uri(query_results->world->raptor_world_ptr, o->value.uri); break; case RASQAL_LITERAL_BLANK: nodeid = rasqal_prefix_id(query_results->result_count, (unsigned char*)o->string); rasqal_free_literal(o); if(!nodeid) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_FATAL, &query->locator, "Could not prefix blank identifier"); rasqal_free_literal(s); rasqal_free_literal(p); return NULL; } o = rasqal_new_simple_literal(query_results->world, RASQAL_LITERAL_BLANK, nodeid); if(!o) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_FATAL, &query->locator, "Could not create a new subject blank literal"); rasqal_free_literal(s); rasqal_free_literal(p); return NULL; } rs->object = raptor_new_term_from_blank(query_results->world->raptor_world_ptr, nodeid); break; case RASQAL_LITERAL_STRING: rs->object = raptor_new_term_from_literal(query_results->world->raptor_world_ptr, o->string, o->datatype, (const unsigned char*)o->language); break; case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_XSD_STRING: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UDT: case RASQAL_LITERAL_INTEGER_SUBTYPE: /* QNames should be gone by the time expression eval happens * Everything else is removed by rasqal_literal_as_node() above. */ case RASQAL_LITERAL_UNKNOWN: default: rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_WARN, &query->locator, "Triple with unknown object skipped"); skipped = 1; break; } if(skipped) { rasqal_free_literal(s); rasqal_free_literal(p); if(o) rasqal_free_literal(o); continue; } /* dispose previous triple if any */ if(query_results->triple) { rasqal_free_triple(query_results->triple); query_results->triple = NULL; } /* for saving s, p, o for later disposal */ query_results->triple = rasqal_new_triple(s, p, o); /* got triple, return it */ break; } return rs; }
static void raptor_librdfa_generate_statement(rdftriple* triple, void* callback_data) { raptor_parser* parser = (raptor_parser*)callback_data; raptor_statement *s = &parser->statement; raptor_term *subject_term = NULL; raptor_term *predicate_term = NULL; raptor_uri *predicate_uri = NULL; raptor_term *object_term = NULL; if(!parser->emitted_default_graph) { raptor_parser_start_graph(parser, NULL, 0); parser->emitted_default_graph++; } if(!parser->statement_handler) goto cleanup; if(!triple->subject || !triple->predicate || !triple->object) { #ifdef RAPTOR_DEBUG RAPTOR_FATAL1("Triple has NULL parts\n"); #else rdfa_free_triple(triple); return; #endif } if(triple->predicate[0] == '_') { raptor_parser_warning(parser, "Ignoring RDFa triple with blank node predicate %s.", triple->predicate); rdfa_free_triple(triple); return; } if(triple->object_type == RDF_TYPE_NAMESPACE_PREFIX) { #ifdef RAPTOR_DEBUG RAPTOR_FATAL1("Triple has namespace object type\n"); #else rdfa_free_triple(triple); return; #endif } if((triple->subject[0] == '_') && (triple->subject[1] == ':')) { subject_term = raptor_new_term_from_blank(parser->world, (const unsigned char*)triple->subject + 2); } else { raptor_uri* subject_uri; subject_uri = raptor_new_uri(parser->world, (const unsigned char*)triple->subject); subject_term = raptor_new_term_from_uri(parser->world, subject_uri); raptor_free_uri(subject_uri); subject_uri = NULL; } s->subject = subject_term; predicate_uri = raptor_new_uri(parser->world, (const unsigned char*)triple->predicate); if(!predicate_uri) goto cleanup; predicate_term = raptor_new_term_from_uri(parser->world, predicate_uri); raptor_free_uri(predicate_uri); predicate_uri = NULL; s->predicate = predicate_term; if(triple->object_type == RDF_TYPE_IRI) { if((triple->object[0] == '_') && (triple->object[1] == ':')) { object_term = raptor_new_term_from_blank(parser->world, (const unsigned char*)triple->object + 2); } else { raptor_uri* object_uri; object_uri = raptor_new_uri(parser->world, (const unsigned char*)triple->object); if(!object_uri) goto cleanup; object_term = raptor_new_term_from_uri(parser->world, object_uri); raptor_free_uri(object_uri); } } else if(triple->object_type == RDF_TYPE_PLAIN_LITERAL) { object_term = raptor_new_term_from_literal(parser->world, (const unsigned char*)triple->object, NULL, (const unsigned char*)triple->language); } else if(triple->object_type == RDF_TYPE_XML_LITERAL) { raptor_uri* datatype_uri; datatype_uri = raptor_new_uri_from_counted_string(parser->world, (const unsigned char*)raptor_xml_literal_datatype_uri_string, raptor_xml_literal_datatype_uri_string_len); object_term = raptor_new_term_from_literal(parser->world, (const unsigned char*)triple->object, datatype_uri, NULL); raptor_free_uri(datatype_uri); } else if(triple->object_type == RDF_TYPE_TYPED_LITERAL) { raptor_uri *datatype_uri = NULL; const unsigned char* language = (const unsigned char*)triple->language; if(triple->datatype) { /* If datatype, no language allowed */ language = NULL; datatype_uri = raptor_new_uri(parser->world, (const unsigned char*)triple->datatype); if(!datatype_uri) goto cleanup; } object_term = raptor_new_term_from_literal(parser->world, (const unsigned char*)triple->object, datatype_uri, language); raptor_free_uri(datatype_uri); } else { raptor_log_error_formatted(parser->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Triple has unknown object term type %u", s->object->type); goto cleanup; } s->object = object_term; /* Generate statement */ (*parser->statement_handler)(parser->user_data, s); cleanup: rdfa_free_triple(triple); if(subject_term) raptor_free_term(subject_term); if(predicate_term) raptor_free_term(predicate_term); if(object_term) raptor_free_term(object_term); }
int main(int argc, char *argv[]) { raptor_world *world; const char *program = raptor_basename(argv[0]); int rc = 0; raptor_term* term1 = NULL; /* URI string 1 */ raptor_term* term2 = NULL; /* literal string1 */ raptor_term* term3 = NULL; /* blank node 1 */ raptor_term* term4 = NULL; /* URI string 2 */ raptor_term* term5 = NULL; /* URI string 1 again */ raptor_uri* uri1; unsigned char* uri_str; size_t uri_len; world = raptor_new_world(); if(!world || raptor_world_open(world)) exit(1); /* check a term for NULL URI fails */ term1 = raptor_new_term_from_uri(world, NULL); if(term1) { fprintf(stderr, "%s: raptor_new_uri(NULL) returned object rather than failing\n", program); rc = 1; goto tidy; } /* check a term for non-NULL URI succeeds */ uri1 = raptor_new_uri(world, uri_string1); if(!uri1) { fprintf(stderr, "%s: raptor_new_uri(%s) failed\n", program, uri_string1); rc = 1; goto tidy; } term1 = raptor_new_term_from_uri(world, uri1); if(!term1) { fprintf(stderr, "%s: raptor_new_term_from_uri_string(URI %s) failed\n", program, uri_string1); rc = 1; goto tidy; } raptor_free_uri(uri1); uri1 = NULL; if(term1->type != uri_string1_type) { fprintf(stderr, "%s: raptor term 1 is of type %d expected %d\n", program, term1->type, uri_string1_type); rc = 1; goto tidy; } /* returns a pointer to shared string */ uri_str = raptor_uri_as_counted_string(term1->value.uri, &uri_len); if(!uri_str) { fprintf(stderr, "%s: raptor_uri_as_counted_string term 1 failed\n", program); rc = 1; goto tidy; } if(uri_len != uri_string1_len) { fprintf(stderr, "%s: raptor term 1 URI is of length %d expected %d\n", program, (int)uri_len, (int)uri_string1_len); rc = 1; goto tidy; } /* check an empty literal is created from a NULL literal pointer succeeds */ term2 = raptor_new_term_from_counted_literal(world, NULL, 0, NULL, NULL, 0); if(!term2) { fprintf(stderr, "%s: raptor_new_term_from_counted_literal() with all NULLs failed\n", program); rc = 1; goto tidy; } raptor_free_term(term2); /* check an empty literal from an empty language literal pointer succeeds */ term2 = raptor_new_term_from_counted_literal(world, NULL, 0, NULL, (const unsigned char*)"", 0); if(!term2) { fprintf(stderr, "%s: raptor_new_term_from_counted_literal() with empty language failed\n", program); rc = 1; goto tidy; } raptor_free_term(term2); /* check a literal with language and datatype fails */ uri1 = raptor_new_uri(world, uri_string1); if(!uri1) { fprintf(stderr, "%s: raptor_new_uri(%s) failed\n", program, uri_string1); rc = 1; goto tidy; } term2 = raptor_new_term_from_counted_literal(world, literal_string1, literal_string1_len, uri1, language1, 0); raptor_free_uri(uri1); uri1 = NULL; if(term2) { fprintf(stderr, "%s: raptor_new_term_from_counted_literal() with language and datatype returned object rather than failing\n", program); rc = 1; goto tidy; } /* check a literal with no language and no datatype succeeds */ term2 = raptor_new_term_from_counted_literal(world, literal_string1, literal_string1_len, NULL, NULL, 0); if(!term2) { fprintf(stderr, "%s: raptor_new_term_from_counted_literal(%s) failed\n", program, literal_string1); rc = 1; goto tidy; } if(term2->type != literal_string1_type) { fprintf(stderr, "%s: raptor term 2 is of type %d expected %d\n", program, term2->type, literal_string1_type); rc = 1; goto tidy; } /* check a blank node term with NULL id generates a new identifier */ term3 = raptor_new_term_from_counted_blank(world, NULL, 0); if(!term3) { fprintf(stderr, "%s: raptor_new_term_from_counted_blank(NULL) failed\n", program); rc = 1; goto tidy; } if(term3->type != bnodeid1_type) { fprintf(stderr, "%s: raptor term 3 is of type %d expected %d\n", program, term3->type, bnodeid1_type); rc = 1; goto tidy; } raptor_free_term(term3); /* check a blank node term with an identifier succeeds */ term3 = raptor_new_term_from_counted_blank(world, bnodeid1, bnodeid1_len); if(!term3) { fprintf(stderr, "%s: raptor_new_term_from_counted_blank(%s) failed\n", program, bnodeid1); rc = 1; goto tidy; } if(term3->type != bnodeid1_type) { fprintf(stderr, "%s: raptor term 3 is of type %d expected %d\n", program, term3->type, bnodeid1_type); rc = 1; goto tidy; } /* check a different URI term succeeds */ term4 = raptor_new_term_from_counted_uri_string(world, uri_string2, uri_string2_len); if(!term4) { fprintf(stderr, "%s: raptor_new_term_from_counted_uri_string(URI %s) failed\n", program, uri_string2); rc = 1; goto tidy; } if(term4->type != uri_string2_type) { fprintf(stderr, "%s: raptor term 4 is of type %d expected %d\n", program, term4->type, uri_string2_type); rc = 1; goto tidy; } /* returns a pointer to shared string */ uri_str = raptor_uri_as_counted_string(term4->value.uri, &uri_len); if(!uri_str) { fprintf(stderr, "%s: raptor_uri_as_counted_string term 4 failed\n", program); rc = 1; goto tidy; } if(uri_len != uri_string2_len) { fprintf(stderr, "%s: raptor term 4 URI is of length %d expected %d\n", program, (int)uri_len, (int)uri_string2_len); rc = 1; goto tidy; } /* check the same URI term as term1 succeeds */ term5 = raptor_new_term_from_uri_string(world, uri_string1); if(!term5) { fprintf(stderr, "%s: raptor_new_term_from_uri_string(URI %s) failed\n", program, uri_string1); rc = 1; goto tidy; } if(raptor_term_equals(term1, term2)) { fprintf(stderr, "%s: raptor_term_equals (URI %s, literal %s) returned equal, expected not-equal\n", program, uri_string1, literal_string1); rc = 1; goto tidy; } if(raptor_term_equals(term1, term3)) { fprintf(stderr, "%s: raptor_term_equals (URI %s, bnode %s) returned equal, expected not-equal\n", program, uri_string1, bnodeid1); rc = 1; goto tidy; } if(raptor_term_equals(term1, term4)) { fprintf(stderr, "%s: raptor_term_equals (URI %s, URI %s) returned equal, expected not-equal\n", program, uri_string1, uri_string2); rc = 1; goto tidy; } if(!raptor_term_equals(term1, term5)) { fprintf(stderr, "%s: raptor_term_equals (URI %s, URI %s) returned not-equal, expected equal\n", program, uri_string1, uri_string1); rc = 1; goto tidy; } if(term1->value.uri != term5->value.uri) { fprintf(stderr, "%s: term1 and term5 URI objects returned not-equal pointers, expected equal\n", program); /* This is not necessarily a failure if the raptor_uri module has had * the URI interning disabled with * raptor_world_set_flag(world, RAPTOR_WORLD_FLAG_URI_INTERNING, 0) * however this test suite does not do that, so it is a failure here. */ rc = 1; goto tidy; } tidy: if(term1) raptor_free_term(term1); if(term2) raptor_free_term(term2); if(term3) raptor_free_term(term3); if(term4) raptor_free_term(term4); if(term5) raptor_free_term(term5); raptor_free_world(world); return rc; }
/* create a new serializer */ static int raptor_turtle_serialize_init(raptor_serializer* serializer, const char *name) { raptor_turtle_context* context = (raptor_turtle_context*)serializer->context; raptor_uri *rdf_type_uri; context->nstack = raptor_new_namespaces(serializer->world, 1); if(!context->nstack) return 1; context->rdf_nspace = raptor_new_namespace(context->nstack, (const unsigned char*)"rdf", (const unsigned char*)raptor_rdf_namespace_uri, 0); context->namespaces = raptor_new_sequence(NULL, NULL); context->subjects = raptor_new_avltree((raptor_data_compare_handler)raptor_abbrev_subject_compare, (raptor_data_free_handler)raptor_free_abbrev_subject, 0); context->blanks = raptor_new_avltree((raptor_data_compare_handler)raptor_abbrev_subject_compare, (raptor_data_free_handler)raptor_free_abbrev_subject, 0); context->nodes = raptor_new_avltree((raptor_data_compare_handler)raptor_abbrev_node_compare, (raptor_data_free_handler)raptor_free_abbrev_node, 0); rdf_type_uri = raptor_new_uri_for_rdf_concept(serializer->world, (const unsigned char*)"type"); if(rdf_type_uri) { raptor_term* uri_term; uri_term = raptor_new_term_from_uri(serializer->world, rdf_type_uri); raptor_free_uri(rdf_type_uri); context->rdf_type = raptor_new_abbrev_node(serializer->world, uri_term); raptor_free_term(uri_term); } else context->rdf_type = NULL; context->rdf_xml_literal_uri = raptor_new_uri(serializer->world, raptor_xml_literal_datatype_uri_string); context->rdf_first_uri = raptor_new_uri(serializer->world, (const unsigned char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#first"); context->rdf_rest_uri = raptor_new_uri(serializer->world, (const unsigned char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#rest"); context->rdf_nil_uri = raptor_new_uri(serializer->world, (const unsigned char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"); if(!context->rdf_nspace || !context->namespaces || !context->subjects || !context->blanks || !context->nodes || !context->rdf_xml_literal_uri || !context->rdf_first_uri || !context->rdf_rest_uri || !context->rdf_nil_uri || !context->rdf_type) { raptor_turtle_serialize_terminate(serializer); return 1; } /* Note: item 0 in the list is rdf:RDF's namespace */ if(raptor_sequence_push(context->namespaces, context->rdf_nspace)) { raptor_turtle_serialize_terminate(serializer); return 1; } return 0; }