/** * librdf_files_temporary_file_name: * * Create a temporary file name. * * @deprecated: Do not use this, it is unsafe. * * Return value: a new filename or NULL on failure. **/ char * librdf_files_temporary_file_name(void) { #if defined(HAVE_MKSTEMP) || defined(HAVE_MKTEMP) const char *tmp_dir; size_t length; char *name; static const char * const file_template="librdf_tmp_XXXXXX"; /* FIXME */ #ifdef HAVE_MKSTEMP int fd; #endif /* FIXME: unix dependencies */ tmp_dir=getenv("TMPDIR"); if(!tmp_dir) tmp_dir="/tmp"; length=strlen(tmp_dir) + strlen(file_template) + 2; /* 2: / sep and \/0 */ name=(char*)LIBRDF_MALLOC(cstring, length); if(!name) return NULL; /* FIXME: unix dependency - file/dir separator */ sprintf(name, "%s/%s", tmp_dir, file_template); #ifdef HAVE_MKSTEMP /* Proritise mkstemp() since GNU libc says: Never use mktemp(). */ fd=mkstemp(name); if(fd<0) { LIBRDF_FREE(cstring, name); return NULL; } close(fd); unlink(name); return name; #else return mktemp(name); #endif #else #ifdef HAVE_TMPNAM /* GNU libc says: Never use this function. Use mkstemp(3) instead. */ char *name; char *new_name; name=tmpnam(NULL); /* NULL ensures statically allocated */ new_name=(char*)LIBRDF_MALLOC(cstring, strlen(name)+1); if(!new_name) return NULL; strcpy(new_name, name); return name; #else /* not tmpnam(), mkstemp() or mktemp() */ HELP #endif #endif }
/** * librdf_new_uri_relative_to_base: * @base_uri: absolute base URI * @uri_string: relative URI string * * Constructor - create a new #librdf_uri object from a URI string relative to a base URI. * * An empty uri_string or NULL is equivalent to * librdf_new_uri_from_uri(base_uri) * * Return value: a new #librdf_uri object or NULL on failure **/ librdf_uri* librdf_new_uri_relative_to_base(librdf_uri* base_uri, const unsigned char *uri_string) { unsigned char *buffer; int buffer_length; librdf_uri* new_uri; librdf_world *world=base_uri->world; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(base_uri, librdf_uri, NULL); if(!uri_string) return NULL; /* If URI string is empty, just copy base URI */ if(!*uri_string) return librdf_new_uri_from_uri(base_uri); /* +2 is for \0 plus an extra 1 for adding any missing URI path '/' */ buffer_length=base_uri->string_length + strlen((const char*)uri_string) +2; buffer=(unsigned char*)LIBRDF_MALLOC(cstring, buffer_length); if(!buffer) return NULL; raptor_uri_resolve_uri_reference(base_uri->string, uri_string, buffer, buffer_length); new_uri=librdf_new_uri(world, buffer); LIBRDF_FREE(cstring, buffer); return new_uri; }
/** * librdf_new_uri_from_uri_local_name: * @old_uri: #librdf_uri object * @local_name: local name to append to URI * * Copy constructor - create a new librdf_uri object from an existing librdf_uri object and a local name. * * Return value: a new #librdf_uri object or NULL on failure **/ librdf_uri* librdf_new_uri_from_uri_local_name (librdf_uri* old_uri, const unsigned char *local_name) { int len; unsigned char *new_string; librdf_uri* new_uri; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(old_uri, librdf_uri, NULL); if(!old_uri) return NULL; len=old_uri->string_length + strlen((const char*)local_name) +1 ; /* +1 for \0 */ new_string=(unsigned char*)LIBRDF_MALLOC(cstring, len); if(!new_string) return NULL; strcpy((char*)new_string, (const char*)old_uri->string); strcat((char*)new_string, (const char*)local_name); new_uri=librdf_new_uri (old_uri->world, new_string); LIBRDF_FREE(cstring, new_string); return new_uri; }
/** * librdf_new_uri_from_uri_local_name: * @old_uri: #librdf_uri object * @local_name: local name to append to URI * * Copy constructor - create a new librdf_uri object from an existing librdf_uri object and a local name. * * Return value: a new #librdf_uri object or NULL on failure **/ librdf_uri* librdf_new_uri_from_uri_local_name (librdf_uri* old_uri, const unsigned char *local_name) { #ifdef LIBRDF_USE_RAPTOR_URI return raptor_new_uri_from_uri_local_name(raptor_uri_get_world(old_uri), old_uri, local_name); #else int len; unsigned char *new_string; librdf_uri* new_uri; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(old_uri, librdf_uri, NULL); if(!old_uri) return NULL; len=old_uri->string_length + strlen((const char*)local_name) +1 ; /* +1 for \0 */ new_string=(unsigned char*)LIBRDF_MALLOC(cstring, len); if(!new_string) return NULL; strcpy((char*)new_string, (const char*)old_uri->string); strcat((char*)new_string, (const char*)local_name); new_uri=librdf_new_uri (old_uri->world, new_string); LIBRDF_FREE(cstring, new_string); return new_uri; #endif /* !LIBRDF_USE_RAPTOR_URI */ }
static librdf_storage_trees_graph* librdf_storage_trees_graph_new(librdf_storage* storage, librdf_node* context_node) { librdf_storage_trees_instance* context=(librdf_storage_trees_instance*)storage->instance; librdf_storage_trees_graph* graph=(librdf_storage_trees_graph*)LIBRDF_MALLOC( librdf_storage_trees_graph, sizeof(librdf_storage_trees_graph)); #ifdef RDF_STORAGE_TREES_WITH_CONTEXTS graph->context=(context_node ? librdf_new_node_from_node(context_node) : NULL); #endif /* Always create SPO index */ graph->spo_tree=librdf_new_avltree(librdf_statement_compare_spo, librdf_storage_trees_avl_free); if(!graph->spo_tree) { LIBRDF_FREE(librdf_storage_trees_graph, graph); return NULL; } if(context->index_sop) graph->sop_tree=librdf_new_avltree(librdf_statement_compare_sop, NULL); else graph->sop_tree=NULL; if(context->index_ops) graph->ops_tree=librdf_new_avltree(librdf_statement_compare_ops, NULL); else graph->ops_tree=NULL; if(context->index_pso) graph->pso_tree=librdf_new_avltree(librdf_statement_compare_pso, NULL); else graph->pso_tree=NULL; return graph; }
/** * librdf_new_uri_normalised_to_base: * @uri_string: URI in string form * @source_uri: source URI to remove * @base_uri: base URI to add * * Constructor - create a new #librdf_uri object from a URI string stripped of the source URI, made relative to the base URI. * * Return value: a new #librdf_uri object or NULL on failure **/ librdf_uri* librdf_new_uri_normalised_to_base(const unsigned char *uri_string, librdf_uri* source_uri, librdf_uri* base_uri) { int uri_string_len; int len; unsigned char *new_uri_string; librdf_uri *new_uri; librdf_world *world=source_uri->world; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source_uri, librdf_uri, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(base_uri, librdf_uri, NULL); if(!uri_string) return NULL; /* empty URI - easy, just make from base_uri */ if(!*uri_string && base_uri) return librdf_new_uri_from_uri(base_uri); /* not a fragment, and no match - easy */ if(*uri_string != '#' && strncmp((const char*)uri_string, (const char*)source_uri->string, source_uri->string_length)) return librdf_new_uri(world, uri_string); /* darn - is a fragment or matches, is a prefix of the source URI */ /* move uri_string pointer to first non-matching char * unless a fragment, when all of the uri_string will * be appended */ if(*uri_string != '#') uri_string += source_uri->string_length; /* size of remaining bytes to copy from uri_string */ uri_string_len=strlen((const char*)uri_string); /* total bytes */ len=uri_string_len + 1 + base_uri->string_length; new_uri_string=(unsigned char*)LIBRDF_MALLOC(cstring, len); if(!new_uri_string) return NULL; strncpy((char*)new_uri_string, (const char*)base_uri->string, base_uri->string_length); /* strcpy not strncpy since I want a \0 on the end */ strcpy((char*)new_uri_string + base_uri->string_length, (const char*)uri_string); new_uri=librdf_new_uri(world, new_uri_string); LIBRDF_FREE(cstring, new_uri_string); /* always free this even on failure */ return new_uri; /* new URI or NULL from librdf_new_uri failure */ }
static int librdf_avltree_sprout(librdf_avltree* tree, librdf_avltree_node* parent, librdf_avltree_node** node_pp, void* p_data, int *rebalancing_p) { int cmp; LIBRDF_AVLTREE_DEBUG1("Enter\n"); /* If grounded, add the node here, set the rebalance flag and return */ if(!*node_pp) { LIBRDF_AVLTREE_DEBUG1("grounded. adding new node, setting rebalancing flag true\n"); *node_pp = (librdf_avltree_node*)LIBRDF_MALLOC(librdf_avltree_node, sizeof(**node_pp)); if(!*node_pp) return LIBRDF_AVLTREE_ENOMEM; (*node_pp)->parent = parent; (*node_pp)->left = NULL; (*node_pp)->right = NULL; (*node_pp)->balance = 0; (*node_pp)->data = p_data; *rebalancing_p = TRUE; tree->size++; return FALSE; } /* compare the data */ cmp = tree->compare_fn(p_data, (*node_pp)->data); if(cmp < 0) /* if LESS, prepare to move to the left. */ return librdf_avltree_sprout_left(tree, node_pp, p_data, rebalancing_p); else if(cmp > 0) /* if MORE, prepare to move to the right. */ return librdf_avltree_sprout_right(tree, node_pp, p_data, rebalancing_p); /* otherwise same key */ *rebalancing_p = FALSE; /* replace */ /*if(tree->free_fn) tree->free_fn((*node_pp)->data); (*node_pp)->data= p_data; return FALSE;*/ /* ignore */ tree->free_fn(p_data); return LIBRDF_AVLTREE_EXISTS; }
/* avltree constructor */ librdf_avltree* librdf_new_avltree(librdf_avltree_data_compare_function compare_fn, librdf_avltree_data_free_function free_fn/*, unsigned int flags*/) { librdf_avltree* tree; tree = (librdf_avltree*)LIBRDF_MALLOC(librdf_avltree, sizeof(*tree)); if(!tree) return NULL; tree->root = NULL; tree->compare_fn = compare_fn; tree->free_fn = free_fn; tree->size = 0; return tree; }
/* Internal */ unsigned char* librdf_world_get_genid(librdf_world* world) { int id, tmpid, counter, tmpcounter, pid, tmppid; int length; unsigned char *buffer; /* This is read-only and thread safe */ tmpid = (id = world->genid_base); #ifdef WITH_THREADS pthread_mutex_lock(world->mutex); #endif tmpcounter = (counter = world->genid_counter++); #ifdef WITH_THREADS pthread_mutex_unlock(world->mutex); #endif /* Add the process ID to the seed to differentiate between * simultaneously executed child processes. */ pid = (int) getpid(); if(!pid) pid = 1; tmppid = pid; /* min length 1 + "r" + min length 1 + "r" + min length 1 + "r" \0 */ length = 7; while(tmpid /= 10) length++; while(tmpcounter /= 10) length++; while(tmppid /= 10) length++; buffer = (unsigned char*)LIBRDF_MALLOC(cstring, length); if(!buffer) return NULL; sprintf((char*)buffer, "r%dr%dr%d", id, pid, counter); return buffer; }
/** * librdf_uri_to_counted_string: * @uri: #librdf_uri object * @len_p: pointer to location to store length * * Format the URI as a counted string. * * Note: this method allocates a new string since this is a _to_ method * and the caller must free the resulting memory. * * Return value: string representation of the URI or NULL on failure **/ unsigned char* librdf_uri_to_counted_string (librdf_uri* uri, size_t* len_p) { unsigned char *s; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(uri, librdf_uri, NULL); if(!uri) return NULL; if(len_p) *len_p=uri->string_length; s=(unsigned char*)LIBRDF_MALLOC(cstring, uri->string_length+1); if(!s) return NULL; strcpy((char*)s, (const char*)uri->string); return s; }
/* FIXME returns an alloced triple pointing to shared strings */ static rs_triple* librdf_storage_tstore_statement_as_rs_triple(librdf_statement *statement) { librdf_node *subject_node=statement->subject; librdf_node *predicate_node=statement->predicate; librdf_node *object_node=statement->object; rs_triple* triple=LIBRDF_MALLOC(rs_triple, sizeof(rs_triple)); if(subject_node) { if(librdf_node_is_blank(subject_node)) triple->subject=(char*)librdf_node_get_blank_identifier(subject_node); else triple->subject=(char*)librdf_uri_as_string(librdf_node_get_uri(subject_node)); } else triple->subject=NULL; if(predicate_node) triple->predicate=(char*)librdf_uri_as_string(librdf_node_get_uri(predicate_node)); else triple->predicate=NULL; /* Assumptions - FIXME */ triple->literal = 0; if(object_node) { if(librdf_node_is_literal(object_node)) { triple->object=(char*)librdf_node_get_literal_value(object_node); triple->literal = 1; } else if(librdf_node_is_blank(object_node)) { triple->object=(char*)librdf_node_get_blank_identifier(object_node); } else { triple->object=(char*)librdf_uri_as_string(librdf_node_get_uri(object_node)); } } else triple->object=NULL; return triple; }
/** * librdf_new_uri2: * @world: redland world object * @uri_string: URI in string form * @length: length of string * * Constructor - create a new #librdf_uri object from a counted URI string. * * A new URI is constructed from a copy of the string. If the string * is a NULL pointer or 0 length or empty (first byte is 0) then the * result is NULL. * * Return value: a new #librdf_uri object or NULL on failure **/ librdf_uri* librdf_new_uri2(librdf_world *world, const unsigned char *uri_string, size_t length) { #ifdef LIBRDF_USE_RAPTOR_URI return raptor_new_uri_from_counted_string(world->raptor_world_ptr, uri_string, length); #else librdf_uri* new_uri; unsigned char *new_string; librdf_hash_datum key, value; /* on stack - not allocated */ librdf_hash_datum *old_value; /* just to be safe */ memset(&key, 0, sizeof(key)); memset(&value, 0, sizeof(value)); librdf_world_open(world); if(!uri_string || !length || !*uri_string) return NULL; #ifdef WITH_THREADS pthread_mutex_lock(world->mutex); #endif key.data = (char*)uri_string; key.size = length; /* if existing URI found in hash, return it */ if((old_value = librdf_hash_get_one(world->uris_hash, &key))) { new_uri = *(librdf_uri**)old_value->data; #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG3("Found existing URI %s in hash with current usage %d\n", uri_string, new_uri->usage); #endif librdf_free_hash_datum(old_value); new_uri->usage++; #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 if(new_uri->usage > new_uri->max_usage) new_uri->max_usage = new_uri->usage; #endif goto unlock; } /* otherwise create a new one */ #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG2("Creating new URI %s in hash\n", uri_string); #endif new_uri = (librdf_uri*)LIBRDF_CALLOC(librdf_uri, 1, sizeof(librdf_uri)); if(!new_uri) goto unlock; new_uri->world = world; new_uri->string_length = length; new_string = (unsigned char*)LIBRDF_MALLOC(cstring, length+1); if(!new_string) { LIBRDF_FREE(librdf_uri, new_uri); new_uri = NULL; goto unlock; } strcpy((char*)new_string, (const char*)uri_string); new_uri->string = new_string; new_uri->usage = 1; #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 new_uri->max_usage = 1; #endif value.data = &new_uri; value.size = sizeof(librdf_uri*); /* store in hash: URI-string => (librdf_uri*) */ if(librdf_hash_put(world->uris_hash, &key, &value)) { LIBRDF_FREE(cstring, new_string); LIBRDF_FREE(librdf_uri, new_uri); new_uri = NULL; } unlock: #ifdef WITH_THREADS pthread_mutex_unlock(world->mutex); #endif return new_uri; #endif /* !LIBRDF_USE_RAPTOR_URI */ }
/** * librdf_hash_bdb_cursor_get - Retrieve a hash value for the given key * @context: BerkeleyDB hash cursor context * @key: pointer to key to use * @value: pointer to value to use * @flags: flags * * Return value: non 0 on failure **/ static int librdf_hash_bdb_cursor_get(void* context, librdf_hash_datum *key, librdf_hash_datum *value, unsigned int flags) { librdf_hash_bdb_cursor_context *cursor=(librdf_hash_bdb_cursor_context*)context; #ifdef HAVE_BDB_CURSOR DBC *bdb_cursor=cursor->cursor; #else /* For BDB V1 */ DB* db; #endif DBT bdb_key; DBT bdb_value; int ret; /* docs say you must zero DBT's before use */ memset(&bdb_key, 0, sizeof(DBT)); memset(&bdb_value, 0, sizeof(DBT)); /* Always initialise BDB version of key */ bdb_key.data = (char*)key->data; bdb_key.size = key->size; #ifdef DB_DBT_MALLOC /* BDB V2 or later? */ bdb_key.flags=DB_DBT_MALLOC; /* Return in malloc() allocated memory */ bdb_value.flags=DB_DBT_MALLOC; #endif #ifndef HAVE_BDB_CURSOR /* For BDB V1 */ db=cursor->hash->db; #endif switch(flags) { case LIBRDF_HASH_CURSOR_SET: #ifdef HAVE_BDB_CURSOR /* V2/V3 prototype: * int DBcursor->c_get(DBC *cursor, DBT *key, DBT *data, u_int32_t flags); */ ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value, DB_SET); #else /* V1 */ ret=db->seq(db, &bdb_key, &bdb_value, 0); #endif break; case LIBRDF_HASH_CURSOR_FIRST: #ifdef HAVE_BDB_CURSOR /* V2/V3 prototype: * int DBcursor->c_get(DBC *cursor, DBT *key, DBT *data, u_int32_t flags); */ ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value, DB_FIRST); #else /* V1 */ ret=db->seq(db, &bdb_key, &bdb_value, R_FIRST); #endif break; case LIBRDF_HASH_CURSOR_NEXT_VALUE: #ifdef HAVE_BDB_CURSOR /* V2/V3 */ ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value, DB_NEXT); #else /* V1 */ ret=db->seq(db, &bdb_key, &bdb_value, R_NEXT); #endif /* If succeeded and key has changed, end */ if(!ret && cursor->last_key && memcmp(cursor->last_key, bdb_key.data, bdb_key.size)) { /* always allocated by BDB using system malloc */ SYSTEM_FREE(bdb_key.data); SYSTEM_FREE(bdb_value.data); #ifdef DB_NOTFOUND /* V2 and V3 */ ret=DB_NOTFOUND; #else ret=1; #endif } break; case LIBRDF_HASH_CURSOR_NEXT: #ifdef HAVE_BDB_CURSOR #ifdef DB_NEXT_NODUP /* V3 */ /* Get next key, or next key/value (when value defined) */ ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value, (value) ? DB_NEXT : DB_NEXT_NODUP); #else /* V2 */ /* Must mess about finding next key - note this relies on * the bdb btree having the keys in sorted order */ while(1) { ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value, DB_NEXT); /* finish on error, want all values or no previous key */ if(ret || value || !cursor->last_key) break; /* else have previous key and want unique keys, so keep * going until the key changes */ if(memcmp(cursor->last_key, bdb_key.data, bdb_key.size)) break; /* always allocated by BDB using system malloc */ SYSTEM_FREE(bdb_key.data); SYSTEM_FREE(bdb_value.data); } #endif #else /* V1 */ ret=db->seq(db, &bdb_key, &bdb_value, R_NEXT); #endif break; default: LIBRDF_ERROR2(cursor->hash->hash->world, "Unknown hash method flag %d\n", flags); return 1; } /* Free previous key and values */ if(cursor->last_key) { LIBRDF_FREE(cstring, cursor->last_key); cursor->last_key=NULL; } if(cursor->last_value) { LIBRDF_FREE(cstring, cursor->last_value); cursor->last_value=NULL; } if(ret) { #ifdef DB_NOTFOUND /* V2 and V3 */ if(ret != DB_NOTFOUND) LIBRDF_DEBUG2("BDB cursor error - %d\n", ret); #endif key->data=NULL; return ret; } cursor->last_key = key->data = LIBRDF_MALLOC(cstring, bdb_key.size); if(!key->data) { /* always allocated by BDB using system malloc */ if(flags != LIBRDF_HASH_CURSOR_SET) SYSTEM_FREE(bdb_key.data); SYSTEM_FREE(bdb_value.data); return 1; } memcpy(key->data, bdb_key.data, bdb_key.size); key->size = bdb_key.size; if(value) { cursor->last_value = value->data = LIBRDF_MALLOC(cstring, bdb_value.size); if(!value->data) { /* always allocated by BDB using system malloc */ if(flags != LIBRDF_HASH_CURSOR_SET) SYSTEM_FREE(bdb_key.data); SYSTEM_FREE(bdb_value.data); return 1; } memcpy(value->data, bdb_value.data, bdb_value.size); value->size = bdb_value.size; } /* always allocated by BDB using system malloc */ if(flags != LIBRDF_HASH_CURSOR_SET) SYSTEM_FREE(bdb_key.data); SYSTEM_FREE(bdb_value.data); return 0; }
/** * librdf_new_sql_config: * @world: librdf_world * @storage_name: SQL storage name * @layout: SQL schema variant * @config_dir: directory for configuration files * @predicate_uri_strings: configuration predicate URIs to look for * * Constructor - Make a new SQL configuration for a layout from a file * * Uses SQL storage name @storage_name and with database schema * @layout to give a configuration that will contain an array of * string values in the #librdf_sql_config field values array. * * Return value: configuration or NULL on failure **/ librdf_sql_config* librdf_new_sql_config(librdf_world* world, const char* storage_name, const char* layout, const char* config_dir, const char** predicate_uri_strings) { raptor_parser* rdf_parser=NULL; unsigned char *uri_string=NULL; raptor_uri *base_uri; raptor_uri *uri; librdf_sql_config* config; size_t len; int i; librdf_world_open(world); config=(librdf_sql_config*)LIBRDF_MALLOC(librdf_sql_config, sizeof(librdf_sql_config)); len=strlen(config_dir) + 1 + strlen(storage_name) + 4 + 1; if(layout) len+= strlen(layout) + 1; config->filename=(char*)LIBRDF_MALLOC(cstring, len); if(layout) sprintf(config->filename, "%s/%s-%s.ttl", config_dir, storage_name, layout); else sprintf(config->filename, "%s/%s.ttl", config_dir, storage_name); config->predicate_uri_strings=predicate_uri_strings; for(i=0; config->predicate_uri_strings[i]; i++) ; config->predicates_count=i; config->values=(char**)LIBRDF_CALLOC(cstring, sizeof(char*), config->predicates_count); LIBRDF_DEBUG4("Attempting to open %s layout %s storage config file %s\n", storage_name, (layout ? layout: "(default)"), config->filename); if(access((const char*)config->filename, R_OK)) { librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, "Failed to open configuration file %s for storage %s layout %s - %s", config->filename, storage_name, (layout ? layout: "(default)"), strerror(errno)); librdf_free_sql_config(config); return NULL; } uri_string=raptor_uri_filename_to_uri_string(config->filename); uri=raptor_new_uri(uri_string); base_uri=raptor_uri_copy(uri); rdf_parser=raptor_new_parser("turtle"); raptor_set_statement_handler(rdf_parser, config, librdf_sql_config_store_triple); raptor_parse_file(rdf_parser, uri, base_uri); raptor_free_parser(rdf_parser); raptor_free_uri(base_uri); raptor_free_memory(uri_string); raptor_free_uri(uri); /* Check all values are given */ for(i=0; i < config->predicates_count; i++) { if(!config->values[i]) { librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, "Configuration %s missing for storage %s", config->predicate_uri_strings[i], storage_name); librdf_free_sql_config(config); return NULL; } } return config; }
/* functions implementing storage api */ static int librdf_storage_file_init(librdf_storage* storage, const char *name, librdf_hash* options) { char *name_copy; char *contexts; int rc = 1; int is_uri = !strcmp(storage->factory->name, "uri"); const char *format_name = (is_uri ? "guess" : "rdfxml"); librdf_storage_file_instance* context; context = (librdf_storage_file_instance*)LIBRDF_CALLOC(librdf_storage_file_instance, 1, sizeof(librdf_storage_file_instance)); if(!context) goto done; librdf_storage_set_instance(storage, context); /* Cannot save contexts in a file; pass everything else on */ contexts = librdf_hash_get_del(options, "contexts"); if(contexts) LIBRDF_FREE(cstring, contexts); context->format_name = librdf_hash_get_del(options, "format"); if(context->format_name) { /* for 'file' and 'uri' storage, check this is a valid parser * for 'file' storage, also check this is a valid serializer */ if(!librdf_parser_check_name(storage->world, context->format_name) || (!is_uri && !librdf_serializer_check_name(storage->world, context->format_name))) { librdf_log(storage->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_STORAGE, NULL, "Ignoring storage %s format option '%s' - using default format '%s'", storage->factory->name, context->format_name, format_name); LIBRDF_FREE(cstring, context->format_name); context->format_name = NULL; } if(context->format_name) format_name = context->format_name; } if(is_uri) context->uri = librdf_new_uri(storage->world, (const unsigned char*)name); else { context->name_len = strlen(name); name_copy = (char*)LIBRDF_MALLOC(cstring, context->name_len+1); if(!name_copy) goto done; strcpy(name_copy,name); context->name = name_copy; context->uri = librdf_new_uri_from_filename(storage->world, context->name); } context->storage = librdf_new_storage_with_options(storage->world, NULL, NULL, options); if(!context->storage) goto done; context->model = librdf_new_model(storage->world, context->storage, NULL); if(!context->model) goto done; if(is_uri || !access((const char*)context->name, F_OK)) { librdf_parser *parser; parser = librdf_new_parser(storage->world, format_name, NULL, NULL); if(!parser) { rc = 1; goto done; } librdf_parser_parse_into_model(parser, context->uri, NULL, context->model); librdf_free_parser(parser); } context->changed = 0; rc = 0; done: /* no more options, might as well free them now */ if(options) librdf_free_hash(options); return rc; }
static int librdf_storage_file_sync(librdf_storage *storage) { librdf_storage_file_instance* context=(librdf_storage_file_instance*)storage->instance; char *backup_name; char *new_name; librdf_serializer* serializer; FILE *fh; int rc=0; if(!context->changed) return 0; if(!context->name) { /* FIXME - URI cannot be written */ context->changed=0; return 0; } backup_name=NULL; if(!access((const char*)context->name, F_OK)) { /* name"~\0" */ backup_name=(char*)LIBRDF_MALLOC(cstring, context->name_len+2); if(!backup_name) return 1; strcpy(backup_name, (const char*)context->name); backup_name[context->name_len]='~'; backup_name[context->name_len+1]='\0'; if(rename(context->name, backup_name) < 0) { librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, "rename of '%s' to '%s' failed - %s", context->name, backup_name, strerror(errno)); LIBRDF_FREE(cstring, backup_name); return 1; } } /* name".new\0" */ new_name=(char*)LIBRDF_MALLOC(cstring, context->name_len+5); if(!new_name) return 1; strcpy(new_name, (const char*)context->name); strcpy(new_name+context->name_len, ".new"); serializer = librdf_new_serializer(storage->world, context->format_name, NULL, NULL); if(!serializer) { LIBRDF_FREE(cstring, new_name); if(backup_name) LIBRDF_FREE(cstring, backup_name); return 1; } fh=fopen(new_name, "w+"); if(!fh) { librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, "failed to open file '%s' for writing - %s", new_name, strerror(errno)); rc=1; } else { librdf_serializer_serialize_model_to_file_handle(serializer, fh, context->uri, context->model); fclose(fh); } librdf_free_serializer(serializer); if(fh && rename(new_name, context->name) < 0) { librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, "rename of '%s' to '%s' failed - %s (%d)", new_name, context->name, strerror(errno), errno); fh=NULL; rc=1; } LIBRDF_FREE(cstring, new_name); /* restore backup on failure (fh=NULL) */ if(!fh && backup_name && rename(backup_name, context->name) < 0) { librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, "rename of '%s' to '%s' failed - %s", backup_name, context->name, strerror(errno)); rc=1; } if(backup_name) LIBRDF_FREE(cstring, backup_name); context->changed=0; return rc; }
/** * librdf_serializer_register_factory: * @world: redland world object * @name: the name of the serializer * @label: the label of the serializer (optional) * @mime_type: MIME type of the syntax (optional) * @uri_string: URI of the syntax (optional) * @factory: function to be called to register the factor parameters * * Register a serializer factory . * **/ REDLAND_EXTERN_C void librdf_serializer_register_factory(librdf_world *world, const char *name, const char *label, const char *mime_type, const unsigned char *uri_string, void (*factory) (librdf_serializer_factory*)) { librdf_serializer_factory *serializer; librdf_world_open(world); #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG2("Received registration for serializer %s\n", name); #endif if(!world->serializers) { world->serializers = raptor_new_sequence((raptor_data_free_handler)librdf_free_serializer_factory, NULL); if(!world->serializers) goto oom; } serializer=(librdf_serializer_factory*)LIBRDF_CALLOC(librdf_serializer_factory, 1, sizeof(librdf_serializer_factory)); if(!serializer) goto oom; serializer->name=(char*)LIBRDF_MALLOC(cstring, strlen(name)+1); if(!serializer->name) goto oom_tidy; strcpy(serializer->name, name); if(label) { serializer->label=(char*)LIBRDF_MALLOC(cstring, strlen(label)+1); if(!serializer->label) goto oom_tidy; strcpy(serializer->label, label); } /* register mime type if any */ if(mime_type) { serializer->mime_type=(char*)LIBRDF_MALLOC(cstring, strlen(mime_type)+1); if(!serializer->mime_type) goto oom_tidy; strcpy(serializer->mime_type, mime_type); } /* register URI if any */ if(uri_string) { serializer->type_uri=librdf_new_uri(world, uri_string); if(!serializer->type_uri) goto oom_tidy; } if(raptor_sequence_push(world->serializers, serializer)) goto oom; /* Call the serializer registration function on the new object */ (*factory)(serializer); #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG3("%s has context size %d\n", name, serializer->context_length); #endif return; oom_tidy: librdf_free_serializer_factory(serializer); oom: LIBRDF_FATAL1(world, LIBRDF_FROM_SERIALIZER, "Out of memory"); }
int main(int argc, char *argv[]) { librdf_statement *statement, *statement2; int size, size2; const char *program=librdf_basename((const char*)argv[0]); char *s, *buffer; librdf_world *world; raptor_iostream *iostr; world=librdf_new_world(); librdf_world_open(world); iostr = raptor_new_iostream_to_file_handle(world->raptor_world_ptr, stdout); fprintf(stdout, "%s: Creating statement\n", program); statement=librdf_new_statement(world); fprintf(stdout, "%s: Empty statement: ", program); librdf_statement_write(statement, iostr); fputs("\n", stdout); librdf_statement_set_subject(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/net/dajobe/")); librdf_statement_set_predicate(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/dc/elements/1.1/#Creator")); librdf_statement_set_object(statement, librdf_new_node_from_literal(world, (const unsigned char*)"Dave Beckett", NULL, 0)); fprintf(stdout, "%s: Resulting statement: ", program); librdf_statement_write(statement, iostr); fputs("\n", stdout); size = librdf_statement_encode2(world, statement, NULL, 0); fprintf(stdout, "%s: Encoding statement requires %d bytes\n", program, size); buffer=(char*)LIBRDF_MALLOC(cstring, size); fprintf(stdout, "%s: Encoding statement in buffer\n", program); size2 = librdf_statement_encode2(world, statement, (unsigned char*)buffer, size); if(size2 != size) { fprintf(stdout, "%s: Encoding statement used %d bytes, expected it to use %d\n", program, size2, size); return(1); } fprintf(stdout, "%s: Creating new statement\n", program); statement2=librdf_new_statement(world); fprintf(stdout, "%s: Decoding statement from buffer\n", program); if(!librdf_statement_decode2(world, statement2, NULL, (unsigned char*)buffer, size)) { fprintf(stdout, "%s: Decoding statement failed\n", program); return(1); } LIBRDF_FREE(cstring, buffer); fprintf(stdout, "%s: New statement is: ", program); librdf_statement_write(statement, iostr); fputs("\n", stdout); fprintf(stdout, "%s: Freeing statements\n", program); librdf_free_statement(statement2); librdf_free_statement(statement); librdf_free_world(world); /* keep gcc -Wall happy */ return(0); }
/** * librdf_statement_to_string: * @statement: the statement * * Format the librdf_statement as a string. * * Formats the statement as a newly allocate string that must be freed by * the caller. * * Return value: the string or NULL on failure. **/ unsigned char * librdf_statement_to_string(librdf_statement *statement) { unsigned char *subject_string, *predicate_string, *object_string; unsigned char *s; int statement_string_len=0; const char *format; #define NULL_STRING_LENGTH 6 static const unsigned char * const null_string=(const unsigned char *)"(null)"; size_t len; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, NULL); if(statement->subject) { subject_string=librdf_node_to_counted_string(statement->subject, &len); if(!subject_string) return NULL; statement_string_len += len; } else { subject_string=(unsigned char*)null_string; statement_string_len += NULL_STRING_LENGTH; } if(statement->predicate) { predicate_string=librdf_node_to_counted_string(statement->predicate, &len); if(!predicate_string) { if(subject_string != null_string) LIBRDF_FREE(cstring, subject_string); return NULL; } statement_string_len += len; } else { predicate_string=(unsigned char*)null_string; statement_string_len += NULL_STRING_LENGTH; } if(statement->object) { object_string=librdf_node_to_counted_string(statement->object, &len); if(!object_string) { if(subject_string != null_string) LIBRDF_FREE(cstring, subject_string); if(predicate_string != null_string) LIBRDF_FREE(cstring, predicate_string); return NULL; } statement_string_len += len; } else { object_string=(unsigned char*)null_string; statement_string_len += NULL_STRING_LENGTH; } #define LIBRDF_STATEMENT_FORMAT_STRING_LITERAL "{%s, %s, \"%s\"}" #define LIBRDF_STATEMENT_FORMAT_RESOURCE_LITERAL "{%s, %s, %s}" statement_string_len += + 1 + /* "{" %s */ 2 + /* ", " %s */ 2 + /* ", " %s */ 1; /* "}" */ if(statement->object && librdf_node_get_type(statement->object) == LIBRDF_NODE_TYPE_LITERAL) { format=LIBRDF_STATEMENT_FORMAT_STRING_LITERAL; statement_string_len+=2; /* Extra "" around literal */ } else { format=LIBRDF_STATEMENT_FORMAT_RESOURCE_LITERAL; } s=(unsigned char*)LIBRDF_MALLOC(cstring, statement_string_len+1); if(s) sprintf((char*)s, format, subject_string, predicate_string, object_string); /* always free allocated intermediate strings */ if(subject_string != null_string) LIBRDF_FREE(cstring, subject_string); if(predicate_string != null_string) LIBRDF_FREE(cstring, predicate_string); if(object_string != null_string) LIBRDF_FREE(cstring, object_string); return s; }
/** * librdf_hash_bdb_open - Open and maybe create a BerkeleyDB hash * @context: BerkeleyDB hash context * @identifier: filename to use for BerkeleyDB file * @mode: file creation mode * @is_writable: is hash writable? * @is_new: is hash new? * @options: hash options (currently unused) * * Return value: non 0 on failure. **/ static int librdf_hash_bdb_open(void* context, char *identifier, int mode, int is_writable, int is_new, librdf_hash* options) { librdf_hash_bdb_context* bdb_context=(librdf_hash_bdb_context*)context; DB* bdb; char *file; int ret; int flags; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(identifier, cstring, 1); #ifdef HAVE_DB_OPEN DB_INFO bdb_info; #endif /* NOTE: If the options parameter is ever used here, the data must be * copied into a private part of the context so that the clone * method can access them */ bdb_context->mode=mode; bdb_context->is_writable=is_writable; bdb_context->is_new=is_new; file=(char*)LIBRDF_MALLOC(cstring, strlen(identifier)+4); if(!file) return 1; sprintf(file, "%s.db", identifier); #ifdef HAVE_DB_CREATE /* V3 prototype: * int db_create(DB **dbp, DB_ENV *dbenv, u_int32_t flags); */ if((ret=db_create(&bdb, NULL, 0))) { LIBRDF_DEBUG2("Failed to create BDB context - %d\n", ret); return 1; } #ifdef HAVE_BDB_SET_FLAGS if((ret=bdb->set_flags(bdb, DB_DUP))) { LIBRDF_DEBUG2("Failed to set BDB duplicate flag - %d\n", ret); return 1; } #endif /* V3 prototype: * int DB->open(DB *db, const char *file, const char *database, * DBTYPE type, u_int32_t flags, int mode); */ flags=is_writable ? DB_CREATE : DB_RDONLY; if(is_new) flags |= DB_TRUNCATE; #endif #if defined(HAVE_BDB_OPEN_6_ARGS) || defined(HAVE_BDB_OPEN_7_ARGS) #ifdef HAVE_BDB_OPEN_6_ARGS /* * int DB->open(DB *db, const char *file, * const char *database, DBTYPE type, u_int32_t flags, int mode); */ if((ret=bdb->open(bdb, file, NULL, DB_BTREE, flags, mode))) { librdf_error(bdb_context->hash->world, "BDB V4.0+ open of '%s' failed - %s", file, db_strerror(ret)); LIBRDF_FREE(cstring, file); return 1; } #else /* Must be HAVE_BDB_OPEN_7_ARGS */ /* * int DB->open(DB *db, DB_TXN *txnid, const char *file, * const char *database, DBTYPE type, u_int32_t flags, int mode); */ if((ret=bdb->open(bdb, NULL, file, NULL, DB_BTREE, flags, mode))) { librdf_error(bdb_context->hash->world, "BDB V4.1+ open of '%s' failed - %s", file, db_strerror(ret)); LIBRDF_FREE(cstring, file); return 1; } #endif #else #ifdef HAVE_DB_OPEN /* V2 prototype: * int db_open(const char *file, DBTYPE type, u_int32_t flags, * int mode, DB_ENV *dbenv, DB_INFO *dbinfo, DB **dbpp); */ memset(&bdb_info, 0, sizeof(DB_INFO)); bdb_info.flags=DB_DUP; flags=is_writable ? DB_CREATE : DB_RDONLY; if(is_new) flags |= DB_TRUNCATE; if((ret=db_open(file, DB_BTREE, flags, mode, NULL, &bdb_info, &bdb))) { librdf_error(bdb_context->hash->world, "BDB V2 open of '%s' failed - %d", file, ret); LIBRDF_FREE(cstring, file); return 1; } #else #ifdef HAVE_DBOPEN /* V1 prototype: const char *file, int flags, int mode, DBTYPE, const void *openinfo */ flags=is_writable ? O_RDWR|O_CREAT : O_RDONLY flags|=R_DUP; /* There does not seem to be a V1 flag for truncate */ if(is_new) remove(file); if((bdb=dbopen(file, flags, mode, DB_BTREE, NULL)) == 0) { librdf_error(bdb_context->hash->world, "BDB V1 open of '%s' failed - %d", file, ret); LIBRDF_FREE(cstring, file); return 1; } ret=0; #else #ifdef HAVE_DB_CREATE /* earlier */ #else ERROR - no idea how to use Berkeley DB #endif #endif #endif #endif bdb_context->db=bdb; bdb_context->file_name=file; return 0; }