Beispiel #1
0
SERD_API
SerdStatus
serd_writer_end_anon(SerdWriter*     writer,
                     const SerdNode* node)
{
	if (writer->syntax == SERD_NTRIPLES) {
		return SERD_SUCCESS;
	}
	if (serd_stack_is_empty(&writer->anon_stack) || writer->indent == 0) {
		w_err(writer, SERD_ERR_UNKNOWN,
		      "unexpected end of anonymous node\n");
		return SERD_ERR_UNKNOWN;
	}
	--writer->indent;
	write_sep(writer, SEP_ANON_END);
	reset_context(writer, true);
	writer->context = *anon_stack_top(writer);
	serd_stack_pop(&writer->anon_stack, sizeof(WriteContext));
	const bool is_subject = serd_node_equals(node, &writer->context.subject);
	if (is_subject) {
		copy_node(&writer->context.subject, node);
		writer->context.predicate.type = SERD_NOTHING;
	}
	return SERD_SUCCESS;
}
Beispiel #2
0
SERD_API
SerdStatus
serd_writer_end_anon(SerdWriter*     writer,
                     const SerdNode* node)
{
	if (writer->syntax == SERD_NTRIPLES) {
		return SERD_SUCCESS;
	}
	if (serd_stack_is_empty(&writer->anon_stack)) {
		fprintf(stderr, "Unexpected end of anonymous node\n");
		return SERD_ERR_UNKNOWN;
	}
	assert(writer->indent > 0);
	--writer->indent;
	serd_writer_write_delim(writer, '\n');
	writer->sink("]", 1, writer->stream);
	reset_context(writer);
	writer->context = *anon_stack_top(writer);
	serd_stack_pop(&writer->anon_stack, sizeof(WriteContext));
	const bool is_subject = serd_node_equals(node, &writer->context.subject);
	if (is_subject) {
		serd_node_free(&writer->context.predicate);
		writer->context.subject   = serd_node_copy(node);
		writer->context.predicate = SERD_NODE_NULL;
	}
	return SERD_SUCCESS;
}
Beispiel #3
0
static inline WriteContext*
anon_stack_top(SerdWriter* writer)
{
	assert(!serd_stack_is_empty(&writer->anon_stack));
	return (WriteContext*)(writer->anon_stack.buf
	                       + writer->anon_stack.size - sizeof(WriteContext));
}
Beispiel #4
0
SERD_API
SerdStatus
serd_writer_write_statement(SerdWriter*        writer,
                            SerdStatementFlags flags,
                            const SerdNode*    graph,
                            const SerdNode*    subject,
                            const SerdNode*    predicate,
                            const SerdNode*    object,
                            const SerdNode*    datatype,
                            const SerdNode*    lang)
{
	if (!subject || !predicate || !object
	    || !subject->buf || !predicate->buf || !object->buf
	    || !is_resource(subject) || !is_resource(predicate)) {
		return SERD_ERR_BAD_ARG;
	}

#define TRY(write_result) \
	if (!write_result) { \
		return SERD_ERR_UNKNOWN; \
	}

	switch (writer->syntax) {
	case SERD_NTRIPLES:
		TRY(write_node(writer, subject, NULL, NULL, FIELD_SUBJECT, flags));
		sink(" ", 1, writer);
		TRY(write_node(writer, predicate, NULL, NULL, FIELD_PREDICATE, flags));
		sink(" ", 1, writer);
		TRY(write_node(writer, object, datatype, lang, FIELD_OBJECT, flags));
		sink(" .\n", 3, writer);
		return SERD_SUCCESS;
	default:
		break;
	}

	if ((flags & SERD_LIST_CONT)) {
		if (write_list_obj(writer, flags, predicate, object, datatype, lang)) {
			// Reached end of list
			if (--writer->list_depth == 0 && writer->list_subj.type) {
				reset_context(writer, true);
				writer->context.subject = writer->list_subj;
				writer->list_subj       = SERD_NODE_NULL;
			}
			return SERD_SUCCESS;
		}
	} else if (serd_node_equals(subject, &writer->context.subject)) {
		if (serd_node_equals(predicate, &writer->context.predicate)) {
			// Abbreviate S P
			if (!(flags & SERD_ANON_O_BEGIN)) {
				++writer->indent;
			}
			write_sep(writer, SEP_END_O);
			write_node(writer, object, datatype, lang, FIELD_OBJECT, flags);
			if (!(flags & SERD_ANON_O_BEGIN)) {
				--writer->indent;
			}
		} else {
			// Abbreviate S
			Sep sep = writer->context.predicate.type ? SEP_END_P : SEP_S_P;
			write_sep(writer, sep);
			write_pred(writer, flags, predicate);
			write_node(writer, object, datatype, lang, FIELD_OBJECT, flags);
		}
	} else {
		// No abbreviation
		if (writer->context.subject.type) {
			assert(writer->indent > 0);
			--writer->indent;
			if (serd_stack_is_empty(&writer->anon_stack)) {
				write_sep(writer, SEP_END_S);
			}
		} else if (!writer->empty) {
			write_sep(writer, SEP_S_P);
		}

		if (!(flags & SERD_ANON_CONT)) {
			write_node(writer, subject, NULL, NULL, FIELD_SUBJECT, flags);
			++writer->indent;
			write_sep(writer, SEP_S_P);
		} else {
			++writer->indent;
		}

		reset_context(writer, true);
		copy_node(&writer->context.subject, subject);

		if (!(flags & SERD_LIST_S_BEGIN)) {
			write_pred(writer, flags, predicate);
		}

		write_node(writer, object, datatype, lang, FIELD_OBJECT, flags);
	}

	if (flags & (SERD_ANON_S_BEGIN|SERD_ANON_O_BEGIN)) {
		WriteContext* ctx = (WriteContext*)serd_stack_push(
			&writer->anon_stack, sizeof(WriteContext));
		*ctx = writer->context;
		WriteContext new_context = {
			serd_node_copy(graph), serd_node_copy(subject), SERD_NODE_NULL };
		if ((flags & SERD_ANON_S_BEGIN)) {
			new_context.predicate = serd_node_copy(predicate);
		}
		writer->context = new_context;
	} else {
		copy_node(&writer->context.graph, graph);
		copy_node(&writer->context.subject, subject);
		copy_node(&writer->context.predicate, predicate);
	}

	return SERD_SUCCESS;
}
Beispiel #5
0
SERD_API
SerdStatus
serd_writer_write_statement(SerdWriter*        writer,
                            SerdStatementFlags flags,
                            const SerdNode*    graph,
                            const SerdNode*    subject,
                            const SerdNode*    predicate,
                            const SerdNode*    object,
                            const SerdNode*    object_datatype,
                            const SerdNode*    object_lang)
{
	assert(subject && predicate && object);
	switch (writer->syntax) {
	case SERD_NTRIPLES:
		write_node(writer, subject, NULL, NULL, FIELD_SUBJECT, flags);
		writer->sink(" ", 1, writer->stream);
		write_node(writer, predicate, NULL, NULL, FIELD_PREDICATE, flags);
		writer->sink(" ", 1, writer->stream);
		if (!write_node(writer, object, object_datatype, object_lang,
		                FIELD_OBJECT, flags)) {
			return SERD_ERR_UNKNOWN;
		}
		writer->sink(" .\n", 3, writer->stream);
		return SERD_SUCCESS;
	case SERD_TURTLE:
		break;
	}
	if (serd_node_equals(subject, &writer->context.subject)) {
		if (serd_node_equals(predicate, &writer->context.predicate)) {
			// Abbreviate S P
			if ((flags & SERD_ANON_O_BEGIN)) {
				writer->sink(" , ", 3, writer->stream);  // ] , [
			} else {
				++writer->indent;
				serd_writer_write_delim(writer, ',');
			}
			write_node(writer, object, object_datatype, object_lang,
			           FIELD_OBJECT, flags);
			if (!(flags & SERD_ANON_O_BEGIN)) {
				--writer->indent;
			}
		} else {
			// Abbreviate S
			if (writer->context.predicate.buf) {
				serd_writer_write_delim(writer, ';');
			} else {
				serd_writer_write_delim(writer, '\n');
			}
			write_node(writer, predicate, NULL, NULL, FIELD_PREDICATE, flags);
			if (writer->context.predicate.buf)
				serd_node_free(&writer->context.predicate);
			writer->context.predicate = serd_node_copy(predicate);
			writer->sink(" ", 1, writer->stream);
			write_node(writer, object, object_datatype, object_lang,
			           FIELD_OBJECT, flags);
		}
	} else {
		if (writer->context.subject.buf) {
			if (writer->indent > 0) {
				--writer->indent;
			}
			if (serd_stack_is_empty(&writer->anon_stack)) {
				serd_writer_write_delim(writer, '.');
				serd_writer_write_delim(writer, '\n');
			}
		} else if (!writer->empty) {
			serd_writer_write_delim(writer, '\n');
		}

		if (!(flags & SERD_ANON_CONT)) {
			write_node(writer, subject, NULL, NULL, FIELD_SUBJECT, flags);
			++writer->indent;
			if (!(flags & SERD_ANON_S_BEGIN)) {
				serd_writer_write_delim(writer, '\n');
			}
		} else {
			++writer->indent;
		}

		reset_context(writer);
		writer->context.subject   = serd_node_copy(subject);
		writer->context.predicate = SERD_NODE_NULL;

		write_node(writer, predicate, NULL, NULL, FIELD_PREDICATE, flags);
		writer->context.predicate = serd_node_copy(predicate);
		writer->sink(" ", 1, writer->stream);

		write_node(writer, object, object_datatype, object_lang,
		           FIELD_OBJECT, flags);
	}

	if (writer->syntax != SERD_NTRIPLES
	    && ((flags & SERD_ANON_S_BEGIN) || (flags & SERD_ANON_O_BEGIN))) {
		WriteContext* ctx = (WriteContext*)serd_stack_push(
			&writer->anon_stack, sizeof(WriteContext));
		*ctx = writer->context;
		writer->context = WRITE_CONTEXT_NULL;  // Prevent deletion...
	}

	const WriteContext new_context = { serd_node_copy(graph),
	                                   serd_node_copy(subject),
	                                   serd_node_copy(predicate) };
	reset_context(writer);  // ... here
	writer->context = new_context;
	return SERD_SUCCESS;
}