cannam@226
|
1 /*
|
cannam@226
|
2 Copyright 2011-2015 David Robillard <http://drobilla.net>
|
cannam@226
|
3
|
cannam@226
|
4 Permission to use, copy, modify, and/or distribute this software for any
|
cannam@226
|
5 purpose with or without fee is hereby granted, provided that the above
|
cannam@226
|
6 copyright notice and this permission notice appear in all copies.
|
cannam@226
|
7
|
cannam@226
|
8 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
cannam@226
|
9 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
cannam@226
|
10 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
cannam@226
|
11 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
cannam@226
|
12 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
cannam@226
|
13 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
cannam@226
|
14 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
cannam@226
|
15 */
|
cannam@226
|
16
|
cannam@226
|
17 #include <assert.h>
|
cannam@226
|
18 #include <stdlib.h>
|
cannam@226
|
19 #include <string.h>
|
cannam@226
|
20
|
cannam@226
|
21 #include "serd/serd.h"
|
cannam@226
|
22
|
cannam@226
|
23 #include "sord_config.h"
|
cannam@226
|
24 #include "sord_internal.h"
|
cannam@226
|
25
|
cannam@226
|
26 struct SordInserterImpl {
|
cannam@226
|
27 SordModel* model;
|
cannam@226
|
28 SerdEnv* env;
|
cannam@226
|
29 };
|
cannam@226
|
30
|
cannam@226
|
31 SordInserter*
|
cannam@226
|
32 sord_inserter_new(SordModel* model,
|
cannam@226
|
33 SerdEnv* env)
|
cannam@226
|
34 {
|
cannam@226
|
35 SordInserter* inserter = (SordInserter*)malloc(sizeof(SordInserter));
|
cannam@226
|
36 inserter->model = model;
|
cannam@226
|
37 inserter->env = env;
|
cannam@226
|
38 return inserter;
|
cannam@226
|
39 }
|
cannam@226
|
40
|
cannam@226
|
41 void
|
cannam@226
|
42 sord_inserter_free(SordInserter* inserter)
|
cannam@226
|
43 {
|
cannam@226
|
44 free(inserter);
|
cannam@226
|
45 }
|
cannam@226
|
46
|
cannam@226
|
47 SerdStatus
|
cannam@226
|
48 sord_inserter_set_base_uri(SordInserter* inserter,
|
cannam@226
|
49 const SerdNode* uri_node)
|
cannam@226
|
50 {
|
cannam@226
|
51 return serd_env_set_base_uri(inserter->env, uri_node);
|
cannam@226
|
52 }
|
cannam@226
|
53
|
cannam@226
|
54 SerdStatus
|
cannam@226
|
55 sord_inserter_set_prefix(SordInserter* inserter,
|
cannam@226
|
56 const SerdNode* name,
|
cannam@226
|
57 const SerdNode* uri_node)
|
cannam@226
|
58 {
|
cannam@226
|
59 return serd_env_set_prefix(inserter->env, name, uri_node);
|
cannam@226
|
60 }
|
cannam@226
|
61
|
cannam@226
|
62 SerdStatus
|
cannam@226
|
63 sord_inserter_write_statement(SordInserter* inserter,
|
cannam@226
|
64 SerdStatementFlags flags,
|
cannam@226
|
65 const SerdNode* graph,
|
cannam@226
|
66 const SerdNode* subject,
|
cannam@226
|
67 const SerdNode* predicate,
|
cannam@226
|
68 const SerdNode* object,
|
cannam@226
|
69 const SerdNode* object_datatype,
|
cannam@226
|
70 const SerdNode* object_lang)
|
cannam@226
|
71 {
|
cannam@226
|
72 SordWorld* world = sord_get_world(inserter->model);
|
cannam@226
|
73 SerdEnv* env = inserter->env;
|
cannam@226
|
74
|
cannam@226
|
75 SordNode* g = sord_node_from_serd_node(world, env, graph, NULL, NULL);
|
cannam@226
|
76 SordNode* s = sord_node_from_serd_node(world, env, subject, NULL, NULL);
|
cannam@226
|
77 SordNode* p = sord_node_from_serd_node(world, env, predicate, NULL, NULL);
|
cannam@226
|
78 SordNode* o = sord_node_from_serd_node(world, env, object,
|
cannam@226
|
79 object_datatype, object_lang);
|
cannam@226
|
80
|
cannam@226
|
81 if (!s || !p || !o) {
|
cannam@226
|
82 return SERD_ERR_BAD_ARG;
|
cannam@226
|
83 }
|
cannam@226
|
84
|
cannam@226
|
85 const SordQuad tup = { s, p, o, g };
|
cannam@226
|
86 sord_add(inserter->model, tup);
|
cannam@226
|
87
|
cannam@226
|
88 sord_node_free(world, o);
|
cannam@226
|
89 sord_node_free(world, p);
|
cannam@226
|
90 sord_node_free(world, s);
|
cannam@226
|
91 sord_node_free(world, g);
|
cannam@226
|
92
|
cannam@226
|
93 return SERD_SUCCESS;
|
cannam@226
|
94 }
|
cannam@226
|
95
|
cannam@226
|
96 SORD_API
|
cannam@226
|
97 SerdReader*
|
cannam@226
|
98 sord_new_reader(SordModel* model,
|
cannam@226
|
99 SerdEnv* env,
|
cannam@226
|
100 SerdSyntax syntax,
|
cannam@226
|
101 SordNode* graph)
|
cannam@226
|
102 {
|
cannam@226
|
103 SordInserter* inserter = sord_inserter_new(model, env);
|
cannam@226
|
104
|
cannam@226
|
105 SerdReader* reader = serd_reader_new(
|
cannam@226
|
106 syntax, inserter, (void (*)(void*))sord_inserter_free,
|
cannam@226
|
107 (SerdBaseSink)sord_inserter_set_base_uri,
|
cannam@226
|
108 (SerdPrefixSink)sord_inserter_set_prefix,
|
cannam@226
|
109 (SerdStatementSink)sord_inserter_write_statement,
|
cannam@226
|
110 NULL);
|
cannam@226
|
111
|
cannam@226
|
112 if (graph) {
|
cannam@226
|
113 serd_reader_set_default_graph(reader, sord_node_to_serd_node(graph));
|
cannam@226
|
114 }
|
cannam@226
|
115
|
cannam@226
|
116 return reader;
|
cannam@226
|
117 }
|
cannam@226
|
118
|
cannam@226
|
119 static SerdStatus
|
cannam@226
|
120 write_statement(SordModel* sord,
|
cannam@226
|
121 SerdWriter* writer,
|
cannam@226
|
122 SordQuad tup,
|
cannam@226
|
123 SerdStatementFlags flags)
|
cannam@226
|
124 {
|
cannam@226
|
125 const SordNode* s = tup[SORD_SUBJECT];
|
cannam@226
|
126 const SordNode* p = tup[SORD_PREDICATE];
|
cannam@226
|
127 const SordNode* o = tup[SORD_OBJECT];
|
cannam@226
|
128 const SordNode* d = sord_node_get_datatype(o);
|
cannam@226
|
129 const SerdNode* ss = sord_node_to_serd_node(s);
|
cannam@226
|
130 const SerdNode* sp = sord_node_to_serd_node(p);
|
cannam@226
|
131 const SerdNode* so = sord_node_to_serd_node(o);
|
cannam@226
|
132 const SerdNode* sd = sord_node_to_serd_node(d);
|
cannam@226
|
133
|
cannam@226
|
134 const char* lang_str = sord_node_get_language(o);
|
cannam@226
|
135 size_t lang_len = lang_str ? strlen(lang_str) : 0;
|
cannam@226
|
136 SerdNode language = SERD_NODE_NULL;
|
cannam@226
|
137 if (lang_str) {
|
cannam@226
|
138 language.type = SERD_LITERAL;
|
cannam@226
|
139 language.n_bytes = lang_len;
|
cannam@226
|
140 language.n_chars = lang_len;
|
cannam@226
|
141 language.buf = (const uint8_t*)lang_str;
|
cannam@226
|
142 };
|
cannam@226
|
143
|
cannam@226
|
144 // TODO: Subject abbreviation
|
cannam@226
|
145
|
cannam@226
|
146 if (sord_node_is_inline_object(s) && !(flags & SERD_ANON_CONT)) {
|
cannam@226
|
147 return SERD_SUCCESS;
|
cannam@226
|
148 }
|
cannam@226
|
149
|
cannam@226
|
150 SerdStatus st = SERD_SUCCESS;
|
cannam@226
|
151 if (sord_node_is_inline_object(o)) {
|
cannam@226
|
152 SordQuad sub_pat = { o, 0, 0, 0 };
|
cannam@226
|
153 SordIter* sub_iter = sord_find(sord, sub_pat);
|
cannam@226
|
154
|
cannam@226
|
155 SerdStatementFlags start_flags = flags
|
cannam@226
|
156 | ((sub_iter) ? SERD_ANON_O_BEGIN : SERD_EMPTY_O);
|
cannam@226
|
157
|
cannam@226
|
158 st = serd_writer_write_statement(
|
cannam@226
|
159 writer, start_flags, NULL, ss, sp, so, sd, &language);
|
cannam@226
|
160
|
cannam@226
|
161 if (!st && sub_iter) {
|
cannam@226
|
162 flags |= SERD_ANON_CONT;
|
cannam@226
|
163 for (; !st && !sord_iter_end(sub_iter); sord_iter_next(sub_iter)) {
|
cannam@226
|
164 SordQuad sub_tup;
|
cannam@226
|
165 sord_iter_get(sub_iter, sub_tup);
|
cannam@226
|
166 st = write_statement(sord, writer, sub_tup, flags);
|
cannam@226
|
167 }
|
cannam@226
|
168 sord_iter_free(sub_iter);
|
cannam@226
|
169 serd_writer_end_anon(writer, so);
|
cannam@226
|
170 }
|
cannam@226
|
171 } else {
|
cannam@226
|
172 st = serd_writer_write_statement(
|
cannam@226
|
173 writer, flags, NULL, ss, sp, so, sd, &language);
|
cannam@226
|
174 }
|
cannam@226
|
175
|
cannam@226
|
176 return st;
|
cannam@226
|
177 }
|
cannam@226
|
178
|
cannam@226
|
179 bool
|
cannam@226
|
180 sord_write(SordModel* model,
|
cannam@226
|
181 SerdWriter* writer,
|
cannam@226
|
182 SordNode* graph)
|
cannam@226
|
183 {
|
cannam@226
|
184 SordQuad pat = { 0, 0, 0, graph };
|
cannam@226
|
185 SordIter* iter = sord_find(model, pat);
|
cannam@226
|
186 return sord_write_iter(iter, writer);
|
cannam@226
|
187 }
|
cannam@226
|
188
|
cannam@226
|
189 bool
|
cannam@226
|
190 sord_write_iter(SordIter* iter,
|
cannam@226
|
191 SerdWriter* writer)
|
cannam@226
|
192 {
|
cannam@226
|
193 if (!iter) {
|
cannam@226
|
194 return false;
|
cannam@226
|
195 }
|
cannam@226
|
196
|
cannam@226
|
197 SordModel* model = (SordModel*)sord_iter_get_model(iter);
|
cannam@226
|
198 SerdStatus st = SERD_SUCCESS;
|
cannam@226
|
199 for (; !st && !sord_iter_end(iter); sord_iter_next(iter)) {
|
cannam@226
|
200 SordQuad tup;
|
cannam@226
|
201 sord_iter_get(iter, tup);
|
cannam@226
|
202 st = write_statement(model, writer, tup, 0);
|
cannam@226
|
203 }
|
cannam@226
|
204 sord_iter_free(iter);
|
cannam@226
|
205
|
cannam@226
|
206 return !st;
|
cannam@226
|
207 }
|