Example #1
0
    void DeckOutput::write( const T& value ) {
        if (default_count > 0) {
            write_sep( );

            os << default_count << "*";
            default_count = 0;
            row_count++;
        }

        write_sep( );
        write_value( value );
        row_count++;
    }
Example #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) || 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;
}
Example #3
0
static void
write_pred(SerdWriter* writer, SerdStatementFlags flags, const SerdNode* pred)
{
	write_node(writer, pred, NULL, NULL, FIELD_PREDICATE, flags);
	write_sep(writer, SEP_P_O);
	copy_node(&writer->context.predicate, pred);
}
Example #4
0
static bool
write_list_obj(SerdWriter*        writer,
               SerdStatementFlags flags,
               const SerdNode*    predicate,
               const SerdNode*    object,
               const SerdNode*    datatype,
               const SerdNode*    lang)
{
	if (!strcmp((const char*)object->buf, NS_RDF "nil")) {
		--writer->indent;
		write_sep(writer, SEP_LIST_END);
		return true;
	} else if (!strcmp((const char*)predicate->buf, NS_RDF "first")) {
		write_sep(writer, SEP_LIST_SEP);
		write_node(writer, object, datatype, lang, FIELD_OBJECT, flags);
	}
	return false;
}
Example #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*    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;
}
Example #6
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;
}