* Move SearchCriteria parsing to its own function.
This commit is contained in:
297
upnpsoap.c
297
upnpsoap.c
@@ -1333,6 +1333,254 @@ browse_error:
|
||||
free(str.data);
|
||||
}
|
||||
|
||||
inline void
|
||||
charcat(struct string_s *str, char c)
|
||||
{
|
||||
if (str->size <= str->off)
|
||||
{
|
||||
str->data[str->size-1] = '\0';
|
||||
return;
|
||||
}
|
||||
str->data[str->off] = c;
|
||||
str->off += 1;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
parse_search_criteria(const char *str)
|
||||
{
|
||||
struct string_s criteria;
|
||||
int len;
|
||||
int literal = 0, like = 0;
|
||||
const char *s;
|
||||
|
||||
if (!str)
|
||||
return strdup("1 = 1");
|
||||
|
||||
len = strlen(str) + 32;
|
||||
criteria.data = malloc(len);
|
||||
criteria.size = len;
|
||||
criteria.off = 0;
|
||||
|
||||
s = str;
|
||||
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
if (literal)
|
||||
{
|
||||
switch (*s) {
|
||||
case '&':
|
||||
if (strncmp(s, """, 6) == 0)
|
||||
s += 5;
|
||||
else if (strncmp(s, "'", 6) == 0)
|
||||
{
|
||||
strcatf(&criteria, "'");
|
||||
s += 6;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
case '"':
|
||||
literal = 0;
|
||||
if (like)
|
||||
{
|
||||
charcat(&criteria, '%');
|
||||
like--;
|
||||
}
|
||||
charcat(&criteria, '"');
|
||||
break;
|
||||
case '\\':
|
||||
if (strncmp(s, "\\"", 7) == 0)
|
||||
{
|
||||
strcatf(&criteria, "&quot;");
|
||||
s += 7;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
if (strncmp(s, "object.", 7) == 0)
|
||||
s += 7;
|
||||
default:
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (*s) {
|
||||
case '\\':
|
||||
if (strncmp(s, "\\"", 7) == 0)
|
||||
{
|
||||
strcatf(&criteria, "&quot;");
|
||||
s += 7;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
case '"':
|
||||
literal = 1;
|
||||
charcat(&criteria, *s);
|
||||
if (like == 2)
|
||||
{
|
||||
charcat(&criteria, '%');
|
||||
like--;
|
||||
}
|
||||
break;
|
||||
case '&':
|
||||
if (strncmp(s, """, 6) == 0)
|
||||
{
|
||||
literal = 1;
|
||||
strcatf(&criteria, "\"");
|
||||
if (like == 2)
|
||||
{
|
||||
charcat(&criteria, '%');
|
||||
like--;
|
||||
}
|
||||
s += 5;
|
||||
}
|
||||
else if (strncmp(s, "'", 6) == 0)
|
||||
{
|
||||
strcatf(&criteria, "'");
|
||||
s += 5;
|
||||
}
|
||||
else if (strncmp(s, "<", 4) == 0)
|
||||
{
|
||||
strcatf(&criteria, "<");
|
||||
s += 3;
|
||||
}
|
||||
else if (strncmp(s, ">", 4) == 0)
|
||||
{
|
||||
strcatf(&criteria, ">");
|
||||
s += 3;
|
||||
}
|
||||
else
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
case '@':
|
||||
if (strncmp(s, "@refID", 6) == 0)
|
||||
{
|
||||
strcatf(&criteria, "REF_ID");
|
||||
s += 6;
|
||||
continue;
|
||||
}
|
||||
else if (strncmp(s, "@id", 3) == 0)
|
||||
{
|
||||
strcatf(&criteria, "OBJECT_ID");
|
||||
s += 3;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
case 'c':
|
||||
if (strncmp(s, "contains", 8) == 0)
|
||||
{
|
||||
strcatf(&criteria, "like");
|
||||
s += 8;
|
||||
like = 2;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
case 'd':
|
||||
if (strncmp(s, "derivedfrom", 11) == 0)
|
||||
{
|
||||
strcatf(&criteria, "like");
|
||||
s += 11;
|
||||
like = 1;
|
||||
continue;
|
||||
}
|
||||
else if (strncmp(s, "dc:date", 7) == 0)
|
||||
{
|
||||
strcatf(&criteria, "d.DATE");
|
||||
s += 7;
|
||||
continue;
|
||||
}
|
||||
else if (strncmp(s, "dc:title", 8) == 0)
|
||||
{
|
||||
strcatf(&criteria, "d.TITLE");
|
||||
s += 8;
|
||||
continue;
|
||||
}
|
||||
else if (strncmp(s, "dc:creator", 10) == 0)
|
||||
{
|
||||
strcatf(&criteria, "d.CREATOR");
|
||||
s += 10;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
case 'e':
|
||||
if (strncmp(s, "exists", 6) == 0)
|
||||
{
|
||||
s += 6;
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
if (strncmp(s, "true", 4) == 0)
|
||||
{
|
||||
strcatf(&criteria, "is not NULL");
|
||||
s += 3;
|
||||
}
|
||||
else if (strncmp(s, "false", 5) == 0)
|
||||
{
|
||||
strcatf(&criteria, "is NULL");
|
||||
s += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
case 'u':
|
||||
if (strncmp(s, "upnp:class", 10) == 0)
|
||||
{
|
||||
strcatf(&criteria, "o.CLASS");
|
||||
s += 10;
|
||||
continue;
|
||||
}
|
||||
else if (strncmp(s, "upnp:actor", 10) == 0)
|
||||
{
|
||||
strcatf(&criteria, "d.ARTIST");
|
||||
s += 10;
|
||||
continue;
|
||||
}
|
||||
else if (strncmp(s, "upnp:artist", 11) == 0)
|
||||
{
|
||||
strcatf(&criteria, "d.ARTIST");
|
||||
s += 11;
|
||||
continue;
|
||||
}
|
||||
else if (strncmp(s, "upnp:album", 10) == 0)
|
||||
{
|
||||
strcatf(&criteria, "d.ALBUM");
|
||||
s += 10;
|
||||
continue;
|
||||
}
|
||||
else if (strncmp(s, "upnp:genre", 10) == 0)
|
||||
{
|
||||
strcatf(&criteria, "d.GENRE");
|
||||
s += 10;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
default:
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
s++;
|
||||
}
|
||||
charcat(&criteria, '\0');
|
||||
|
||||
return criteria.data;
|
||||
}
|
||||
|
||||
static void
|
||||
SearchContentDirectory(struct upnphttp * h, const char * action)
|
||||
{
|
||||
@@ -1349,7 +1597,7 @@ SearchContentDirectory(struct upnphttp * h, const char * action)
|
||||
int totalMatches;
|
||||
int ret;
|
||||
char *ContainerID, *Filter, *SearchCriteria, *SortCriteria;
|
||||
char *newSearchCriteria = NULL, *orderBy = NULL;
|
||||
char *orderBy = NULL;
|
||||
char groupBy[] = "group by DETAIL_ID";
|
||||
struct NameValueParserData data;
|
||||
int RequestedCount = 0;
|
||||
@@ -1426,49 +1674,8 @@ SearchContentDirectory(struct upnphttp * h, const char * action)
|
||||
*ContainerID = '*';
|
||||
else if( strcmp(ContainerID, MUSIC_ALL_ID) == 0 )
|
||||
groupBy[0] = '\0';
|
||||
if( !SearchCriteria )
|
||||
{
|
||||
newSearchCriteria = strdup("1 = 1");
|
||||
SearchCriteria = newSearchCriteria;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchCriteria = modifyString(SearchCriteria, """, "\"", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "'", "'", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "<", "<", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, ">", ">", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "object.", "", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "derivedfrom", "like", 1);
|
||||
SearchCriteria = modifyString(SearchCriteria, "contains", "like", 2);
|
||||
SearchCriteria = modifyString(SearchCriteria, "dc:date", "d.DATE", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "dc:title", "d.TITLE", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "dc:creator", "d.CREATOR", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "upnp:class", "o.CLASS", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "upnp:actor", "d.ARTIST", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "upnp:artist", "d.ARTIST", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "upnp:album", "d.ALBUM", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "upnp:genre", "d.GENRE", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "exists true", "is not NULL", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "exists false", "is NULL", 0);
|
||||
SearchCriteria = modifyString(SearchCriteria, "@refID", "REF_ID", 0);
|
||||
if( strstr(SearchCriteria, "@id") )
|
||||
{
|
||||
newSearchCriteria = strdup(SearchCriteria);
|
||||
SearchCriteria = newSearchCriteria = modifyString(newSearchCriteria, "@id", "OBJECT_ID", 0);
|
||||
}
|
||||
if( strstr(SearchCriteria, "res is ") )
|
||||
{
|
||||
if( !newSearchCriteria )
|
||||
newSearchCriteria = strdup(SearchCriteria);
|
||||
SearchCriteria = newSearchCriteria = modifyString(newSearchCriteria, "res is ", "MIME is ", 0);
|
||||
}
|
||||
if( strstr(SearchCriteria, "\\\"") )
|
||||
{
|
||||
if( !newSearchCriteria )
|
||||
newSearchCriteria = strdup(SearchCriteria);
|
||||
SearchCriteria = newSearchCriteria = modifyString(newSearchCriteria, "\\\"", "&quot;", 0);
|
||||
}
|
||||
}
|
||||
|
||||
SearchCriteria = parse_search_criteria(SearchCriteria);
|
||||
DPRINTF(E_DEBUG, L_HTTP, "Translated SearchCriteria: %s\n", SearchCriteria);
|
||||
|
||||
totalMatches = sql_get_int_field(db, "SELECT (select count(distinct DETAIL_ID)"
|
||||
@@ -1538,7 +1745,7 @@ search_error:
|
||||
if( args.flags & FLAG_FREE_OBJECT_ID )
|
||||
sqlite3_free(ContainerID);
|
||||
free(orderBy);
|
||||
free(newSearchCriteria);
|
||||
free(SearchCriteria);
|
||||
free(str.data);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user