15 #include <libxml/xmlregexp.h>
34 impl_token_type_unset = 0,
35 impl_token_type_delimiter,
36 impl_token_type_operation,
37 impl_token_type_string,
51 impl_parse_string_filter(
59 impl_parse_string_function(
67 impl_parse_string_sugar(
75 impl_parse_string_term(
83 impl_parse_string_factor(
91 impl_parse_string_relation(
135 impl_AdaptiveQueryCriteria_object_parse_filter(
144 impl_AdaptiveQueryCriteria_object_parse_select(
149 impl_AdaptiveQueryCriteria_object_parse_sort(
180 afw_query_criteria_filter_op_id_and,
187 afw_query_criteria_filter_op_id_or,
194 afw_query_criteria_filter_op_id_in,
201 afw_query_criteria_filter_op_id_out,
208 afw_query_criteria_filter_op_id_contains,
215 afw_query_criteria_filter_op_id_excludes,
222 afw_query_criteria_filter_op_id_match,
229 afw_query_criteria_filter_op_id_differ,
236 afw_query_criteria_filter_op_id_eq,
243 afw_query_criteria_filter_op_id_lt,
250 afw_query_criteria_filter_op_id_le,
257 afw_query_criteria_filter_op_id_gt,
264 afw_query_criteria_filter_op_id_ge,
271 afw_query_criteria_filter_op_id_ne,
458 impl_string_parser_set_error_z(
463 afw_error_set_fz(afw_error_code_syntax,
464 source_z, parser->xctx,
467 parser->c - parser->start - parser->token.len,
474 impl_string_parser_set_error_fz(
482 va_start(ap, format_z);
484 parser->p, parser->xctx);
487 impl_string_parser_set_error_z(parser, source_z, message_z);
492 #define IMPL_STRING_THROW_ERROR_Z(message_z) \
494 impl_string_parser_set_error_z(parser, \
495 AFW__FILE_LINE__, message_z); \
496 longjmp(((parser->xctx)->current_try->throw_jmp_buf), \
497 (afw_error_code_syntax)); \
502 #define IMPL_STRING_THROW_ERROR_FZ(format_z, ...) \
504 impl_string_parser_set_error_fz(parser, \
505 AFW__FILE_LINE__, format_z, __VA_ARGS__); \
506 longjmp(((parser->xctx)->current_try->throw_jmp_buf), \
507 (afw_error_code_syntax)); \
533 AFW_DEFINE_STATIC_INLINE(
void)
537 memcpy(to, &parser->token,
sizeof(
afw_utf8_t));
547 delimiter = impl_delimiter;
549 if (*delimiter == ch)
return true;
550 if (*delimiter == 0)
break;
565 if (parser->token_type == impl_token_type_end) {
566 IMPL_STRING_THROW_ERROR_Z(
567 "call to impl_get_token() after end");
571 parser->token.s = parser->c;
574 if (*(parser->c) == 0 || *(parser->c) ==
'#') {
575 parser->token.len = 0;
576 parser->token_type = impl_token_type_end;
584 if (parser->expect_an_operation &&
585 (*(parser->c) ==
'=' || *(parser->c) ==
'!'))
587 parser->token_type = impl_token_type_operation;
588 parser->token.len = 1;
590 if (*(parser->c) ==
'=') {
593 parser->token.len = c - parser->c + 1;
596 if (impl_is_delimiter(*c))
break;
602 parser->token.len = 2;
608 else if (impl_is_delimiter(*(parser->c))) {
609 parser->token_type = impl_token_type_delimiter;
610 parser->token.len = 1;
616 !impl_is_delimiter(*c) &&
617 (!parser->bang_is_a_delimiter || *c !=
'!');
619 parser->token.len = c - parser->c;
620 parser->token_type = impl_token_type_string;
624 parser->c += parser->token.len;
627 parser->bang_is_a_delimiter =
false;
628 parser->expect_an_operation =
false;
635 parser->p, parser->xctx);
645 parser->p, parser->xctx);
654 entry->alt_op_id = entry->op_id;
655 entry->alt_not =
true;
656 switch (entry->op_id) {
658 case afw_query_criteria_filter_op_id_ne:
659 entry->alt_op_id = afw_query_criteria_filter_op_id_eq;
662 case afw_query_criteria_filter_op_id_ge:
663 entry->alt_op_id = afw_query_criteria_filter_op_id_lt;
666 case afw_query_criteria_filter_op_id_gt:
667 entry->alt_op_id = afw_query_criteria_filter_op_id_le;
670 case afw_query_criteria_filter_op_id_differ:
671 entry->alt_op_id = afw_query_criteria_filter_op_id_match;
674 case afw_query_criteria_filter_op_id_excludes:
675 entry->alt_op_id = afw_query_criteria_filter_op_id_contains;
678 case afw_query_criteria_filter_op_id_out:
679 entry->alt_op_id = afw_query_criteria_filter_op_id_in;
682 case afw_query_criteria_filter_op_id_and:
683 case afw_query_criteria_filter_op_id_or:
684 entry->alt_op_id = afw_query_criteria_filter_op_id_na;
686 entry->alt_not =
false;
708 impl_get_token(parser);
711 if (*(parser->token.s) ==
'-') {
712 entry->descending =
true;
714 (parser->token.len)--;
716 else if (*(parser->token.s) ==
'+') {
717 impl_get_token(parser);
721 else if (*(parser->token.s) ==
'%' &&
722 parser->token.len > 3 &&
723 *(parser->token.s + 1) ==
'2')
726 if (*(parser->token.s + 2) ==
'b' ||
727 *(parser->token.s + 2) ==
'B')
729 parser->token.s += 3;
730 parser->token.len -= 3;
734 else if (*(parser->token.s + 2) ==
'd' ||
735 *(parser->token.s + 2) ==
'D')
737 entry->descending =
true;
738 parser->token.s += 3;
739 parser->token.len -= 3;
744 if (parser->token_type != impl_token_type_string) {
745 IMPL_STRING_THROW_ERROR_Z(
"Invalid sort value");
749 entry->property_name = impl_decode_token(parser);
750 if (parser->criteria->object_type && entry->property_name) {
752 parser->criteria->object_type,
753 entry->property_name, parser->xctx);
754 if (!entry->pt || !entry->pt->allow_query) {
755 IMPL_STRING_THROW_ERROR_FZ(
764 if (!previous_entry) {
768 previous_entry->next = entry;
770 previous_entry = entry;
776 impl_get_token(parser);
777 if (*(parser->token.s) ==
')')
break;
778 if (*(parser->token.s) ==
',' || *(parser->token.s) ==
' ')
continue;
779 IMPL_STRING_THROW_ERROR_Z(
"Invalid sort value");
797 parser->p, parser->xctx);
803 impl_get_token(parser);
804 if (parser->token_type != impl_token_type_string) {
805 IMPL_STRING_THROW_ERROR_Z(
"Invalid property name");
809 property_name = impl_decode_token(parser);
817 impl_get_token(parser);
818 if (*(parser->token.s) ==
')')
break;
819 if (*(parser->token.s) ==
',' || *(parser->token.s) ==
' ')
continue;
820 IMPL_STRING_THROW_ERROR_Z(
"Invalid select value");
828 parser->p, parser->xctx);
838 apr_array_header_t *values;
852 impl_get_token(parser);
856 if (*(parser->token.s) ==
'+' || *(parser->token.s) ==
'-') {
857 sign.s = parser->token.s;
858 sign.len = parser->token.len;
859 impl_get_token(parser);
863 if (parser->token_type != impl_token_type_string) {
864 IMPL_STRING_THROW_ERROR_Z(
"Invalid list item in relation");
871 value = impl_decode_token(parser);
875 memcpy(apr_array_push(values), value,
sizeof(
afw_utf8_t));
878 impl_get_token(parser);
881 if (*(parser->token.s) ==
',')
887 if (*(parser->token.s) ==
')') {
895 values->nelts, parser->p, parser->xctx);
903 impl_parse_string_relation(
917 parser->last->next = entry;
919 parser->last = entry;
922 entry->on_true = on_true;
923 entry->on_false = on_false;
926 parser->bang_is_a_delimiter =
true;
927 impl_get_token(parser);
928 if (parser->token_type != impl_token_type_string) {
929 IMPL_STRING_THROW_ERROR_Z(
930 "Invalid or missing property name in relation");
932 entry->property_name = impl_decode_token(parser);
933 if (parser->criteria->object_type && entry->property_name) {
935 parser->criteria->object_type,
936 entry->property_name, parser->xctx);
937 if (!entry->pt || !entry->pt->allow_query) {
938 IMPL_STRING_THROW_ERROR_FZ(
945 parser->expect_an_operation =
true;
946 impl_get_token(parser);
947 if (parser->token_type != impl_token_type_operation) {
948 IMPL_STRING_THROW_ERROR_Z(
949 "Invalid or missing operation in relation");
953 for (o = &impl_fiql_op[0]; o->fiql_z; o++) {
954 if (strlen(o->fiql_z) == parser->token.len &&
955 memcmp(parser->token.s, o->fiql_z, parser->token.len) == 0)
961 IMPL_STRING_THROW_ERROR_Z(
962 "Invalid operation in relation");
964 entry->op_name = o->op->name;
965 entry->op_id = o->op->op_id;
969 if (!o->op->is_list) {
970 impl_get_token(parser);
971 if (parser->token_type != impl_token_type_string) {
972 IMPL_STRING_THROW_ERROR_Z(
"Invalid value in relation");
974 decoded = impl_decode_token(parser);
976 decoded, parser->p, parser->xctx);
982 impl_get_token(parser);
983 if (*(parser->token.s) !=
'(') {
984 IMPL_STRING_THROW_ERROR_Z(
"Expecting '(' in relation");
986 entry->value = impl_parse_string_list_value(parser);
990 if (entry->op_id == afw_query_criteria_filter_op_id_match) {
992 entry->op_specific = xmlRegexpCompile(s_z);
993 if (entry->op_specific == NULL) {
994 IMPL_STRING_THROW_ERROR_Z(
"regexp syntax error");
1005 impl_parse_string_factor(
1012 if (*(parser->c) ==
'(') {
1014 impl_parse_string_sugar(parser, filter, tree,
1016 if (*(parser->c) !=
')') {
1017 IMPL_STRING_THROW_ERROR_Z(
"missing ')'");
1022 *filter = impl_parse_string_relation(parser, on_true, on_false);
1038 entry && entry != new_on;
1041 if (entry->on_true == old_on) {
1042 entry->on_true = new_on;
1044 if (entry->on_false == old_on) {
1045 entry->on_false = new_on;
1054 impl_parse_string_term(
1067 impl_parse_string_factor(parser, filter, tree, on_true, on_false);
1069 if (*(parser->c) ==
'&' || *(parser->c) ==
';') {
1070 new_entry = *filter;
1074 and_entry->op_name = &afw_s_and;
1075 and_entry->op_id = afw_query_criteria_filter_op_id_and;
1076 and_entry->first_conjunctive_child = *tree;
1081 previous_entry = new_entry;
1082 previous_normalized = new_tree;
1083 impl_parse_string_factor(parser, &new_entry, &new_tree,
1085 impl_patch_on(previous_entry, on_true, new_entry);
1086 previous_normalized->next_conjunctive_sibling = new_tree;
1087 }
while (*(parser->c) ==
'&' || *(parser->c) ==
';');
1094 impl_parse_string_sugar(
1107 impl_parse_string_term(parser, filter, tree, on_true, on_false);
1109 if (*(parser->c) ==
'|' || *(parser->c) ==
',') {
1110 new_entry = *filter;
1115 or_entry->op_name = &afw_s_or;
1116 or_entry->op_id = afw_query_criteria_filter_op_id_or;
1117 or_entry->first_conjunctive_child = *tree;
1122 previous_entry = new_entry;
1123 previous_normalized = new_tree;
1124 impl_parse_string_term(parser, &new_entry, &new_tree,
1126 impl_patch_on(previous_entry, on_false, new_entry);
1127 previous_normalized->next_conjunctive_sibling = new_tree;
1128 }
while (*(parser->c) ==
'|' || *(parser->c) ==
',');
1139 result = &impl_rql_op[0];
1140 (
char *)result < (
char *)&impl_rql_op[0] +
sizeof(impl_rql_op);
1154 impl_parse_string_function(
1170 impl_get_token(parser);
1171 rql_op = impl_find_rql_op(&parser->token);
1173 IMPL_STRING_THROW_ERROR_FZ(
1179 impl_get_token(parser);
1180 if (!impl_token_equal_z(parser,
"(")) {
1181 IMPL_STRING_THROW_ERROR_Z(
"Expecting '(' after operator");
1191 parser->last->next = entry;
1193 parser->last = entry;
1194 entry->op_name = rql_op->op->name;
1195 entry->op_id = rql_op->op->op_id;
1196 impl_set_alt(entry);
1199 if (entry->op_id == afw_query_criteria_filter_op_id_and ||
1200 entry->op_id == afw_query_criteria_filter_op_id_or)
1203 previous_entry = previous_tree = NULL
1205 ; previous_entry = child_entry, previous_tree = child_tree)
1207 impl_parse_string_function(parser,
1212 if (!previous_entry) {
1213 entry->first_conjunctive_child = child_tree;
1214 *filter = child_entry;
1217 previous_tree->next_conjunctive_sibling = child_tree;
1220 if (entry->op_id == afw_query_criteria_filter_op_id_and) {
1221 impl_patch_on(previous_entry, previous_entry->on_true,
1227 impl_patch_on(previous_entry, previous_entry->on_false,
1233 impl_get_token(parser);
1234 if (impl_token_equal_z(parser,
")")) {
1237 if (!impl_token_equal_z(parser,
",")) {
1238 IMPL_STRING_THROW_ERROR_Z(
"Expecting ','");
1245 entry->on_true = on_true;
1246 entry->on_false = on_false;
1250 impl_get_token(parser);
1251 if (parser->token_type != impl_token_type_string) {
1252 IMPL_STRING_THROW_ERROR_Z(
1253 "Expecting property name as first parameter of operator");
1255 entry->property_name = impl_decode_token(parser);
1256 if (parser->criteria->object_type && entry->property_name) {
1258 parser->criteria->object_type,
1259 entry->property_name, parser->xctx);
1260 if (!entry->pt || !entry->pt->allow_query) {
1261 IMPL_STRING_THROW_ERROR_FZ(
1268 impl_get_token(parser);
1269 if (!impl_token_equal_z(parser,
",")) {
1270 IMPL_STRING_THROW_ERROR_Z(
"Expecting ','");
1274 if (!rql_op->op->is_list) {
1275 impl_get_token(parser);
1276 if (parser->token_type != impl_token_type_string) {
1277 IMPL_STRING_THROW_ERROR_Z(
"Invalid value in relation");
1279 entry->value = impl_token_to_value(parser);
1280 impl_get_token(parser);
1287 parser->p, parser->xctx);
1289 impl_get_token(parser);
1290 if (parser->token_type != impl_token_type_string) {
1291 IMPL_STRING_THROW_ERROR_Z(
"Expecting string value");
1294 impl_token_to_value(parser), parser->xctx);
1296 impl_get_token(parser);
1297 if (impl_token_equal_z(parser,
")")) {
1300 if (!impl_token_equal_z(parser,
",")) {
1301 IMPL_STRING_THROW_ERROR_Z(
"Expecting ','");
1306 if (!impl_token_equal_z(parser,
")")) {
1307 IMPL_STRING_THROW_ERROR_Z(
"Expecting ')'");
1316 impl_parse_string_filter(
1332 impl_get_token(parser);
1333 if (parser->token_type == impl_token_type_string) {
1334 impl_get_token(parser);
1337 impl_parse_string_function(parser, filter, tree,
1345 impl_parse_string_sugar(parser, filter, tree, on_true, on_false);
1354 impl_AdaptiveQueryCriteria_object_parse_filter(
1376 &afw_s_op, parser->xctx);
1380 rql_op = impl_find_rql_op(s);
1394 parser->last->next = entry;
1396 parser->last = entry;
1397 entry->op_name = rql_op->op->name;
1398 entry->op_id = rql_op->op->op_id;
1399 impl_set_alt(entry);
1402 if (entry->op_id == afw_query_criteria_filter_op_id_and ||
1403 entry->op_id == afw_query_criteria_filter_op_id_or)
1406 &afw_s_filters, parser->xctx);
1407 if (!filters_list) {
1409 "Property \"filters\" for this op",
1414 previous_entry = previous_tree = NULL,
1417 ; previous_entry = child_entry, previous_tree = child_tree)
1420 parser->p, parser->xctx);
1426 "Property \"filters\" list entries must be objects",
1431 impl_AdaptiveQueryCriteria_object_parse_filter(
1432 parser, child_object,
1437 if (!previous_entry) {
1438 entry->first_conjunctive_child = child_tree;
1439 *filter = child_entry;
1442 previous_tree->next_conjunctive_sibling = child_tree;
1445 if (entry->op_id == afw_query_criteria_filter_op_id_and) {
1446 impl_patch_on(previous_entry, previous_entry->on_true,
1452 impl_patch_on(previous_entry, previous_entry->on_false,
1461 entry->on_true = on_true;
1462 entry->on_false = on_false;
1465 filter_object, &afw_s_property, parser->xctx);
1466 if (parser->criteria->object_type && entry->property_name) {
1468 parser->criteria->object_type,
1469 entry->property_name, parser->xctx);
1470 if (!entry->pt || !entry->pt->allow_query) {
1478 filter_object, &afw_s_value, parser->xctx);
1485 impl_AdaptiveQueryCriteria_object_parse_select(
1496 parser->p, parser->xctx);
1497 for (iterator = NULL;;) {
1499 parser->p, parser->xctx);
1510 parser->p, parser->xctx);
1516 impl_AdaptiveQueryCriteria_object_parse_sort(
1527 for (iterator = NULL, result = NULL, curr = NULL;;)
1530 parser->p, parser->xctx);
1544 if (name->len <= 2 ||
1545 (*name->s !=
'+' && *name->s !=
'-')
1549 "sort property name is missing or does not start with "
1553 curr->descending = *name->s ==
'-';
1555 parser->p, parser->xctx);
1574 const void *i1, *i2;
1586 entry_value = entry->value;
1587 if (entry->op_id != afw_query_criteria_filter_op_id_match &&
1588 entry->op_id != afw_query_criteria_filter_op_id_contains)
1590 if (value->inf != entry_value->inf) {
1615 &list_for_single_internal,
1618 list = (
afw_list_t *)&list_for_single_internal;
1622 switch (entry->op_id) {
1624 case afw_query_criteria_filter_op_id_eq:
1626 for (is_true =
false, iterator = NULL;;) {
1631 if (data_type != entry_data_type) {
1643 case afw_query_criteria_filter_op_id_ne:
1645 for (is_true =
true, iterator = NULL;;) {
1650 if (data_type != entry_data_type) {
1662 case afw_query_criteria_filter_op_id_lt:
1664 for (is_true =
false, iterator = NULL;;) {
1669 if (data_type != entry_data_type) {
1681 case afw_query_criteria_filter_op_id_le:
1683 for (is_true =
false, iterator = NULL;;) {
1688 if (data_type != entry_data_type) {
1700 case afw_query_criteria_filter_op_id_gt:
1702 for (is_true =
false, iterator = NULL;;) {
1707 if (data_type != entry_data_type) {
1719 case afw_query_criteria_filter_op_id_ge:
1721 for (is_true =
false, iterator = NULL;;) {
1726 if (data_type != entry_data_type) {
1738 case afw_query_criteria_filter_op_id_in:
1768 case afw_query_criteria_filter_op_id_match:
1790 case afw_query_criteria_filter_op_id_contains:
1812 "Error occurred processing query filter", xctx);
1875 memset(&parser, 0,
sizeof(parser));
1881 criteria->object_type = object_type;
1882 parser.criteria = criteria;
1885 if (!url_encoded_rql_string ||
1886 url_encoded_rql_string->len == 0 ||
1887 *(url_encoded_rql_string->s) ==
'#')
1893 queryz =
afw_utf8_z_create(url_encoded_rql_string->s, url_encoded_rql_string->len, p, xctx);
1895 url_encoded_rql_string->len, p, xctx);
1896 parser.start = parser.criteria->origin_query_string->s;
1897 parser.c = parser.start;
1899 if (*(parser.c) != 0) {
1904 if (parser.criteria->first_sort) {
1906 "sort() specified multiple times in query string",
1909 parser.c += strlen(
"sort(");
1910 parser.criteria->first_sort = impl_parse_string_sort(&parser);
1915 if (parser.criteria->select) {
1917 "select() specified multiple times in query string",
1920 parser.c += strlen(
"select(");
1921 parser.criteria->select = impl_parse_string_select(&parser);
1938 if (parser.criteria->filter) {
1940 "Filter in query string is malformed", xctx);
1942 impl_parse_string_filter(&parser,
1947 parser.criteria->filter = filter;
1948 parser.criteria->tree = tree;
1955 impl_get_token(&parser);
1956 if (parser.token_type == impl_token_type_end) {
1959 if ((parser.token_type != impl_token_type_delimiter) ||
1960 (*(parser.token.s) !=
'&'))
1963 "query filter is malformed", xctx);
1992 query_object, &afw_s_urlEncodedRQLString, xctx);
1993 if (url_encoded_rql_string) {
1996 for (iterator = NULL;;) {
1998 &iterator, &property_name, xctx);
2002 if (!
afw_utf8_equal(property_name, &afw_s_urlEncodedRQLString)) {
2004 "Property urlEncodedRQLString must be specified alone",
2011 url_encoded_rql_string, object_type, p, xctx);
2016 criteria->query_object = query_object;
2017 criteria->object_type = object_type;
2018 memset(&parser, 0,
sizeof(parser));
2021 parser.criteria = criteria;
2027 property_name = NULL;
2031 &iterator, &property_name, xctx);
2039 impl_AdaptiveQueryCriteria_object_parse_filter(&parser,
2040 filter_object, &criteria->filter, &criteria->tree,
2047 criteria->select = impl_AdaptiveQueryCriteria_object_parse_select(
2054 criteria->first_sort = impl_AdaptiveQueryCriteria_object_parse_sort(
2083 entry = (criteria) ? criteria->filter : NULL;
2087 entry->property_name, xctx);
2104 "Object values are not supported in query string",
2109 is_true = impl_compare_value(entry, value, p, xctx);
2118 entry = entry->on_true;
2128 entry = entry->on_false;
2145 impl_criteria_filter_to_property_value(
2163 if (entry->op_id == afw_query_criteria_filter_op_id_and ||
2164 entry->op_id == afw_query_criteria_filter_op_id_or)
2168 for (e = entry->first_conjunctive_child; e; e = e->next_conjunctive_sibling) {
2169 o = impl_criteria_filter_to_property_value(e, p, xctx);
2177 &afw_s_property, entry->property_name, xctx);
2186 impl_criteria_select_to_property_value(
2201 for (e = select; *e; e++) {
2212 impl_criteria_sort_to_property_value(
2228 for (e = sort_entry; e; e = e->next) {
2230 v->internal.len = e->property_name->len + 1;
2232 *c++ = (e->descending) ?
'-' :
'+';
2233 memcpy(c, e->property_name->s, e->property_name->len);
2265 filter = impl_criteria_filter_to_property_value(
2266 criteria->tree, object->p, xctx);
2269 &afw_s_filter, filter, xctx);
2273 if (criteria->select) {
2274 select = impl_criteria_select_to_property_value(
2275 criteria->select, object->p, xctx);
2277 &afw_s_select, select, xctx);
2281 if (criteria->first_sort) {
2282 sort = impl_criteria_sort_to_property_value(
2283 criteria->first_sort, object->p, xctx);
2285 &afw_s_sort, sort, xctx);
2299 impl_entry_to_query_string(
2326 if (style_function) {
2327 for (child = entry->first_conjunctive_child, first_loop =
true;
2329 child = child->next_conjunctive_sibling)
2332 if (need_ampersand) {
2342 impl_entry_to_query_string(w, child,
2343 style_function, style_long,
2344 style_semi_colon_comma,
false,
true , p, xctx);
2351 need_close_parenthesis =
false;
2353 ? (style_semi_colon_comma ?
";" :
"&")
2354 : (style_semi_colon_comma ?
"," :
"|");
2355 for (child = entry->first_conjunctive_child, first_loop =
true;
2357 child = child->next_conjunctive_sibling)
2361 if (need_ampersand) {
2364 if (inner_conjunction ||
2365 (!inner_conjunction &&
2369 need_close_parenthesis =
true;
2376 impl_entry_to_query_string(w, child,
2377 style_function, style_long,
2378 style_semi_colon_comma,
false,
true, p, xctx);
2382 if (need_close_parenthesis) {
2390 if (need_ampersand) {
2394 rql_op = impl_find_rql_op(entry->op_name);
2395 if (!rql_op || !rql_op->can_be_property) {
2401 AFW_URI_OCTET_UNRESERVED, p, xctx);
2403 if (style_function) {
2407 if (rql_op->op->is_list) {
2409 for (iterator = NULL, first_time =
true;;) {
2459 if (rql_op->op->is_list) {
2461 for (iterator = NULL, first_time =
true;;) {
2511 return &afw_s_a_empty_string;
2515 needs_ampersand =
false;
2519 if (criteria->select) {
2520 for (sa = criteria->select, first_inner =
true; *sa; sa++)
2523 first_inner =
false;
2525 needs_ampersand =
true;
2531 AFW_URI_OCTET_UNRESERVED, p, xctx);
2540 for (se = criteria->first_sort, first_inner =
true; se; se = se->next)
2543 first_inner =
false;
2544 if (needs_ampersand) {
2548 needs_ampersand =
true;
2554 if (se->descending) {
2561 AFW_URI_OCTET_UNRESERVED, p, xctx);
2570 if (criteria->filter) {
2571 style_function =
false;
2573 style_semi_colon_comma =
false;
2576 case afw_query_criteria_style_operator:
2579 case afw_query_criteria_style_operator_long:
2583 case afw_query_criteria_style_semicolon_comma:
2584 style_semi_colon_comma =
true;
2587 case afw_query_criteria_style_function:
2588 style_function =
true;
2595 impl_entry_to_query_string(w, criteria->tree,
2596 style_function, style_long, style_semi_colon_comma,
2597 needs_ampersand,
false, p, xctx);
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
afw_value_create_list(const afw_list_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type list value.
#define afw_value_is_list(A_VALUE)
Macro to determine if value is evaluated list.
#define afw_object_old_get_property_as_list(object, property_name, xctx)
Get property function for data type list value.
afw_value_as_list(const afw_value_t *value, afw_xctx_t *xctx)
Typesafe cast of data type list.
afw_object_set_property_as_list(const afw_object_t *object, const afw_utf8_t *property_name, const afw_list_t *internal, afw_xctx_t *xctx)
Set property function for data type list values.
#define afw_value_is_object(A_VALUE)
Macro to determine if value is evaluated object.
afw_object_set_property_as_object(const afw_object_t *object, const afw_utf8_t *property_name, const afw_object_t *internal, afw_xctx_t *xctx)
Set property function for data type object values.
afw_value_create_object(const afw_object_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type object value.
afw_value_as_object(const afw_value_t *value, afw_xctx_t *xctx)
Typesafe cast of data type object.
afw_value_create_string(const afw_utf8_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type string value.
#define afw_object_old_get_property_as_string(object, property_name, xctx)
Get property function for data type string value.
afw_value_allocate_string(const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for unmanaged data type string value.
afw_data_type_string
Data type struct for string.
afw_object_set_property_as_string(const afw_object_t *object, const afw_utf8_t *property_name, const afw_utf8_t *internal, afw_xctx_t *xctx)
Set property function for data type string values.
afw_value_as_string(const afw_value_t *value, afw_xctx_t *xctx)
Typesafe cast of data type string.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
struct afw_iterator_s afw_iterator_t
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
afw_utf8_octet_t afw_utf8_z_t
NFC normalized UTF-8 null terminated string.
char afw_utf8_octet_t
8 bits of utf-8 codepoint.
struct afw_const_utf8_a_stack_s afw_const_utf8_a_stack_t
#define AFW_SIZE_T_FMT
Format string specifier used for afw_size_t.
#define afw_data_type_compare_internal(instance, internal1, internal2, xctx)
Call method compare_internal of interface afw_data_type.
#define AFW_CATCH_UNHANDLED
Catch an unhandled error that occurs in a AFW_TRY block.
#define AFW_ENDTRY
Ends an AFW try block.
#define AFW_TRY
Begin an AFW TRY block.
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
#define afw_list_get_next_internal(instance, iterator, data_type, internal, xctx)
Call method get_next_internal of interface afw_list.
#define afw_list_get_next_value(instance, iterator, p, xctx)
Call method get_next_value of interface afw_list.
#define afw_list_get_data_type(instance, xctx)
Call method get_data_type of interface afw_list.
#define AFW_LIST_INITIALIZE_WRAPPER_FOR_ARRAY(instance, _internal, _indirect, _data_type, _count)
Helper macro to fill out afw_list_wrapper_for_array_self_t.
afw_list_create_wrapper_for_array(const void *array, afw_boolean_t indirect, const afw_data_type_t *data_type, afw_size_t count, const afw_pool_t *p, afw_xctx_t *xctx)
Create a immutable list wrapper for an array.
#define afw_list_create_generic(p, xctx)
Create an value list in memory.
afw_list_add_value(const afw_list_t *instance, const afw_value_t *value, afw_xctx_t *xctx)
Call method add_value of interface afw_list_setter.
#define afw_memory_copy(to, from)
Copy to preallocated memory of same type.
#define afw_object_get_property(instance, property_name, xctx)
Call method get_property of interface afw_object.
#define afw_object_get_next_property(instance, iterator, property_name, xctx)
Call method get_next_property of interface afw_object.
afw_object_type_property_type_get(const afw_object_type_t *object_type, const afw_utf8_t *property_name, afw_xctx_t *xctx)
Get property type object for property.
afw_object_get_property_extended(const afw_object_t *instance, const afw_utf8_t *property_name_extended, afw_xctx_t *xctx)
Get the value of an object's own property or embedded property.
#define afw_object_create_managed(p, xctx)
Create an empty entity object in its own pool.
#define afw_object_create(p, xctx)
Create an empty unmanaged object in memory.
afw_object_set_property(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_value_t *value, afw_xctx_t *xctx)
Set the value of an object's property.
#define afw_pool_malloc(instance, size, xctx)
Call method malloc of interface afw_pool.
#define afw_pool_get_apr_pool(instance)
Call method get_apr_pool of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
afw_query_criteria_test_object(const afw_object_t *obj, const afw_query_criteria_t *criteria, const afw_pool_t *p, afw_xctx_t *xctx)
Test object against query criteria.
#define AFW_QUERY_CRITERIA_FALSE
afw_query_criteria_to_query_string(const afw_query_criteria_t *criteria, afw_query_criteria_style_t style, const afw_pool_t *p, afw_xctx_t *xctx)
Convert query criteria to query string.
afw_query_criteria_filter_op_id_t
afw_query_criteria_parse_AdaptiveQueryCriteria_object(const afw_object_t *query_object, const afw_object_type_t *object_type, const afw_pool_t *p, afw_xctx_t *xctx)
Parse URI encoded query string.
afw_query_criteria_style_t
Query string style.
afw_query_criteria_to_AdaptiveQueryCriteria_object(const afw_query_criteria_t *criteria, const afw_pool_t *p, afw_xctx_t *xctx)
Convert query criteria to a AdaptiveQueryCriteria object.
afw_query_criteria_parse_url_encoded_rql_string(const afw_utf8_t *url_encoded_rql_string, const afw_object_type_t *object_type, const afw_pool_t *p, afw_xctx_t *xctx)
Parse URI encoded RQL query string.
#define AFW_QUERY_CRITERIA_TRUE
#define afw_stack_copy_and_release(instance, count, ptr, p, xctx)
Copy and release stack.
#define afw_stack_create(typedef_name, initial_count, maximum_count, create_subpool_pool, p, xctx)
Create a stack for the specified typedef.
#define afw_stack_push(instance, xctx)
Increment stack->top to location of next entry and returns *top.
#define AFW_URI_OCTET_ENCODE_COMPONENT_VALUE
encode except A-Z a-z 0-9 - _ . ! ~ * '
afw_uri_decode_create(const afw_utf8_octet_t *s, afw_size_t len, const afw_pool_t *p, afw_xctx_t *xctx)
Create a URI decoded string.
afw_uri_encode(const afw_utf8_t *string, afw_uri_octet_type_t mask, const afw_pool_t *p, afw_xctx_t *xctx)
URI encode a string.
const afw_utf8_t * afw_utf8_concat(const afw_pool_t *p, afw_xctx_t *xctx,...)
Concatenate strings with result in specifed pool.
afw_boolean_t afw_utf8_equal_utf8_z(const afw_utf8_t *s1, const afw_utf8_z_t *s2_z)
Check to see if a string equals a utf8_z string.
void afw_utf8_writer_current_string(const afw_writer_t *writer, afw_utf8_t *current_string, afw_xctx_t *xctx)
Get the current string in a UTF-8 writer.
afw_utf8_z_printf_v(const afw_utf8_z_t *format_z, va_list ap, const afw_pool_t *p, afw_xctx_t *xctx)
afw_boolean_t afw_utf8_equal(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string equals another string.
afw_boolean_t afw_utf8_z_starts_with_z(const afw_utf8_z_t *s1_z, const afw_utf8_z_t *s2_z)
Returns true if zero terminated s1 starts with zero terminated string s2.
afw_utf8_z_create(const afw_utf8_octet_t *s, afw_size_t len, const afw_pool_t *p, afw_xctx_t *xctx)
Create a NFC Normalized zero terminated UTF-8 string in specified pool.
const afw_writer_t * afw_utf8_writer_create(const afw_utf8_t *tab, const afw_pool_t *p, afw_xctx_t *xctx)
Create UTF-8 writer.
const afw_utf8_t * afw_utf8_clone(const afw_utf8_t *string, const afw_pool_t *p, afw_xctx_t *xctx)
Clone a utf-8 string into a specific pool.
const afw_utf8_z_t * afw_utf8_to_utf8_z(const afw_utf8_t *string, const afw_pool_t *p, afw_xctx_t *xctx)
Convert utf8 to utf8_z in specified pool.
#define afw_utf8_create(s, len, p, xctx)
Create utf-8 string without copy unless necessary in pool specified.
#define afw_value_get_data_type(instance, xctx)
Call method get_data_type of interface afw_value.
afw_value_as_utf8(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
#define afw_value_is_defined_and_evaluated(A_VALUE)
Macro to determine if value is defined and evaluated.
afw_value_convert(const afw_value_t *value, const afw_data_type_t *to_data_type, afw_boolean_t required, const afw_pool_t *p, afw_xctx_t *xctx)
Convert a value to a value/data type.
#define afw_writer_release(instance, xctx)
Call method release of interface afw_writer.
#define afw_writer_write_z(writer, s_z, xctx)
Call afw_writer_write() with zero terminated string.
#define afw_writer_write_utf8(writer, S, xctx)
Call afw_writer_write() with a afw_utf8_t string.
Interface afw_data_type public struct.
Interface afw_list public struct.
Self for immutable list wrapper for a array.
Interface afw_object public struct.
Struct for afw_object_type_t.
Interface afw_pool public struct.
Parsed filter entry from query string.
NFC normalized UTF-8 string.
Struct to access internal of all evaluated values.
struct for data type list values.
Interface afw_value public struct.
struct for data type string values.
Interface afw_writer public struct.
Interface afw_xctx public struct.