Example #1
0
bool
SocketWriter::write(const LV2_Atom* msg)
{
	sratom_write(_sratom, &_map.urid_unmap_feature()->urid_unmap, 0,
	             NULL, NULL, msg->type, msg->size, LV2_ATOM_BODY_CONST(msg));
	serd_writer_finish(_writer);
	return true;
}
Example #2
0
SRATOM_API
int
sratom_write(Sratom*         sratom,
             LV2_URID_Unmap* unmap,
             uint32_t        flags,
             const SerdNode* subject,
             const SerdNode* predicate,
             uint32_t        type_urid,
             uint32_t        size,
             const void*     body)
{
	const char* const type        = unmap->unmap(unmap->handle, type_urid);
	uint8_t           idbuf[12]   = "b0000000000";
	SerdNode          id          = serd_node_from_string(SERD_BLANK, idbuf);
	uint8_t           nodebuf[12] = "b0000000000";
	SerdNode          node        = serd_node_from_string(SERD_BLANK, nodebuf);
	SerdNode          object      = SERD_NODE_NULL;
	SerdNode          datatype    = SERD_NODE_NULL;
	SerdNode          language    = SERD_NODE_NULL;
	bool              new_node    = false;
	if (type_urid == 0 && size == 0) {
		object = serd_node_from_string(SERD_URI, USTR(NS_RDF "nil"));
	} else if (type_urid == sratom->forge.String) {
		object = serd_node_from_string(SERD_LITERAL, (const uint8_t*)body);
	} else if (type_urid == sratom->forge.Chunk) {
		datatype = serd_node_from_string(SERD_URI, NS_XSD "base64Binary");
		object   = serd_node_new_blob(body, size, true);
		new_node = true;
	} else if (type_urid == sratom->forge.Literal) {
		const LV2_Atom_Literal_Body* lit = (const LV2_Atom_Literal_Body*)body;
		const uint8_t*         str = USTR(lit + 1);
		object = serd_node_from_string(SERD_LITERAL, str);
		if (lit->datatype) {
			datatype = serd_node_from_string(
				SERD_URI, USTR(unmap->unmap(unmap->handle, lit->datatype)));
		} else if (lit->lang) {
			const char*  lang       = unmap->unmap(unmap->handle, lit->lang);
			const char*  prefix     = "http://lexvo.org/id/iso639-3/";
			const size_t prefix_len = strlen(prefix);
			if (lang && !strncmp(lang, prefix, prefix_len)) {
				language = serd_node_from_string(
					SERD_LITERAL, USTR(lang + prefix_len));
			} else {
				fprintf(stderr, "Unknown language URID %d\n", lit->lang);
			}
		}
	} else if (type_urid == sratom->forge.URID) {
		const uint32_t urid = *(const uint32_t*)body;
		const uint8_t* str  = USTR(unmap->unmap(unmap->handle, urid));
		object = serd_node_from_string(SERD_URI, str);
	} else if (type_urid == sratom->forge.Path) {
		const uint8_t* str = USTR(body);
		if (path_is_absolute((const char*)str)) {
			new_node = true;
			object   = serd_node_new_file_uri(str, NULL, NULL, false);
		} else {
			SerdURI base_uri = SERD_URI_NULL;
			if (!sratom->base_uri.buf ||
			    strncmp((const char*)sratom->base_uri.buf, "file://", 7)) {
				fprintf(stderr, "warning: Relative path but base is not a file URI.\n");
				fprintf(stderr, "warning: Writing ambiguous atom:Path literal.\n");
				object   = serd_node_from_string(SERD_LITERAL, str);
				datatype = serd_node_from_string(SERD_URI, USTR(LV2_ATOM__Path));
			} else {
				if (sratom->base_uri.buf) {
					serd_uri_parse(sratom->base_uri.buf, &base_uri);
				}
				new_node = true;
				SerdNode rel = serd_node_new_file_uri(str, NULL, NULL, false);
				object = serd_node_new_uri_from_node(&rel, &base_uri, NULL);
				serd_node_free(&rel);
			}
		}
	} else if (type_urid == sratom->forge.URI) {
		const uint8_t* str = USTR(body);
		object = serd_node_from_string(SERD_URI, str);
	} else if (type_urid == sratom->forge.Int) {
		new_node = true;
		object   = serd_node_new_integer(*(const int32_t*)body);
		datatype = serd_node_from_string(SERD_URI, (sratom->pretty_numbers)
		                                 ? NS_XSD "integer" : NS_XSD "int");
	} else if (type_urid == sratom->forge.Long) {
		new_node = true;
		object   = serd_node_new_integer(*(const int64_t*)body);
		datatype = serd_node_from_string(SERD_URI, (sratom->pretty_numbers)
		                                 ? NS_XSD "integer" : NS_XSD "long");
	} else if (type_urid == sratom->forge.Float) {
		new_node = true;
		object   = serd_node_new_decimal(*(const float*)body, 8);
		datatype = serd_node_from_string(SERD_URI, (sratom->pretty_numbers)
		                                 ? NS_XSD "decimal" : NS_XSD "float");
	} else if (type_urid == sratom->forge.Double) {
		new_node = true;
		object   = serd_node_new_decimal(*(const double*)body, 16);
		datatype = serd_node_from_string(SERD_URI, (sratom->pretty_numbers)
		                                 ? NS_XSD "decimal" : NS_XSD "double");
	} else if (type_urid == sratom->forge.Bool) {
		const int32_t val = *(const int32_t*)body;
		datatype = serd_node_from_string(SERD_URI, NS_XSD "boolean");
		object   = serd_node_from_string(SERD_LITERAL,
		                                 USTR(val ? "true" : "false"));
	} else if (type_urid == sratom->midi_MidiEvent) {
		new_node = true;
		datatype = serd_node_from_string(SERD_URI, USTR(LV2_MIDI__MidiEvent));
		uint8_t* str = (uint8_t*)calloc(size * 2 + 1, 1);
		for (uint32_t i = 0; i < size; ++i) {
			snprintf((char*)str + (2 * i), size * 2 + 1, "%02X",
			         (unsigned)(uint8_t)*((const uint8_t*)body + i));
		}
		object = serd_node_from_string(SERD_LITERAL, USTR(str));
	} else if (type_urid == sratom->atom_Event) {
		const LV2_Atom_Event* ev = (const LV2_Atom_Event*)body;
		gensym(&id, 'e', sratom->next_id++);
		start_object(sratom, &flags, subject, predicate, &id, NULL);
		// TODO: beat time
		SerdNode time = serd_node_new_integer(ev->time.frames);
		SerdNode p    = serd_node_from_string(SERD_URI,
		                                      USTR(LV2_ATOM__frameTime));
		datatype = serd_node_from_string(SERD_URI, NS_XSD "decimal");
		sratom->write_statement(sratom->handle, SERD_ANON_CONT, NULL,
		                        &id, &p, &time, &datatype, &language);
		serd_node_free(&time);

		p = serd_node_from_string(SERD_URI, NS_RDF "value");
		sratom_write(sratom, unmap, SERD_ANON_CONT, &id, &p,
		             ev->body.type, ev->body.size, LV2_ATOM_BODY(&ev->body));
		if (sratom->end_anon) {
			sratom->end_anon(sratom->handle, &id);
		}
	} else if (type_urid == sratom->forge.Tuple) {
		gensym(&id, 't', sratom->next_id++);
		start_object(sratom, &flags, subject, predicate, &id, type);
		SerdNode p = serd_node_from_string(SERD_URI, NS_RDF "value");
		flags |= SERD_LIST_O_BEGIN;
		LV2_ATOM_TUPLE_BODY_FOREACH(body, size, i) {
			list_append(sratom, unmap, &flags, &id, &p, &node,
			            i->size, i->type, LV2_ATOM_BODY(i));
		}
Example #3
0
static int
lilv_state_write(LilvWorld*       world,
                 LV2_URID_Map*    map,
                 LV2_URID_Unmap*  unmap,
                 const LilvState* state,
                 SerdWriter*      writer,
                 const char*      uri,
                 const char*      dir)
{
	SerdNode lv2_appliesTo = serd_node_from_string(
		SERD_CURIE, USTR("lv2:appliesTo"));

	const SerdNode* plugin_uri = sord_node_to_serd_node(
		state->plugin_uri->node);

	SerdNode subject = serd_node_from_string(SERD_URI, USTR(uri ? uri : ""));

	// <subject> a pset:Preset
	SerdNode p = serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type"));
	SerdNode o = serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset));
	serd_writer_write_statement(writer, 0, NULL,
	                            &subject, &p, &o, NULL, NULL);

	// <subject> lv2:appliesTo <http://example.org/plugin>
	serd_writer_write_statement(writer, 0, NULL,
	                            &subject,
	                            &lv2_appliesTo,
	                            plugin_uri, NULL, NULL);

	// <subject> rdfs:label label
	if (state->label) {
		p = serd_node_from_string(SERD_URI, USTR(LILV_NS_RDFS "label"));
		o = serd_node_from_string(SERD_LITERAL, USTR(state->label));
		serd_writer_write_statement(writer, 0,
		                            NULL, &subject, &p, &o, NULL, NULL);
	}

	SerdEnv*        env  = serd_writer_get_env(writer);
	const SerdNode* base = serd_env_get_base_uri(env, NULL);

	Sratom* sratom = sratom_new(map);
	sratom_set_sink(sratom, (const char*)base->buf,
	                (SerdStatementSink)serd_writer_write_statement,
	                (SerdEndSink)serd_writer_end_anon,
	                writer);

	// Write port values as pretty numbers
	sratom_set_pretty_numbers(sratom, true);

	// Write port values
	for (uint32_t i = 0; i < state->num_values; ++i) {
		PortValue* const value = &state->values[i];

		const SerdNode port = serd_node_from_string(
			SERD_BLANK, USTR(value->symbol));

		// <> lv2:port _:symbol
		p = serd_node_from_string(SERD_URI, USTR(LV2_CORE__port));
		serd_writer_write_statement(writer, SERD_ANON_O_BEGIN,
		                            NULL, &subject, &p, &port, NULL, NULL);

		// _:symbol lv2:symbol "symbol"
		p = serd_node_from_string(SERD_URI, USTR(LV2_CORE__symbol));
		o = serd_node_from_string(SERD_LITERAL, USTR(value->symbol));
		serd_writer_write_statement(writer, SERD_ANON_CONT,
		                            NULL, &port, &p, &o, NULL, NULL);

		// _:symbol pset:value value
		p = serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__value));
		sratom_write(sratom, unmap, SERD_ANON_CONT, &port, &p,
		             value->type, value->size, value->value);

		serd_writer_end_anon(writer, &port);
	}

	// Write property values with precise types
	sratom_set_pretty_numbers(sratom, false);

	// Write properties
	const SerdNode state_node = serd_node_from_string(SERD_BLANK,
	                                                  USTR("2state"));
	if (state->num_props > 0) {
		p = serd_node_from_string(SERD_URI, USTR(LV2_STATE__state));
		serd_writer_write_statement(writer, SERD_ANON_O_BEGIN, NULL,
		                            &subject, &p, &state_node, NULL, NULL);
	}
	for (uint32_t i = 0; i < state->num_props; ++i) {
		Property*   prop = &state->props[i];
		const char* key  = unmap->unmap(unmap->handle, prop->key);

		p = serd_node_from_string(SERD_URI, USTR(key));
		if (prop->type == state->atom_Path && !dir) {
			const char* path     = (const char*)prop->value;
			const char* abs_path = lilv_state_rel2abs(state, path);
			sratom_write(sratom, unmap, SERD_ANON_CONT,
			             &state_node, &p, prop->type,
			             strlen(abs_path) + 1, abs_path);
		} else {
			sratom_write(sratom, unmap, SERD_ANON_CONT,
			             &state_node, &p, prop->type, prop->size, prop->value);
		}
	}
	if (state->num_props > 0) {
		serd_writer_end_anon(writer, &state_node);
	}

	sratom_free(sratom);
	return 0;
}