11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
22PROMEKI_NAMESPACE_BEGIN
33using AudioStreamDescRegistry = StringRegistry<
"AudioStreamDesc">;
98class AudioStreamDesc {
100 PROMEKI_DATATYPE(AudioStreamDesc, DataTypeAudioStreamDesc, 1)
108 Error writeToStream(DataStream &s) const;
114 template <uint32_t V> static Result<AudioStreamDesc> readFromStream(DataStream &s);
129 static constexpr ID Undefined = 0;
132 AudioStreamDesc() = default;
141 explicit AudioStreamDesc(ID
id) : _id(
id) {}
156 explicit AudioStreamDesc(
const String &name) {
157 if (name.isEmpty()) {
161 if (containsReservedDelimiter(name)) {
162 promekiWarn(
"AudioStreamDesc: name '%s' contains "
163 "a reserved delimiter (':' or ','); "
164 "rejected — using Undefined",
169 _id = AudioStreamDescRegistry::instance().findOrCreateProbe(name);
173 ID id()
const {
return _id; }
182 String name()
const {
183 if (_id == Undefined)
return String(
"Undefined");
184 return AudioStreamDescRegistry::instance().name(_id);
188 bool isUndefined()
const {
return _id == Undefined; }
191 bool isValid()
const {
192 if (_id == Undefined)
return true;
193 return !AudioStreamDescRegistry::instance().name(_id).isEmpty();
197 bool operator==(
const AudioStreamDesc &o)
const {
return _id == o._id; }
198 bool operator!=(
const AudioStreamDesc &o)
const {
return _id != o._id; }
199 bool operator<(
const AudioStreamDesc &o)
const {
return _id < o._id; }
202 String toString()
const {
return name(); }
223 static Result<AudioStreamDesc> fromString(
const String &name) {
224 if (name.isEmpty() || name ==
"Undefined")
return makeResult(AudioStreamDesc());
225 if (containsReservedDelimiter(name))
return makeError<AudioStreamDesc>(Error::Invalid);
226 return makeResult(AudioStreamDesc(AudioStreamDescRegistry::instance().findOrCreateProbe(name)));
240 static AudioStreamDesc lookup(
const String &name) {
241 if (name.isEmpty() || name ==
"Undefined")
return AudioStreamDesc();
242 if (containsReservedDelimiter(name)) {
243 promekiWarn(
"AudioStreamDesc::lookup: name '%s' "
244 "contains a reserved delimiter (':' "
245 "or ','); rejected — returning Undefined",
247 return AudioStreamDesc();
249 ID
id = AudioStreamDescRegistry::instance().findId(name);
250 if (
id == AudioStreamDescRegistry::InvalidID)
return AudioStreamDesc();
251 return AudioStreamDesc(
id);
258 static bool containsReservedDelimiter(
const String &name) {
259 return name.find(
':') != String::npos || name.find(
',') != String::npos;
263inline Error AudioStreamDesc::writeToStream(DataStream &s)
const {
265 return s.status() == DataStream::Ok ? Error::Ok : s.toError();
269inline Result<AudioStreamDesc> AudioStreamDesc::readFromStream<1>(DataStream &s) {
272 if (s.status() != DataStream::Ok)
return makeError<AudioStreamDesc>(s.toError());
273 if (name.isEmpty() || name ==
"Undefined")
return makeResult(AudioStreamDesc());
278 return makeResult(AudioStreamDesc(name));
283PROMEKI_FORMAT_VIA_TOSTRING(promeki::AudioStreamDesc);
293template <>
struct std::hash<promeki::AudioStreamDesc> {
294 size_t operator()(
const promeki::AudioStreamDesc &v)
const noexcept {
295 return std::hash<uint64_t>()(v.id());