Example #1
0
void
AtomWriter::forge_uri(const Raul::URI& uri)
{
	if (serd_uri_string_has_scheme((const uint8_t*)uri.c_str())) {
		lv2_atom_forge_urid(&_forge, _map.map_uri(uri.c_str()));
	} else {
		lv2_atom_forge_uri(&_forge, uri.c_str(), uri.length());
	}
}
Example #2
0
static SordNode*
sord_new_uri_counted(SordWorld* world, const uint8_t* str,
                     size_t n_bytes, size_t n_chars, bool copy)
{
	if (!serd_uri_string_has_scheme(str)) {
		error(world, SERD_ERR_BAD_ARG,
		      "attempt to map invalid URI `%s'\n", str);
		return NULL;  // Can't intern relative URIs
	}

	const SordNode key = {
		{ str, n_bytes, n_chars, 0, SERD_URI }, 1, { { 0 } }
	};

	return sord_insert_node(world, &key, copy);
}
Example #3
0
SordNode*
sord_new_relative_uri(SordWorld*     world,
                      const uint8_t* str,
                      const uint8_t* base_str)
{
	if (serd_uri_string_has_scheme(str)) {
		return sord_new_uri(world, str);
	}
	SerdURI  buri = SERD_URI_NULL;
	SerdNode base = serd_node_new_uri_from_string(base_str, NULL, &buri);
	SerdNode node = serd_node_new_uri_from_string(str, &buri, NULL);

	SordNode* ret = sord_new_uri_counted(
		world, node.buf, node.n_bytes, node.n_chars, false);

	serd_node_free(&base);
	return ret;
}
Example #4
0
SERD_API
const uint8_t*
serd_uri_to_path(const uint8_t* uri)
{
	const uint8_t* path = uri;
	if (!is_windows_path(uri) && serd_uri_string_has_scheme(uri)) {
		if (strncmp((const char*)uri, "file:", 5)) {
			fprintf(stderr, "Non-file URI `%s'\n", uri);
			return NULL;
		} else if (!strncmp((const char*)uri, "file://localhost/", 17)) {
			path = uri + 16;
		} else if (!strncmp((const char*)uri, "file://", 7)) {
			path = uri + 7;
		} else {
			fprintf(stderr, "Invalid file URI `%s'\n", uri);
			return NULL;
		}
		if (is_windows_path(path + 1)) {
			++path;  // Special case for terrible Windows file URIs
		}
	}
	return path;
}
Example #5
0
SERD_API
SerdStatus
serd_env_set_prefix(SerdEnv*        env,
                    const SerdNode* name,
                    const SerdNode* uri_node)
{
	if (!name->buf || uri_node->type != SERD_URI) {
		return SERD_ERR_BAD_ARG;
	} else if (serd_uri_string_has_scheme(uri_node->buf)) {
		// Set prefix to absolute URI
		serd_env_add(env, name, uri_node);
	} else {
		// Resolve relative URI and create a new node and URI for it
		SerdURI  abs_uri;
		SerdNode abs_uri_node = serd_node_new_uri_from_node(
			uri_node, &env->base_uri, &abs_uri);

		// Set prefix to resolved (absolute) URI
		serd_env_add(env, name, &abs_uri_node);
		serd_node_free(&abs_uri_node);
	}
	return SERD_SUCCESS;
}
Example #6
0
SordNode*
sord_node_from_serd_node(SordWorld*      world,
                         SerdEnv*        env,
                         const SerdNode* sn,
                         const SerdNode* datatype,
                         const SerdNode* lang)
{
	if (!sn) {
		return NULL;
	}

	SordNode* datatype_node = NULL;
	SordNode* ret           = NULL;
	switch (sn->type) {
	case SERD_NOTHING:
		return NULL;
	case SERD_LITERAL:
		datatype_node = sord_node_from_serd_node(
			world, env, datatype, NULL, NULL),
		ret = sord_new_literal_counted(
			world,
			datatype_node,
			sn->buf,
			sn->n_bytes,
			sn->n_chars,
			sn->flags,
			lang ? (const char*)lang->buf : NULL);
		sord_node_free(world, datatype_node);
		return ret;
	case SERD_URI:
		if (serd_uri_string_has_scheme(sn->buf)) {
			return sord_new_uri_counted(
				world, sn->buf, sn->n_bytes, sn->n_chars, true);
		} else {
			SerdURI base_uri;
			serd_env_get_base_uri(env, &base_uri);
			SerdURI  abs_uri;
			SerdNode abs_uri_node = serd_node_new_uri_from_node(
				sn, &base_uri, &abs_uri);
			ret = sord_new_uri_counted(world,
			                           abs_uri_node.buf,
			                           abs_uri_node.n_bytes,
			                           abs_uri_node.n_chars,
			                           true);
			serd_node_free(&abs_uri_node);
			return ret;
		}
	case SERD_CURIE: {
		SerdChunk uri_prefix;
		SerdChunk uri_suffix;
		if (serd_env_expand(env, sn, &uri_prefix, &uri_suffix)) {
			error(world, SERD_ERR_BAD_CURIE,
			      "failed to expand CURIE `%s'\n", sn->buf);
			return NULL;
		}
		const size_t uri_len = uri_prefix.len + uri_suffix.len;
		uint8_t*     buf     = (uint8_t*)malloc(uri_len + 1);
		memcpy(buf,                  uri_prefix.buf, uri_prefix.len);
		memcpy(buf + uri_prefix.len, uri_suffix.buf, uri_suffix.len);
		buf[uri_len] = '\0';
		ret = sord_new_uri_counted(
			world, buf, uri_prefix.len + uri_suffix.len,
			uri_prefix.len + uri_suffix.len, false);  // FIXME: UTF-8
		return ret;
	}
	case SERD_BLANK:
		return sord_new_blank_counted(world, sn->buf, sn->n_bytes, sn->n_chars);
	}
	return NULL;
}
Example #7
0
static bool
write_node(SerdWriter*        writer,
           const SerdNode*    node,
           const SerdNode*    datatype,
           const SerdNode*    lang,
           Field              field,
           SerdStatementFlags flags)
{
	SerdChunk uri_prefix;
	SerdChunk uri_suffix;
	bool      has_scheme;
	switch (node->type) {
	case SERD_BLANK:
		if (writer->syntax != SERD_NTRIPLES
		    && ((field == FIELD_SUBJECT && (flags & SERD_ANON_S_BEGIN))
		        || (field == FIELD_OBJECT && (flags & SERD_ANON_O_BEGIN)))) {
			++writer->indent;
			write_sep(writer, SEP_ANON_BEGIN);
		} else if (writer->syntax != SERD_NTRIPLES
		           && (field == FIELD_SUBJECT && (flags & SERD_LIST_S_BEGIN))) {
			assert(writer->list_depth == 0);
			copy_node(&writer->list_subj, node);
			++writer->list_depth;
			++writer->indent;
			write_sep(writer, SEP_LIST_BEGIN);
		} else if (writer->syntax != SERD_NTRIPLES
		           && (field == FIELD_OBJECT && (flags & SERD_LIST_O_BEGIN))) {
			++writer->indent;
			++writer->list_depth;
			write_sep(writer, SEP_LIST_BEGIN);
		} else if (writer->syntax != SERD_NTRIPLES
		           && ((field == FIELD_SUBJECT && (flags & SERD_EMPTY_S))
		               || (field == FIELD_OBJECT && (flags & SERD_EMPTY_O)))) {
			sink("[]", 2, writer);
		} else {
			sink("_:", 2, writer);
			if (writer->bprefix && !strncmp((const char*)node->buf,
			                                (const char*)writer->bprefix,
			                                writer->bprefix_len)) {
				sink(node->buf + writer->bprefix_len,
				     node->n_bytes - writer->bprefix_len,
				     writer);
			} else {
				sink(node->buf, node->n_bytes, writer);
			}
		}
		break;
	case SERD_CURIE:
		switch (writer->syntax) {
		case SERD_NTRIPLES:
			if (serd_env_expand(writer->env, node, &uri_prefix, &uri_suffix)) {
				w_err(writer, SERD_ERR_BAD_CURIE,
				      "undefined namespace prefix `%s'\n", node->buf);
				return false;
			}
			sink("<", 1, writer);
			write_uri(writer, uri_prefix.buf, uri_prefix.len);
			write_uri(writer, uri_suffix.buf, uri_suffix.len);
			sink(">", 1, writer);
			break;
		case SERD_TURTLE:
			write_lname(writer, node->buf, node->n_bytes);
		}
		break;
	case SERD_LITERAL:
		if (writer->syntax == SERD_TURTLE && datatype && datatype->buf) {
			const char* type_uri = (const char*)datatype->buf;
			if (!strncmp(type_uri, NS_XSD, sizeof(NS_XSD) - 1) && (
				    !strcmp(type_uri + sizeof(NS_XSD) - 1, "boolean") ||
				    !strcmp(type_uri + sizeof(NS_XSD) - 1, "integer"))) {
				sink(node->buf, node->n_bytes, writer);
				break;
			} else if (!strcmp(type_uri + sizeof(NS_XSD) - 1, "decimal") &&
			           strchr((const char*)node->buf, '.') &&
			           node->buf[node->n_bytes - 1] != '.') {
				/* xsd:decimal literals without trailing digits, e.g. "5.", can
				   not be written bare in Turtle.  We could add a 0 which is
				   prettier, but changes the text and breaks round tripping.
				*/
				sink(node->buf, node->n_bytes, writer);
				break;
			}
		}
		if (writer->syntax != SERD_NTRIPLES
		    && (node->flags & (SERD_HAS_NEWLINE|SERD_HAS_QUOTE))) {
			sink("\"\"\"", 3, writer);
			write_text(writer, WRITE_LONG_STRING, node->buf, node->n_bytes);
			sink("\"\"\"", 3, writer);
		} else {
			sink("\"", 1, writer);
			write_text(writer, WRITE_STRING, node->buf, node->n_bytes);
			sink("\"", 1, writer);
		}
		if (lang && lang->buf) {
			sink("@", 1, writer);
			sink(lang->buf, lang->n_bytes, writer);
		} else if (datatype && datatype->buf) {
			sink("^^", 2, writer);
			write_node(writer, datatype, NULL, NULL, FIELD_NONE, flags);
		}
		break;
	case SERD_URI:
		has_scheme = serd_uri_string_has_scheme(node->buf);
		if (field == FIELD_PREDICATE && (writer->syntax == SERD_TURTLE)
		    && !strcmp((const char*)node->buf, NS_RDF "type")) {
			sink("a", 1, writer);
			break;
		} else if ((writer->syntax == SERD_TURTLE)
		           && !strcmp((const char*)node->buf, NS_RDF "nil")) {
			sink("()", 2, writer);
			break;
		} else if (has_scheme && (writer->style & SERD_STYLE_CURIED)) {
			SerdNode  prefix;
			SerdChunk suffix;
			if (serd_env_qualify(writer->env, node, &prefix, &suffix)) {
				write_uri(writer, prefix.buf, prefix.n_bytes);
				sink(":", 1, writer);
				write_uri(writer, suffix.buf, suffix.len);
				break;
			}
		}
		sink("<", 1, writer);
		if (writer->style & SERD_STYLE_RESOLVED) {
			SerdURI in_base_uri, uri, abs_uri;
			serd_env_get_base_uri(writer->env, &in_base_uri);
			serd_uri_parse(node->buf, &uri);
			serd_uri_resolve(&uri, &in_base_uri, &abs_uri);
			bool rooted = uri_is_under(&writer->base_uri, &writer->root_uri);
			SerdURI* root = rooted ? &writer->root_uri : & writer->base_uri;
			if (!uri_is_under(&abs_uri, root) ||
			    writer->syntax == SERD_NTRIPLES) {
				serd_uri_serialise(&abs_uri, uri_sink, writer);
			} else {
				serd_uri_serialise_relative(
					&uri, &writer->base_uri, root, uri_sink, writer);
			}
		} else {
			write_uri(writer, node->buf, node->n_bytes);
		}
		sink(">", 1, writer);
	default:
		break;
	}
	writer->last_sep = SEP_NONE;
	return true;
}
Example #8
0
static bool
write_node(SerdWriter*        writer,
           const SerdNode*    node,
           const SerdNode*    datatype,
           const SerdNode*    lang,
           Field              field,
           SerdStatementFlags flags)
{
	SerdChunk uri_prefix;
	SerdChunk uri_suffix;
	switch (node->type) {
	case SERD_NOTHING:
		return false;
	case SERD_BLANK:
		if (writer->syntax != SERD_NTRIPLES
		    && ((field == FIELD_SUBJECT && (flags & SERD_ANON_S_BEGIN))
		        || (field == FIELD_OBJECT && (flags & SERD_ANON_O_BEGIN)))) {
			++writer->indent;
			serd_writer_write_delim(writer, '[');
		} else if (writer->syntax != SERD_NTRIPLES
		    && ((field == FIELD_SUBJECT && (flags & SERD_EMPTY_S))
		        || (field == FIELD_OBJECT && (flags & SERD_EMPTY_O)))) {
			writer->sink("[]", 2, writer->stream);
		} else {
			writer->sink("_:", 2, writer->stream);
			if (writer->bprefix && !strncmp((const char*)node->buf,
			                                (const char*)writer->bprefix,
			                                writer->bprefix_len)) {
				writer->sink(node->buf + writer->bprefix_len,
				             node->n_bytes - writer->bprefix_len,
				             writer->stream);
			} else {
				writer->sink(node->buf, node->n_bytes, writer->stream);
			}
		}
		break;
	case SERD_CURIE:
		switch (writer->syntax) {
		case SERD_NTRIPLES:
			if (serd_env_expand(writer->env, node, &uri_prefix, &uri_suffix)) {
				fprintf(stderr, "Undefined namespace prefix `%s'\n", node->buf);
				return false;
			}
			writer->sink("<", 1, writer->stream);
			write_text(writer, WRITE_URI, uri_prefix.buf, uri_prefix.len, '>');
			write_text(writer, WRITE_URI, uri_suffix.buf, uri_suffix.len, '>');
			writer->sink(">", 1, writer->stream);
			break;
		case SERD_TURTLE:
			writer->sink(node->buf, node->n_bytes, writer->stream);
		}
		break;
	case SERD_LITERAL:
		if (writer->syntax == SERD_TURTLE && datatype && datatype->buf) {
			// TODO: compare against NS_XSD prefix once
			if (!strcmp((const char*)datatype->buf,    NS_XSD "boolean")
			    || !strcmp((const char*)datatype->buf, NS_XSD "decimal")
			    || !strcmp((const char*)datatype->buf, NS_XSD "integer")) {
				writer->sink(node->buf, node->n_bytes, writer->stream);
				break;
			}
		}
		if (writer->syntax != SERD_NTRIPLES
		    && ((node->flags & SERD_HAS_NEWLINE)
		        || (node->flags & SERD_HAS_QUOTE))) {
			writer->sink("\"\"\"", 3, writer->stream);
			write_text(writer, WRITE_LONG_STRING,
			           node->buf, node->n_bytes, '\0');
			writer->sink("\"\"\"", 3, writer->stream);
		} else {
			writer->sink("\"", 1, writer->stream);
			write_text(writer, WRITE_STRING, node->buf, node->n_bytes, '"');
			writer->sink("\"", 1, writer->stream);
		}
		if (lang && lang->buf) {
			writer->sink("@", 1, writer->stream);
			writer->sink(lang->buf, lang->n_bytes, writer->stream);
		} else if (datatype && datatype->buf) {
			writer->sink("^^", 2, writer->stream);
			write_node(writer, datatype, NULL, NULL, FIELD_NONE, flags);
		}
		break;
	case SERD_URI:
		if ((writer->syntax == SERD_TURTLE)
		    && !strcmp((const char*)node->buf, NS_RDF "type")) {
			writer->sink("a", 1, writer->stream);
			return true;
		} else if ((writer->style & SERD_STYLE_CURIED)
		           && serd_uri_string_has_scheme(node->buf)) {
			SerdNode  prefix;
			SerdChunk suffix;
			if (serd_env_qualify(writer->env, node, &prefix, &suffix)) {
				write_text(writer, WRITE_URI, prefix.buf, prefix.n_bytes, '>');
				writer->sink(":", 1, writer->stream);
				write_text(writer, WRITE_URI, suffix.buf, suffix.len, '>');
				return true;
			}
		} else if ((writer->style & SERD_STYLE_RESOLVED)
		           && !serd_uri_string_has_scheme(node->buf)) {
			SerdURI uri;
			if (!serd_uri_parse(node->buf, &uri)) {
				SerdURI abs_uri;
				serd_uri_resolve(&uri, &writer->base_uri, &abs_uri);
				writer->sink("<", 1, writer->stream);
				serd_uri_serialise(&abs_uri, writer->sink, writer->stream);
				writer->sink(">", 1, writer->stream);
				return true;
			}
		}
		writer->sink("<", 1, writer->stream);
		write_text(writer, WRITE_URI, node->buf, node->n_bytes, '>');
		writer->sink(">", 1, writer->stream);
		return true;
	}
	return true;
}