fs_value fn_contains(fs_query *q, fs_value arg1, fs_value arg2) { if (!fs_is_plain_or_string(arg1) || !fs_is_plain_or_string(arg2)) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } arg1 = fs_value_fill_lexical(q, arg1); arg2 = fs_value_fill_lexical(q, arg2); return fs_value_boolean(strstr(arg1.lex, arg2.lex) != NULL); }
fs_value fn_strends(fs_query *q, fs_value arg1, fs_value arg2) { if (!fs_is_plain_or_string(arg1) || !fs_is_plain_or_string(arg2)) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } arg1 = fs_value_fill_lexical(q, arg1); arg2 = fs_value_fill_lexical(q, arg2); const int a1l = strlen(arg1.lex); const int a2l = strlen(arg2.lex); if (a2l > a1l) { return fs_value_boolean(0); } return fs_value_boolean(strncmp(arg1.lex + a1l - a2l, arg2.lex, a2l) == 0); }
/* return true if arg1 and arg2 are compatible, as per * http://www.w3.org/TR/sparql11-query/#func-arg-compatibility */ int fs_arg_compatible(fs_value arg1, fs_value arg2) { /* The arguments are simple literals or literals typed as xsd:string */ if (fs_is_plain_or_string(arg1) && fs_is_plain_or_string(arg2)) { return 1; } /* The arguments are plain literals with identical language tags */ if (arg1.attr == arg2.attr && FS_IS_LITERAL(arg1.attr)) { return 1; } /* The first argument is a plain literal with language tag and the second * argument is a simple literal or literal typed as xsd:string */ if (FS_IS_LITERAL(arg1.attr) && fs_is_plain_or_string(arg2)) { return 1; } return 0; }
fs_value fn_lcase(fs_query *q, fs_value v) { if (!fs_is_plain_or_string(v)) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } v = fs_value_fill_lexical(q, v); char *lex = g_utf8_strdown(v.lex, -1); fs_query_add_freeable(q, lex); fs_value ret = fs_value_plain(lex); ret.attr = v.attr; return ret; }
fs_value fn_encode_for_uri(fs_query *q, fs_value v) { if (!fs_is_plain_or_string(v)) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } v = fs_value_fill_lexical(q, v); #ifdef HAVE_G_URI_ESCAPE_STRING char *lex = g_uri_escape_string(v.lex, NULL, TRUE); #else char *lex = fs_uri_escape(v.lex); #endif fs_query_add_freeable(q, lex); fs_value ret = fs_value_plain(lex); return ret; }
fs_value fn_substring(fs_query *q, fs_value str, fs_value start, fs_value length) { if (!fs_is_plain_or_string(str)) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } if (!fs_is_numeric(&start)) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } start = cast_integer(start); /* 2 arg form */ if (length.rid == FS_RID_NULL) { length = fs_value_integer(INT_MAX); } else { if (!fs_is_numeric(&length)) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } length = cast_integer(length); } str = fs_value_fill_lexical(q, str); const int slen = g_utf8_strlen(str.lex, -1); if (start.in > slen || length.in <= 0) { fs_value ret = fs_value_plain(""); ret.attr = str.attr; return ret; } gchar *spos = g_utf8_offset_to_pointer(str.lex, start.in - 1); int retlen_utf8 = g_utf8_strlen(spos, -1); if (retlen_utf8 > length.in) { retlen_utf8 = length.in; } gchar *epos = g_utf8_offset_to_pointer(spos, retlen_utf8); int retlen_bytes = epos - spos + 1; char *retstr = g_malloc(retlen_bytes+1); retstr[retlen_bytes] = '\0'; g_utf8_strncpy(retstr, spos, retlen_utf8); fs_query_add_freeable(q, retstr); fs_value ret = fs_value_plain(retstr); ret.attr = str.attr; return ret; }