/** * raptor_term_compare: * @t1: first term * @t2: second term * * Compare a pair of #raptor_term * * If types are different, the #raptor_term_type order is used. * * Resource and datatype URIs are compared with raptor_uri_compare(), * blank nodes and literals with strcmp(). If one literal has no * language, it is earlier than one with a language. If one literal * has no datatype, it is earlier than one with a datatype. * * Return value: <0 if t1 is before t2, 0 if equal, >0 if t1 is after t2 */ int raptor_term_compare(const raptor_term *t1, const raptor_term *t2) { int d = 0; /* check for NULL terms */ if(!t1 || !t2) { if(!t1 && !t2) return 0; /* both NULL */ /* place NULLs before any other term */ return t1 ? 1 : -1; } if(t1->type != t2->type) return (t1->type - t2->type); switch(t1->type) { case RAPTOR_TERM_TYPE_URI: d = raptor_uri_compare(t1->value.uri, t2->value.uri); break; case RAPTOR_TERM_TYPE_BLANK: d = strcmp((const char*)t1->value.blank.string, (const char*)t2->value.blank.string); break; case RAPTOR_TERM_TYPE_LITERAL: d = strcmp((const char*)t1->value.literal.string, (const char*)t2->value.literal.string); if(d) break; if(t1->value.literal.language && t2->value.literal.language) { /* both have a language */ d = strcmp((const char*)t1->value.literal.language, (const char*)t2->value.literal.language); } else if(t1->value.literal.language || t2->value.literal.language) /* only one has a language; the language-less one is earlier */ d = (!t1->value.literal.language ? -1 : 1); if(d) break; if(t1->value.literal.datatype && t2->value.literal.datatype) { /* both have a datatype */ d = raptor_uri_compare(t1->value.literal.datatype, t2->value.literal.datatype); } else if(t1->value.literal.datatype || t2->value.literal.datatype) /* only one has a datatype; the datatype-less one is earlier */ d = (!t1->value.literal.datatype ? -1 : 1); break; case RAPTOR_TERM_TYPE_UNKNOWN: default: break; } return d; }
static int librdf_storage_trees_node_compare(librdf_node* n1, librdf_node* n2) { if (n1 == n2) { return 0; } else if (n1->type != n2->type) { return n2->type - n1->type; } else { switch (n1->type) { case RAPTOR_TERM_TYPE_URI: return librdf_uri_compare(n1->value.uri, n2->value.uri); case RAPTOR_TERM_TYPE_LITERAL: if(1) { const unsigned char l1 = n1->value.literal.language_len; const unsigned char l2 = n2->value.literal.language_len; const unsigned char l = (l1 < l2) ? l1 : l2; /* compare first by data type */ int r = raptor_uri_compare(n1->value.literal.datatype, n2->value.literal.datatype); if(r) return r; /* if data type is equal, compare by value */ r = strcmp((const char*)n1->value.literal.string, (const char*)n2->value.literal.string); if(r) return r; /* if both data type and value are equal, compare by language */ if(l) { return strncmp((const char*)n1->value.literal.language, (const char*)n2->value.literal.language, (size_t)l); } else { /* if l == 0 strncmp will always return 0; in that case * consider the node with no language to be lesser. */ return l1 - l2; } } case RAPTOR_TERM_TYPE_BLANK: return strcmp((char*)n1->value.blank.string, (char*)n2->value.blank.string); case RAPTOR_TERM_TYPE_UNKNOWN: default: return (char*)n2-(char*)n1; /* ? */ } } }
/** * librdf_uri_compare: * @uri1: #librdf_uri object 1 or NULL * @uri2: #librdf_uri object 2 or NULL * * Compare two librdf_uri objects lexicographically. * * A NULL URI is always less than (never equal to) a non-NULL URI. * * Return value: <0 if @uri1 is less than @uri2, 0 if equal, >0 if @uri1 is greater than @uri2 **/ int librdf_uri_compare(librdf_uri* uri1, librdf_uri* uri2) { #ifdef LIBRDF_USE_RAPTOR_URI return raptor_uri_compare(uri1, uri2); #else if(uri1 == uri2) return 0; else if(!uri1) return -1; else if(!uri2) return 1; else return strcmp((const char*)uri1->string, (const char*)uri2->string); #endif }
/** * librdf_uri_compare: * @uri1: #librdf_uri object 1 or NULL * @uri2: #librdf_uri object 2 or NULL * * Compare two librdf_uri objects lexicographically. * * A NULL URI is always less than (never equal to) a non-NULL URI. * * Return value: <0 if @uri1 is less than @uri2, 0 if equal, >0 if @uri1 is greater than @uri2 **/ int librdf_uri_compare(librdf_uri* uri1, librdf_uri* uri2) { return raptor_uri_compare(uri1, uri2); }
/* compare two raptor_abbrev_nodes. * * This needs to be a strong ordering for use by raptor_avltree. * This is very performance critical, anything to make it faster is worth it. */ int raptor_abbrev_node_cmp(raptor_abbrev_node* node1, raptor_abbrev_node* node2) { int rv = 0; if(node1 == node2) { return 0; } else if(node1->type < node2->type) { return -1; } else if(node1->type > node2->type) { return 1; } switch (node1->type) { case RAPTOR_IDENTIFIER_TYPE_RESOURCE: case RAPTOR_IDENTIFIER_TYPE_PREDICATE: rv = raptor_uri_compare(node1->value.resource.uri, node2->value.resource.uri); break; case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: rv = strcmp((const char*)node1->value.blank.string, (const char*)node2->value.blank.string); break; case RAPTOR_IDENTIFIER_TYPE_LITERAL: case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL: if((char *)node1->value.literal.string != NULL && (char *)node2->value.literal.string != NULL) { /* string */ rv = strcmp((const char*)node1->value.literal.string, (const char*)node2->value.literal.string); if(rv != 0) { break; /* if string is equal, order by language */ } else { if((const char*)node1->value.literal.language != NULL && (const char*)node2->value.literal.language != NULL) { rv = strcmp((const char*)node1->value.literal.language, (const char*)node2->value.literal.language); } else if(node1->value.literal.language == NULL) { rv = -1; break; } else { rv = 1; break; } } /* if string and language are equal, order by datatype */ /* (rv == 0 if we get here) */ if(node1->value.literal.datatype != NULL && node2->value.literal.datatype != NULL) { rv = strcmp((char*)node1->value.literal.datatype, (char*)node2->value.literal.datatype); } else if(node1->value.literal.datatype == NULL) { rv = -1; } else { rv = 1; } } else { RAPTOR_FATAL1("string must be non-NULL for literal or xml literal\n"); rv = 0; } break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: if(node1->value.ordinal.ordinal == node2->value.ordinal.ordinal) rv = 0; else if(node1->value.ordinal.ordinal < node2->value.ordinal.ordinal) rv = -1; else rv = 1; break; case RAPTOR_IDENTIFIER_TYPE_UNKNOWN: default: /* Nothing to do */ break; } return rv; }
int main(int argc, char *argv[]) { const char *base_uri = "http://example.org/bpath/cpath/d;p?querystr#frag"; const char *base_uri_xmlbase = "http://example.org/bpath/cpath/d;p"; const char *base_uri_retrievable = "http://example.org/bpath/cpath/d;p?querystr"; #ifndef WIN32 #if defined(HAVE_UNISTD_H) && defined(HAVE_SYS_STAT_H) const char* dirs[6] = { "/etc", "/bin", "/tmp", "/lib", "/var", NULL }; unsigned char uri_buffer[16]; /* strlen("file:///DIR/foo")+1 */ int i; const char *dir; #endif #endif unsigned char *str; raptor_uri *uri1, *uri2, *uri3; int failures=0; if((program=strrchr(argv[0], '/'))) program++; else if((program=strrchr(argv[0], '\\'))) program++; else program=argv[0]; #ifdef WIN32 failures += assert_filename_to_uri ("c:\\windows\\system", "file:///c:/windows/system"); failures += assert_filename_to_uri ("\\\\server\\share\\file.doc", "file://server/share/file.doc"); failures += assert_filename_to_uri ("a:foo", "file:///a:./foo"); failures += assert_filename_to_uri ("C:\\Documents and Settings\\myapp\\foo.bat", "file:///C:/Documents%20and%20Settings/myapp/foo.bat"); failures += assert_filename_to_uri ("C:\\My Documents\\%age.txt", "file:///C:/My%20Documents/%25age.txt"); failures += assert_uri_to_filename ("file:///c|/windows/system", "c:\\windows\\system"); failures += assert_uri_to_filename ("file:///c:/windows/system", "c:\\windows\\system"); failures += assert_uri_to_filename ("file://server/share/file.doc", "\\\\server\\share\\file.doc"); failures += assert_uri_to_filename ("file:///a:./foo", "a:foo"); failures += assert_uri_to_filename ("file:///C:/Documents%20and%20Settings/myapp/foo.bat", "C:\\Documents and Settings\\myapp\\foo.bat"); failures += assert_uri_to_filename ("file:///C:/My%20Documents/%25age.txt", "C:\\My Documents\\%age.txt"); failures += assert_uri_to_filename ("file:c:\\thing", "c:\\thing"); failures += assert_uri_to_filename ("file:/c:\\thing", "c:\\thing"); failures += assert_uri_to_filename ("file://c:\\thing", NULL); failures += assert_uri_to_filename ("file:///c:\\thing", "c:\\thing"); failures += assert_uri_to_filename ("file://localhost/", NULL); failures += assert_uri_to_filename ("file://c:\\foo\\bar\\x.rdf", NULL); #else failures += assert_filename_to_uri ("/path/to/file", "file:///path/to/file"); failures += assert_filename_to_uri ("/path/to/file with spaces", "file:///path/to/file%20with%20spaces"); failures += assert_uri_to_filename ("file:///path/to/file", "/path/to/file"); failures += assert_uri_to_filename ("file:///path/to/file%20with%20spaces", "/path/to/file with spaces"); #if defined(HAVE_UNISTD_H) && defined(HAVE_SYS_STAT_H) /* Need to test this with a real dir (preferably not /) * This is just a test so pretty likely to work on all development systems * that are not WIN32 */ for(i=0; (dir=dirs[i]); i++) { struct stat buf; if(!lstat(dir, &buf) && S_ISDIR(buf.st_mode) && !S_ISLNK(buf.st_mode)) { if(!chdir(dir)) break; } } if(!dir) fprintf(stderr, "%s: WARNING: Found no convenient directory - not testing relative files\n", program); else { sprintf((char*)uri_buffer, "file://%s/foo", dir); fprintf(stderr, "%s: Checking relative file name 'foo' in dir %s expecting URI %s\n", program, dir, uri_buffer); failures += assert_filename_to_uri ("foo", (const char*)uri_buffer); } #endif #endif raptor_uri_init(); uri1=raptor_new_uri((const unsigned char*)base_uri); str=raptor_uri_as_string(uri1); if(strcmp((const char*)str, base_uri)) { fprintf(stderr, "%s: raptor_uri_as_string(%s) FAILED gaving %s != %s\n", program, base_uri, str, base_uri); failures++; } uri2=raptor_new_uri_for_xmlbase(uri1); str=raptor_uri_as_string(uri2); if(strcmp((const char*)str, base_uri_xmlbase)) { fprintf(stderr, "%s: raptor_new_uri_for_xmlbase(URI %s) FAILED giving %s != %s\n", program, base_uri, str, base_uri_xmlbase); failures++; } uri3=raptor_new_uri_for_retrieval(uri1); str=raptor_uri_as_string(uri3); if(strcmp((const char*)str, base_uri_retrievable)) { fprintf(stderr, "%s: raptor_new_uri_for_retrievable(%s) FAILED gaving %s != %s\n", program, base_uri, str, base_uri_retrievable); failures++; } raptor_free_uri(uri3); raptor_free_uri(uri2); raptor_free_uri(uri1); failures += assert_uri_to_relative(NULL, "http://example.com/foo/bar", "http://example.com/foo/bar"); failures += assert_uri_to_relative("", "http://example.com/foo/bar", "http://example.com/foo/bar"); failures += assert_uri_to_relative("foo:", "http://example.com/foo/bar", "http://example.com/foo/bar"); failures += assert_uri_to_relative("http://example.com/base/foo?foo#foo", "http://example.com/base/bar?bar#bar", "bar?bar#bar"); failures += assert_uri_to_relative("http://example.com/base/foo", "http://example.com/base/foo/", "foo/"); failures += assert_uri_to_relative("http://example.com/base/foo", "http://example.com/base/foo/.foo", "foo/.foo"); failures += assert_uri_to_relative("http://example.com/base/foo", "http://example.com/base/foo/.foo#bar", "foo/.foo#bar"); failures += assert_uri_to_relative("http://example.com/base/foo", "http://example.com/base/foo/bar", "foo/bar"); failures += assert_uri_to_relative("http://example.com/base/foo", "http://example.com/base/foo#bar", "#bar"); failures += assert_uri_to_relative("http://example.com/base/foo", "http://example.com/base/bar#foo", "bar#foo"); failures += assert_uri_to_relative("http://example.com/base/foo", "http://example.com/otherbase/bar", "../otherbase/bar"); failures += assert_uri_to_relative("http://example.com/base/foo", "http://example.com/base/#foo", ".#foo"); failures += assert_uri_to_relative("http://example.com/base/foo", "http://example2.com/base/bar", "http://example2.com/base/bar"); failures += assert_uri_to_relative("http://example.com/base/one?path=/should/be/ignored", "http://example.com/base/two?path=/should/be/ignored", "two?path=/should/be/ignored"); failures += assert_uri_to_relative("http://example.org/base#", "http://www.foo.org", "http://www.foo.org"); failures += assert_uri_to_relative("http://example.org", "http://a.example.org/", "http://a.example.org/"); failures += assert_uri_to_relative("http://example.org", "http://a.example.org", "http://a.example.org"); failures += assert_uri_to_relative("http://abcdefgh.example.org/foo/bar/", "http://ijklmnop.example.org/", "http://ijklmnop.example.org/"); if(1) { raptor_uri_handler uri_handler; int ret; raptor_uri* u1; raptor_uri* u2; int called; /* URI Interface V1 */ uri_handler.new_uri = raptor_default_new_uri; uri_handler.free_uri = raptor_default_free_uri; uri_handler.uri_compare = raptor_test_uri_compare; uri_handler.initialised=1; called=0; raptor_uri_set_handler(&uri_handler, &called); u1=raptor_new_uri((const unsigned char *)"http://example.org/abc"); u2=raptor_new_uri((const unsigned char *)"http://example.org/def"); ret=raptor_uri_compare(u1, u2); if(!(ret < 0)) { fprintf(stderr, "%s: raptor_uri_compare(%s, %s) FAILED V1 gave %d expected <0\n", program, raptor_uri_as_string(u1), raptor_uri_as_string(u2), ret); failures++; } if(called) { fprintf(stderr, "%s: raptor_uri_compare(%s, %s) FAILED V1 called user handler\n", program, raptor_uri_as_string(u1), raptor_uri_as_string(u2)); failures++; } /* URI Interface V2 */ uri_handler.initialised=2; called=0; raptor_uri_set_handler(&uri_handler, &called); ret=raptor_uri_compare(u1, u2); if(!(ret < 0)) { fprintf(stderr, "%s: raptor_uri_compare(%s, %s) FAILED V2 gave %d expected <0\n", program, raptor_uri_as_string(u1), raptor_uri_as_string(u2), ret); failures++; } if(!called) { fprintf(stderr, "%s: raptor_uri_compare(%s, %s) FAILED V2 did not call user handler\n", program, raptor_uri_as_string(u1), raptor_uri_as_string(u2)); failures++; } raptor_free_uri(u1); raptor_free_uri(u2); } return failures ; }