Skip to content

Commit

Permalink
playlist: added search support for multivalue fields; fixed thread sa…
Browse files Browse the repository at this point in the history
…fety issue; added tests
  • Loading branch information
Oleksiy-Yakovenko committed Oct 24, 2018
1 parent 3b08a64 commit d3fc2fd
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 52 deletions.
62 changes: 62 additions & 0 deletions osx/Tests/PlaylistTest.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// PlaylistTest.m
// Tests
//
// Created by Oleksiy Yakovenko on 24/10/2018.
// Copyright © 2018 Alexey Yakovenko. All rights reserved.
//

#import <XCTest/XCTest.h>
#include "deadbeef.h"
#include "../../common.h"
#include "playlist.h"

@interface PlaylistTest : XCTestCase

@end

@implementation PlaylistTest

- (void)setUp {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

- (void)test_SearchForValueInSingleValueItems_FindsTheItem {
playlist_t *plt = plt_alloc("test");
playItem_t *it = pl_item_alloc();

plt_insert_item(plt, NULL, it);

pl_add_meta(it, "title", "value");

plt_search_process(plt, "value");

XCTAssertTrue(plt->head[PL_SEARCH] != NULL);
XCTAssertTrue(plt->head[PL_MAIN]->selected);

plt_unref (plt);
}


- (void)test_SearchFor2ndValueInMultiValueItems_FindsTheItem {
playlist_t *plt = plt_alloc("test");
playItem_t *it = pl_item_alloc();

plt_insert_item(plt, NULL, it);

const char values[] = "value1\0value2\0";
pl_add_meta_full(it, "title", values, sizeof(values));

plt_search_process(plt, "value2");

XCTAssertTrue(plt->head[PL_SEARCH] != NULL);
XCTAssertTrue(plt->head[PL_MAIN]->selected);

plt_unref (plt);
}

@end
16 changes: 10 additions & 6 deletions osx/deadbeef.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1712,15 +1712,15 @@
4D6CF18D20EB788A00811034 /* MP3Decoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D6CF18C20EB788A00811034 /* MP3Decoder.m */; };
4D6CF18E20EB7A9900811034 /* mp3parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D8FEDCE20EA54D4008EB080 /* mp3parser.c */; };
4D877B36183BBF1F008A114B /* btnplayTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4D877B35183BBF1F008A114B /* btnplayTemplate.pdf */; };
4D8FEDCF20EA54D4008EB080 /* mp3parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D8FEDC020EA54D3008EB080 /* mp3parser.h */; };
4D8FEDD020EA54D4008EB080 /* mp3parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D8FEDCE20EA54D4008EB080 /* mp3parser.c */; };
4D90AAFF20EA5CA500D13537 /* DDBTestInitializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D90AAFE20EA5CA500D13537 /* DDBTestInitializer.m */; };
4D9272C521414BA900E7B4D0 /* PresetManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D9272C421414BA900E7B4D0 /* PresetManagerTest.swift */; };
4D9272C621414BF400E7B4D0 /* PresetManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13B5192140154900CA7AE4 /* PresetManager.swift */; };
4D9272C721414BF400E7B4D0 /* DSPPresetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D9272B521411B6600E7B4D0 /* DSPPresetController.swift */; };
4D9272C821414BF500E7B4D0 /* PresetManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13B5192140154900CA7AE4 /* PresetManager.swift */; };
4D9272C921414BF500E7B4D0 /* DSPPresetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D9272B521411B6600E7B4D0 /* DSPPresetController.swift */; };
4D9272D0214156E300E7B4D0 /* PresetManagerData in Resources */ = {isa = PBXBuildFile; fileRef = 4D9272CF214156E300E7B4D0 /* PresetManagerData */; };
4D8FEDCF20EA54D4008EB080 /* mp3parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D8FEDC020EA54D3008EB080 /* mp3parser.h */; };
4D8FEDD020EA54D4008EB080 /* mp3parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D8FEDCE20EA54D4008EB080 /* mp3parser.c */; };
4D90AAFF20EA5CA500D13537 /* DDBTestInitializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D90AAFE20EA5CA500D13537 /* DDBTestInitializer.m */; };
4D9BF4001FE134200032B6CF /* libopusfile.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 4D9C629E1FDEC51000D83CEF /* libopusfile.dylib */; };
4D9C5B0E1FDEBAFC00D83CEF /* opus.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 4D9C5AEF1FDEBAAE00D83CEF /* opus.dylib */; };
4D9C5B0F1FDEBAFC00D83CEF /* libopuslib.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 4D9C5B051FDEBACC00D83CEF /* libopuslib.dylib */; };
Expand Down Expand Up @@ -1956,6 +1956,7 @@
4DA72BEC1838EAAB00A98C62 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4DA72BE51838EAAB00A98C62 /* Images.xcassets */; };
4DA72BED1838EAAB00A98C62 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DA72BE61838EAAB00A98C62 /* main.m */; };
4DAF343F19B75FF500EE96ED /* ddb_dumb.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 4D44E66E19B7530A00F780FC /* ddb_dumb.dylib */; };
4DC416FE2180919D0056133E /* PlaylistTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DC416FD2180919D0056133E /* PlaylistTest.m */; };
4DC96E701E4CC9670093CFD3 /* dsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DC96E6E1E4CC9670093CFD3 /* dsp.h */; };
4DE28473205BE0B20023063E /* HelpViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4DE28470205BE0B20023063E /* HelpViewer.xib */; };
8374A47E1B8946A800C6A572 /* ChipMapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 8374A3671B8946A800C6A572 /* ChipMapper.c */; };
Expand Down Expand Up @@ -4479,13 +4480,13 @@
4D6CF17D20EB783900811034 /* MP3ParserTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MP3ParserTest.m; sourceTree = "<group>"; };
4D6CF18C20EB788A00811034 /* MP3Decoder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MP3Decoder.m; sourceTree = "<group>"; };
4D877B35183BBF1F008A114B /* btnplayTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = btnplayTemplate.pdf; path = images/btnplayTemplate.pdf; sourceTree = "<group>"; };
4D9272B521411B6600E7B4D0 /* DSPPresetController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DSPPresetController.swift; path = PresetManager/DSPPresetController.swift; sourceTree = "<group>"; };
4D9272C421414BA900E7B4D0 /* PresetManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresetManagerTest.swift; sourceTree = "<group>"; };
4D9272CF214156E300E7B4D0 /* PresetManagerData */ = {isa = PBXFileReference; lastKnownFileType = folder; path = PresetManagerData; sourceTree = "<group>"; };
4D8FEDC020EA54D3008EB080 /* mp3parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mp3parser.h; path = plugins/mp3/mp3parser.h; sourceTree = "<group>"; };
4D8FEDCE20EA54D4008EB080 /* mp3parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mp3parser.c; path = plugins/mp3/mp3parser.c; sourceTree = "<group>"; };
4D90AAF020EA5CA400D13537 /* DDBTestInitializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDBTestInitializer.h; sourceTree = "<group>"; };
4D90AAFE20EA5CA500D13537 /* DDBTestInitializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDBTestInitializer.m; sourceTree = "<group>"; };
4D9272B521411B6600E7B4D0 /* DSPPresetController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DSPPresetController.swift; path = PresetManager/DSPPresetController.swift; sourceTree = "<group>"; };
4D9272C421414BA900E7B4D0 /* PresetManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresetManagerTest.swift; sourceTree = "<group>"; };
4D9272CF214156E300E7B4D0 /* PresetManagerData */ = {isa = PBXFileReference; lastKnownFileType = folder; path = PresetManagerData; sourceTree = "<group>"; };
4D9C5AEF1FDEBAAE00D83CEF /* opus.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = opus.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
4D9C5B051FDEBACC00D83CEF /* libopuslib.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libopuslib.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
4D9C60281FDEBCF500D83CEF /* opus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opus.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4715,6 +4716,7 @@
4DA72BDF1838EAAB00A98C62 /* deadbeef-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "deadbeef-Prefix.pch"; sourceTree = "<group>"; };
4DA72BE51838EAAB00A98C62 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
4DA72BE61838EAAB00A98C62 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
4DC416FD2180919D0056133E /* PlaylistTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlaylistTest.m; sourceTree = "<group>"; };
4DC96E6D1E4CC9670093CFD3 /* dsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsp.c; sourceTree = "<group>"; };
4DC96E6E1E4CC9670093CFD3 /* dsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsp.h; sourceTree = "<group>"; };
4DE28470205BE0B20023063E /* HelpViewer.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HelpViewer.xib; sourceTree = "<group>"; };
Expand Down Expand Up @@ -7245,6 +7247,7 @@
4D0B0CED20162D95004162DA /* FormatConversion.m */,
4D9272C421414BA900E7B4D0 /* PresetManagerTest.swift */,
4D6CF18C20EB788A00811034 /* MP3Decoder.m */,
4DC416FD2180919D0056133E /* PlaylistTest.m */,
);
path = Tests;
sourceTree = "<group>";
Expand Down Expand Up @@ -12417,6 +12420,7 @@
2D7F38031B2858AC00692A7B /* Junklib.m in Sources */,
4D9272C821414BF500E7B4D0 /* PresetManager.swift in Sources */,
4D0B0CEE20162D95004162DA /* FormatConversion.m in Sources */,
4DC416FE2180919D0056133E /* PlaylistTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
91 changes: 45 additions & 46 deletions playlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -3269,7 +3269,23 @@ plt_search_reset (playlist_t *playlist) {
plt_search_reset_int (playlist, 1);
}

// FIXME: multivalue support
static void
_plsearch_append (playlist_t *plt, playItem_t *it, int select_results) {
it->next[PL_SEARCH] = NULL;
it->prev[PL_SEARCH] = plt->tail[PL_SEARCH];
if (plt->tail[PL_SEARCH]) {
plt->tail[PL_SEARCH]->next[PL_SEARCH] = it;
plt->tail[PL_SEARCH] = it;
}
else {
plt->head[PL_SEARCH] = plt->tail[PL_SEARCH] = it;
}
if (select_results) {
pl_set_selected_in_playlist(plt, it, 1);
}
plt->count[PL_SEARCH]++;
}

void
plt_search_process2 (playlist_t *playlist, const char *text, int select_results) {
LOCK;
Expand Down Expand Up @@ -3297,10 +3313,9 @@ plt_search_process2 (playlist_t *playlist, const char *text, int select_results)

int lc_is_valid_u8 = u8_valid (lc, (int)strlen (lc), NULL);

static int cmpidx = 0;
cmpidx++;
if (cmpidx > 127) {
cmpidx = 1;
playlist->search_cmpidx++;
if (playlist->search_cmpidx > 127) {
playlist->search_cmpidx = 1;
}

for (playItem_t *it = playlist->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
Expand All @@ -3314,7 +3329,13 @@ plt_search_process2 (playlist_t *playlist, const char *text, int select_results)
if ((m->key[0] == ':' && !is_uri) || m->key[0] == '_' || m->key[0] == '!') {
break;
}
if (!strcasecmp(m->key, "cuesheet") || !strcasecmp (m->key, "log")) {
continue;
}

const char *value = m->value;
const char *end = value + m->valuesize;

if (is_uri) {
value = strrchr (value, '/');
if (value) {
Expand All @@ -3324,49 +3345,27 @@ plt_search_process2 (playlist_t *playlist, const char *text, int select_results)
value = m->value;
}
}
if (strcasecmp(m->key, "cuesheet") && strcasecmp (m->key, "log")) {
char cmp = *(m->value-1);

if (abs (cmp) == cmpidx) {
if (cmp > 0) {
it->next[PL_SEARCH] = NULL;
it->prev[PL_SEARCH] = playlist->tail[PL_SEARCH];
if (playlist->tail[PL_SEARCH]) {
playlist->tail[PL_SEARCH]->next[PL_SEARCH] = it;
playlist->tail[PL_SEARCH] = it;
}
else {
playlist->head[PL_SEARCH] = playlist->tail[PL_SEARCH] = it;
}
if (select_results) {
pl_set_selected_in_playlist(playlist, it, 1);
}
playlist->count[PL_SEARCH]++;
break;
}
}
else if (lc_is_valid_u8 && u8_valid(value, (int)strlen(value), NULL) && utfcasestr_fast (value, lc)) {
//fprintf (stderr, "%s -> %s match (%s.%s)\n", text, value, pl_find_meta_raw (it, ":URI"), m->key);
// add to list
it->next[PL_SEARCH] = NULL;
it->prev[PL_SEARCH] = playlist->tail[PL_SEARCH];
if (playlist->tail[PL_SEARCH]) {
playlist->tail[PL_SEARCH]->next[PL_SEARCH] = it;
playlist->tail[PL_SEARCH] = it;
}
else {
playlist->head[PL_SEARCH] = playlist->tail[PL_SEARCH] = it;
}
if (select_results) {
pl_set_selected_in_playlist(playlist, it, 1);
}
playlist->count[PL_SEARCH]++;
*((char *)m->value-1) = cmpidx;

char cmp = *(m->value-1);

if (abs (cmp) == playlist->search_cmpidx) { // string was already compared in this search
if (cmp > 0) { // it's a match -- append to search results
_plsearch_append (playlist, it, select_results);
break;
}
else {
*((char *)m->value-1) = -cmpidx;
}
}
else {
int match = -playlist->search_cmpidx; // assume no match
do {
int len = (int)strlen(value);
if (lc_is_valid_u8 && u8_valid(value, len, NULL) && utfcasestr_fast (value, lc)) {
_plsearch_append (playlist, it, select_results);
match = playlist->search_cmpidx; // it's a match
break;
}
value += len+1;
} while (value < end);
*((char *)m->value-1) = match;
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions playlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ typedef struct playlist_s {

int64_t cue_numsamples;
int cue_samplerate;

int search_cmpidx;

unsigned fast_mode : 1;
unsigned files_adding : 1;
Expand Down

0 comments on commit d3fc2fd

Please sign in to comment.