File: streaminfo.cpp

package info (click to toggle)
liblsl 1.16.2b1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 1,724 kB
  • sloc: cpp: 12,515; ansic: 666; python: 28; sh: 25; makefile: 18
file content (90 lines) | stat: -rw-r--r-- 2,871 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "../src/api_config.h"
#include "../src/stream_info_impl.h"
#include <cctype>
#include <loguru.hpp>
// include loguru before catch
#include <catch2/catch.hpp>

// clazy:excludeall=non-pod-global-static

template<typename T, const std::size_t N>
bool contains(const T(&valid)[N], const T target) {
	for(T e: valid)
		if(e==target) return true;
	return false;
}

TEST_CASE("uid", "[basic][streaminfo]") {
	lsl::stream_info_impl info;
	const std::string uid = info.reset_uid();
	INFO(uid)
	REQUIRE(uid.length() == 36);
	for(auto i=0u; i<uid.size(); ++i)
		if(i==8||i==13||i==18||i==23) REQUIRE(uid[i] == '-');
		else REQUIRE(std::isxdigit(uid[i]));
	const char version = uid[14];
	REQUIRE(contains("1345", version));

	const char variant = uid[19];
	REQUIRE(contains("89abAB", variant));
	REQUIRE(uid != info.reset_uid());
}

TEST_CASE("streaminfo matching via XPath", "[basic][streaminfo][xml]") {
	lsl::stream_info_impl info(
		"streamname", "streamtype", 8, 500, lsl_channel_format_t::cft_string, "sourceid");
	auto channels = info.desc().append_child("channels");
	for (int i = 0; i < 4; ++i)
		channels.append_child("channel")
			.append_child("type")
			.append_child(pugi::node_pcdata)
			.set_value("EEG");
	for (int i = 0; i < 4; ++i)
		channels.append_child("channel")
			.append_child("type")
			.append_child(pugi::node_pcdata)
			.set_value("EOG");

	INFO(info.to_fullinfo_message());
	REQUIRE(info.matches_query("name='streamname'"));
	REQUIRE(info.matches_query("name='streamname' and type='streamtype'"));
	REQUIRE(info.matches_query("channel_count > 5"));
	REQUIRE(info.matches_query("nominal_srate >= 499"));
	REQUIRE(info.matches_query("count(desc/channels/channel[type='EEG'])>3"));

	LOG_F(INFO, "The following warning is harmless and expected");
	REQUIRE(!info.matches_query("in'va'lid"));
	REQUIRE(!info.matches_query("name='othername'"));

#ifdef CATCH_CONFIG_ENABLE_BENCHMARKING
	// Append lots of dummy channels for performance tests
	for (int i = 0; i < 50000; ++i)
		channels.append_child("chn")
			.append_child("type")
			.append_child(pugi::node_pcdata)
			.set_value("foobar");
	for (int i = 0; i < 2000; ++i) {
		channels = channels.append_child("chn");
		channels.append_child(pugi::node_pcdata).set_value("1");
	}

	BENCHMARK("trivial query") {
		return info.matches_query("name='streamname' and type='streamtype'", true);
	};
	BENCHMARK("complicated query") {
		return info.matches_query("count(desc/channels/channel[type='EEG'])>3", true);
	};
	BENCHMARK("Cached query") {
		return info.matches_query("count(desc/channels/channel[type='EEG'])>3", false);
	};

	// test how well the cache copes with lots of different queries
	BENCHMARK("partially cached queries (x1000)") {
		int matches = 0;
		for (int j = 0; j < 1000; ++j)
			matches += info.matches_query(("0<=" + std::to_string(j)).c_str());
		return matches;
	};

#endif
}