libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
audiostreamdesc.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
13#include <cstdint>
14#include <functional>
15#include <promeki/namespace.h>
16#include <promeki/datastream.h>
17#include <promeki/logger.h>
18#include <promeki/result.h>
19#include <promeki/string.h>
21
22PROMEKI_NAMESPACE_BEGIN
23
33using AudioStreamDescRegistry = StringRegistry<"AudioStreamDesc">;
34
98class AudioStreamDesc {
99 public:
100 PROMEKI_DATATYPE(AudioStreamDesc, DataTypeAudioStreamDesc, 1)
101
102
108 Error writeToStream(DataStream &s) const;
109
114 template <uint32_t V> static Result<AudioStreamDesc> readFromStream(DataStream &s);
115
117 using ID = uint64_t;
118
129 static constexpr ID Undefined = 0;
130
132 AudioStreamDesc() = default;
133
141 explicit AudioStreamDesc(ID id) : _id(id) {}
142
156 explicit AudioStreamDesc(const String &name) {
157 if (name.isEmpty()) {
158 _id = Undefined;
159 return;
160 }
161 if (containsReservedDelimiter(name)) {
162 promekiWarn("AudioStreamDesc: name '%s' contains "
163 "a reserved delimiter (':' or ','); "
164 "rejected — using Undefined",
165 name.cstr());
166 _id = Undefined;
167 return;
168 }
169 _id = AudioStreamDescRegistry::instance().findOrCreateProbe(name);
170 }
171
173 ID id() const { return _id; }
174
182 String name() const {
183 if (_id == Undefined) return String("Undefined");
184 return AudioStreamDescRegistry::instance().name(_id);
185 }
186
188 bool isUndefined() const { return _id == Undefined; }
189
191 bool isValid() const {
192 if (_id == Undefined) return true; // Undefined is a valid value
193 return !AudioStreamDescRegistry::instance().name(_id).isEmpty();
194 }
195
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; }
200
202 String toString() const { return name(); }
203
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)));
227 }
228
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",
246 name.cstr());
247 return AudioStreamDesc();
248 }
249 ID id = AudioStreamDescRegistry::instance().findId(name);
250 if (id == AudioStreamDescRegistry::InvalidID) return AudioStreamDesc();
251 return AudioStreamDesc(id);
252 }
253
254 private:
255 ID _id = Undefined;
256
258 static bool containsReservedDelimiter(const String &name) {
259 return name.find(':') != String::npos || name.find(',') != String::npos;
260 }
261};
262
263inline Error AudioStreamDesc::writeToStream(DataStream &s) const {
264 s << name();
265 return s.status() == DataStream::Ok ? Error::Ok : s.toError();
266}
267
268template <>
269inline Result<AudioStreamDesc> AudioStreamDesc::readFromStream<1>(DataStream &s) {
270 String name;
271 s >> name;
272 if (s.status() != DataStream::Ok) return makeError<AudioStreamDesc>(s.toError());
273 if (name.isEmpty() || name == "Undefined") return makeResult(AudioStreamDesc());
274 // Re-register the name so cross-process round-trips are
275 // self-consistent — the receiving side may not have seen this
276 // name yet. Names containing reserved delimiters produce
277 // Undefined and a warning (handled by the ctor).
278 return makeResult(AudioStreamDesc(name));
279}
280
281PROMEKI_NAMESPACE_END
282
283PROMEKI_FORMAT_VIA_TOSTRING(promeki::AudioStreamDesc);
284
293template <> struct std::hash<promeki::AudioStreamDesc> {
294 size_t operator()(const promeki::AudioStreamDesc &v) const noexcept {
295 return std::hash<uint64_t>()(v.id());
296 }
297};
298
299#endif // PROMEKI_ENABLE_PROAV