Bläddra i källkod

Make graph.encode an iterator; fix literal datatype bug.

scossu 6 dagar sedan
förälder
incheckning
9044372793
4 ändrade filer med 46 tillägg och 26 borttagningar
  1. 1 1
      ext/volksdata
  2. 31 23
      src/lua_graph.c
  3. 6 1
      src/lua_term.c
  4. 8 1
      test.lua

+ 1 - 1
ext/volksdata

@@ -1 +1 @@
-Subproject commit 98fad894222013e529d9642359e48a68aa54f9d7
+Subproject commit 5c3eac5aa151530e8cb9e900fa7932a1ee161043

+ 31 - 23
src/lua_graph.c

@@ -300,39 +300,47 @@ static int l_graph_lookup (lua_State *L)
 }
 
 
-static int l_graph_encode (lua_State *L)
+static int graph_encode_iter_next (lua_State *L)
+{
+    void *it = lua_touserdata (L, lua_upvalueindex (1));
+    const VOLK_Codec *codec = lua_touserdata (L, lua_upvalueindex (2));
+
+    char *out = NULL;
+    VOLK_rc rc = codec->encode_graph_iter (it, &out);
+    LUA_PCHECK (rc, "Encoding failed");
+    //LOG_DEBUG ("Serialized fragment: %s", out);
+    if (rc == VOLK_END) {
+        codec->encode_graph_done (it);
+
+        return 0;
+    }
+
+    lua_pushstring (L, out);
+    free (out);
+
+    return 1;
+}
+
+
+static int l_graph_encode_iter (lua_State *L)
 {
     const VOLK_Graph *gr = check_graph (L, 1);
     const char *codec_str = lua_tostring (L, 2);
 
-    VOLK_Codec codec;
+    const VOLK_Codec *codec_p;
     if (strcmp(codec_str, "nt") == 0)
-        codec = nt_codec;
+        codec_p = &nt_codec;
     else if (strcmp(codec_str, "ttl") == 0)
-        codec = ttl_codec;
+        codec_p = &ttl_codec;
     else
         return luaL_error(L, "Invalid encoding format: %s", codec_str);
 
-    char *out = calloc (1, 1);
-    LUA_NLCHECK (out, "Error allocating codec iterator.");
-    void *it = codec.encode_graph_init (gr);
+    void *it = codec_p->encode_graph_init (gr);
     LUA_NLCHECK (it, "Error creating codec iterator.");
 
-    char *tmp = NULL;
-    VOLK_rc rc;
-    while ((rc = codec.encode_graph_iter (it, &tmp)) != VOLK_END) {
-        //log_debug ("Serialized fragment: %s\n", tmp);
-        LUA_PCHECK (rc, "Encoding failed");
-        out = realloc (out, strlen(out) + strlen (tmp) + 1);
-        LUA_NLCHECK (out, "Error reallocating serialization buffer.");
-        out = strcat (out, tmp);
-        LUA_NLCHECK (out, "Error filling serialization buffer.");
-    }
-    codec.encode_graph_done (it);
-
-    lua_pushstring (L, out);
-    free (tmp);
-    free (out);
+    lua_pushlightuserdata (L, it);
+    lua_pushlightuserdata (L, (void *)codec_p);
+    lua_pushcclosure (L, graph_encode_iter_next, 2);
 
     return 1;
 }
@@ -507,7 +515,7 @@ static const luaL_Reg graph_lib_meth [] = {
     {"term_set", l_graph_term_set},
     {"unique_terms", l_graph_unique_terms},
     {"attr", l_graph_attr},
-    {"encode", l_graph_encode},
+    {"encode", l_graph_encode_iter},
 
     {NULL}
 };

+ 6 - 1
src/lua_term.c

@@ -178,6 +178,8 @@ static int l_new_iriref_rel (lua_State *L)
  * Argument 2 (data type) and 3 (lang) are exclusive. If both are specified,
  * datatype has precedence. If both are nil, datatype is set to the default
  * (xsd:string).
+ *
+ * Data type can be either a namespace-prefixed or a fully qualified URI.
  */
 static int l_new_lit (lua_State *L)
 {
@@ -191,8 +193,11 @@ static int l_new_lit (lua_State *L)
 
     if (dtype_str) {
         // TODO check memory leak.
-        dtype = VOLK_iriref_new (dtype_str);
+        dtype = VOLK_iriref_new_ns (dtype_str);
+        if (!dtype) dtype = VOLK_iriref_new (dtype_str);
+        LUA_NLCHECK (dtype, "Error creating data type URI.");
         *tp = VOLK_literal_new (data, dtype);
+        LUA_NLCHECK (tp, "Error creating literal term.");
     }
     else if (lang) *tp = VOLK_lt_literal_new (data, (char *)lang);
     else *tp = VOLK_literal_new (data, NULL);

+ 8 - 1
test.lua

@@ -7,7 +7,7 @@ namespace = require "volksdata.namespace"
 ---[[
 t1 = term.new_bnode()
 t2 = term.new_iriref("urn:p:11")
-t3 = term.new_lit("123", "xsd:int")
+t3 = term.new_lit("123", "xsd:integer")
 t4 = term.new_lit("Hola", nil, "es_ES")
 t5 = term.new_lit("مرحبا", nil, "ar_AR")
 
@@ -103,3 +103,10 @@ local it = gr1_copy:add_init()
 for _, trp in ipairs(triples) do it:add_iter(trp) end
 it:add_done()
 assert(gr1 == gr1_copy)
+
+encode_it = gr1:encode("ttl")
+local chunk = encode_it()
+while chunk do
+    print(chunk)
+    chunk = encode_it()
+end